mirror of
https://github.com/crash-utility/crash
synced 2024-12-14 13:14:31 +00:00
f64b1a5954
Since this required a large number of patches to be applied to architecture-neutral files in the gdb-7.6 tree, the changes are only applied if the host build system is a ppc64le. (ptesarik@suse.cz, normand@linux.vnet.ibm.com)
4951 lines
171 KiB
Diff
4951 lines
171 KiB
Diff
|
||
#
|
||
# gdb-7.6-ppc64_sysv_abi_push_float.patch
|
||
#
|
||
|
||
From: Tiago Daitx <tdaitx@sourceware.org>
|
||
Date: Mon Apr 1 04:05:35 2013 +0000
|
||
Git-commit: d81e75c0756f21d2c3d45ce86d8b45c65f01ef67
|
||
References: ppc64le enablement
|
||
|
||
gdb/ChangeLog
|
||
2013-03-01 Tiago Stürmer Daitx <tdaitx@linux.vnet.ibm.com>
|
||
|
||
* ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function.
|
||
(ppc64_sysv_abi_push_dummy_call): Handle complex arguments.
|
||
|
||
Acked-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
gdb/ChangeLog | 5 +
|
||
gdb/ppc-sysv-tdep.c | 196 +++++++++++++++++++++++++++++++++-------------------
|
||
2 files changed, 131 insertions(+), 70 deletions(-)
|
||
|
||
--- a/gdb/ChangeLog
|
||
+++ b/gdb/ChangeLog
|
||
@@ -1,3 +1,8 @@
|
||
+2013-03-31 Tiago Stürmer Daitx <tdaitx@linux.vnet.ibm.com>
|
||
+
|
||
+ * ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function.
|
||
+ (ppc64_sysv_abi_push_dummy_call): Handle complex arguments.
|
||
+
|
||
2013-04-26 Joel Brobecker <brobecker@adacore.com>
|
||
|
||
* NEWS: Change "since GDB 7.5" into "in GDB 7.6".
|
||
--- a/gdb/ppc-sysv-tdep.c
|
||
+++ b/gdb/ppc-sysv-tdep.c
|
||
@@ -1101,6 +1101,83 @@ convert_code_addr_to_desc_addr (CORE_ADD
|
||
return 1;
|
||
}
|
||
|
||
+/* Push a float in either registers, or in the stack. Using the ppc 64 bit
|
||
+ SysV ABI.
|
||
+
|
||
+ This implements a dumbed down version of the ABI. It always writes
|
||
+ values to memory, GPR and FPR, even when not necessary. Doing this
|
||
+ greatly simplifies the logic. */
|
||
+
|
||
+static void
|
||
+ppc64_sysv_abi_push_float (struct gdbarch *gdbarch, struct regcache *regcache,
|
||
+ struct gdbarch_tdep *tdep, struct type *type,
|
||
+ const bfd_byte *val, int freg, int greg,
|
||
+ CORE_ADDR gparam)
|
||
+{
|
||
+ gdb_byte regval[MAX_REGISTER_SIZE];
|
||
+ const gdb_byte *p;
|
||
+
|
||
+ if (TYPE_LENGTH (type) <= 8)
|
||
+ {
|
||
+ /* Version 1.7 of the 64-bit PowerPC ELF ABI says:
|
||
+
|
||
+ "Single precision floating point values are mapped to
|
||
+ the first word in a single doubleword."
|
||
+
|
||
+ And version 1.9 says:
|
||
+
|
||
+ "Single precision floating point values are mapped to
|
||
+ the second word in a single doubleword."
|
||
+
|
||
+ GDB then writes single precision floating point values
|
||
+ at both words in a doubleword, to support both ABIs. */
|
||
+ if (TYPE_LENGTH (type) == 4)
|
||
+ {
|
||
+ memcpy (regval, val, 4);
|
||
+ memcpy (regval + 4, val, 4);
|
||
+ p = regval;
|
||
+ }
|
||
+ else
|
||
+ p = val;
|
||
+
|
||
+ /* Write value in the stack's parameter save area. */
|
||
+ write_memory (gparam, p, 8);
|
||
+
|
||
+ /* Floats and Doubles go in f1 .. f13. They also consume a left aligned
|
||
+ GREG, and can end up in memory. */
|
||
+ if (freg <= 13)
|
||
+ {
|
||
+ struct type *regtype;
|
||
+
|
||
+ regtype = register_type (gdbarch, tdep->ppc_fp0_regnum + freg);
|
||
+ convert_typed_floating (val, type, regval, regtype);
|
||
+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval);
|
||
+ }
|
||
+ if (greg <= 10)
|
||
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* IBM long double stored in two doublewords of the
|
||
+ parameter save area and corresponding registers. */
|
||
+ if (!tdep->soft_float && freg <= 13)
|
||
+ {
|
||
+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, val);
|
||
+ if (freg <= 12)
|
||
+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg + 1,
|
||
+ val + 8);
|
||
+ }
|
||
+ if (greg <= 10)
|
||
+ {
|
||
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, val);
|
||
+ if (greg <= 9)
|
||
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg + 1,
|
||
+ val + 8);
|
||
+ }
|
||
+ write_memory (gparam, val, TYPE_LENGTH (type));
|
||
+ }
|
||
+}
|
||
+
|
||
/* Pass the arguments in either registers, or in the stack. Using the
|
||
ppc 64 bit SysV ABI.
|
||
|
||
@@ -1218,53 +1295,9 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
|
||
if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8)
|
||
{
|
||
- /* Floats and Doubles go in f1 .. f13. They also
|
||
- consume a left aligned GREG,, and can end up in
|
||
- memory. */
|
||
if (write_pass)
|
||
- {
|
||
- gdb_byte regval[MAX_REGISTER_SIZE];
|
||
- const gdb_byte *p;
|
||
-
|
||
- /* Version 1.7 of the 64-bit PowerPC ELF ABI says:
|
||
-
|
||
- "Single precision floating point values are mapped to
|
||
- the first word in a single doubleword."
|
||
-
|
||
- And version 1.9 says:
|
||
-
|
||
- "Single precision floating point values are mapped to
|
||
- the second word in a single doubleword."
|
||
-
|
||
- GDB then writes single precision floating point values
|
||
- at both words in a doubleword, to support both ABIs. */
|
||
- if (TYPE_LENGTH (type) == 4)
|
||
- {
|
||
- memcpy (regval, val, 4);
|
||
- memcpy (regval + 4, val, 4);
|
||
- p = regval;
|
||
- }
|
||
- else
|
||
- p = val;
|
||
-
|
||
- /* Write value in the stack's parameter save area. */
|
||
- write_memory (gparam, p, 8);
|
||
-
|
||
- if (freg <= 13)
|
||
- {
|
||
- struct type *regtype
|
||
- = register_type (gdbarch, tdep->ppc_fp0_regnum);
|
||
-
|
||
- convert_typed_floating (val, type, regval, regtype);
|
||
- regcache_cooked_write (regcache,
|
||
- tdep->ppc_fp0_regnum + freg,
|
||
- regval);
|
||
- }
|
||
- if (greg <= 10)
|
||
- regcache_cooked_write (regcache,
|
||
- tdep->ppc_gp0_regnum + greg,
|
||
- regval);
|
||
- }
|
||
+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type,
|
||
+ val, freg, greg, gparam);
|
||
|
||
freg++;
|
||
greg++;
|
||
@@ -1276,35 +1309,58 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
&& (gdbarch_long_double_format (gdbarch)
|
||
== floatformats_ibm_long_double))
|
||
{
|
||
- /* IBM long double stored in two doublewords of the
|
||
- parameter save area and corresponding registers. */
|
||
if (write_pass)
|
||
+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type,
|
||
+ val, freg, greg, gparam);
|
||
+ freg += 2;
|
||
+ greg += 2;
|
||
+ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
|
||
+ }
|
||
+ else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX
|
||
+ && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16))
|
||
+ {
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < 2; i++)
|
||
{
|
||
- if (!tdep->soft_float && freg <= 13)
|
||
- {
|
||
- regcache_cooked_write (regcache,
|
||
- tdep->ppc_fp0_regnum + freg,
|
||
- val);
|
||
- if (freg <= 12)
|
||
- regcache_cooked_write (regcache,
|
||
- tdep->ppc_fp0_regnum + freg + 1,
|
||
- val + 8);
|
||
- }
|
||
- if (greg <= 10)
|
||
+ if (write_pass)
|
||
{
|
||
- regcache_cooked_write (regcache,
|
||
- tdep->ppc_gp0_regnum + greg,
|
||
- val);
|
||
- if (greg <= 9)
|
||
- regcache_cooked_write (regcache,
|
||
- tdep->ppc_gp0_regnum + greg + 1,
|
||
- val + 8);
|
||
+ struct type *target_type;
|
||
+
|
||
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
||
+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep,
|
||
+ target_type, val + i *
|
||
+ TYPE_LENGTH (target_type),
|
||
+ freg, greg, gparam);
|
||
}
|
||
- write_memory (gparam, val, TYPE_LENGTH (type));
|
||
+ freg++;
|
||
+ greg++;
|
||
+ /* Always consume parameter stack space. */
|
||
+ gparam = align_up (gparam + 8, tdep->wordsize);
|
||
+ }
|
||
+ }
|
||
+ else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX
|
||
+ && TYPE_LENGTH (type) == 32
|
||
+ && (gdbarch_long_double_format (gdbarch)
|
||
+ == floatformats_ibm_long_double))
|
||
+ {
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < 2; i++)
|
||
+ {
|
||
+ struct type *target_type;
|
||
+
|
||
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
||
+ if (write_pass)
|
||
+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep,
|
||
+ target_type, val + i *
|
||
+ TYPE_LENGTH (target_type),
|
||
+ freg, greg, gparam);
|
||
+ freg += 2;
|
||
+ greg += 2;
|
||
+ gparam = align_up (gparam + TYPE_LENGTH (target_type),
|
||
+ tdep->wordsize);
|
||
}
|
||
- freg += 2;
|
||
- greg += 2;
|
||
- gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
|
||
}
|
||
else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT
|
||
&& TYPE_LENGTH (type) <= 8)
|
||
|
||
|
||
|
||
#
|
||
# gdb-7.6-bound_minimal_symbol.patch
|
||
#
|
||
|
||
From: Tom Tromey <tromey@redhat.com>
|
||
Date: Mon Apr 8 19:59:09 2013 +0000
|
||
Git-commit: 7cbd4a934e9cf3808e1199c62e65b4c25b24b4e5
|
||
References: ppc64le enablement
|
||
|
||
* minsyms.h (struct bound_minimal_symbol): New.
|
||
(lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol.
|
||
Remove objfile argument.
|
||
(lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc):
|
||
Return bound_minimal_symbol.
|
||
* minsyms.c (lookup_minimal_symbol_by_pc_1)
|
||
(lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc):
|
||
Return bound_minimal_symbol.
|
||
(in_gnu_ifunc_stub): Update.
|
||
(lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol.
|
||
Remove 'objfile_p' argument.
|
||
(lookup_solib_trampoline_symbol_by_pc): Update.
|
||
* ada-tasks.c, amd64-windows-tdep.c, arm-tdep.c,
|
||
arm-wince-tdep.c, block.c, blockframe.c, breakpoint.c, btrace.c,
|
||
c-valprint.c, dwarf2loc.c, elfread.c, frame.c, frv-tdep.c,
|
||
glibc-tdep.c, gnu-v2-abi.c, gnu-v3-abi.c, hppa-hpux-tdep.c,
|
||
i386-tdep.c, ia64-tdep.c, infcall.c, infcmd.c, jit.c,
|
||
linux-fork.c, m32c-tdep.c, m68hc11-tdep.c, maint.c,
|
||
mips-tdep.c, p-valprint.c, parse.c, ppc-linux-tdep.c,
|
||
ppc-sysv-tdep.c, printcmd.c, rs6000-tdep.c, sh64-tdep.c,
|
||
stack.c, symtab.c, tui/tui-disasm.c: Update.
|
||
|
||
Acked-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
gdb/ChangeLog | 24 +++++++++++++++++++
|
||
gdb/ada-tasks.c | 6 ++--
|
||
gdb/amd64-windows-tdep.c | 12 +++++----
|
||
gdb/arm-tdep.c | 23 +++++++++---------
|
||
gdb/arm-wince-tdep.c | 14 +++++------
|
||
gdb/block.c | 5 ++--
|
||
gdb/blockframe.c | 8 +++---
|
||
gdb/breakpoint.c | 6 ++--
|
||
gdb/btrace.c | 8 +++---
|
||
gdb/c-valprint.c | 14 +++++------
|
||
gdb/coff-pe-read.c | 19 ++++++---------
|
||
gdb/dwarf2loc.c | 51 ++++++++++++++++++++++++------------------
|
||
gdb/elfread.c | 10 ++++----
|
||
gdb/frame.c | 2 -
|
||
gdb/frv-tdep.c | 8 +++---
|
||
gdb/glibc-tdep.c | 11 ++++-----
|
||
gdb/gnu-v2-abi.c | 6 ++--
|
||
gdb/gnu-v3-abi.c | 4 +--
|
||
gdb/hppa-hpux-tdep.c | 37 +++++++++++++++++-------------
|
||
gdb/i386-tdep.c | 10 ++++----
|
||
gdb/ia64-tdep.c | 4 +--
|
||
gdb/infcall.c | 6 ++--
|
||
gdb/infcmd.c | 6 ++--
|
||
gdb/jit.c | 18 ++++++++------
|
||
gdb/linux-fork.c | 6 ++--
|
||
gdb/m32c-tdep.c | 15 ++++++------
|
||
gdb/m68hc11-tdep.c | 8 +++---
|
||
gdb/maint.c | 10 ++++----
|
||
gdb/minsyms.c | 57 ++++++++++++++++++++++++++++++++---------------
|
||
gdb/minsyms.h | 32 ++++++++++++++++++--------
|
||
gdb/mips-tdep.c | 48 +++++++++++++++++++--------------------
|
||
gdb/p-valprint.c | 13 +++++-----
|
||
gdb/parse.c | 7 +++--
|
||
gdb/ppc-linux-tdep.c | 9 ++++---
|
||
gdb/ppc-sysv-tdep.c | 7 +++--
|
||
gdb/printcmd.c | 5 ++--
|
||
gdb/rs6000-tdep.c | 16 ++++++-------
|
||
gdb/sh64-tdep.c | 6 ++--
|
||
gdb/stack.c | 28 ++++++++++++-----------
|
||
gdb/symtab.c | 23 +++++++++---------
|
||
gdb/tui/tui-disasm.c | 2 -
|
||
41 files changed, 345 insertions(+), 259 deletions(-)
|
||
|
||
--- a/gdb/ChangeLog
|
||
+++ b/gdb/ChangeLog
|
||
@@ -1,3 +1,27 @@
|
||
+2013-04-08 Tom Tromey <tromey@redhat.com>
|
||
+
|
||
+ * minsyms.h (struct bound_minimal_symbol): New.
|
||
+ (lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol.
|
||
+ Remove objfile argument.
|
||
+ (lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc):
|
||
+ Return bound_minimal_symbol.
|
||
+ * minsyms.c (lookup_minimal_symbol_by_pc_1)
|
||
+ (lookup_minimal_symbol_by_pc_section, lookup_minimal_symbol_by_pc):
|
||
+ Return bound_minimal_symbol.
|
||
+ (in_gnu_ifunc_stub): Update.
|
||
+ (lookup_minimal_symbol_and_objfile): Return bound_minimal_symbol.
|
||
+ Remove 'objfile_p' argument.
|
||
+ (lookup_solib_trampoline_symbol_by_pc): Update.
|
||
+ * ada-tasks.c, amd64-windows-tdep.c, arm-tdep.c,
|
||
+ arm-wince-tdep.c, block.c, blockframe.c, breakpoint.c, btrace.c,
|
||
+ c-valprint.c, dwarf2loc.c, elfread.c, frame.c, frv-tdep.c,
|
||
+ glibc-tdep.c, gnu-v2-abi.c, gnu-v3-abi.c, hppa-hpux-tdep.c,
|
||
+ i386-tdep.c, ia64-tdep.c, infcall.c, infcmd.c, jit.c,
|
||
+ linux-fork.c, m32c-tdep.c, m68hc11-tdep.c, maint.c,
|
||
+ mips-tdep.c, p-valprint.c, parse.c, ppc-linux-tdep.c,
|
||
+ ppc-sysv-tdep.c, printcmd.c, rs6000-tdep.c, sh64-tdep.c,
|
||
+ stack.c, symtab.c, tui/tui-disasm.c: Update.
|
||
+
|
||
2013-03-31 Tiago Stürmer Daitx <tdaitx@linux.vnet.ibm.com>
|
||
|
||
* ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function.
|
||
--- a/gdb/ada-tasks.c
|
||
+++ b/gdb/ada-tasks.c
|
||
@@ -635,12 +635,12 @@ read_atcb (CORE_ADDR task_id, struct ada
|
||
sizeof (task_info->name) - 1);
|
||
else
|
||
{
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
|
||
msym = lookup_minimal_symbol_by_pc (task_id);
|
||
- if (msym)
|
||
+ if (msym.minsym)
|
||
{
|
||
- const char *full_name = SYMBOL_LINKAGE_NAME (msym);
|
||
+ const char *full_name = SYMBOL_LINKAGE_NAME (msym.minsym);
|
||
const char *task_name = full_name;
|
||
const char *p;
|
||
|
||
--- a/gdb/amd64-windows-tdep.c
|
||
+++ b/gdb/amd64-windows-tdep.c
|
||
@@ -140,14 +140,14 @@ amd64_skip_main_prologue (struct gdbarch
|
||
|
||
if (target_read_memory (pc + 1, buf, sizeof buf) == 0)
|
||
{
|
||
- struct minimal_symbol *s;
|
||
+ struct bound_minimal_symbol s;
|
||
CORE_ADDR call_dest;
|
||
|
||
call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order);
|
||
s = lookup_minimal_symbol_by_pc (call_dest);
|
||
- if (s != NULL
|
||
- && SYMBOL_LINKAGE_NAME (s) != NULL
|
||
- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0)
|
||
+ if (s.minsym != NULL
|
||
+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL
|
||
+ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0)
|
||
pc += 5;
|
||
}
|
||
}
|
||
@@ -175,7 +175,9 @@ amd64_windows_skip_trampoline_code (stru
|
||
CORE_ADDR indirect_addr = pc + offset + 6;
|
||
|
||
struct minimal_symbol *indsym
|
||
- = indirect_addr ? lookup_minimal_symbol_by_pc (indirect_addr) : NULL;
|
||
+ = (indirect_addr
|
||
+ ? lookup_minimal_symbol_by_pc (indirect_addr).minsym
|
||
+ : NULL);
|
||
const char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : NULL;
|
||
|
||
if (symname)
|
||
--- a/gdb/arm-tdep.c
|
||
+++ b/gdb/arm-tdep.c
|
||
@@ -381,7 +381,7 @@ arm_find_mapping_symbol (CORE_ADDR memad
|
||
int
|
||
arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr)
|
||
{
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
char type;
|
||
struct displaced_step_closure* dsc
|
||
= get_displaced_step_closure_by_addr(memaddr);
|
||
@@ -423,8 +423,8 @@ arm_pc_is_thumb (struct gdbarch *gdbarch
|
||
|
||
/* Thumb functions have a "special" bit set in minimal symbols. */
|
||
sym = lookup_minimal_symbol_by_pc (memaddr);
|
||
- if (sym)
|
||
- return (MSYMBOL_IS_SPECIAL (sym));
|
||
+ if (sym.minsym)
|
||
+ return (MSYMBOL_IS_SPECIAL (sym.minsym));
|
||
|
||
/* If the user wants to override the fallback mode, let them. */
|
||
if (strcmp (arm_fallback_mode_string, "arm") == 0)
|
||
@@ -468,14 +468,14 @@ static int
|
||
skip_prologue_function (struct gdbarch *gdbarch, CORE_ADDR pc, int is_thumb)
|
||
{
|
||
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
|
||
msym = lookup_minimal_symbol_by_pc (pc);
|
||
- if (msym != NULL
|
||
- && SYMBOL_VALUE_ADDRESS (msym) == pc
|
||
- && SYMBOL_LINKAGE_NAME (msym) != NULL)
|
||
+ if (msym.minsym != NULL
|
||
+ && SYMBOL_VALUE_ADDRESS (msym.minsym) == pc
|
||
+ && SYMBOL_LINKAGE_NAME (msym.minsym) != NULL)
|
||
{
|
||
- const char *name = SYMBOL_LINKAGE_NAME (msym);
|
||
+ const char *name = SYMBOL_LINKAGE_NAME (msym.minsym);
|
||
|
||
/* The GNU linker's Thumb call stub to foo is named
|
||
__foo_from_thumb. */
|
||
@@ -1284,7 +1284,7 @@ arm_skip_stack_protector(CORE_ADDR pc, s
|
||
{
|
||
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
|
||
unsigned int basereg;
|
||
- struct minimal_symbol *stack_chk_guard;
|
||
+ struct bound_minimal_symbol stack_chk_guard;
|
||
int offset;
|
||
int is_thumb = arm_pc_is_thumb (gdbarch, pc);
|
||
CORE_ADDR addr;
|
||
@@ -1299,8 +1299,9 @@ arm_skip_stack_protector(CORE_ADDR pc, s
|
||
/* If name of symbol doesn't start with '__stack_chk_guard', this
|
||
instruction sequence is not for stack protector. If symbol is
|
||
removed, we conservatively think this sequence is for stack protector. */
|
||
- if (stack_chk_guard
|
||
- && strncmp (SYMBOL_LINKAGE_NAME (stack_chk_guard), "__stack_chk_guard",
|
||
+ if (stack_chk_guard.minsym
|
||
+ && strncmp (SYMBOL_LINKAGE_NAME (stack_chk_guard.minsym),
|
||
+ "__stack_chk_guard",
|
||
strlen ("__stack_chk_guard")) != 0)
|
||
return pc;
|
||
|
||
--- a/gdb/arm-wince-tdep.c
|
||
+++ b/gdb/arm-wince-tdep.c
|
||
@@ -43,7 +43,7 @@ arm_pe_skip_trampoline_code (struct fram
|
||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||
ULONGEST indirect;
|
||
- struct minimal_symbol *indsym;
|
||
+ struct bound_minimal_symbol indsym;
|
||
const char *symname;
|
||
CORE_ADDR next_pc;
|
||
|
||
@@ -62,10 +62,10 @@ arm_pe_skip_trampoline_code (struct fram
|
||
return 0;
|
||
|
||
indsym = lookup_minimal_symbol_by_pc (indirect);
|
||
- if (indsym == NULL)
|
||
+ if (indsym.minsym == NULL)
|
||
return 0;
|
||
|
||
- symname = SYMBOL_LINKAGE_NAME (indsym);
|
||
+ symname = SYMBOL_LINKAGE_NAME (indsym.minsym);
|
||
if (symname == NULL || strncmp (symname, "__imp_", 6) != 0)
|
||
return 0;
|
||
|
||
@@ -100,11 +100,11 @@ arm_wince_skip_main_prologue (struct gdb
|
||
|
||
long offset = sign_extend (this_instr & 0x000fffff, 23) << 2;
|
||
CORE_ADDR call_dest = (pc + 8 + offset) & 0xffffffffU;
|
||
- struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest);
|
||
+ struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest);
|
||
|
||
- if (s != NULL
|
||
- && SYMBOL_LINKAGE_NAME (s) != NULL
|
||
- && strcmp (SYMBOL_LINKAGE_NAME (s), "__gccmain") == 0)
|
||
+ if (s.minsym != NULL
|
||
+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL
|
||
+ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__gccmain") == 0)
|
||
pc += 4;
|
||
}
|
||
|
||
--- a/gdb/block.c
|
||
+++ b/gdb/block.c
|
||
@@ -208,7 +208,7 @@ call_site_for_pc (struct gdbarch *gdbarc
|
||
|
||
if (slot == NULL)
|
||
{
|
||
- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (pc);
|
||
+ struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc);
|
||
|
||
/* DW_TAG_gnu_call_site will be missing just if GCC could not determine
|
||
the call target. */
|
||
@@ -216,7 +216,8 @@ call_site_for_pc (struct gdbarch *gdbarc
|
||
_("DW_OP_GNU_entry_value resolving cannot find "
|
||
"DW_TAG_GNU_call_site %s in %s"),
|
||
paddress (gdbarch, pc),
|
||
- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
||
+ (msym.minsym == NULL ? "???"
|
||
+ : SYMBOL_PRINT_NAME (msym.minsym)));
|
||
}
|
||
|
||
return *slot;
|
||
--- a/gdb/blockframe.c
|
||
+++ b/gdb/blockframe.c
|
||
@@ -88,7 +88,7 @@ CORE_ADDR
|
||
get_pc_function_start (CORE_ADDR pc)
|
||
{
|
||
struct block *bl;
|
||
- struct minimal_symbol *msymbol;
|
||
+ struct bound_minimal_symbol msymbol;
|
||
|
||
bl = block_for_pc (pc);
|
||
if (bl)
|
||
@@ -103,9 +103,9 @@ get_pc_function_start (CORE_ADDR pc)
|
||
}
|
||
|
||
msymbol = lookup_minimal_symbol_by_pc (pc);
|
||
- if (msymbol)
|
||
+ if (msymbol.minsym)
|
||
{
|
||
- CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol);
|
||
+ CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol.minsym);
|
||
|
||
if (find_pc_section (fstart))
|
||
return fstart;
|
||
@@ -218,7 +218,7 @@ find_pc_partial_function_gnu_ifunc (CORE
|
||
&& section == cache_pc_function_section)
|
||
goto return_cached_value;
|
||
|
||
- msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
|
||
+ msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section).minsym;
|
||
ALL_OBJFILES (objfile)
|
||
{
|
||
if (objfile->sf)
|
||
--- a/gdb/breakpoint.c
|
||
+++ b/gdb/breakpoint.c
|
||
@@ -9824,14 +9824,14 @@ resolve_sal_pc (struct symtab_and_line *
|
||
if we have line numbers but no functions (as can
|
||
happen in assembly source). */
|
||
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
struct cleanup *old_chain = save_current_space_and_thread ();
|
||
|
||
switch_to_program_space_and_thread (sal->pspace);
|
||
|
||
msym = lookup_minimal_symbol_by_pc (sal->pc);
|
||
- if (msym)
|
||
- sal->section = SYMBOL_OBJ_SECTION (msym);
|
||
+ if (msym.minsym)
|
||
+ sal->section = SYMBOL_OBJ_SECTION (msym.minsym);
|
||
|
||
do_cleanups (old_chain);
|
||
}
|
||
--- a/gdb/btrace.c
|
||
+++ b/gdb/btrace.c
|
||
@@ -272,7 +272,7 @@ compute_ftrace (VEC (btrace_inst_s) *itr
|
||
for (idx = 0; VEC_iterate (btrace_inst_s, itrace, idx, binst); ++idx)
|
||
{
|
||
struct symtab_and_line sal;
|
||
- struct minimal_symbol *mfun;
|
||
+ struct bound_minimal_symbol mfun;
|
||
struct symbol *fun;
|
||
const char *filename;
|
||
CORE_ADDR pc;
|
||
@@ -285,7 +285,7 @@ compute_ftrace (VEC (btrace_inst_s) *itr
|
||
fun = find_pc_function (pc);
|
||
mfun = lookup_minimal_symbol_by_pc (pc);
|
||
|
||
- if (fun == NULL && mfun == NULL)
|
||
+ if (fun == NULL && mfun.minsym == NULL)
|
||
{
|
||
DEBUG_FTRACE ("no symbol at %u, pc=%s", idx,
|
||
core_addr_to_string_nz (pc));
|
||
@@ -293,11 +293,11 @@ compute_ftrace (VEC (btrace_inst_s) *itr
|
||
}
|
||
|
||
/* If we're switching functions, we start over. */
|
||
- if (ftrace_function_switched (bfun, mfun, fun))
|
||
+ if (ftrace_function_switched (bfun, mfun.minsym, fun))
|
||
{
|
||
bfun = VEC_safe_push (btrace_func_s, ftrace, NULL);
|
||
|
||
- ftrace_init_func (bfun, mfun, fun, idx);
|
||
+ ftrace_init_func (bfun, mfun.minsym, fun, idx);
|
||
ftrace_debug (bfun, "init");
|
||
}
|
||
|
||
--- a/gdb/c-valprint.c
|
||
+++ b/gdb/c-valprint.c
|
||
@@ -310,18 +310,18 @@ c_val_print (struct type *type, const gd
|
||
CORE_ADDR vt_address = unpack_pointer (type,
|
||
valaddr
|
||
+ embedded_offset);
|
||
- struct minimal_symbol *msymbol =
|
||
- lookup_minimal_symbol_by_pc (vt_address);
|
||
+ struct bound_minimal_symbol msymbol =
|
||
+ lookup_minimal_symbol_by_pc (vt_address);
|
||
|
||
/* If 'symbol_print' is set, we did the work above. */
|
||
if (!options->symbol_print
|
||
- && (msymbol != NULL)
|
||
- && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
|
||
+ && (msymbol.minsym != NULL)
|
||
+ && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol.minsym)))
|
||
{
|
||
if (want_space)
|
||
fputs_filtered (" ", stream);
|
||
fputs_filtered (" <", stream);
|
||
- fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream);
|
||
+ fputs_filtered (SYMBOL_PRINT_NAME (msymbol.minsym), stream);
|
||
fputs_filtered (">", stream);
|
||
want_space = 1;
|
||
}
|
||
@@ -337,8 +337,8 @@ c_val_print (struct type *type, const gd
|
||
if (want_space)
|
||
fputs_filtered (" ", stream);
|
||
|
||
- if (msymbol != NULL)
|
||
- wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
|
||
+ if (msymbol.minsym != NULL)
|
||
+ wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol.minsym),
|
||
block, VAR_DOMAIN,
|
||
&is_this_fld);
|
||
|
||
--- a/gdb/coff-pe-read.c
|
||
+++ b/gdb/coff-pe-read.c
|
||
@@ -203,8 +203,7 @@ add_pe_forwarded_sym (const char *sym_na
|
||
const char *dll_name, struct objfile *objfile)
|
||
{
|
||
CORE_ADDR vma;
|
||
- struct objfile *forward_objfile;
|
||
- struct minimal_symbol *msymbol;
|
||
+ struct bound_minimal_symbol msymbol;
|
||
short section;
|
||
enum minimal_symbol_type msymtype;
|
||
int dll_name_len = strlen (dll_name);
|
||
@@ -218,20 +217,18 @@ add_pe_forwarded_sym (const char *sym_na
|
||
forward_func_name);
|
||
|
||
|
||
- msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name,
|
||
- &forward_objfile);
|
||
+ msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name);
|
||
|
||
- if (!msymbol)
|
||
+ if (!msymbol.minsym)
|
||
{
|
||
int i;
|
||
|
||
for (i = 0; i < forward_dll_name_len; i++)
|
||
forward_qualified_name[i] = tolower (forward_qualified_name[i]);
|
||
- msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name,
|
||
- &forward_objfile);
|
||
+ msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name);
|
||
}
|
||
|
||
- if (!msymbol)
|
||
+ if (!msymbol.minsym)
|
||
{
|
||
if (debug_coff_pe_read)
|
||
fprintf_unfiltered (gdb_stdlog, _("Unable to find function \"%s\" in"
|
||
@@ -246,9 +243,9 @@ add_pe_forwarded_sym (const char *sym_na
|
||
" \"%s\" in dll \"%s\", pointing to \"%s\"\n"),
|
||
sym_name, dll_name, forward_qualified_name);
|
||
|
||
- vma = SYMBOL_VALUE_ADDRESS (msymbol);
|
||
- section = SYMBOL_SECTION (msymbol);
|
||
- msymtype = MSYMBOL_TYPE (msymbol);
|
||
+ vma = SYMBOL_VALUE_ADDRESS (msymbol.minsym);
|
||
+ section = SYMBOL_SECTION (msymbol.minsym);
|
||
+ msymtype = MSYMBOL_TYPE (msymbol.minsym);
|
||
|
||
/* Generate a (hopefully unique) qualified name using the first part
|
||
of the dll name, e.g. KERNEL32!AddAtomA. This matches the style
|
||
--- a/gdb/dwarf2loc.c
|
||
+++ b/gdb/dwarf2loc.c
|
||
@@ -500,19 +500,20 @@ call_site_to_target_addr (struct gdbarch
|
||
dwarf_block = FIELD_DWARF_BLOCK (call_site->target);
|
||
if (dwarf_block == NULL)
|
||
{
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
|
||
msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
|
||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||
_("DW_AT_GNU_call_site_target is not specified "
|
||
"at %s in %s"),
|
||
paddress (call_site_gdbarch, call_site->pc),
|
||
- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
||
+ (msym.minsym == NULL ? "???"
|
||
+ : SYMBOL_PRINT_NAME (msym.minsym)));
|
||
|
||
}
|
||
if (caller_frame == NULL)
|
||
{
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
|
||
msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
|
||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||
@@ -520,7 +521,8 @@ call_site_to_target_addr (struct gdbarch
|
||
"requires known frame which is currently not "
|
||
"available at %s in %s"),
|
||
paddress (call_site_gdbarch, call_site->pc),
|
||
- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
||
+ (msym.minsym == NULL ? "???"
|
||
+ : SYMBOL_PRINT_NAME (msym.minsym)));
|
||
|
||
}
|
||
caller_arch = get_frame_arch (caller_frame);
|
||
@@ -547,7 +549,7 @@ call_site_to_target_addr (struct gdbarch
|
||
msym = lookup_minimal_symbol (physname, NULL, NULL);
|
||
if (msym == NULL)
|
||
{
|
||
- msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
|
||
+ msym = lookup_minimal_symbol_by_pc (call_site->pc - 1).minsym;
|
||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||
_("Cannot find function \"%s\" for a call site target "
|
||
"at %s in %s"),
|
||
@@ -643,14 +645,15 @@ func_verify_no_selftailcall (struct gdba
|
||
|
||
if (target_addr == verify_addr)
|
||
{
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
|
||
msym = lookup_minimal_symbol_by_pc (verify_addr);
|
||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||
_("DW_OP_GNU_entry_value resolving has found "
|
||
"function \"%s\" at %s can call itself via tail "
|
||
"calls"),
|
||
- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym),
|
||
+ (msym.minsym == NULL ? "???"
|
||
+ : SYMBOL_PRINT_NAME (msym.minsym)),
|
||
paddress (gdbarch, verify_addr));
|
||
}
|
||
|
||
@@ -674,10 +677,11 @@ static void
|
||
tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site)
|
||
{
|
||
CORE_ADDR addr = call_site->pc;
|
||
- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (addr - 1);
|
||
+ struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1);
|
||
|
||
fprintf_unfiltered (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr),
|
||
- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
||
+ (msym.minsym == NULL ? "???"
|
||
+ : SYMBOL_PRINT_NAME (msym.minsym)));
|
||
|
||
}
|
||
|
||
@@ -907,7 +911,7 @@ call_site_find_chain_1 (struct gdbarch *
|
||
|
||
if (retval == NULL)
|
||
{
|
||
- struct minimal_symbol *msym_caller, *msym_callee;
|
||
+ struct bound_minimal_symbol msym_caller, msym_callee;
|
||
|
||
msym_caller = lookup_minimal_symbol_by_pc (caller_pc);
|
||
msym_callee = lookup_minimal_symbol_by_pc (callee_pc);
|
||
@@ -915,11 +919,11 @@ call_site_find_chain_1 (struct gdbarch *
|
||
_("There are no unambiguously determinable intermediate "
|
||
"callers or callees between caller function \"%s\" at %s "
|
||
"and callee function \"%s\" at %s"),
|
||
- (msym_caller == NULL
|
||
- ? "???" : SYMBOL_PRINT_NAME (msym_caller)),
|
||
+ (msym_caller.minsym == NULL
|
||
+ ? "???" : SYMBOL_PRINT_NAME (msym_caller.minsym)),
|
||
paddress (gdbarch, caller_pc),
|
||
- (msym_callee == NULL
|
||
- ? "???" : SYMBOL_PRINT_NAME (msym_callee)),
|
||
+ (msym_callee.minsym == NULL
|
||
+ ? "???" : SYMBOL_PRINT_NAME (msym_callee.minsym)),
|
||
paddress (gdbarch, callee_pc));
|
||
}
|
||
|
||
@@ -1011,7 +1015,8 @@ dwarf_expr_reg_to_entry_parameter (struc
|
||
caller_frame = get_prev_frame (frame);
|
||
if (gdbarch != frame_unwind_arch (frame))
|
||
{
|
||
- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr);
|
||
+ struct bound_minimal_symbol msym
|
||
+ = lookup_minimal_symbol_by_pc (func_addr);
|
||
struct gdbarch *caller_gdbarch = frame_unwind_arch (frame);
|
||
|
||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||
@@ -1019,18 +1024,21 @@ dwarf_expr_reg_to_entry_parameter (struc
|
||
"(of %s (%s)) does not match caller gdbarch %s"),
|
||
gdbarch_bfd_arch_info (gdbarch)->printable_name,
|
||
paddress (gdbarch, func_addr),
|
||
- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym),
|
||
+ (msym.minsym == NULL ? "???"
|
||
+ : SYMBOL_PRINT_NAME (msym.minsym)),
|
||
gdbarch_bfd_arch_info (caller_gdbarch)->printable_name);
|
||
}
|
||
|
||
if (caller_frame == NULL)
|
||
{
|
||
- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (func_addr);
|
||
+ struct bound_minimal_symbol msym
|
||
+ = lookup_minimal_symbol_by_pc (func_addr);
|
||
|
||
throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_GNU_entry_value resolving "
|
||
"requires caller of %s (%s)"),
|
||
paddress (gdbarch, func_addr),
|
||
- msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
|
||
+ (msym.minsym == NULL ? "???"
|
||
+ : SYMBOL_PRINT_NAME (msym.minsym)));
|
||
}
|
||
caller_pc = get_frame_pc (caller_frame);
|
||
call_site = call_site_for_pc (gdbarch, caller_pc);
|
||
@@ -1040,8 +1048,8 @@ dwarf_expr_reg_to_entry_parameter (struc
|
||
{
|
||
struct minimal_symbol *target_msym, *func_msym;
|
||
|
||
- target_msym = lookup_minimal_symbol_by_pc (target_addr);
|
||
- func_msym = lookup_minimal_symbol_by_pc (func_addr);
|
||
+ target_msym = lookup_minimal_symbol_by_pc (target_addr).minsym;
|
||
+ func_msym = lookup_minimal_symbol_by_pc (func_addr).minsym;
|
||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||
_("DW_OP_GNU_entry_value resolving expects callee %s at %s "
|
||
"but the called frame is for %s at %s"),
|
||
@@ -1064,7 +1072,8 @@ dwarf_expr_reg_to_entry_parameter (struc
|
||
}
|
||
if (iparams == call_site->parameter_count)
|
||
{
|
||
- struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (caller_pc);
|
||
+ struct minimal_symbol *msym
|
||
+ = lookup_minimal_symbol_by_pc (caller_pc).minsym;
|
||
|
||
/* DW_TAG_GNU_call_site_parameter will be missing just if GCC could not
|
||
determine its value. */
|
||
--- a/gdb/elfread.c
|
||
+++ b/gdb/elfread.c
|
||
@@ -735,7 +735,7 @@ elf_gnu_ifunc_cache_eq (const void *a_vo
|
||
static int
|
||
elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr)
|
||
{
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
asection *sect;
|
||
struct objfile *objfile;
|
||
htab_t htab;
|
||
@@ -743,13 +743,13 @@ elf_gnu_ifunc_record_cache (const char *
|
||
void **slot;
|
||
|
||
msym = lookup_minimal_symbol_by_pc (addr);
|
||
- if (msym == NULL)
|
||
+ if (msym.minsym == NULL)
|
||
return 0;
|
||
- if (SYMBOL_VALUE_ADDRESS (msym) != addr)
|
||
+ if (SYMBOL_VALUE_ADDRESS (msym.minsym) != addr)
|
||
return 0;
|
||
/* minimal symbols have always SYMBOL_OBJ_SECTION non-NULL. */
|
||
- sect = SYMBOL_OBJ_SECTION (msym)->the_bfd_section;
|
||
- objfile = SYMBOL_OBJ_SECTION (msym)->objfile;
|
||
+ sect = SYMBOL_OBJ_SECTION (msym.minsym)->the_bfd_section;
|
||
+ objfile = SYMBOL_OBJ_SECTION (msym.minsym)->objfile;
|
||
|
||
/* If .plt jumps back to .plt the symbol is still deferred for later
|
||
resolution and it has no use for GDB. Besides ".text" this symbol can
|
||
--- a/gdb/frame.c
|
||
+++ b/gdb/frame.c
|
||
@@ -1678,7 +1678,7 @@ get_prev_frame_1 (struct frame_info *thi
|
||
|
||
/* gcc -fsplit-stack __morestack can continue the stack anywhere. */
|
||
this_pc_in_block = get_frame_address_in_block (this_frame);
|
||
- morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block);
|
||
+ morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block).minsym;
|
||
if (morestack_msym)
|
||
morestack_name = SYMBOL_LINKAGE_NAME (morestack_msym);
|
||
if (!morestack_name || strcmp (morestack_name, "__morestack") != 0)
|
||
--- a/gdb/frv-tdep.c
|
||
+++ b/gdb/frv-tdep.c
|
||
@@ -1072,7 +1072,7 @@ frv_skip_main_prologue (struct gdbarch *
|
||
{
|
||
LONGEST displ;
|
||
CORE_ADDR call_dest;
|
||
- struct minimal_symbol *s;
|
||
+ struct bound_minimal_symbol s;
|
||
|
||
displ = ((op & 0xfe000000) >> 7) | (op & 0x0003ffff);
|
||
if ((displ & 0x00800000) != 0)
|
||
@@ -1081,9 +1081,9 @@ frv_skip_main_prologue (struct gdbarch *
|
||
call_dest = pc + 4 * displ;
|
||
s = lookup_minimal_symbol_by_pc (call_dest);
|
||
|
||
- if (s != NULL
|
||
- && SYMBOL_LINKAGE_NAME (s) != NULL
|
||
- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0)
|
||
+ if (s.minsym != NULL
|
||
+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL
|
||
+ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0)
|
||
{
|
||
pc += 4;
|
||
return pc;
|
||
--- a/gdb/glibc-tdep.c
|
||
+++ b/gdb/glibc-tdep.c
|
||
@@ -53,19 +53,18 @@ glibc_skip_solib_resolver (struct gdbarc
|
||
of GNU/Linux will provide a portable, efficient interface for
|
||
debugging programs that use shared libraries. */
|
||
|
||
- struct objfile *objfile;
|
||
- struct minimal_symbol *resolver
|
||
- = lookup_minimal_symbol_and_objfile ("_dl_runtime_resolve", &objfile);
|
||
+ struct bound_minimal_symbol resolver
|
||
+ = lookup_minimal_symbol_and_objfile ("_dl_runtime_resolve");
|
||
|
||
- if (resolver)
|
||
+ if (resolver.minsym)
|
||
{
|
||
/* The dynamic linker began using this name in early 2005. */
|
||
struct minimal_symbol *fixup
|
||
- = lookup_minimal_symbol ("_dl_fixup", NULL, objfile);
|
||
+ = lookup_minimal_symbol ("_dl_fixup", NULL, resolver.objfile);
|
||
|
||
/* This is the name used in older versions. */
|
||
if (! fixup)
|
||
- fixup = lookup_minimal_symbol ("fixup", NULL, objfile);
|
||
+ fixup = lookup_minimal_symbol ("fixup", NULL, resolver.objfile);
|
||
|
||
if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
|
||
return frame_unwind_caller_pc (get_current_frame ());
|
||
--- a/gdb/gnu-v2-abi.c
|
||
+++ b/gdb/gnu-v2-abi.c
|
||
@@ -191,7 +191,7 @@ gnuv2_value_rtti_type (struct value *v,
|
||
struct type *known_type;
|
||
struct type *rtti_type;
|
||
CORE_ADDR vtbl;
|
||
- struct minimal_symbol *minsym;
|
||
+ struct bound_minimal_symbol minsym;
|
||
char *demangled_name, *p;
|
||
const char *linkage_name;
|
||
struct type *btype;
|
||
@@ -245,8 +245,8 @@ gnuv2_value_rtti_type (struct value *v,
|
||
|
||
/* Try to find a symbol that is the vtable. */
|
||
minsym=lookup_minimal_symbol_by_pc(vtbl);
|
||
- if (minsym==NULL
|
||
- || (linkage_name=SYMBOL_LINKAGE_NAME (minsym))==NULL
|
||
+ if (minsym.minsym==NULL
|
||
+ || (linkage_name=SYMBOL_LINKAGE_NAME (minsym.minsym))==NULL
|
||
|| !is_vtable_name (linkage_name))
|
||
return NULL;
|
||
|
||
--- a/gdb/gnu-v3-abi.c
|
||
+++ b/gdb/gnu-v3-abi.c
|
||
@@ -306,7 +306,7 @@ gnuv3_rtti_type (struct value *value,
|
||
/* Find the linker symbol for this vtable. */
|
||
vtable_symbol
|
||
= lookup_minimal_symbol_by_pc (value_address (vtable)
|
||
- + value_embedded_offset (vtable));
|
||
+ + value_embedded_offset (vtable)).minsym;
|
||
if (! vtable_symbol)
|
||
return NULL;
|
||
|
||
@@ -988,7 +988,7 @@ gnuv3_skip_trampoline (struct frame_info
|
||
real_stop_pc = stop_pc;
|
||
|
||
/* Find the linker symbol for this potential thunk. */
|
||
- thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc);
|
||
+ thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc).minsym;
|
||
section = find_pc_section (real_stop_pc);
|
||
if (thunk_sym == NULL || section == NULL)
|
||
return 0;
|
||
--- a/gdb/hppa-hpux-tdep.c
|
||
+++ b/gdb/hppa-hpux-tdep.c
|
||
@@ -89,7 +89,7 @@ hppa32_hpux_in_solib_call_trampoline (st
|
||
CORE_ADDR pc, char *name)
|
||
{
|
||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||
- struct minimal_symbol *minsym;
|
||
+ struct bound_minimal_symbol minsym;
|
||
struct unwind_table_entry *u;
|
||
|
||
/* First see if PC is in one of the two C-library trampolines. */
|
||
@@ -98,7 +98,8 @@ hppa32_hpux_in_solib_call_trampoline (st
|
||
return 1;
|
||
|
||
minsym = lookup_minimal_symbol_by_pc (pc);
|
||
- if (minsym && strcmp (SYMBOL_LINKAGE_NAME (minsym), ".stub") == 0)
|
||
+ if (minsym.minsym
|
||
+ && strcmp (SYMBOL_LINKAGE_NAME (minsym.minsym), ".stub") == 0)
|
||
return 1;
|
||
|
||
/* Get the unwind descriptor corresponding to PC, return zero
|
||
@@ -174,16 +175,16 @@ hppa64_hpux_in_solib_call_trampoline (st
|
||
step. If it does, then assume we are not in a stub and return.
|
||
|
||
Finally peek at the instructions to see if they look like a stub. */
|
||
- struct minimal_symbol *minsym;
|
||
+ struct bound_minimal_symbol minsym;
|
||
asection *sec;
|
||
CORE_ADDR addr;
|
||
int insn;
|
||
|
||
minsym = lookup_minimal_symbol_by_pc (pc);
|
||
- if (! minsym)
|
||
+ if (! minsym.minsym)
|
||
return 0;
|
||
|
||
- sec = SYMBOL_OBJ_SECTION (minsym)->the_bfd_section;
|
||
+ sec = SYMBOL_OBJ_SECTION (minsym.minsym)->the_bfd_section;
|
||
|
||
if (bfd_get_section_vma (sec->owner, sec) <= pc
|
||
&& pc < (bfd_get_section_vma (sec->owner, sec)
|
||
@@ -311,7 +312,7 @@ hppa_hpux_skip_trampoline_code (struct f
|
||
int word_size = gdbarch_ptr_bit (gdbarch) / 8;
|
||
long orig_pc = pc;
|
||
long prev_inst, curr_inst, loc;
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
struct unwind_table_entry *u;
|
||
|
||
/* Addresses passed to dyncall may *NOT* be the actual address
|
||
@@ -366,10 +367,12 @@ hppa_hpux_skip_trampoline_code (struct f
|
||
/*--------------------------------------------------------------------------*/
|
||
msym = lookup_minimal_symbol_by_pc (pc);
|
||
|
||
- if (msym == NULL || MSYMBOL_TYPE (msym) != mst_solib_trampoline)
|
||
+ if (msym.minsym == NULL
|
||
+ || MSYMBOL_TYPE (msym.minsym) != mst_solib_trampoline)
|
||
return orig_pc == pc ? 0 : pc & ~0x3;
|
||
|
||
- else if (msym != NULL && MSYMBOL_TYPE (msym) == mst_solib_trampoline)
|
||
+ else if (msym.minsym != NULL
|
||
+ && MSYMBOL_TYPE (msym.minsym) == mst_solib_trampoline)
|
||
{
|
||
struct objfile *objfile;
|
||
struct minimal_symbol *msymbol;
|
||
@@ -384,7 +387,7 @@ hppa_hpux_skip_trampoline_code (struct f
|
||
{
|
||
if (MSYMBOL_TYPE (msymbol) == mst_text
|
||
&& strcmp (SYMBOL_LINKAGE_NAME (msymbol),
|
||
- SYMBOL_LINKAGE_NAME (msym)) == 0)
|
||
+ SYMBOL_LINKAGE_NAME (msym.minsym)) == 0)
|
||
{
|
||
function_found = 1;
|
||
break;
|
||
@@ -401,7 +404,7 @@ hppa_hpux_skip_trampoline_code (struct f
|
||
should be mst_text. So we need to fix the msym, and also
|
||
get out of this function. */
|
||
{
|
||
- MSYMBOL_TYPE (msym) = mst_text;
|
||
+ MSYMBOL_TYPE (msym.minsym) = mst_text;
|
||
return orig_pc == pc ? 0 : pc & ~0x3;
|
||
}
|
||
}
|
||
@@ -472,21 +475,22 @@ hppa_hpux_skip_trampoline_code (struct f
|
||
(curr_inst == 0xeaa0d000) ||
|
||
(curr_inst == 0xeaa0d002))
|
||
{
|
||
- struct minimal_symbol *stubsym, *libsym;
|
||
+ struct bound_minimal_symbol stubsym;
|
||
+ struct minimal_symbol *libsym;
|
||
|
||
stubsym = lookup_minimal_symbol_by_pc (loc);
|
||
- if (stubsym == NULL)
|
||
+ if (stubsym.minsym == NULL)
|
||
{
|
||
warning (_("Unable to find symbol for 0x%lx"), loc);
|
||
return orig_pc == pc ? 0 : pc & ~0x3;
|
||
}
|
||
|
||
- libsym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (stubsym),
|
||
+ libsym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (stubsym.minsym),
|
||
NULL, NULL);
|
||
if (libsym == NULL)
|
||
{
|
||
warning (_("Unable to find library symbol for %s."),
|
||
- SYMBOL_PRINT_NAME (stubsym));
|
||
+ SYMBOL_PRINT_NAME (stubsym.minsym));
|
||
return orig_pc == pc ? 0 : pc & ~0x3;
|
||
}
|
||
|
||
@@ -1025,7 +1029,8 @@ static CORE_ADDR
|
||
hppa_hpux_find_import_stub_for_addr (CORE_ADDR funcaddr)
|
||
{
|
||
struct objfile *objfile;
|
||
- struct minimal_symbol *funsym, *stubsym;
|
||
+ struct bound_minimal_symbol funsym;
|
||
+ struct minimal_symbol *stubsym;
|
||
CORE_ADDR stubaddr;
|
||
|
||
funsym = lookup_minimal_symbol_by_pc (funcaddr);
|
||
@@ -1034,7 +1039,7 @@ hppa_hpux_find_import_stub_for_addr (COR
|
||
ALL_OBJFILES (objfile)
|
||
{
|
||
stubsym = lookup_minimal_symbol_solib_trampoline
|
||
- (SYMBOL_LINKAGE_NAME (funsym), objfile);
|
||
+ (SYMBOL_LINKAGE_NAME (funsym.minsym), objfile);
|
||
|
||
if (stubsym)
|
||
{
|
||
--- a/gdb/i386-tdep.c
|
||
+++ b/gdb/i386-tdep.c
|
||
@@ -1687,15 +1687,15 @@ i386_skip_main_prologue (struct gdbarch
|
||
{
|
||
/* Make sure address is computed correctly as a 32bit
|
||
integer even if CORE_ADDR is 64 bit wide. */
|
||
- struct minimal_symbol *s;
|
||
+ struct bound_minimal_symbol s;
|
||
CORE_ADDR call_dest;
|
||
|
||
call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order);
|
||
call_dest = call_dest & 0xffffffffU;
|
||
s = lookup_minimal_symbol_by_pc (call_dest);
|
||
- if (s != NULL
|
||
- && SYMBOL_LINKAGE_NAME (s) != NULL
|
||
- && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0)
|
||
+ if (s.minsym != NULL
|
||
+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL
|
||
+ && strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0)
|
||
pc += 5;
|
||
}
|
||
}
|
||
@@ -3352,7 +3352,7 @@ i386_pe_skip_trampoline_code (struct fra
|
||
unsigned long indirect =
|
||
read_memory_unsigned_integer (pc + 2, 4, byte_order);
|
||
struct minimal_symbol *indsym =
|
||
- indirect ? lookup_minimal_symbol_by_pc (indirect) : 0;
|
||
+ indirect ? lookup_minimal_symbol_by_pc (indirect).minsym : 0;
|
||
const char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : 0;
|
||
|
||
if (symname)
|
||
--- a/gdb/ia64-tdep.c
|
||
+++ b/gdb/ia64-tdep.c
|
||
@@ -3651,11 +3651,11 @@ ia64_convert_from_func_ptr_addr (struct
|
||
/* There are also descriptors embedded in vtables. */
|
||
if (s)
|
||
{
|
||
- struct minimal_symbol *minsym;
|
||
+ struct bound_minimal_symbol minsym;
|
||
|
||
minsym = lookup_minimal_symbol_by_pc (addr);
|
||
|
||
- if (minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym)))
|
||
+ if (minsym.minsym && is_vtable_name (SYMBOL_LINKAGE_NAME (minsym.minsym)))
|
||
return read_memory_unsigned_integer (addr, 8, byte_order);
|
||
}
|
||
|
||
--- a/gdb/infcall.c
|
||
+++ b/gdb/infcall.c
|
||
@@ -355,10 +355,10 @@ get_function_name (CORE_ADDR funaddr, ch
|
||
|
||
{
|
||
/* Try the minimal symbols. */
|
||
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
|
||
+ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (funaddr);
|
||
|
||
- if (msymbol)
|
||
- return SYMBOL_PRINT_NAME (msymbol);
|
||
+ if (msymbol.minsym)
|
||
+ return SYMBOL_PRINT_NAME (msymbol.minsym);
|
||
}
|
||
|
||
{
|
||
--- a/gdb/infcmd.c
|
||
+++ b/gdb/infcmd.c
|
||
@@ -1332,12 +1332,12 @@ until_next_command (int from_tty)
|
||
|
||
if (!func)
|
||
{
|
||
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
|
||
+ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);
|
||
|
||
- if (msymbol == NULL)
|
||
+ if (msymbol.minsym == NULL)
|
||
error (_("Execution is not within a known function."));
|
||
|
||
- tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol);
|
||
+ tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol.minsym);
|
||
tp->control.step_range_end = pc;
|
||
}
|
||
else
|
||
--- a/gdb/jit.c
|
||
+++ b/gdb/jit.c
|
||
@@ -1016,8 +1016,8 @@ static int
|
||
jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
|
||
struct jit_program_space_data *ps_data)
|
||
{
|
||
- struct minimal_symbol *reg_symbol, *desc_symbol;
|
||
- struct objfile *objf;
|
||
+ struct bound_minimal_symbol reg_symbol;
|
||
+ struct minimal_symbol *desc_symbol;
|
||
struct jit_objfile_data *objf_data;
|
||
CORE_ADDR addr;
|
||
|
||
@@ -1025,19 +1025,21 @@ jit_breakpoint_re_set_internal (struct g
|
||
{
|
||
/* Lookup the registration symbol. If it is missing, then we
|
||
assume we are not attached to a JIT. */
|
||
- reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name, &objf);
|
||
- if (reg_symbol == NULL || SYMBOL_VALUE_ADDRESS (reg_symbol) == 0)
|
||
+ reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name);
|
||
+ if (reg_symbol.minsym == NULL
|
||
+ || SYMBOL_VALUE_ADDRESS (reg_symbol.minsym) == 0)
|
||
return 1;
|
||
|
||
- desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, objf);
|
||
+ desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL,
|
||
+ reg_symbol.objfile);
|
||
if (desc_symbol == NULL || SYMBOL_VALUE_ADDRESS (desc_symbol) == 0)
|
||
return 1;
|
||
|
||
- objf_data = get_jit_objfile_data (objf);
|
||
- objf_data->register_code = reg_symbol;
|
||
+ objf_data = get_jit_objfile_data (reg_symbol.objfile);
|
||
+ objf_data->register_code = reg_symbol.minsym;
|
||
objf_data->descriptor = desc_symbol;
|
||
|
||
- ps_data->objfile = objf;
|
||
+ ps_data->objfile = reg_symbol.objfile;
|
||
}
|
||
else
|
||
objf_data = get_jit_objfile_data (ps_data->objfile);
|
||
--- a/gdb/linux-fork.c
|
||
+++ b/gdb/linux-fork.c
|
||
@@ -592,11 +592,11 @@ info_checkpoints_command (char *arg, int
|
||
printf_filtered (_(", line %d"), sal.line);
|
||
if (!sal.symtab && !sal.line)
|
||
{
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
|
||
msym = lookup_minimal_symbol_by_pc (pc);
|
||
- if (msym)
|
||
- printf_filtered (", <%s>", SYMBOL_LINKAGE_NAME (msym));
|
||
+ if (msym.minsym)
|
||
+ printf_filtered (", <%s>", SYMBOL_LINKAGE_NAME (msym.minsym));
|
||
}
|
||
|
||
putchar_filtered ('\n');
|
||
--- a/gdb/m32c-tdep.c
|
||
+++ b/gdb/m32c-tdep.c
|
||
@@ -2457,14 +2457,15 @@ m32c_m16c_address_to_pointer (struct gdb
|
||
struct minimal_symbol *tramp_msym;
|
||
|
||
/* Try to find a linker symbol at this address. */
|
||
- struct minimal_symbol *func_msym = lookup_minimal_symbol_by_pc (addr);
|
||
+ struct bound_minimal_symbol func_msym
|
||
+ = lookup_minimal_symbol_by_pc (addr);
|
||
|
||
- if (! func_msym)
|
||
+ if (! func_msym.minsym)
|
||
error (_("Cannot convert code address %s to function pointer:\n"
|
||
"couldn't find a symbol at that address, to find trampoline."),
|
||
paddress (gdbarch, addr));
|
||
|
||
- func_name = SYMBOL_LINKAGE_NAME (func_msym);
|
||
+ func_name = SYMBOL_LINKAGE_NAME (func_msym.minsym);
|
||
tramp_name = xmalloc (strlen (func_name) + 5);
|
||
strcpy (tramp_name, func_name);
|
||
strcat (tramp_name, ".plt");
|
||
@@ -2535,11 +2536,11 @@ m32c_m16c_pointer_to_address (struct gdb
|
||
{
|
||
/* See if there is a minimal symbol at that address whose name is
|
||
"NAME.plt". */
|
||
- struct minimal_symbol *ptr_msym = lookup_minimal_symbol_by_pc (ptr);
|
||
+ struct bound_minimal_symbol ptr_msym = lookup_minimal_symbol_by_pc (ptr);
|
||
|
||
- if (ptr_msym)
|
||
+ if (ptr_msym.minsym)
|
||
{
|
||
- const char *ptr_msym_name = SYMBOL_LINKAGE_NAME (ptr_msym);
|
||
+ const char *ptr_msym_name = SYMBOL_LINKAGE_NAME (ptr_msym.minsym);
|
||
int len = strlen (ptr_msym_name);
|
||
|
||
if (len > 4
|
||
@@ -2572,7 +2573,7 @@ m32c_m16c_pointer_to_address (struct gdb
|
||
{
|
||
ptr_msym = lookup_minimal_symbol_by_pc ((aspace << 16) | ptr);
|
||
|
||
- if (ptr_msym)
|
||
+ if (ptr_msym.minsym)
|
||
ptr |= aspace << 16;
|
||
}
|
||
}
|
||
--- a/gdb/m68hc11-tdep.c
|
||
+++ b/gdb/m68hc11-tdep.c
|
||
@@ -587,18 +587,18 @@ m68hc11_analyze_instruction (struct gdba
|
||
static enum insn_return_kind
|
||
m68hc11_get_return_insn (CORE_ADDR pc)
|
||
{
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
|
||
/* A flag indicating that this is a STO_M68HC12_FAR or STO_M68HC12_INTERRUPT
|
||
function is stored by elfread.c in the high bit of the info field.
|
||
Use this to decide which instruction the function uses to return. */
|
||
sym = lookup_minimal_symbol_by_pc (pc);
|
||
- if (sym == 0)
|
||
+ if (sym.minsym == 0)
|
||
return RETURN_RTS;
|
||
|
||
- if (MSYMBOL_IS_RTC (sym))
|
||
+ if (MSYMBOL_IS_RTC (sym.minsym))
|
||
return RETURN_RTC;
|
||
- else if (MSYMBOL_IS_RTI (sym))
|
||
+ else if (MSYMBOL_IS_RTI (sym.minsym))
|
||
return RETURN_RTI;
|
||
else
|
||
return RETURN_RTS;
|
||
--- a/gdb/maint.c
|
||
+++ b/gdb/maint.c
|
||
@@ -445,7 +445,7 @@ maintenance_translate_address (char *arg
|
||
CORE_ADDR address;
|
||
struct obj_section *sect;
|
||
char *p;
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
struct objfile *objfile;
|
||
|
||
if (arg == NULL || *arg == 0)
|
||
@@ -480,13 +480,13 @@ maintenance_translate_address (char *arg
|
||
else
|
||
sym = lookup_minimal_symbol_by_pc (address);
|
||
|
||
- if (sym)
|
||
+ if (sym.minsym)
|
||
{
|
||
- const char *symbol_name = SYMBOL_PRINT_NAME (sym);
|
||
+ const char *symbol_name = SYMBOL_PRINT_NAME (sym.minsym);
|
||
const char *symbol_offset
|
||
- = pulongest (address - SYMBOL_VALUE_ADDRESS (sym));
|
||
+ = pulongest (address - SYMBOL_VALUE_ADDRESS (sym.minsym));
|
||
|
||
- sect = SYMBOL_OBJ_SECTION(sym);
|
||
+ sect = SYMBOL_OBJ_SECTION(sym.minsym);
|
||
if (sect != NULL)
|
||
{
|
||
const char *section_name;
|
||
--- a/gdb/minsyms.c
|
||
+++ b/gdb/minsyms.c
|
||
@@ -474,7 +474,7 @@ lookup_minimal_symbol_solib_trampoline (
|
||
there are text and trampoline symbols at the same address.
|
||
Otherwise prefer mst_text symbols. */
|
||
|
||
-static struct minimal_symbol *
|
||
+static struct bound_minimal_symbol
|
||
lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
|
||
struct obj_section *section,
|
||
int want_trampoline)
|
||
@@ -485,6 +485,8 @@ lookup_minimal_symbol_by_pc_section_1 (C
|
||
struct objfile *objfile;
|
||
struct minimal_symbol *msymbol;
|
||
struct minimal_symbol *best_symbol = NULL;
|
||
+ struct objfile *best_objfile = NULL;
|
||
+ struct bound_minimal_symbol result;
|
||
enum minimal_symbol_type want_type, other_type;
|
||
|
||
want_type = want_trampoline ? mst_solib_trampoline : mst_text;
|
||
@@ -690,14 +692,18 @@ lookup_minimal_symbol_by_pc_section_1 (C
|
||
SYMBOL_VALUE_ADDRESS (&msymbol[hi]))))
|
||
{
|
||
best_symbol = &msymbol[hi];
|
||
+ best_objfile = objfile;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
- return (best_symbol);
|
||
+
|
||
+ result.minsym = best_symbol;
|
||
+ result.objfile = best_objfile;
|
||
+ return result;
|
||
}
|
||
|
||
-struct minimal_symbol *
|
||
+struct bound_minimal_symbol
|
||
lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, struct obj_section *section)
|
||
{
|
||
if (section == NULL)
|
||
@@ -707,17 +713,31 @@ lookup_minimal_symbol_by_pc_section (COR
|
||
debugging) always returns NULL making the call somewhat useless. */
|
||
section = find_pc_section (pc);
|
||
if (section == NULL)
|
||
- return NULL;
|
||
+ {
|
||
+ struct bound_minimal_symbol result;
|
||
+
|
||
+ memset (&result, 0, sizeof (result));
|
||
+ return result;
|
||
+ }
|
||
}
|
||
return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0);
|
||
}
|
||
|
||
/* See minsyms.h. */
|
||
|
||
-struct minimal_symbol *
|
||
+struct bound_minimal_symbol
|
||
lookup_minimal_symbol_by_pc (CORE_ADDR pc)
|
||
{
|
||
- return lookup_minimal_symbol_by_pc_section (pc, NULL);
|
||
+ struct obj_section *section = find_pc_section (pc);
|
||
+
|
||
+ if (section == NULL)
|
||
+ {
|
||
+ struct bound_minimal_symbol result;
|
||
+
|
||
+ memset (&result, 0, sizeof (result));
|
||
+ return result;
|
||
+ }
|
||
+ return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0);
|
||
}
|
||
|
||
/* Return non-zero iff PC is in an STT_GNU_IFUNC function resolver. */
|
||
@@ -725,9 +745,9 @@ lookup_minimal_symbol_by_pc (CORE_ADDR p
|
||
int
|
||
in_gnu_ifunc_stub (CORE_ADDR pc)
|
||
{
|
||
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
|
||
+ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);
|
||
|
||
- return msymbol && MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc;
|
||
+ return msymbol.minsym && MSYMBOL_TYPE (msymbol.minsym) == mst_text_gnu_ifunc;
|
||
}
|
||
|
||
/* See elf_gnu_ifunc_resolve_addr for its real implementation. */
|
||
@@ -785,10 +805,10 @@ const struct gnu_ifunc_fns *gnu_ifunc_fn
|
||
|
||
/* See minsyms.h. */
|
||
|
||
-struct minimal_symbol *
|
||
-lookup_minimal_symbol_and_objfile (const char *name,
|
||
- struct objfile **objfile_p)
|
||
+struct bound_minimal_symbol
|
||
+lookup_minimal_symbol_and_objfile (const char *name)
|
||
{
|
||
+ struct bound_minimal_symbol result;
|
||
struct objfile *objfile;
|
||
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
||
|
||
@@ -802,13 +822,15 @@ lookup_minimal_symbol_and_objfile (const
|
||
{
|
||
if (strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0)
|
||
{
|
||
- *objfile_p = objfile;
|
||
- return msym;
|
||
+ result.minsym = msym;
|
||
+ result.objfile = objfile;
|
||
+ return result;
|
||
}
|
||
}
|
||
}
|
||
|
||
- return 0;
|
||
+ memset (&result, 0, sizeof (result));
|
||
+ return result;
|
||
}
|
||
|
||
|
||
@@ -1287,14 +1309,15 @@ static struct minimal_symbol *
|
||
lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
|
||
{
|
||
struct obj_section *section = find_pc_section (pc);
|
||
- struct minimal_symbol *msymbol;
|
||
+ struct bound_minimal_symbol msymbol;
|
||
|
||
if (section == NULL)
|
||
return NULL;
|
||
msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section, 1);
|
||
|
||
- if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
|
||
- return msymbol;
|
||
+ if (msymbol.minsym != NULL
|
||
+ && MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline)
|
||
+ return msymbol.minsym;
|
||
return NULL;
|
||
}
|
||
|
||
--- a/gdb/minsyms.h
|
||
+++ b/gdb/minsyms.h
|
||
@@ -20,6 +20,23 @@
|
||
#ifndef MINSYMS_H
|
||
#define MINSYMS_H
|
||
|
||
+/* Several lookup functions return both a minimal symbol and the
|
||
+ objfile in which it is found. This structure is used in these
|
||
+ cases. */
|
||
+
|
||
+struct bound_minimal_symbol
|
||
+{
|
||
+ /* The minimal symbol that was found, or NULL if no minimal symbol
|
||
+ was found. */
|
||
+
|
||
+ struct minimal_symbol *minsym;
|
||
+
|
||
+ /* If MINSYM is not NULL, then this is the objfile in which the
|
||
+ symbol is defined. */
|
||
+
|
||
+ struct objfile *objfile;
|
||
+};
|
||
+
|
||
/* This header declares most of the API for dealing with minimal
|
||
symbols and minimal symbol tables. A few things are declared
|
||
elsewhere; see below.
|
||
@@ -169,12 +186,9 @@ struct minimal_symbol *lookup_minimal_sy
|
||
struct objfile *);
|
||
|
||
/* Find the minimal symbol named NAME, and return both the minsym
|
||
- struct and its objfile. This only checks the linkage name. Sets
|
||
- *OBJFILE_P and returns the minimal symbol, if it is found. If it
|
||
- is not found, returns NULL. */
|
||
+ struct and its objfile. This only checks the linkage name. */
|
||
|
||
-struct minimal_symbol *lookup_minimal_symbol_and_objfile (const char *,
|
||
- struct objfile **);
|
||
+struct bound_minimal_symbol lookup_minimal_symbol_and_objfile (const char *);
|
||
|
||
/* Look through all the current minimal symbol tables and find the
|
||
first minimal symbol that matches NAME and has text type. If OBJF
|
||
@@ -213,10 +227,10 @@ struct minimal_symbol *lookup_minimal_sy
|
||
If SECTION is NULL, this uses the result of find_pc_section
|
||
instead.
|
||
|
||
- Returns a pointer to the minimal symbol if such a symbol is found,
|
||
- or NULL if PC is not in a suitable range. */
|
||
+ The result has a non-NULL 'minsym' member if such a symbol is
|
||
+ found, or NULL if PC is not in a suitable range. */
|
||
|
||
-struct minimal_symbol *lookup_minimal_symbol_by_pc_section
|
||
+struct bound_minimal_symbol lookup_minimal_symbol_by_pc_section
|
||
(CORE_ADDR,
|
||
struct obj_section *);
|
||
|
||
@@ -226,7 +240,7 @@ struct minimal_symbol *lookup_minimal_sy
|
||
This is a wrapper that calls lookup_minimal_symbol_by_pc_section
|
||
with a NULL section argument. */
|
||
|
||
-struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR);
|
||
+struct bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR);
|
||
|
||
/* Iterate over all the minimal symbols in the objfile OBJF which
|
||
match NAME. Both the ordinary and demangled names of each symbol
|
||
--- a/gdb/mips-tdep.c
|
||
+++ b/gdb/mips-tdep.c
|
||
@@ -1115,15 +1115,15 @@ show_mask_address (struct ui_file *file,
|
||
int
|
||
mips_pc_is_mips (CORE_ADDR memaddr)
|
||
{
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
|
||
/* Flags indicating that this is a MIPS16 or microMIPS function is
|
||
stored by elfread.c in the high bit of the info field. Use this
|
||
to decide if the function is standard MIPS. Otherwise if bit 0
|
||
of the address is clear, then this is a standard MIPS function. */
|
||
sym = lookup_minimal_symbol_by_pc (memaddr);
|
||
- if (sym)
|
||
- return msymbol_is_mips (sym);
|
||
+ if (sym.minsym)
|
||
+ return msymbol_is_mips (sym.minsym);
|
||
else
|
||
return is_mips_addr (memaddr);
|
||
}
|
||
@@ -1133,15 +1133,15 @@ mips_pc_is_mips (CORE_ADDR memaddr)
|
||
int
|
||
mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr)
|
||
{
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
|
||
/* A flag indicating that this is a MIPS16 function is stored by
|
||
elfread.c in the high bit of the info field. Use this to decide
|
||
if the function is MIPS16. Otherwise if bit 0 of the address is
|
||
set, then ELF file flags will tell if this is a MIPS16 function. */
|
||
sym = lookup_minimal_symbol_by_pc (memaddr);
|
||
- if (sym)
|
||
- return msymbol_is_mips16 (sym);
|
||
+ if (sym.minsym)
|
||
+ return msymbol_is_mips16 (sym.minsym);
|
||
else
|
||
return is_mips16_addr (gdbarch, memaddr);
|
||
}
|
||
@@ -1151,7 +1151,7 @@ mips_pc_is_mips16 (struct gdbarch *gdbar
|
||
int
|
||
mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr)
|
||
{
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
|
||
/* A flag indicating that this is a microMIPS function is stored by
|
||
elfread.c in the high bit of the info field. Use this to decide
|
||
@@ -1159,8 +1159,8 @@ mips_pc_is_micromips (struct gdbarch *gd
|
||
is set, then ELF file flags will tell if this is a microMIPS
|
||
function. */
|
||
sym = lookup_minimal_symbol_by_pc (memaddr);
|
||
- if (sym)
|
||
- return msymbol_is_micromips (sym);
|
||
+ if (sym.minsym)
|
||
+ return msymbol_is_micromips (sym.minsym);
|
||
else
|
||
return is_micromips_addr (gdbarch, memaddr);
|
||
}
|
||
@@ -1171,7 +1171,7 @@ mips_pc_is_micromips (struct gdbarch *gd
|
||
static enum mips_isa
|
||
mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr)
|
||
{
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
|
||
/* A flag indicating that this is a MIPS16 or a microMIPS function
|
||
is stored by elfread.c in the high bit of the info field. Use
|
||
@@ -1179,11 +1179,11 @@ mips_pc_isa (struct gdbarch *gdbarch, CO
|
||
MIPS. Otherwise if bit 0 of the address is set, then ELF file
|
||
flags will tell if this is a MIPS16 or a microMIPS function. */
|
||
sym = lookup_minimal_symbol_by_pc (memaddr);
|
||
- if (sym)
|
||
+ if (sym.minsym)
|
||
{
|
||
- if (msymbol_is_micromips (sym))
|
||
+ if (msymbol_is_micromips (sym.minsym))
|
||
return ISA_MICROMIPS;
|
||
- else if (msymbol_is_mips16 (sym))
|
||
+ else if (msymbol_is_mips16 (sym.minsym))
|
||
return ISA_MIPS16;
|
||
else
|
||
return ISA_MIPS;
|
||
@@ -3582,7 +3582,7 @@ mips_stub_frame_sniffer (const struct fr
|
||
gdb_byte dummy[4];
|
||
struct obj_section *s;
|
||
CORE_ADDR pc = get_frame_address_in_block (this_frame);
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
|
||
/* Use the stub unwinder for unreadable code. */
|
||
if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
|
||
@@ -3602,9 +3602,9 @@ mips_stub_frame_sniffer (const struct fr
|
||
/* Calling a PIC function from a non-PIC function passes through a
|
||
stub. The stub for foo is named ".pic.foo". */
|
||
msym = lookup_minimal_symbol_by_pc (pc);
|
||
- if (msym != NULL
|
||
- && SYMBOL_LINKAGE_NAME (msym) != NULL
|
||
- && strncmp (SYMBOL_LINKAGE_NAME (msym), ".pic.", 5) == 0)
|
||
+ if (msym.minsym != NULL
|
||
+ && SYMBOL_LINKAGE_NAME (msym.minsym) != NULL
|
||
+ && strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) == 0)
|
||
return 1;
|
||
|
||
return 0;
|
||
@@ -7626,7 +7626,7 @@ mips_skip_pic_trampoline_code (struct fr
|
||
{
|
||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||
- struct minimal_symbol *msym;
|
||
+ struct bound_minimal_symbol msym;
|
||
int i;
|
||
gdb_byte stub_code[16];
|
||
int32_t stub_words[4];
|
||
@@ -7635,18 +7635,18 @@ mips_skip_pic_trampoline_code (struct fr
|
||
instructions inserted before foo or a three instruction sequence
|
||
which jumps to foo. */
|
||
msym = lookup_minimal_symbol_by_pc (pc);
|
||
- if (msym == NULL
|
||
- || SYMBOL_VALUE_ADDRESS (msym) != pc
|
||
- || SYMBOL_LINKAGE_NAME (msym) == NULL
|
||
- || strncmp (SYMBOL_LINKAGE_NAME (msym), ".pic.", 5) != 0)
|
||
+ if (msym.minsym == NULL
|
||
+ || SYMBOL_VALUE_ADDRESS (msym.minsym) != pc
|
||
+ || SYMBOL_LINKAGE_NAME (msym.minsym) == NULL
|
||
+ || strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) != 0)
|
||
return 0;
|
||
|
||
/* A two-instruction header. */
|
||
- if (MSYMBOL_SIZE (msym) == 8)
|
||
+ if (MSYMBOL_SIZE (msym.minsym) == 8)
|
||
return pc + 8;
|
||
|
||
/* A three-instruction (plus delay slot) trampoline. */
|
||
- if (MSYMBOL_SIZE (msym) == 16)
|
||
+ if (MSYMBOL_SIZE (msym.minsym) == 16)
|
||
{
|
||
if (target_read_memory (pc, stub_code, 16) != 0)
|
||
return 0;
|
||
--- a/gdb/p-valprint.c
|
||
+++ b/gdb/p-valprint.c
|
||
@@ -221,18 +221,18 @@ pascal_val_print (struct type *type, con
|
||
/* Print vtbl's nicely. */
|
||
CORE_ADDR vt_address = unpack_pointer (type,
|
||
valaddr + embedded_offset);
|
||
- struct minimal_symbol *msymbol =
|
||
+ struct bound_minimal_symbol msymbol =
|
||
lookup_minimal_symbol_by_pc (vt_address);
|
||
|
||
/* If 'symbol_print' is set, we did the work above. */
|
||
if (!options->symbol_print
|
||
- && (msymbol != NULL)
|
||
- && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
|
||
+ && (msymbol.minsym != NULL)
|
||
+ && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol.minsym)))
|
||
{
|
||
if (want_space)
|
||
fputs_filtered (" ", stream);
|
||
fputs_filtered ("<", stream);
|
||
- fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream);
|
||
+ fputs_filtered (SYMBOL_PRINT_NAME (msymbol.minsym), stream);
|
||
fputs_filtered (">", stream);
|
||
want_space = 1;
|
||
}
|
||
@@ -247,8 +247,9 @@ pascal_val_print (struct type *type, con
|
||
if (want_space)
|
||
fputs_filtered (" ", stream);
|
||
|
||
- if (msymbol != NULL)
|
||
- wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), block,
|
||
+ if (msymbol.minsym != NULL)
|
||
+ wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol.minsym),
|
||
+ block,
|
||
VAR_DOMAIN, &is_this_fld);
|
||
|
||
if (wsym)
|
||
--- a/gdb/parse.c
|
||
+++ b/gdb/parse.c
|
||
@@ -508,13 +508,14 @@ write_exp_msymbol (struct minimal_symbol
|
||
pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, ¤t_target);
|
||
if (pc != addr)
|
||
{
|
||
- struct minimal_symbol *ifunc_msym = lookup_minimal_symbol_by_pc (pc);
|
||
+ struct bound_minimal_symbol ifunc_msym = lookup_minimal_symbol_by_pc (pc);
|
||
|
||
/* In this case, assume we have a code symbol instead of
|
||
a data symbol. */
|
||
|
||
- if (ifunc_msym != NULL && MSYMBOL_TYPE (ifunc_msym) == mst_text_gnu_ifunc
|
||
- && SYMBOL_VALUE_ADDRESS (ifunc_msym) == pc)
|
||
+ if (ifunc_msym.minsym != NULL
|
||
+ && MSYMBOL_TYPE (ifunc_msym.minsym) == mst_text_gnu_ifunc
|
||
+ && SYMBOL_VALUE_ADDRESS (ifunc_msym.minsym) == pc)
|
||
{
|
||
/* A function descriptor has been resolved but PC is still in the
|
||
STT_GNU_IFUNC resolver body (such as because inferior does not
|
||
--- a/gdb/ppc-linux-tdep.c
|
||
+++ b/gdb/ppc-linux-tdep.c
|
||
@@ -332,7 +332,7 @@ static struct ppc_insn_pattern powerpc32
|
||
static int
|
||
powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
|
||
{
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
|
||
/* Check whether PC is in the dynamic linker. This also checks
|
||
whether it is in the .plt section, used by non-PIC executables. */
|
||
@@ -341,9 +341,10 @@ powerpc_linux_in_dynsym_resolve_code (CO
|
||
|
||
/* Check if we are in the resolver. */
|
||
sym = lookup_minimal_symbol_by_pc (pc);
|
||
- if (sym != NULL
|
||
- && (strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink") == 0
|
||
- || strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink_PLTresolve") == 0))
|
||
+ if (sym.minsym != NULL
|
||
+ && (strcmp (SYMBOL_LINKAGE_NAME (sym.minsym), "__glink") == 0
|
||
+ || strcmp (SYMBOL_LINKAGE_NAME (sym.minsym),
|
||
+ "__glink_PLTresolve") == 0))
|
||
return 1;
|
||
|
||
return 0;
|
||
--- a/gdb/ppc-sysv-tdep.c
|
||
+++ b/gdb/ppc-sysv-tdep.c
|
||
@@ -1076,12 +1076,13 @@ static int
|
||
convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr)
|
||
{
|
||
struct obj_section *dot_fn_section;
|
||
- struct minimal_symbol *dot_fn;
|
||
+ struct bound_minimal_symbol dot_fn;
|
||
struct minimal_symbol *fn;
|
||
+
|
||
/* Find the minimal symbol that corresponds to CODE_ADDR (should
|
||
have a name of the form ".FN"). */
|
||
dot_fn = lookup_minimal_symbol_by_pc (code_addr);
|
||
- if (dot_fn == NULL || SYMBOL_LINKAGE_NAME (dot_fn)[0] != '.')
|
||
+ if (dot_fn.minsym == NULL || SYMBOL_LINKAGE_NAME (dot_fn.minsym)[0] != '.')
|
||
return 0;
|
||
/* Get the section that contains CODE_ADDR. Need this for the
|
||
"objfile" that it contains. */
|
||
@@ -1092,7 +1093,7 @@ convert_code_addr_to_desc_addr (CORE_ADD
|
||
address. Only look for the minimal symbol in ".FN"'s object file
|
||
- avoids problems when two object files (i.e., shared libraries)
|
||
contain a minimal symbol with the same name. */
|
||
- fn = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn) + 1, NULL,
|
||
+ fn = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn.minsym) + 1, NULL,
|
||
dot_fn_section->objfile);
|
||
if (fn == NULL)
|
||
return 0;
|
||
--- a/gdb/printcmd.c
|
||
+++ b/gdb/printcmd.c
|
||
@@ -668,7 +668,7 @@ build_address_symbolic (struct gdbarch *
|
||
save some memory, but for many debug format--ELF/DWARF or
|
||
anything/stabs--it would be inconvenient to eliminate those minimal
|
||
symbols anyway). */
|
||
- msymbol = lookup_minimal_symbol_by_pc_section (addr, section);
|
||
+ msymbol = lookup_minimal_symbol_by_pc_section (addr, section).minsym;
|
||
symbol = find_pc_sect_function (addr, section);
|
||
|
||
if (symbol)
|
||
@@ -1166,7 +1166,8 @@ sym_info (char *arg, int from_tty)
|
||
|
||
if (obj_section_addr (osect) <= sect_addr
|
||
&& sect_addr < obj_section_endaddr (osect)
|
||
- && (msymbol = lookup_minimal_symbol_by_pc_section (sect_addr, osect)))
|
||
+ && (msymbol
|
||
+ = lookup_minimal_symbol_by_pc_section (sect_addr, osect).minsym))
|
||
{
|
||
const char *obj_name, *mapped, *sec_name, *msym_name;
|
||
char *loc_string;
|
||
--- a/gdb/rs6000-tdep.c
|
||
+++ b/gdb/rs6000-tdep.c
|
||
@@ -2152,15 +2152,15 @@ rs6000_skip_main_prologue (struct gdbarc
|
||
{
|
||
CORE_ADDR displ = op & BL_DISPLACEMENT_MASK;
|
||
CORE_ADDR call_dest = pc + 4 + displ;
|
||
- struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest);
|
||
+ struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest);
|
||
|
||
/* We check for ___eabi (three leading underscores) in addition
|
||
to __eabi in case the GCC option "-fleading-underscore" was
|
||
used to compile the program. */
|
||
- if (s != NULL
|
||
- && SYMBOL_LINKAGE_NAME (s) != NULL
|
||
- && (strcmp (SYMBOL_LINKAGE_NAME (s), "__eabi") == 0
|
||
- || strcmp (SYMBOL_LINKAGE_NAME (s), "___eabi") == 0))
|
||
+ if (s.minsym != NULL
|
||
+ && SYMBOL_LINKAGE_NAME (s.minsym) != NULL
|
||
+ && (strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__eabi") == 0
|
||
+ || strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "___eabi") == 0))
|
||
pc += 4;
|
||
}
|
||
return pc;
|
||
@@ -2226,7 +2226,7 @@ rs6000_skip_trampoline_code (struct fram
|
||
unsigned int ii, op;
|
||
int rel;
|
||
CORE_ADDR solib_target_pc;
|
||
- struct minimal_symbol *msymbol;
|
||
+ struct bound_minimal_symbol msymbol;
|
||
|
||
static unsigned trampoline_code[] =
|
||
{
|
||
@@ -2242,9 +2242,9 @@ rs6000_skip_trampoline_code (struct fram
|
||
|
||
/* Check for bigtoc fixup code. */
|
||
msymbol = lookup_minimal_symbol_by_pc (pc);
|
||
- if (msymbol
|
||
+ if (msymbol.minsym
|
||
&& rs6000_in_solib_return_trampoline (gdbarch, pc,
|
||
- SYMBOL_LINKAGE_NAME (msymbol)))
|
||
+ SYMBOL_LINKAGE_NAME (msymbol.minsym)))
|
||
{
|
||
/* Double-check that the third instruction from PC is relative "b". */
|
||
op = read_memory_integer (pc + 8, 4, byte_order);
|
||
--- a/gdb/sh64-tdep.c
|
||
+++ b/gdb/sh64-tdep.c
|
||
@@ -237,7 +237,7 @@ sh64_elf_make_msymbol_special (asymbol *
|
||
static int
|
||
pc_is_isa32 (bfd_vma memaddr)
|
||
{
|
||
- struct minimal_symbol *sym;
|
||
+ struct bound_minimal_symbol sym;
|
||
|
||
/* If bit 0 of the address is set, assume this is a
|
||
ISA32 (shmedia) address. */
|
||
@@ -248,8 +248,8 @@ pc_is_isa32 (bfd_vma memaddr)
|
||
the high bit of the info field. Use this to decide if the function is
|
||
ISA16 or ISA32. */
|
||
sym = lookup_minimal_symbol_by_pc (memaddr);
|
||
- if (sym)
|
||
- return MSYMBOL_IS_SPECIAL (sym);
|
||
+ if (sym.minsym)
|
||
+ return MSYMBOL_IS_SPECIAL (sym.minsym);
|
||
else
|
||
return 0;
|
||
}
|
||
--- a/gdb/stack.c
|
||
+++ b/gdb/stack.c
|
||
@@ -1036,23 +1036,25 @@ find_frame_funname (struct frame_info *f
|
||
changed (and we'll create a find_pc_minimal_function or some
|
||
such). */
|
||
|
||
- struct minimal_symbol *msymbol = NULL;
|
||
+ struct bound_minimal_symbol msymbol;
|
||
|
||
/* Don't attempt to do this for inlined functions, which do not
|
||
have a corresponding minimal symbol. */
|
||
if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func)))
|
||
msymbol
|
||
= lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame));
|
||
+ else
|
||
+ memset (&msymbol, 0, sizeof (msymbol));
|
||
|
||
- if (msymbol != NULL
|
||
- && (SYMBOL_VALUE_ADDRESS (msymbol)
|
||
+ if (msymbol.minsym != NULL
|
||
+ && (SYMBOL_VALUE_ADDRESS (msymbol.minsym)
|
||
> BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
|
||
{
|
||
/* We also don't know anything about the function besides
|
||
its address and name. */
|
||
func = 0;
|
||
- *funname = SYMBOL_PRINT_NAME (msymbol);
|
||
- *funlang = SYMBOL_LANGUAGE (msymbol);
|
||
+ *funname = SYMBOL_PRINT_NAME (msymbol.minsym);
|
||
+ *funlang = SYMBOL_LANGUAGE (msymbol.minsym);
|
||
}
|
||
else
|
||
{
|
||
@@ -1079,17 +1081,17 @@ find_frame_funname (struct frame_info *f
|
||
}
|
||
else
|
||
{
|
||
- struct minimal_symbol *msymbol;
|
||
+ struct bound_minimal_symbol msymbol;
|
||
CORE_ADDR pc;
|
||
|
||
if (!get_frame_address_in_block_if_available (frame, &pc))
|
||
return;
|
||
|
||
msymbol = lookup_minimal_symbol_by_pc (pc);
|
||
- if (msymbol != NULL)
|
||
+ if (msymbol.minsym != NULL)
|
||
{
|
||
- *funname = SYMBOL_PRINT_NAME (msymbol);
|
||
- *funlang = SYMBOL_LANGUAGE (msymbol);
|
||
+ *funname = SYMBOL_PRINT_NAME (msymbol.minsym);
|
||
+ *funlang = SYMBOL_LANGUAGE (msymbol.minsym);
|
||
}
|
||
}
|
||
}
|
||
@@ -1423,13 +1425,13 @@ frame_info (char *addr_exp, int from_tty
|
||
}
|
||
else if (frame_pc_p)
|
||
{
|
||
- struct minimal_symbol *msymbol;
|
||
+ struct bound_minimal_symbol msymbol;
|
||
|
||
msymbol = lookup_minimal_symbol_by_pc (frame_pc);
|
||
- if (msymbol != NULL)
|
||
+ if (msymbol.minsym != NULL)
|
||
{
|
||
- funname = SYMBOL_PRINT_NAME (msymbol);
|
||
- funlang = SYMBOL_LANGUAGE (msymbol);
|
||
+ funname = SYMBOL_PRINT_NAME (msymbol.minsym);
|
||
+ funlang = SYMBOL_LANGUAGE (msymbol.minsym);
|
||
}
|
||
}
|
||
calling_frame_info = get_prev_frame (fi);
|
||
--- a/gdb/symtab.c
|
||
+++ b/gdb/symtab.c
|
||
@@ -956,7 +956,7 @@ find_pc_sect_symtab_via_partial (CORE_AD
|
||
/* If we know that this is not a text address, return failure. This is
|
||
necessary because we loop based on texthigh and textlow, which do
|
||
not include the data ranges. */
|
||
- msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
|
||
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym;
|
||
if (msymbol
|
||
&& (MSYMBOL_TYPE (msymbol) == mst_data
|
||
|| MSYMBOL_TYPE (msymbol) == mst_bss
|
||
@@ -2088,7 +2088,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struc
|
||
addresses, which do not include the data ranges, and because
|
||
we call find_pc_sect_psymtab which has a similar restriction based
|
||
on the partial_symtab's texthigh and textlow. */
|
||
- msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
|
||
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym;
|
||
if (msymbol
|
||
&& (MSYMBOL_TYPE (msymbol) == mst_data
|
||
|| MSYMBOL_TYPE (msymbol) == mst_bss
|
||
@@ -2219,7 +2219,7 @@ find_pc_sect_line (CORE_ADDR pc, struct
|
||
struct linetable_entry *item;
|
||
struct symtab_and_line val;
|
||
struct blockvector *bv;
|
||
- struct minimal_symbol *msymbol;
|
||
+ struct bound_minimal_symbol msymbol;
|
||
struct minimal_symbol *mfunsym;
|
||
struct objfile *objfile;
|
||
|
||
@@ -2305,11 +2305,12 @@ find_pc_sect_line (CORE_ADDR pc, struct
|
||
* infinite recursion.
|
||
*/
|
||
msymbol = lookup_minimal_symbol_by_pc (pc);
|
||
- if (msymbol != NULL)
|
||
- if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
|
||
+ if (msymbol.minsym != NULL)
|
||
+ if (MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline)
|
||
{
|
||
- mfunsym = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol),
|
||
- NULL);
|
||
+ mfunsym
|
||
+ = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol.minsym),
|
||
+ NULL);
|
||
if (mfunsym == NULL)
|
||
/* I eliminated this warning since it is coming out
|
||
* in the following situation:
|
||
@@ -2325,7 +2326,7 @@ find_pc_sect_line (CORE_ADDR pc, struct
|
||
;
|
||
/* fall through */
|
||
else if (SYMBOL_VALUE_ADDRESS (mfunsym)
|
||
- == SYMBOL_VALUE_ADDRESS (msymbol))
|
||
+ == SYMBOL_VALUE_ADDRESS (msymbol.minsym))
|
||
/* Avoid infinite recursion */
|
||
/* See above comment about why warning is commented out. */
|
||
/* warning ("In stub for %s; unable to find real function/line info",
|
||
@@ -2838,7 +2839,7 @@ skip_prologue_sal (struct symtab_and_lin
|
||
else
|
||
{
|
||
struct minimal_symbol *msymbol
|
||
- = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
|
||
+ = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section).minsym;
|
||
|
||
if (msymbol == NULL)
|
||
{
|
||
@@ -2894,8 +2895,8 @@ skip_prologue_sal (struct symtab_and_lin
|
||
if (skip && start_sal.pc != pc
|
||
&& (sym ? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end
|
||
&& start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
|
||
- : (lookup_minimal_symbol_by_pc_section (start_sal.end, section)
|
||
- == lookup_minimal_symbol_by_pc_section (pc, section))))
|
||
+ : (lookup_minimal_symbol_by_pc_section (start_sal.end, section).minsym
|
||
+ == lookup_minimal_symbol_by_pc_section (pc, section).minsym)))
|
||
{
|
||
/* First pc of next line */
|
||
pc = start_sal.end;
|
||
--- a/gdb/tui/tui-disasm.c
|
||
+++ b/gdb/tui/tui-disasm.c
|
||
@@ -121,7 +121,7 @@ tui_find_disassembly_address (struct gdb
|
||
pos = max_lines - 1;
|
||
do {
|
||
new_low -= 1 * max_lines;
|
||
- msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0);
|
||
+ msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0).minsym;
|
||
|
||
if (msymbol)
|
||
new_low = SYMBOL_VALUE_ADDRESS (msymbol);
|
||
|
||
|
||
#
|
||
# gdb-7.6-add-powerpc64le-linux.patch
|
||
#
|
||
|
||
From: Alan Modra <amodra@gmail.com>
|
||
Date: Thu Apr 25 13:22:52 2013 +0000
|
||
Git-commit: 49926cd0c84887c581110fb2a471b21ff19048d2
|
||
References: ppc64le enablement
|
||
|
||
bfd/
|
||
* config.bfd: Add powerpc64le-linux.
|
||
|
||
Acked-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
bfd/ChangeLog | 4 ++++
|
||
bfd/config.bfd | 3 ++-
|
||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||
|
||
--- a/bfd/ChangeLog
|
||
+++ b/bfd/ChangeLog
|
||
@@ -1,3 +1,7 @@
|
||
+2013-04-25 Alan Modra <amodra@gmail.com>
|
||
+
|
||
+ * config.bfd: Add powerpc64le-linux.
|
||
+
|
||
2013-03-08 Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
|
||
|
||
* elf64-aarch64.c (elf_backend_can_gc_sections): Enable gc-section
|
||
--- a/bfd/config.bfd
|
||
+++ b/bfd/config.bfd
|
||
@@ -1242,7 +1242,8 @@ case "${targ}" in
|
||
targ_selvecs="bfd_elf64_powerpcle_vec bfd_elf32_powerpc_vec bfd_elf32_powerpcle_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec"
|
||
want64=true
|
||
;;
|
||
- powerpc64le-*-elf* | powerpcle-*-elf64*)
|
||
+ powerpc64le-*-elf* | powerpcle-*-elf64* | powerpc64le-*-linux* | \
|
||
+ powerpc64le-*-*bsd*)
|
||
targ_defvec=bfd_elf64_powerpcle_vec
|
||
targ_selvecs="bfd_elf64_powerpc_vec bfd_elf32_powerpcle_vec bfd_elf32_powerpc_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec"
|
||
want64=true
|
||
|
||
|
||
#
|
||
# gdb-7.6-update-autoconf-2013-04-24.patch
|
||
#
|
||
|
||
From: Jan-Benedict Glaw <jbglaw@lug-owl.de>
|
||
Date: Mon Apr 29 15:13:53 2013 +0000
|
||
Git-commit: 5dad867ccace0a74c90b729372c9c01392756875
|
||
References: ppc64le enablement
|
||
|
||
* config.guess: Update from config repo.
|
||
* config.sub: Ditto.
|
||
|
||
Acked-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
ChangeLog | 5 +++++
|
||
config.guess | 25 +++++++++++++++++--------
|
||
config.sub | 23 +++++++++++------------
|
||
3 files changed, 33 insertions(+), 20 deletions(-)
|
||
|
||
--- a/ChangeLog
|
||
+++ b/ChangeLog
|
||
@@ -1,3 +1,8 @@
|
||
+2013-04-29 Jan-Benedict Glaw <jbglaw@lug-owl.de>
|
||
+
|
||
+ * config.guess: Update from config repo.
|
||
+ * config.sub: Ditto.
|
||
+
|
||
2013-02-15 Yufeng Zhang <yufeng.zhang@arm.com>
|
||
|
||
* configure.ac: Sync with GCC repo.
|
||
--- a/config.guess
|
||
+++ b/config.guess
|
||
@@ -1,10 +1,8 @@
|
||
#! /bin/sh
|
||
# Attempt to guess a canonical system name.
|
||
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||
-# 2011, 2012, 2013 Free Software Foundation, Inc.
|
||
+# Copyright 1992-2013 Free Software Foundation, Inc.
|
||
|
||
-timestamp='2012-12-30'
|
||
+timestamp='2013-04-24'
|
||
|
||
# This file is free software; you can redistribute it and/or modify it
|
||
# under the terms of the GNU General Public License as published by
|
||
@@ -52,9 +50,7 @@ version="\
|
||
GNU config.guess ($timestamp)
|
||
|
||
Originally written by Per Bothner.
|
||
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
|
||
-2012, 2013 Free Software Foundation, Inc.
|
||
+Copyright 1992-2013 Free Software Foundation, Inc.
|
||
|
||
This is free software; see the source for copying conditions. There is NO
|
||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||
@@ -887,6 +883,9 @@ EOF
|
||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||
exit ;;
|
||
+ arc:Linux:*:* | arceb:Linux:*:*)
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ exit ;;
|
||
arm*:Linux:*:*)
|
||
eval $set_cc_for_build
|
||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||
@@ -925,6 +924,11 @@ EOF
|
||
#ifdef __dietlibc__
|
||
LIBC=dietlibc
|
||
#endif
|
||
+ #else
|
||
+ #include <features.h>
|
||
+ #ifdef __UCLIBC__
|
||
+ LIBC=uclibc
|
||
+ #endif
|
||
EOF
|
||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||
@@ -957,6 +961,9 @@ EOF
|
||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||
;;
|
||
+ or1k:Linux:*:*)
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ exit ;;
|
||
or32:Linux:*:*)
|
||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
exit ;;
|
||
@@ -999,7 +1006,9 @@ EOF
|
||
echo ${UNAME_MACHINE}-dec-linux-gnu
|
||
exit ;;
|
||
x86_64:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ LIBC=gnu
|
||
+ test -r /lib/libc.so && od -An -S13 /lib/libc.so | grep -q __uClibc_main && LIBC=uclibc
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
xtensa*:Linux:*:*)
|
||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
--- a/config.sub
|
||
+++ b/config.sub
|
||
@@ -1,10 +1,8 @@
|
||
#! /bin/sh
|
||
# Configuration validation subroutine script.
|
||
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||
-# 2011, 2012, 2013 Free Software Foundation, Inc.
|
||
+# Copyright 1992-2013 Free Software Foundation, Inc.
|
||
|
||
-timestamp='2013-01-11'
|
||
+timestamp='2013-04-24'
|
||
|
||
# This file is free software; you can redistribute it and/or modify it
|
||
# under the terms of the GNU General Public License as published by
|
||
@@ -70,9 +68,7 @@ Report bugs and patches to <config-patch
|
||
version="\
|
||
GNU config.sub ($timestamp)
|
||
|
||
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
|
||
-2012, 2013 Free Software Foundation, Inc.
|
||
+Copyright 1992-2013 Free Software Foundation, Inc.
|
||
|
||
This is free software; see the source for copying conditions. There is NO
|
||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||
@@ -256,7 +252,7 @@ case $basic_machine in
|
||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||
| am33_2.0 \
|
||
- | arc \
|
||
+ | arc | arceb \
|
||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||
| avr | avr32 \
|
||
| be32 | be64 \
|
||
@@ -297,10 +293,10 @@ case $basic_machine in
|
||
| mt \
|
||
| msp430 \
|
||
| nds32 | nds32le | nds32be \
|
||
- | nios | nios2 \
|
||
+ | nios | nios2 | nios2eb | nios2el \
|
||
| ns16k | ns32k \
|
||
| open8 \
|
||
- | or32 \
|
||
+ | or1k | or32 \
|
||
| pdp10 | pdp11 | pj | pjl \
|
||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||
| pyramid \
|
||
@@ -370,7 +366,7 @@ case $basic_machine in
|
||
| aarch64-* | aarch64_be-* \
|
||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||
| avr-* | avr32-* \
|
||
| be32-* | be64-* \
|
||
@@ -414,7 +410,7 @@ case $basic_machine in
|
||
| mt-* \
|
||
| msp430-* \
|
||
| nds32-* | nds32le-* | nds32be-* \
|
||
- | nios-* | nios2-* \
|
||
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
|
||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||
| open8-* \
|
||
| orion-* \
|
||
@@ -1593,6 +1589,9 @@ case $basic_machine in
|
||
mips*-*)
|
||
os=-elf
|
||
;;
|
||
+ or1k-*)
|
||
+ os=-elf
|
||
+ ;;
|
||
or32-*)
|
||
os=-coff
|
||
;;
|
||
|
||
#
|
||
# gdb-7.6-ppc_insns_match_pattern.patch
|
||
#
|
||
|
||
From: Alan Modra <amodra@gmail.com>
|
||
Date: Tue Jun 4 02:44:35 2013 +0000
|
||
Git-commit: 845d47080b7d7e068e4ec3d11fe6e27b403ac6e3
|
||
References: ppc64le enablement
|
||
|
||
* ppc-tdep.h (ppc_insns_match_pattern): Update prototype.
|
||
* rs6000-tdep.c (read_insn): Add frame param, don't assume big-endian.
|
||
(ppc_insns_match_pattern): Add frame param. Avoid multiple
|
||
target mem reads on optional insns.
|
||
* ppc-linux-tdep.c (ppc_skip_trampoline_code): Update
|
||
ppc_insns_match_pattern calls.
|
||
* ppc64-tdep.c (ppc64_standard_linkage2, ppc64_standard_linkage3):
|
||
Add match for power7 thread safety insns, and new order of
|
||
std 2,40(1) insn. Correct code shown for _dl_runtime_resolve
|
||
invocation in comment, and update rest of comment.
|
||
(PPC64_STANDARD_LINKAGE1_LEN, PPC64_STANDARD_LINKAGE2_LEN,
|
||
PPC64_STANDARD_LINKAGE3_LEN): Delete.
|
||
(ppc64_standard_linkage2_target): Update insn offsets.
|
||
(ppc64_skip_trampoline_code): Use a single insn buffer. Match newer
|
||
stubs first. Update calls.
|
||
|
||
Acked-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
gdb/ChangeLog | 18 ++++++
|
||
gdb/ppc-linux-tdep.c | 4 -
|
||
gdb/ppc-tdep.h | 4 -
|
||
gdb/ppc64-tdep.c | 140 ++++++++++++++++++++++++++++++---------------------
|
||
gdb/rs6000-tdep.c | 35 +++++++-----
|
||
5 files changed, 128 insertions(+), 73 deletions(-)
|
||
|
||
--- a/gdb/ChangeLog
|
||
+++ b/gdb/ChangeLog
|
||
@@ -1,3 +1,21 @@
|
||
+2013-06-04 Alan Modra <amodra@gmail.com>
|
||
+
|
||
+ * ppc-tdep.h (ppc_insns_match_pattern): Update prototype.
|
||
+ * rs6000-tdep.c (read_insn): Add frame param, don't assume big-endian.
|
||
+ (ppc_insns_match_pattern): Add frame param. Avoid multiple
|
||
+ target mem reads on optional insns.
|
||
+ * ppc-linux-tdep.c (ppc_skip_trampoline_code): Update
|
||
+ ppc_insns_match_pattern calls.
|
||
+ * ppc64-tdep.c (ppc64_standard_linkage2, ppc64_standard_linkage3):
|
||
+ Add match for power7 thread safety insns, and new order of
|
||
+ std 2,40(1) insn. Correct code shown for _dl_runtime_resolve
|
||
+ invocation in comment, and update rest of comment.
|
||
+ (PPC64_STANDARD_LINKAGE1_LEN, PPC64_STANDARD_LINKAGE2_LEN,
|
||
+ PPC64_STANDARD_LINKAGE3_LEN): Delete.
|
||
+ (ppc64_standard_linkage2_target): Update insn offsets.
|
||
+ (ppc64_skip_trampoline_code): Use a single insn buffer. Match newer
|
||
+ stubs first. Update calls.
|
||
+
|
||
2013-04-08 Tom Tromey <tromey@redhat.com>
|
||
|
||
* minsyms.h (struct bound_minimal_symbol): New.
|
||
--- a/gdb/ppc-linux-tdep.c
|
||
+++ b/gdb/ppc-linux-tdep.c
|
||
@@ -361,7 +361,7 @@ ppc_skip_trampoline_code (struct frame_i
|
||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||
CORE_ADDR target = 0;
|
||
|
||
- if (ppc_insns_match_pattern (pc, powerpc32_plt_stub, insnbuf))
|
||
+ if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
|
||
{
|
||
/* Insn pattern is
|
||
lis r11, xxxx
|
||
@@ -373,7 +373,7 @@ ppc_skip_trampoline_code (struct frame_i
|
||
target = read_memory_unsigned_integer (target, 4, byte_order);
|
||
}
|
||
|
||
- if (ppc_insns_match_pattern (pc, powerpc32_plt_stub_so, insnbuf))
|
||
+ if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf))
|
||
{
|
||
/* Insn pattern is
|
||
lwz r11, xxxx(r30)
|
||
--- a/gdb/ppc-tdep.h
|
||
+++ b/gdb/ppc-tdep.h
|
||
@@ -300,9 +300,9 @@ struct ppc_insn_pattern
|
||
int optional; /* If non-zero, this insn may be absent. */
|
||
};
|
||
|
||
-extern int ppc_insns_match_pattern (CORE_ADDR pc,
|
||
+extern int ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
|
||
struct ppc_insn_pattern *pattern,
|
||
- unsigned int *insn);
|
||
+ unsigned int *insns);
|
||
extern CORE_ADDR ppc_insn_d_field (unsigned int insn);
|
||
|
||
extern CORE_ADDR ppc_insn_ds_field (unsigned int insn);
|
||
--- a/gdb/ppc64-tdep.c
|
||
+++ b/gdb/ppc64-tdep.c
|
||
@@ -59,9 +59,10 @@ ppc64_desc_entry_point (struct gdbarch *
|
||
return (CORE_ADDR) read_memory_unsigned_integer (desc, 8, byte_order);
|
||
}
|
||
|
||
-/* Pattern for the standard linkage function. These are built by
|
||
- build_plt_stub in elf64-ppc.c, whose GLINK argument is always
|
||
- zero. */
|
||
+/* Patterns for the standard linkage functions. These are built by
|
||
+ build_plt_stub in bfd/elf64-ppc.c. */
|
||
+
|
||
+/* Old PLT call stub. */
|
||
|
||
static struct ppc_insn_pattern ppc64_standard_linkage1[] =
|
||
{
|
||
@@ -95,15 +96,23 @@ static struct ppc_insn_pattern ppc64_sta
|
||
{ 0, 0, 0 }
|
||
};
|
||
|
||
-#define PPC64_STANDARD_LINKAGE1_LEN ARRAY_SIZE (ppc64_standard_linkage1)
|
||
+/* Current PLT call stub to access PLT entries more than +/- 32k from r2.
|
||
+ Also supports older stub with different placement of std 2,40(1),
|
||
+ a stub that omits the std 2,40(1), and both versions of power7
|
||
+ thread safety read barriers. Note that there are actually two more
|
||
+ instructions following "cmpldi r2, 0", "bnectr+" and "b <glink_i>",
|
||
+ but there isn't any need to match them. */
|
||
|
||
static struct ppc_insn_pattern ppc64_standard_linkage2[] =
|
||
{
|
||
+ /* std r2, 40(r1) <optional> */
|
||
+ { -1, insn_ds (62, 2, 1, 40, 0), 1 },
|
||
+
|
||
/* addis r12, r2, <any> */
|
||
{ insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 },
|
||
|
||
- /* std r2, 40(r1) */
|
||
- { -1, insn_ds (62, 2, 1, 40, 0), 0 },
|
||
+ /* std r2, 40(r1) <optional> */
|
||
+ { -1, insn_ds (62, 2, 1, 40, 0), 1 },
|
||
|
||
/* ld r11, <any>(r12) */
|
||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
|
||
@@ -114,24 +123,33 @@ static struct ppc_insn_pattern ppc64_sta
|
||
/* mtctr r11 */
|
||
{ insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 },
|
||
|
||
+ /* xor r11, r11, r11 <optional> */
|
||
+ { -1, 0x7d6b5a78, 1 },
|
||
+
|
||
+ /* add r12, r12, r11 <optional> */
|
||
+ { -1, 0x7d8c5a14, 1 },
|
||
+
|
||
/* ld r2, <any>(r12) */
|
||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 },
|
||
|
||
/* ld r11, <any>(r12) <optional> */
|
||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 1 },
|
||
|
||
- /* bctr */
|
||
- { -1, 0x4e800420, 0 },
|
||
+ /* bctr <optional> */
|
||
+ { -1, 0x4e800420, 1 },
|
||
+
|
||
+ /* cmpldi r2, 0 <optional> */
|
||
+ { -1, 0x28220000, 1 },
|
||
|
||
{ 0, 0, 0 }
|
||
};
|
||
|
||
-#define PPC64_STANDARD_LINKAGE2_LEN ARRAY_SIZE (ppc64_standard_linkage2)
|
||
+/* Current PLT call stub to access PLT entries within +/- 32k of r2. */
|
||
|
||
static struct ppc_insn_pattern ppc64_standard_linkage3[] =
|
||
{
|
||
- /* std r2, 40(r1) */
|
||
- { -1, insn_ds (62, 2, 1, 40, 0), 0 },
|
||
+ /* std r2, 40(r1) <optional> */
|
||
+ { -1, insn_ds (62, 2, 1, 40, 0), 1 },
|
||
|
||
/* ld r11, <any>(r2) */
|
||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 0 },
|
||
@@ -142,56 +160,71 @@ static struct ppc_insn_pattern ppc64_sta
|
||
/* mtctr r11 */
|
||
{ insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 },
|
||
|
||
+ /* xor r11, r11, r11 <optional> */
|
||
+ { -1, 0x7d6b5a78, 1 },
|
||
+
|
||
+ /* add r2, r2, r11 <optional> */
|
||
+ { -1, 0x7c425a14, 1 },
|
||
+
|
||
/* ld r11, <any>(r2) <optional> */
|
||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 },
|
||
|
||
/* ld r2, <any>(r2) */
|
||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 },
|
||
|
||
- /* bctr */
|
||
- { -1, 0x4e800420, 0 },
|
||
+ /* bctr <optional> */
|
||
+ { -1, 0x4e800420, 1 },
|
||
+
|
||
+ /* cmpldi r2, 0 <optional> */
|
||
+ { -1, 0x28220000, 1 },
|
||
|
||
{ 0, 0, 0 }
|
||
};
|
||
|
||
-#define PPC64_STANDARD_LINKAGE3_LEN ARRAY_SIZE (ppc64_standard_linkage3)
|
||
-
|
||
/* When the dynamic linker is doing lazy symbol resolution, the first
|
||
call to a function in another object will go like this:
|
||
|
||
- The user's function calls the linkage function:
|
||
|
||
- 100007c4: 4b ff fc d5 bl 10000498
|
||
- 100007c8: e8 41 00 28 ld r2,40(r1)
|
||
+ 100003d4: 4b ff ff ad bl 10000380 <nnnn.plt_call.printf>
|
||
+ 100003d8: e8 41 00 28 ld r2,40(r1)
|
||
|
||
- - The linkage function loads the entry point (and other stuff) from
|
||
- the function descriptor in the PLT, and jumps to it:
|
||
+ - The linkage function loads the entry point and toc pointer from
|
||
+ the function descriptor in the PLT, and jumps to it:
|
||
|
||
- 10000498: 3d 82 00 00 addis r12,r2,0
|
||
- 1000049c: f8 41 00 28 std r2,40(r1)
|
||
- 100004a0: e9 6c 80 98 ld r11,-32616(r12)
|
||
- 100004a4: e8 4c 80 a0 ld r2,-32608(r12)
|
||
- 100004a8: 7d 69 03 a6 mtctr r11
|
||
- 100004ac: e9 6c 80 a8 ld r11,-32600(r12)
|
||
- 100004b0: 4e 80 04 20 bctr
|
||
+ <nnnn.plt_call.printf>:
|
||
+ 10000380: f8 41 00 28 std r2,40(r1)
|
||
+ 10000384: e9 62 80 78 ld r11,-32648(r2)
|
||
+ 10000388: 7d 69 03 a6 mtctr r11
|
||
+ 1000038c: e8 42 80 80 ld r2,-32640(r2)
|
||
+ 10000390: 28 22 00 00 cmpldi r2,0
|
||
+ 10000394: 4c e2 04 20 bnectr+
|
||
+ 10000398: 48 00 03 a0 b 10000738 <printf@plt>
|
||
|
||
- But since this is the first time that PLT entry has been used, it
|
||
- sends control to its glink entry. That loads the number of the
|
||
- PLT entry and jumps to the common glink0 code:
|
||
+ sends control to its glink entry. That loads the number of the
|
||
+ PLT entry and jumps to the common glink0 code:
|
||
|
||
- 10000c98: 38 00 00 00 li r0,0
|
||
- 10000c9c: 4b ff ff dc b 10000c78
|
||
+ <printf@plt>:
|
||
+ 10000738: 38 00 00 01 li r0,1
|
||
+ 1000073c: 4b ff ff bc b 100006f8 <__glink_PLTresolve>
|
||
|
||
- The common glink0 code then transfers control to the dynamic
|
||
- linker's fixup code:
|
||
+ linker's fixup code:
|
||
|
||
- 10000c78: e8 41 00 28 ld r2,40(r1)
|
||
- 10000c7c: 3d 82 00 00 addis r12,r2,0
|
||
- 10000c80: e9 6c 80 80 ld r11,-32640(r12)
|
||
- 10000c84: e8 4c 80 88 ld r2,-32632(r12)
|
||
- 10000c88: 7d 69 03 a6 mtctr r11
|
||
- 10000c8c: e9 6c 80 90 ld r11,-32624(r12)
|
||
- 10000c90: 4e 80 04 20 bctr
|
||
+ 100006f0: 0000000000010440 .quad plt0 - (. + 16)
|
||
+ <__glink_PLTresolve>:
|
||
+ 100006f8: 7d 88 02 a6 mflr r12
|
||
+ 100006fc: 42 9f 00 05 bcl 20,4*cr7+so,10000700
|
||
+ 10000700: 7d 68 02 a6 mflr r11
|
||
+ 10000704: e8 4b ff f0 ld r2,-16(r11)
|
||
+ 10000708: 7d 88 03 a6 mtlr r12
|
||
+ 1000070c: 7d 82 5a 14 add r12,r2,r11
|
||
+ 10000710: e9 6c 00 00 ld r11,0(r12)
|
||
+ 10000714: e8 4c 00 08 ld r2,8(r12)
|
||
+ 10000718: 7d 69 03 a6 mtctr r11
|
||
+ 1000071c: e9 6c 00 10 ld r11,16(r12)
|
||
+ 10000720: 4e 80 04 20 bctr
|
||
|
||
Eventually, this code will figure out how to skip all of this,
|
||
including the dynamic linker. At the moment, we just get through
|
||
@@ -234,8 +267,8 @@ ppc64_standard_linkage2_target (struct f
|
||
CORE_ADDR desc
|
||
= ((CORE_ADDR) get_frame_register_unsigned (frame,
|
||
tdep->ppc_gp0_regnum + 2)
|
||
- + (ppc_insn_d_field (insn[0]) << 16)
|
||
- + ppc_insn_ds_field (insn[2]));
|
||
+ + (ppc_insn_d_field (insn[1]) << 16)
|
||
+ + ppc_insn_ds_field (insn[3]));
|
||
|
||
/* The first word of the descriptor is the entry point. Return that. */
|
||
return ppc64_desc_entry_point (gdbarch, desc);
|
||
@@ -266,23 +299,20 @@ ppc64_standard_linkage3_target (struct f
|
||
CORE_ADDR
|
||
ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||
{
|
||
- unsigned int ppc64_standard_linkage1_insn[PPC64_STANDARD_LINKAGE1_LEN];
|
||
- unsigned int ppc64_standard_linkage2_insn[PPC64_STANDARD_LINKAGE2_LEN];
|
||
- unsigned int ppc64_standard_linkage3_insn[PPC64_STANDARD_LINKAGE3_LEN];
|
||
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||
+ unsigned int insns[MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1),
|
||
+ ARRAY_SIZE (ppc64_standard_linkage2)),
|
||
+ ARRAY_SIZE (ppc64_standard_linkage3)) - 1];
|
||
CORE_ADDR target;
|
||
|
||
- if (ppc_insns_match_pattern (pc, ppc64_standard_linkage1,
|
||
- ppc64_standard_linkage1_insn))
|
||
- pc = ppc64_standard_linkage1_target (frame, pc,
|
||
- ppc64_standard_linkage1_insn);
|
||
- else if (ppc_insns_match_pattern (pc, ppc64_standard_linkage2,
|
||
- ppc64_standard_linkage2_insn))
|
||
- pc = ppc64_standard_linkage2_target (frame, pc,
|
||
- ppc64_standard_linkage2_insn);
|
||
- else if (ppc_insns_match_pattern (pc, ppc64_standard_linkage3,
|
||
- ppc64_standard_linkage3_insn))
|
||
- pc = ppc64_standard_linkage3_target (frame, pc,
|
||
- ppc64_standard_linkage3_insn);
|
||
+ if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
|
||
+ && (insns[8] != 0 || insns[9] != 0))
|
||
+ pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
||
+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns)
|
||
+ && (insns[10] != 0 || insns[11] != 0))
|
||
+ pc = ppc64_standard_linkage2_target (frame, pc, insns);
|
||
+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns))
|
||
+ pc = ppc64_standard_linkage1_target (frame, pc, insns);
|
||
else
|
||
return 0;
|
||
|
||
--- a/gdb/rs6000-tdep.c
|
||
+++ b/gdb/rs6000-tdep.c
|
||
@@ -4238,14 +4238,15 @@ show_powerpc_exact_watchpoints (struct u
|
||
fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value);
|
||
}
|
||
|
||
-/* Read a PPC instruction from memory. PPC instructions are always
|
||
- big-endian, no matter what endianness the program is running in, so
|
||
- we can hardcode BFD_ENDIAN_BIG for read_memory_unsigned_integer. */
|
||
+/* Read a PPC instruction from memory. */
|
||
|
||
static unsigned int
|
||
-read_insn (CORE_ADDR pc)
|
||
+read_insn (struct frame_info *frame, CORE_ADDR pc)
|
||
{
|
||
- return read_memory_unsigned_integer (pc, 4, BFD_ENDIAN_BIG);
|
||
+ struct gdbarch *gdbarch = get_frame_arch (frame);
|
||
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||
+
|
||
+ return read_memory_unsigned_integer (pc, 4, byte_order);
|
||
}
|
||
|
||
/* Return non-zero if the instructions at PC match the series
|
||
@@ -4262,19 +4263,25 @@ read_insn (CORE_ADDR pc)
|
||
i'th instruction in memory. */
|
||
|
||
int
|
||
-ppc_insns_match_pattern (CORE_ADDR pc, struct ppc_insn_pattern *pattern,
|
||
- unsigned int *insn)
|
||
+ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
|
||
+ struct ppc_insn_pattern *pattern,
|
||
+ unsigned int *insns)
|
||
{
|
||
int i;
|
||
+ unsigned int insn;
|
||
|
||
- for (i = 0; pattern[i].mask; i++)
|
||
+ for (i = 0, insn = 0; pattern[i].mask; i++)
|
||
{
|
||
- insn[i] = read_insn (pc);
|
||
- if ((insn[i] & pattern[i].mask) == pattern[i].data)
|
||
- pc += 4;
|
||
- else if (pattern[i].optional)
|
||
- insn[i] = 0;
|
||
- else
|
||
+ if (insn == 0)
|
||
+ insn = read_insn (frame, pc);
|
||
+ insns[i] = 0;
|
||
+ if ((insn & pattern[i].mask) == pattern[i].data)
|
||
+ {
|
||
+ insns[i] = insn;
|
||
+ pc += 4;
|
||
+ insn = 0;
|
||
+ }
|
||
+ else if (!pattern[i].optional)
|
||
return 0;
|
||
}
|
||
|
||
|
||
#
|
||
# gdb-7.6-floatformat.patch
|
||
#
|
||
|
||
From: DJ Delorie <dj@redhat.com>
|
||
Date: Tue Aug 20 06:02:53 2013 +0000
|
||
Git-commit: 21290977cbdd41c6f4e7b297e63901ad491acadd
|
||
References: ppc64le enablement
|
||
|
||
merge from gcc
|
||
|
||
Acked-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
include/ChangeLog | 10 ++++++++++
|
||
include/dwarf2.def | 3 +++
|
||
include/floatformat.h | 3 ++-
|
||
libiberty/ChangeLog | 6 ++++++
|
||
libiberty/floatformat.c | 13 +++++++++++--
|
||
5 files changed, 32 insertions(+), 3 deletions(-)
|
||
|
||
--- a/include/ChangeLog
|
||
+++ b/include/ChangeLog
|
||
@@ -1,3 +1,13 @@
|
||
+2013-08-20 Alan Modra <amodra@gmail.com>
|
||
+
|
||
+ * floatformat.h (floatformat_ibm_long_double): Delete.
|
||
+ (floatformat_ibm_long_double_big): Declare.
|
||
+ (floatformat_ibm_long_double_little): Declare.
|
||
+
|
||
+2013-08-19 Dehao Chen <dehao@google.com>
|
||
+
|
||
+ * dwarf2.def (DW_AT_GNU_discriminator): New attribute.
|
||
+
|
||
2013-03-12 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||
|
||
* opcode/nios2.h: Edit comment.
|
||
--- a/include/dwarf2.def
|
||
+++ b/include/dwarf2.def
|
||
@@ -390,6 +390,9 @@ DW_AT (DW_AT_GNU_ranges_base, 0x2132)
|
||
DW_AT (DW_AT_GNU_addr_base, 0x2133)
|
||
DW_AT (DW_AT_GNU_pubnames, 0x2134)
|
||
DW_AT (DW_AT_GNU_pubtypes, 0x2135)
|
||
+/* Attribute for discriminator.
|
||
+ See http://gcc.gnu.org/wiki/Discriminator */
|
||
+DW_AT (DW_AT_GNU_discriminator, 0x2136)
|
||
/* VMS extensions. */
|
||
DW_AT (DW_AT_VMS_rtnbeg_pd_address, 0x2201)
|
||
/* GNAT extensions. */
|
||
--- a/include/floatformat.h
|
||
+++ b/include/floatformat.h
|
||
@@ -128,7 +128,8 @@ extern const struct floatformat floatfor
|
||
extern const struct floatformat floatformat_ia64_quad_big;
|
||
extern const struct floatformat floatformat_ia64_quad_little;
|
||
/* IBM long double (double+double). */
|
||
-extern const struct floatformat floatformat_ibm_long_double;
|
||
+extern const struct floatformat floatformat_ibm_long_double_big;
|
||
+extern const struct floatformat floatformat_ibm_long_double_little;
|
||
|
||
/* Convert from FMT to a double.
|
||
FROM is the address of the extended float.
|
||
--- a/libiberty/ChangeLog
|
||
+++ b/libiberty/ChangeLog
|
||
@@ -1,3 +1,9 @@
|
||
+2013-08-20 Alan Modra <amodra@gmail.com>
|
||
+
|
||
+ * floatformat.c (floatformat_ibm_long_double): Rename to..
|
||
+ (floatformat_ibm_long_double_big): ..this.
|
||
+ (floatformat_ibm_long_double_little): New.
|
||
+
|
||
2013-03-01 Andreas Schwab <schwab@linux-m68k.org>
|
||
|
||
* obstacks.texi (Obstacks): Trim @node to only contain the
|
||
--- a/libiberty/floatformat.c
|
||
+++ b/libiberty/floatformat.c
|
||
@@ -371,14 +371,23 @@ floatformat_ibm_long_double_is_valid (co
|
||
}
|
||
}
|
||
|
||
-const struct floatformat floatformat_ibm_long_double =
|
||
+const struct floatformat floatformat_ibm_long_double_big =
|
||
{
|
||
floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
|
||
floatformat_intbit_no,
|
||
- "floatformat_ibm_long_double",
|
||
+ "floatformat_ibm_long_double_big",
|
||
floatformat_ibm_long_double_is_valid,
|
||
&floatformat_ieee_double_big
|
||
};
|
||
+
|
||
+const struct floatformat floatformat_ibm_long_double_little =
|
||
+{
|
||
+ floatformat_little, 128, 0, 1, 11, 1023, 2047, 12, 52,
|
||
+ floatformat_intbit_no,
|
||
+ "floatformat_ibm_long_double_little",
|
||
+ floatformat_ibm_long_double_is_valid,
|
||
+ &floatformat_ieee_double_little
|
||
+};
|
||
|
||
|
||
#ifndef min
|
||
|
||
#
|
||
# gdb-7.6-ppc64-ELFv2-trampoline-match.patch
|
||
#
|
||
|
||
From: Alan Modra <amodra@gmail.com>
|
||
Date: Mon Nov 11 14:14:40 2013 +1030
|
||
Git-commit: ef1bc9e72fd2f0310ac3113acc41e1c115e3ac79
|
||
References: ppc64le enablement
|
||
|
||
PowerPC64 ELFv2 trampoline match
|
||
|
||
ELFv2 needs different plt call stubs to ELFv1, register usage differs
|
||
too. When I added these to ld I changed register usage in the ELFv1
|
||
stubs as well, simplifying the linker code and (perhaps) future
|
||
maintenance. All well and good, but this means gdb needs to cope with
|
||
more stub variants. This patch also handles skipping over addis/addi
|
||
setting up r2 in ELFv2 global entry code. We want breakpoints to be
|
||
set past this point to catch calls via the local entry point.
|
||
|
||
* ppc64-tdep.c (ppc64_plt_entry_point): Renamed from..
|
||
(ppc64_desc_entry_point): ..this. Update comments here and at
|
||
call points.
|
||
(ppc64_standard_linkage1, ppc64_standard_linkage2,
|
||
ppc64_standard_linkage3): Update comments.
|
||
(ppc64_standard_linkage4, ppc64_standard_linkage5,
|
||
(ppc64_standard_linkage6, ppc64_standard_linkage7): New insn
|
||
patterns.
|
||
(ppc64_standard_linkage4_target): New function.
|
||
(ppc64_skip_trampoline_code): Skip ELFv2 patterns too.
|
||
* rs6000-tdep.c (skip_prologue): Skip ELFv2 r2 setup. Correct
|
||
nop match. Fix comment wrap.
|
||
|
||
Acked-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
gdb/ChangeLog | 15 ++++
|
||
gdb/ppc64-tdep.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++--------
|
||
gdb/rs6000-tdep.c | 20 ++++-
|
||
3 files changed, 203 insertions(+), 33 deletions(-)
|
||
|
||
--- a/gdb/ChangeLog
|
||
+++ b/gdb/ChangeLog
|
||
@@ -1,3 +1,18 @@
|
||
+2013-11-15 Alan Modra <amodra@gmail.com>
|
||
+
|
||
+ * ppc64-tdep.c (ppc64_plt_entry_point): Renamed from..
|
||
+ (ppc64_desc_entry_point): ..this. Update comments here and at
|
||
+ call points.
|
||
+ (ppc64_standard_linkage1, ppc64_standard_linkage2,
|
||
+ ppc64_standard_linkage3): Update comments.
|
||
+ (ppc64_standard_linkage4, ppc64_standard_linkage5,
|
||
+ (ppc64_standard_linkage6, ppc64_standard_linkage7): New insn
|
||
+ patterns.
|
||
+ (ppc64_standard_linkage4_target): New function.
|
||
+ (ppc64_skip_trampoline_code): Skip ELFv2 patterns too.
|
||
+ * rs6000-tdep.c (skip_prologue): Skip ELFv2 r2 setup. Correct
|
||
+ nop match. Fix comment wrap.
|
||
+
|
||
2013-06-04 Alan Modra <amodra@gmail.com>
|
||
|
||
* ppc-tdep.h (ppc_insns_match_pattern): Update prototype.
|
||
--- a/gdb/ppc64-tdep.c
|
||
+++ b/gdb/ppc64-tdep.c
|
||
@@ -48,21 +48,21 @@
|
||
| (((spr) & 0x3e0) << 6) \
|
||
| (((xo) & 0x3ff) << 1))
|
||
|
||
-/* If DESC is the address of a 64-bit PowerPC FreeBSD function
|
||
- descriptor, return the descriptor's entry point. */
|
||
+/* If PLT is the address of a 64-bit PowerPC PLT entry,
|
||
+ return the function's entry point. */
|
||
|
||
static CORE_ADDR
|
||
-ppc64_desc_entry_point (struct gdbarch *gdbarch, CORE_ADDR desc)
|
||
+ppc64_plt_entry_point (struct gdbarch *gdbarch, CORE_ADDR plt)
|
||
{
|
||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||
- /* The first word of the descriptor is the entry point. */
|
||
- return (CORE_ADDR) read_memory_unsigned_integer (desc, 8, byte_order);
|
||
+ /* The first word of the PLT entry is the function entry point. */
|
||
+ return (CORE_ADDR) read_memory_unsigned_integer (plt, 8, byte_order);
|
||
}
|
||
|
||
/* Patterns for the standard linkage functions. These are built by
|
||
build_plt_stub in bfd/elf64-ppc.c. */
|
||
|
||
-/* Old PLT call stub. */
|
||
+/* Old ELFv1 PLT call stub. */
|
||
|
||
static struct ppc_insn_pattern ppc64_standard_linkage1[] =
|
||
{
|
||
@@ -96,7 +96,7 @@ static struct ppc_insn_pattern ppc64_sta
|
||
{ 0, 0, 0 }
|
||
};
|
||
|
||
-/* Current PLT call stub to access PLT entries more than +/- 32k from r2.
|
||
+/* ELFv1 PLT call stub to access PLT entries more than +/- 32k from r2.
|
||
Also supports older stub with different placement of std 2,40(1),
|
||
a stub that omits the std 2,40(1), and both versions of power7
|
||
thread safety read barriers. Note that there are actually two more
|
||
@@ -144,7 +144,7 @@ static struct ppc_insn_pattern ppc64_sta
|
||
{ 0, 0, 0 }
|
||
};
|
||
|
||
-/* Current PLT call stub to access PLT entries within +/- 32k of r2. */
|
||
+/* ELFv1 PLT call stub to access PLT entries within +/- 32k of r2. */
|
||
|
||
static struct ppc_insn_pattern ppc64_standard_linkage3[] =
|
||
{
|
||
@@ -181,6 +181,128 @@ static struct ppc_insn_pattern ppc64_sta
|
||
{ 0, 0, 0 }
|
||
};
|
||
|
||
+/* ELFv1 PLT call stub to access PLT entries more than +/- 32k from r2.
|
||
+ A more modern variant of ppc64_standard_linkage2 differing in
|
||
+ register usage. */
|
||
+
|
||
+static struct ppc_insn_pattern ppc64_standard_linkage4[] =
|
||
+ {
|
||
+ /* std r2, 40(r1) <optional> */
|
||
+ { -1, insn_ds (62, 2, 1, 40, 0), 1 },
|
||
+
|
||
+ /* addis r11, r2, <any> */
|
||
+ { insn_d (-1, -1, -1, 0), insn_d (15, 11, 2, 0), 0 },
|
||
+
|
||
+ /* ld r12, <any>(r11) */
|
||
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 11, 0, 0), 0 },
|
||
+
|
||
+ /* addi r11, r11, <any> <optional> */
|
||
+ { insn_d (-1, -1, -1, 0), insn_d (14, 11, 11, 0), 1 },
|
||
+
|
||
+ /* mtctr r12 */
|
||
+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 },
|
||
+
|
||
+ /* xor r2, r12, r12 <optional> */
|
||
+ { -1, 0x7d826278, 1 },
|
||
+
|
||
+ /* add r11, r11, r2 <optional> */
|
||
+ { -1, 0x7d6b1214, 1 },
|
||
+
|
||
+ /* ld r2, <any>(r11) */
|
||
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 11, 0, 0), 0 },
|
||
+
|
||
+ /* ld r11, <any>(r11) <optional> */
|
||
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 11, 0, 0), 1 },
|
||
+
|
||
+ /* bctr <optional> */
|
||
+ { -1, 0x4e800420, 1 },
|
||
+
|
||
+ /* cmpldi r2, 0 <optional> */
|
||
+ { -1, 0x28220000, 1 },
|
||
+
|
||
+ { 0, 0, 0 }
|
||
+ };
|
||
+
|
||
+/* ELFv1 PLT call stub to access PLT entries within +/- 32k of r2.
|
||
+ A more modern variant of ppc64_standard_linkage3 differing in
|
||
+ register usage. */
|
||
+
|
||
+static struct ppc_insn_pattern ppc64_standard_linkage5[] =
|
||
+ {
|
||
+ /* std r2, 40(r1) <optional> */
|
||
+ { -1, insn_ds (62, 2, 1, 40, 0), 1 },
|
||
+
|
||
+ /* ld r12, <any>(r2) */
|
||
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 },
|
||
+
|
||
+ /* addi r2, r2, <any> <optional> */
|
||
+ { insn_d (-1, -1, -1, 0), insn_d (14, 2, 2, 0), 1 },
|
||
+
|
||
+ /* mtctr r12 */
|
||
+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 },
|
||
+
|
||
+ /* xor r11, r12, r12 <optional> */
|
||
+ { -1, 0x7d8b6278, 1 },
|
||
+
|
||
+ /* add r2, r2, r11 <optional> */
|
||
+ { -1, 0x7c425a14, 1 },
|
||
+
|
||
+ /* ld r11, <any>(r2) <optional> */
|
||
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 },
|
||
+
|
||
+ /* ld r2, <any>(r2) */
|
||
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 },
|
||
+
|
||
+ /* bctr <optional> */
|
||
+ { -1, 0x4e800420, 1 },
|
||
+
|
||
+ /* cmpldi r2, 0 <optional> */
|
||
+ { -1, 0x28220000, 1 },
|
||
+
|
||
+ { 0, 0, 0 }
|
||
+ };
|
||
+
|
||
+/* ELFv2 PLT call stub to access PLT entries more than +/- 32k from r2. */
|
||
+
|
||
+static struct ppc_insn_pattern ppc64_standard_linkage6[] =
|
||
+ {
|
||
+ /* std r2, 24(r1) <optional> */
|
||
+ { -1, insn_ds (62, 2, 1, 24, 0), 1 },
|
||
+
|
||
+ /* addis r11, r2, <any> */
|
||
+ { insn_d (-1, -1, -1, 0), insn_d (15, 11, 2, 0), 0 },
|
||
+
|
||
+ /* ld r12, <any>(r11) */
|
||
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 11, 0, 0), 0 },
|
||
+
|
||
+ /* mtctr r12 */
|
||
+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 },
|
||
+
|
||
+ /* bctr */
|
||
+ { -1, 0x4e800420, 0 },
|
||
+
|
||
+ { 0, 0, 0 }
|
||
+ };
|
||
+
|
||
+/* ELFv2 PLT call stub to access PLT entries within +/- 32k of r2. */
|
||
+
|
||
+static struct ppc_insn_pattern ppc64_standard_linkage7[] =
|
||
+ {
|
||
+ /* std r2, 24(r1) <optional> */
|
||
+ { -1, insn_ds (62, 2, 1, 40, 0), 1 },
|
||
+
|
||
+ /* ld r12, <any>(r2) */
|
||
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 },
|
||
+
|
||
+ /* mtctr r12 */
|
||
+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 },
|
||
+
|
||
+ /* bctr */
|
||
+ { -1, 0x4e800420, 0 },
|
||
+
|
||
+ { 0, 0, 0 }
|
||
+ };
|
||
+
|
||
/* When the dynamic linker is doing lazy symbol resolution, the first
|
||
call to a function in another object will go like this:
|
||
|
||
@@ -243,16 +365,14 @@ ppc64_standard_linkage1_target (struct f
|
||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||
|
||
- /* The address of the function descriptor this linkage function
|
||
- references. */
|
||
- CORE_ADDR desc
|
||
+ /* The address of the PLT entry this linkage function references. */
|
||
+ CORE_ADDR plt
|
||
= ((CORE_ADDR) get_frame_register_unsigned (frame,
|
||
tdep->ppc_gp0_regnum + 2)
|
||
+ (ppc_insn_d_field (insn[0]) << 16)
|
||
+ ppc_insn_ds_field (insn[2]));
|
||
|
||
- /* The first word of the descriptor is the entry point. Return that. */
|
||
- return ppc64_desc_entry_point (gdbarch, desc);
|
||
+ return ppc64_plt_entry_point (gdbarch, plt);
|
||
}
|
||
|
||
static CORE_ADDR
|
||
@@ -262,16 +382,14 @@ ppc64_standard_linkage2_target (struct f
|
||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||
|
||
- /* The address of the function descriptor this linkage function
|
||
- references. */
|
||
- CORE_ADDR desc
|
||
+ /* The address of the PLT entry this linkage function references. */
|
||
+ CORE_ADDR plt
|
||
= ((CORE_ADDR) get_frame_register_unsigned (frame,
|
||
tdep->ppc_gp0_regnum + 2)
|
||
+ (ppc_insn_d_field (insn[1]) << 16)
|
||
+ ppc_insn_ds_field (insn[3]));
|
||
|
||
- /* The first word of the descriptor is the entry point. Return that. */
|
||
- return ppc64_desc_entry_point (gdbarch, desc);
|
||
+ return ppc64_plt_entry_point (gdbarch, plt);
|
||
}
|
||
|
||
static CORE_ADDR
|
||
@@ -281,15 +399,28 @@ ppc64_standard_linkage3_target (struct f
|
||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||
|
||
- /* The address of the function descriptor this linkage function
|
||
- references. */
|
||
- CORE_ADDR desc
|
||
+ /* The address of the PLT entry this linkage function references. */
|
||
+ CORE_ADDR plt
|
||
= ((CORE_ADDR) get_frame_register_unsigned (frame,
|
||
tdep->ppc_gp0_regnum + 2)
|
||
+ ppc_insn_ds_field (insn[1]));
|
||
|
||
- /* The first word of the descriptor is the entry point. Return that. */
|
||
- return ppc64_desc_entry_point (gdbarch, desc);
|
||
+ return ppc64_plt_entry_point (gdbarch, plt);
|
||
+}
|
||
+
|
||
+static CORE_ADDR
|
||
+ppc64_standard_linkage4_target (struct frame_info *frame,
|
||
+ CORE_ADDR pc, unsigned int *insn)
|
||
+{
|
||
+ struct gdbarch *gdbarch = get_frame_arch (frame);
|
||
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||
+
|
||
+ CORE_ADDR plt
|
||
+ = ((CORE_ADDR) get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 2)
|
||
+ + (ppc_insn_d_field (insn[1]) << 16)
|
||
+ + ppc_insn_ds_field (insn[2]));
|
||
+
|
||
+ return ppc64_plt_entry_point (gdbarch, plt);
|
||
}
|
||
|
||
|
||
@@ -300,13 +431,27 @@ CORE_ADDR
|
||
ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||
{
|
||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||
- unsigned int insns[MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1),
|
||
- ARRAY_SIZE (ppc64_standard_linkage2)),
|
||
- ARRAY_SIZE (ppc64_standard_linkage3)) - 1];
|
||
+ unsigned int insns[MAX (MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1),
|
||
+ ARRAY_SIZE (ppc64_standard_linkage2)),
|
||
+ MAX (ARRAY_SIZE (ppc64_standard_linkage3),
|
||
+ ARRAY_SIZE (ppc64_standard_linkage4))),
|
||
+ MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage5),
|
||
+ ARRAY_SIZE (ppc64_standard_linkage6)),
|
||
+ ARRAY_SIZE (ppc64_standard_linkage7))) - 1];
|
||
CORE_ADDR target;
|
||
|
||
- if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
|
||
- && (insns[8] != 0 || insns[9] != 0))
|
||
+ if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns))
|
||
+ pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
||
+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns))
|
||
+ pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
||
+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns)
|
||
+ && (insns[8] != 0 || insns[9] != 0))
|
||
+ pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
||
+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns)
|
||
+ && (insns[9] != 0 || insns[10] != 0))
|
||
+ pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
||
+ else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
|
||
+ && (insns[8] != 0 || insns[9] != 0))
|
||
pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns)
|
||
&& (insns[10] != 0 || insns[11] != 0))
|
||
--- a/gdb/rs6000-tdep.c
|
||
+++ b/gdb/rs6000-tdep.c
|
||
@@ -1616,7 +1616,19 @@ skip_prologue (struct gdbarch *gdbarch,
|
||
continue;
|
||
|
||
}
|
||
- else if ((op & 0xffff0000) == 0x60000000)
|
||
+ else if ((op & 0xffff0000) == 0x3c4c0000
|
||
+ || (op & 0xffff0000) == 0x3c400000
|
||
+ || (op & 0xffff0000) == 0x38420000)
|
||
+ {
|
||
+ /* . 0: addis 2,12,.TOC.-0b@ha
|
||
+ . addi 2,2,.TOC.-0b@l
|
||
+ or
|
||
+ . lis 2,.TOC.@ha
|
||
+ . addi 2,2,.TOC.@l
|
||
+ used by ELFv2 global entry points to set up r2. */
|
||
+ continue;
|
||
+ }
|
||
+ else if (op == 0x60000000)
|
||
{
|
||
/* nop */
|
||
/* Allow nops in the prologue, but do not consider them to
|
||
@@ -1627,8 +1639,7 @@ skip_prologue (struct gdbarch *gdbarch,
|
||
|
||
}
|
||
else if ((op & 0xffff0000) == 0x3c000000)
|
||
- { /* addis 0,0,NUM, used
|
||
- for >= 32k frames */
|
||
+ { /* addis 0,0,NUM, used for >= 32k frames */
|
||
fdata->offset = (op & 0x0000ffff) << 16;
|
||
fdata->frameless = 0;
|
||
r0_contains_arg = 0;
|
||
@@ -1636,8 +1647,7 @@ skip_prologue (struct gdbarch *gdbarch,
|
||
|
||
}
|
||
else if ((op & 0xffff0000) == 0x60000000)
|
||
- { /* ori 0,0,NUM, 2nd ha
|
||
- lf of >= 32k frames */
|
||
+ { /* ori 0,0,NUM, 2nd half of >= 32k frames */
|
||
fdata->offset |= (op & 0x0000ffff);
|
||
fdata->frameless = 0;
|
||
r0_contains_arg = 0;
|
||
|
||
#
|
||
# gdb-7.6-update-autoconf-2013-06-10.patch
|
||
#
|
||
|
||
From: Alan Modra <amodra@gmail.com>
|
||
Date: Sat Nov 23 08:55:31 2013 +1030
|
||
Git-commit: f3f51a69187bd04f61373f54afd359e595d18011
|
||
References: ppc64le enablement
|
||
|
||
Import config.sub and config.guess from upstream.
|
||
|
||
Acked-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
ChangeLog | 4 +
|
||
config.guess | 144 ++++++++++++++++++++++++++++++++---------------------------
|
||
config.sub | 17 ++++--
|
||
3 files changed, 94 insertions(+), 71 deletions(-)
|
||
|
||
--- a/ChangeLog
|
||
+++ b/ChangeLog
|
||
@@ -1,3 +1,7 @@
|
||
+2013-11-23 Alan Modra <amodra@gmail.com>
|
||
+
|
||
+ * config.sub, config.guess: Import from upstream.
|
||
+
|
||
2013-04-29 Jan-Benedict Glaw <jbglaw@lug-owl.de>
|
||
|
||
* config.guess: Update from config repo.
|
||
--- a/config.guess
|
||
+++ b/config.guess
|
||
@@ -2,7 +2,7 @@
|
||
# Attempt to guess a canonical system name.
|
||
# Copyright 1992-2013 Free Software Foundation, Inc.
|
||
|
||
-timestamp='2013-04-24'
|
||
+timestamp='2013-06-10'
|
||
|
||
# This file is free software; you can redistribute it and/or modify it
|
||
# under the terms of the GNU General Public License as published by
|
||
@@ -132,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` |
|
||
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||
|
||
+case "${UNAME_SYSTEM}" in
|
||
+Linux|GNU|GNU/*)
|
||
+ # If the system lacks a compiler, then just pick glibc.
|
||
+ # We could probably try harder.
|
||
+ LIBC=gnu
|
||
+
|
||
+ eval $set_cc_for_build
|
||
+ cat <<-EOF > $dummy.c
|
||
+ #include <features.h>
|
||
+ #if defined(__UCLIBC__)
|
||
+ LIBC=uclibc
|
||
+ #elif defined(__dietlibc__)
|
||
+ LIBC=dietlibc
|
||
+ #else
|
||
+ LIBC=gnu
|
||
+ #endif
|
||
+ EOF
|
||
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
||
+ ;;
|
||
+esac
|
||
+
|
||
# Note: order is significant - the case branches are not exclusive.
|
||
|
||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||
@@ -853,21 +874,21 @@ EOF
|
||
exit ;;
|
||
*:GNU:*:*)
|
||
# the GNU system
|
||
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||
exit ;;
|
||
*:GNU/*:*:*)
|
||
# other systems with GNU libc and userland
|
||
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
||
exit ;;
|
||
i*86:Minix:*:*)
|
||
echo ${UNAME_MACHINE}-pc-minix
|
||
exit ;;
|
||
aarch64:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
aarch64_be:Linux:*:*)
|
||
UNAME_MACHINE=aarch64_be
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
alpha:Linux:*:*)
|
||
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
||
@@ -880,67 +901,54 @@ EOF
|
||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||
esac
|
||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
arc:Linux:*:* | arceb:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
arm*:Linux:*:*)
|
||
eval $set_cc_for_build
|
||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||
| grep -q __ARM_EABI__
|
||
then
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
else
|
||
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
||
| grep -q __ARM_PCS_VFP
|
||
then
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
|
||
else
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
|
||
fi
|
||
fi
|
||
exit ;;
|
||
avr32*:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
cris:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-axis-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||
exit ;;
|
||
crisv32:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-axis-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||
exit ;;
|
||
frv:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
hexagon:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
i*86:Linux:*:*)
|
||
- LIBC=gnu
|
||
- eval $set_cc_for_build
|
||
- sed 's/^ //' << EOF >$dummy.c
|
||
- #ifdef __dietlibc__
|
||
- LIBC=dietlibc
|
||
- #endif
|
||
- #else
|
||
- #include <features.h>
|
||
- #ifdef __UCLIBC__
|
||
- LIBC=uclibc
|
||
- #endif
|
||
-EOF
|
||
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
||
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
|
||
exit ;;
|
||
ia64:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
m32r*:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
m68*:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
mips:Linux:*:* | mips64:Linux:*:*)
|
||
eval $set_cc_for_build
|
||
@@ -959,59 +967,63 @@ EOF
|
||
#endif
|
||
EOF
|
||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
||
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
|
||
;;
|
||
or1k:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
or32:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
padre:Linux:*:*)
|
||
- echo sparc-unknown-linux-gnu
|
||
+ echo sparc-unknown-linux-${LIBC}
|
||
exit ;;
|
||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||
- echo hppa64-unknown-linux-gnu
|
||
+ echo hppa64-unknown-linux-${LIBC}
|
||
exit ;;
|
||
parisc:Linux:*:* | hppa:Linux:*:*)
|
||
# Look for CPU level
|
||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
|
||
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
|
||
- *) echo hppa-unknown-linux-gnu ;;
|
||
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
|
||
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
|
||
+ *) echo hppa-unknown-linux-${LIBC} ;;
|
||
esac
|
||
exit ;;
|
||
ppc64:Linux:*:*)
|
||
- echo powerpc64-unknown-linux-gnu
|
||
+ echo powerpc64-unknown-linux-${LIBC}
|
||
exit ;;
|
||
ppc:Linux:*:*)
|
||
- echo powerpc-unknown-linux-gnu
|
||
+ echo powerpc-unknown-linux-${LIBC}
|
||
+ exit ;;
|
||
+ ppc64le:Linux:*:*)
|
||
+ echo powerpc64le-unknown-linux-${LIBC}
|
||
+ exit ;;
|
||
+ ppcle:Linux:*:*)
|
||
+ echo powerpcle-unknown-linux-${LIBC}
|
||
exit ;;
|
||
s390:Linux:*:* | s390x:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-ibm-linux
|
||
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
|
||
exit ;;
|
||
sh64*:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
sh*:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
tile*:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
vax:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-dec-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
||
exit ;;
|
||
x86_64:Linux:*:*)
|
||
- LIBC=gnu
|
||
- test -r /lib/libc.so && od -An -S13 /lib/libc.so | grep -q __uClibc_main && LIBC=uclibc
|
||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
xtensa*:Linux:*:*)
|
||
- echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||
exit ;;
|
||
i*86:DYNIX/ptx:4*:*)
|
||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
||
@@ -1244,19 +1256,21 @@ EOF
|
||
exit ;;
|
||
*:Darwin:*:*)
|
||
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
||
- case $UNAME_PROCESSOR in
|
||
- i386)
|
||
- eval $set_cc_for_build
|
||
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||
- grep IS_64BIT_ARCH >/dev/null
|
||
- then
|
||
- UNAME_PROCESSOR="x86_64"
|
||
- fi
|
||
- fi ;;
|
||
- unknown) UNAME_PROCESSOR=powerpc ;;
|
||
- esac
|
||
+ eval $set_cc_for_build
|
||
+ if test "$UNAME_PROCESSOR" = unknown ; then
|
||
+ UNAME_PROCESSOR=powerpc
|
||
+ fi
|
||
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||
+ grep IS_64BIT_ARCH >/dev/null
|
||
+ then
|
||
+ case $UNAME_PROCESSOR in
|
||
+ i386) UNAME_PROCESSOR=x86_64 ;;
|
||
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
|
||
+ esac
|
||
+ fi
|
||
+ fi
|
||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||
exit ;;
|
||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||
--- a/config.sub
|
||
+++ b/config.sub
|
||
@@ -2,7 +2,7 @@
|
||
# Configuration validation subroutine script.
|
||
# Copyright 1992-2013 Free Software Foundation, Inc.
|
||
|
||
-timestamp='2013-04-24'
|
||
+timestamp='2013-10-01'
|
||
|
||
# This file is free software; you can redistribute it and/or modify it
|
||
# under the terms of the GNU General Public License as published by
|
||
@@ -257,7 +257,7 @@ case $basic_machine in
|
||
| avr | avr32 \
|
||
| be32 | be64 \
|
||
| bfin \
|
||
- | c4x | clipper \
|
||
+ | c4x | c8051 | clipper \
|
||
| d10v | d30v | dlx | dsp16xx \
|
||
| epiphany \
|
||
| fido | fr30 | frv \
|
||
@@ -265,6 +265,7 @@ case $basic_machine in
|
||
| hexagon \
|
||
| i370 | i860 | i960 | ia64 \
|
||
| ip2k | iq2000 \
|
||
+ | k1om \
|
||
| le32 | le64 \
|
||
| lm32 \
|
||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||
@@ -324,7 +325,7 @@ case $basic_machine in
|
||
c6x)
|
||
basic_machine=tic6x-unknown
|
||
;;
|
||
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
|
||
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
|
||
basic_machine=$basic_machine-unknown
|
||
os=-none
|
||
;;
|
||
@@ -372,7 +373,7 @@ case $basic_machine in
|
||
| be32-* | be64-* \
|
||
| bfin-* | bs2000-* \
|
||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||
- | clipper-* | craynv-* | cydra-* \
|
||
+ | c8051-* | clipper-* | craynv-* | cydra-* \
|
||
| d10v-* | d30v-* | dlx-* \
|
||
| elxsi-* \
|
||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||
@@ -381,6 +382,7 @@ case $basic_machine in
|
||
| hexagon-* \
|
||
| i*86-* | i860-* | i960-* | ia64-* \
|
||
| ip2k-* | iq2000-* \
|
||
+ | k1om-* \
|
||
| le32-* | le64-* \
|
||
| lm32-* \
|
||
| m32c-* | m32r-* | m32rle-* \
|
||
@@ -794,7 +796,7 @@ case $basic_machine in
|
||
os=-mingw64
|
||
;;
|
||
mingw32)
|
||
- basic_machine=i386-pc
|
||
+ basic_machine=i686-pc
|
||
os=-mingw32
|
||
;;
|
||
mingw32ce)
|
||
@@ -830,7 +832,7 @@ case $basic_machine in
|
||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||
;;
|
||
msys)
|
||
- basic_machine=i386-pc
|
||
+ basic_machine=i686-pc
|
||
os=-msys
|
||
;;
|
||
mvs)
|
||
@@ -1546,6 +1548,9 @@ case $basic_machine in
|
||
c4x-* | tic4x-*)
|
||
os=-coff
|
||
;;
|
||
+ c8051-*)
|
||
+ os=-elf
|
||
+ ;;
|
||
hexagon-*)
|
||
os=-elf
|
||
;;
|
||
|
||
#
|
||
# gdb-7.6-ppc64le.patch
|
||
#
|
||
|
||
From: Ulrich Weigand <uweigand@de.ibm.com>
|
||
References: ppc64le enablement
|
||
Patch-mainline: not yet
|
||
|
||
Signed-off-by: Ulrich Weigand <uweigand@de.ibm.com>
|
||
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
|
||
|
||
---
|
||
gdb/auxv.c | 1
|
||
gdb/configure.host | 4
|
||
gdb/configure.tgt | 2
|
||
gdb/doublest.c | 49 +-
|
||
gdb/gdbarch.c | 33 +
|
||
gdb/gdbarch.h | 6
|
||
gdb/gdbarch.sh | 1
|
||
gdb/gdbtypes.c | 4
|
||
gdb/infrun.c | 4
|
||
gdb/ppc-linux-tdep.c | 60 ++-
|
||
gdb/ppc-sysv-tdep.c | 534 ++++++++++++++++++++++++---
|
||
gdb/ppc-tdep.h | 11
|
||
gdb/ppc64-tdep.c | 2
|
||
gdb/rs6000-tdep.c | 43 +-
|
||
gdb/symtab.c | 2
|
||
gdb/testsuite/gdb.arch/altivec-regs.exp | 2
|
||
gdb/testsuite/gdb.arch/powerpc-d128-regs.exp | 2
|
||
gdb/testsuite/gdb.arch/vsx-regs.exp | 39 +
|
||
gdb/testsuite/gdb.base/sigbpt.exp | 2
|
||
gdb/testsuite/gdb.base/step-bt.exp | 2
|
||
include/elf/common.h | 1
|
||
include/elf/ppc64.h | 54 ++
|
||
22 files changed, 752 insertions(+), 106 deletions(-)
|
||
|
||
--- a/gdb/ppc64-tdep.c
|
||
+++ b/gdb/ppc64-tdep.c
|
||
@@ -289,7 +289,7 @@ static struct ppc_insn_pattern ppc64_sta
|
||
static struct ppc_insn_pattern ppc64_standard_linkage7[] =
|
||
{
|
||
/* std r2, 24(r1) <optional> */
|
||
- { -1, insn_ds (62, 2, 1, 40, 0), 1 },
|
||
+ { -1, insn_ds (62, 2, 1, 24, 0), 1 },
|
||
|
||
/* ld r12, <any>(r2) */
|
||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 2, 0, 0), 0 },
|
||
--- a/gdb/rs6000-tdep.c
|
||
+++ b/gdb/rs6000-tdep.c
|
||
@@ -48,6 +48,7 @@
|
||
|
||
#include "elf-bfd.h"
|
||
#include "elf/ppc.h"
|
||
+#include "elf/ppc64.h"
|
||
|
||
#include "solib-svr4.h"
|
||
#include "ppc-tdep.h"
|
||
@@ -2672,10 +2673,10 @@ dfp_pseudo_register_read (struct gdbarch
|
||
else
|
||
{
|
||
status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
|
||
- 2 * reg_index + 1, buffer + 8);
|
||
+ 2 * reg_index + 1, buffer);
|
||
if (status == REG_VALID)
|
||
status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
|
||
- 2 * reg_index, buffer);
|
||
+ 2 * reg_index, buffer + 8);
|
||
}
|
||
|
||
return status;
|
||
@@ -2701,9 +2702,9 @@ dfp_pseudo_register_write (struct gdbarc
|
||
else
|
||
{
|
||
regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
|
||
- 2 * reg_index + 1, buffer + 8);
|
||
+ 2 * reg_index + 1, buffer);
|
||
regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
|
||
- 2 * reg_index, buffer);
|
||
+ 2 * reg_index, buffer + 8);
|
||
}
|
||
}
|
||
|
||
@@ -2781,7 +2782,8 @@ efpr_pseudo_register_read (struct gdbarc
|
||
int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
|
||
|
||
/* Read the portion that overlaps the VMX register. */
|
||
- return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0,
|
||
+ int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
|
||
+ return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, offset,
|
||
register_size (gdbarch, reg_nr), buffer);
|
||
}
|
||
|
||
@@ -2794,7 +2796,8 @@ efpr_pseudo_register_write (struct gdbar
|
||
int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
|
||
|
||
/* Write the portion that overlaps the VMX register. */
|
||
- regcache_raw_write_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0,
|
||
+ int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
|
||
+ regcache_raw_write_part (regcache, tdep->ppc_vr0_regnum + reg_index, offset,
|
||
register_size (gdbarch, reg_nr), buffer);
|
||
}
|
||
|
||
@@ -3550,6 +3553,7 @@ rs6000_gdbarch_init (struct gdbarch_info
|
||
enum auto_boolean soft_float_flag = powerpc_soft_float_global;
|
||
int soft_float;
|
||
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
|
||
+ enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
|
||
int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0,
|
||
have_vsx = 0;
|
||
int tdesc_wordsize = -1;
|
||
@@ -3856,6 +3860,21 @@ rs6000_gdbarch_init (struct gdbarch_info
|
||
}
|
||
|
||
#ifdef HAVE_ELF
|
||
+ if (from_elf_exec)
|
||
+ {
|
||
+ switch (elf_elfheader (info.abfd)->e_flags & EF_PPC64_ABI)
|
||
+ {
|
||
+ case 1:
|
||
+ elf_abi = POWERPC_ELF_V1;
|
||
+ break;
|
||
+ case 2:
|
||
+ elf_abi = POWERPC_ELF_V2;
|
||
+ break;
|
||
+ default:
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+
|
||
if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec)
|
||
{
|
||
switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
|
||
@@ -3892,6 +3911,15 @@ rs6000_gdbarch_init (struct gdbarch_info
|
||
}
|
||
#endif
|
||
|
||
+ /* Default to ELFv2 ABI on 64-bit little-endian, and ELFv1 otherwise. */
|
||
+ if (elf_abi == POWERPC_ELF_AUTO)
|
||
+ {
|
||
+ if (wordsize == 8 && info.byte_order == BFD_ENDIAN_LITTLE)
|
||
+ elf_abi = POWERPC_ELF_V2;
|
||
+ else
|
||
+ elf_abi = POWERPC_ELF_V1;
|
||
+ }
|
||
+
|
||
if (soft_float_flag == AUTO_BOOLEAN_TRUE)
|
||
soft_float = 1;
|
||
else if (soft_float_flag == AUTO_BOOLEAN_FALSE)
|
||
@@ -3934,6 +3962,8 @@ rs6000_gdbarch_init (struct gdbarch_info
|
||
meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform
|
||
separate word size check. */
|
||
tdep = gdbarch_tdep (arches->gdbarch);
|
||
+ if (tdep && tdep->elf_abi != elf_abi)
|
||
+ continue;
|
||
if (tdep && tdep->soft_float != soft_float)
|
||
continue;
|
||
if (tdep && tdep->vector_abi != vector_abi)
|
||
@@ -3956,6 +3986,7 @@ rs6000_gdbarch_init (struct gdbarch_info
|
||
|
||
tdep = XCALLOC (1, struct gdbarch_tdep);
|
||
tdep->wordsize = wordsize;
|
||
+ tdep->elf_abi = elf_abi;
|
||
tdep->soft_float = soft_float;
|
||
tdep->vector_abi = vector_abi;
|
||
|
||
--- a/gdb/auxv.c
|
||
+++ b/gdb/auxv.c
|
||
@@ -441,6 +441,7 @@ fprint_target_auxv (struct ui_file *file
|
||
TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
|
||
TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
|
||
TAG (AT_RANDOM, _("Address of 16 random bytes"), hex);
|
||
+ TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), hex);
|
||
TAG (AT_EXECFN, _("File name of executable"), str);
|
||
TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
|
||
TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
|
||
--- a/gdb/configure.host
|
||
+++ b/gdb/configure.host
|
||
@@ -129,18 +129,18 @@ mips64*-*-openbsd*) gdb_host=obsd64 ;;
|
||
powerpc-*-aix* | rs6000-*-*)
|
||
gdb_host=aix ;;
|
||
powerpc*-*-freebsd*) gdb_host=fbsd ;;
|
||
-powerpc-*-linux*) gdb_host=linux ;;
|
||
powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
|
||
gdb_host=nbsd ;;
|
||
powerpc-*-openbsd*) gdb_host=obsd ;;
|
||
|
||
-powerpc64-*-linux*) gdb_host=ppc64-linux
|
||
+powerpc64*-*-linux*) gdb_host=ppc64-linux
|
||
# Support 'pseudo-native' debugging on the Cell BE
|
||
if test "${target_cpu}" = "spu"; then
|
||
gdb_host=spu-linux
|
||
gdb_native=yes
|
||
fi
|
||
;;
|
||
+powerpc*-*-linux*) gdb_host=linux ;;
|
||
|
||
s390*-*-*) gdb_host=s390 ;;
|
||
|
||
--- a/gdb/configure.tgt
|
||
+++ b/gdb/configure.tgt
|
||
@@ -421,7 +421,7 @@ powerpc-*-aix* | rs6000-*-*)
|
||
ppc-sysv-tdep.o solib-svr4.o \
|
||
ravenscar-thread.o ppc-ravenscar-thread.o"
|
||
;;
|
||
-powerpc-*-linux* | powerpc64-*-linux*)
|
||
+powerpc*-*-linux*)
|
||
# Target: PowerPC running Linux
|
||
gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
|
||
ppc64-tdep.o solib-svr4.o solib-spu.o \
|
||
--- a/gdb/doublest.c
|
||
+++ b/gdb/doublest.c
|
||
@@ -190,7 +190,8 @@ convert_floatformat_to_doublest (const s
|
||
{
|
||
double dto;
|
||
|
||
- floatformat_to_double (fmt, from, &dto);
|
||
+ floatformat_to_double (fmt->split_half ? fmt->split_half : fmt,
|
||
+ from, &dto);
|
||
*to = (DOUBLEST) dto;
|
||
return;
|
||
}
|
||
@@ -561,6 +562,11 @@ floatformat_is_negative (const struct fl
|
||
gdb_assert (fmt->totalsize
|
||
<= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
|
||
|
||
+ /* An IBM long double (a two element array of double) always takes the
|
||
+ sign of the first double. */
|
||
+ if (fmt->split_half)
|
||
+ fmt = fmt->split_half;
|
||
+
|
||
order = floatformat_normalize_byteorder (fmt, uval, newfrom);
|
||
|
||
if (order != fmt->byteorder)
|
||
@@ -587,6 +593,13 @@ floatformat_classify (const struct float
|
||
gdb_assert (fmt->totalsize
|
||
<= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
|
||
|
||
+ /* An IBM long double (a two element array of double) can be classified
|
||
+ by looking at the first double. inf and nan are specified as
|
||
+ ignoring the second double. zero and subnormal will always have
|
||
+ the second double 0.0 if the long double is correctly rounded. */
|
||
+ if (fmt->split_half)
|
||
+ fmt = fmt->split_half;
|
||
+
|
||
order = floatformat_normalize_byteorder (fmt, uval, newfrom);
|
||
|
||
if (order != fmt->byteorder)
|
||
@@ -669,6 +682,16 @@ floatformat_mantissa (const struct float
|
||
gdb_assert (fmt->totalsize
|
||
<= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);
|
||
|
||
+ /* For IBM long double (a two element array of double), return the
|
||
+ mantissa of the first double. The problem with returning the
|
||
+ actual mantissa from both doubles is that there can be an
|
||
+ arbitrary number of implied 0's or 1's between the mantissas
|
||
+ of the first and second double. In any case, this function
|
||
+ is only used for dumping out nans, and a nan is specified to
|
||
+ ignore the value in the second double. */
|
||
+ if (fmt->split_half)
|
||
+ fmt = fmt->split_half;
|
||
+
|
||
order = floatformat_normalize_byteorder (fmt, uval, newfrom);
|
||
|
||
if (order != fmt->byteorder)
|
||
@@ -926,27 +949,3 @@ convert_typed_floating (const void *from
|
||
floatformat_from_doublest (to_fmt, &d, to);
|
||
}
|
||
}
|
||
-
|
||
-const struct floatformat *floatformat_ieee_single[BFD_ENDIAN_UNKNOWN];
|
||
-const struct floatformat *floatformat_ieee_double[BFD_ENDIAN_UNKNOWN];
|
||
-const struct floatformat *floatformat_ieee_quad[BFD_ENDIAN_UNKNOWN];
|
||
-const struct floatformat *floatformat_arm_ext[BFD_ENDIAN_UNKNOWN];
|
||
-const struct floatformat *floatformat_ia64_spill[BFD_ENDIAN_UNKNOWN];
|
||
-
|
||
-extern void _initialize_doublest (void);
|
||
-
|
||
-extern void
|
||
-_initialize_doublest (void)
|
||
-{
|
||
- floatformat_ieee_single[BFD_ENDIAN_LITTLE] = &floatformat_ieee_single_little;
|
||
- floatformat_ieee_single[BFD_ENDIAN_BIG] = &floatformat_ieee_single_big;
|
||
- floatformat_ieee_double[BFD_ENDIAN_LITTLE] = &floatformat_ieee_double_little;
|
||
- floatformat_ieee_double[BFD_ENDIAN_BIG] = &floatformat_ieee_double_big;
|
||
- floatformat_arm_ext[BFD_ENDIAN_LITTLE]
|
||
- = &floatformat_arm_ext_littlebyte_bigword;
|
||
- floatformat_arm_ext[BFD_ENDIAN_BIG] = &floatformat_arm_ext_big;
|
||
- floatformat_ia64_spill[BFD_ENDIAN_LITTLE] = &floatformat_ia64_spill_little;
|
||
- floatformat_ia64_spill[BFD_ENDIAN_BIG] = &floatformat_ia64_spill_big;
|
||
- floatformat_ieee_quad[BFD_ENDIAN_LITTLE] = &floatformat_ia64_quad_little;
|
||
- floatformat_ieee_quad[BFD_ENDIAN_BIG] = &floatformat_ia64_quad_big;
|
||
-}
|
||
--- a/gdb/gdbarch.c
|
||
+++ b/gdb/gdbarch.c
|
||
@@ -200,6 +200,7 @@ struct gdbarch
|
||
gdbarch_return_in_first_hidden_param_p_ftype *return_in_first_hidden_param_p;
|
||
gdbarch_skip_prologue_ftype *skip_prologue;
|
||
gdbarch_skip_main_prologue_ftype *skip_main_prologue;
|
||
+ gdbarch_skip_entrypoint_ftype *skip_entrypoint;
|
||
gdbarch_inner_than_ftype *inner_than;
|
||
gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc;
|
||
gdbarch_remote_breakpoint_from_pc_ftype *remote_breakpoint_from_pc;
|
||
@@ -371,6 +372,7 @@ struct gdbarch startup_gdbarch =
|
||
default_return_in_first_hidden_param_p, /* return_in_first_hidden_param_p */
|
||
0, /* skip_prologue */
|
||
0, /* skip_main_prologue */
|
||
+ 0, /* skip_entrypoint */
|
||
0, /* inner_than */
|
||
0, /* breakpoint_from_pc */
|
||
default_remote_breakpoint_from_pc, /* remote_breakpoint_from_pc */
|
||
@@ -672,6 +674,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||
if (gdbarch->skip_prologue == 0)
|
||
fprintf_unfiltered (log, "\n\tskip_prologue");
|
||
/* Skip verify of skip_main_prologue, has predicate. */
|
||
+ /* Skip verify of skip_entrypoint, has predicate. */
|
||
if (gdbarch->inner_than == 0)
|
||
fprintf_unfiltered (log, "\n\tinner_than");
|
||
if (gdbarch->breakpoint_from_pc == 0)
|
||
@@ -1285,6 +1288,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
|
||
"gdbarch_dump: single_step_through_delay = <%s>\n",
|
||
host_address_to_string (gdbarch->single_step_through_delay));
|
||
fprintf_unfiltered (file,
|
||
+ "gdbarch_dump: gdbarch_skip_entrypoint_p() = %d\n",
|
||
+ gdbarch_skip_entrypoint_p (gdbarch));
|
||
+ fprintf_unfiltered (file,
|
||
+ "gdbarch_dump: skip_entrypoint = <%s>\n",
|
||
+ host_address_to_string (gdbarch->skip_entrypoint));
|
||
+ fprintf_unfiltered (file,
|
||
"gdbarch_dump: gdbarch_skip_main_prologue_p() = %d\n",
|
||
gdbarch_skip_main_prologue_p (gdbarch));
|
||
fprintf_unfiltered (file,
|
||
@@ -2635,6 +2644,30 @@ set_gdbarch_skip_main_prologue (struct g
|
||
}
|
||
|
||
int
|
||
+gdbarch_skip_entrypoint_p (struct gdbarch *gdbarch)
|
||
+{
|
||
+ gdb_assert (gdbarch != NULL);
|
||
+ return gdbarch->skip_entrypoint != NULL;
|
||
+}
|
||
+
|
||
+CORE_ADDR
|
||
+gdbarch_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR ip)
|
||
+{
|
||
+ gdb_assert (gdbarch != NULL);
|
||
+ gdb_assert (gdbarch->skip_entrypoint != NULL);
|
||
+ if (gdbarch_debug >= 2)
|
||
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_entrypoint called\n");
|
||
+ return gdbarch->skip_entrypoint (gdbarch, ip);
|
||
+}
|
||
+
|
||
+void
|
||
+set_gdbarch_skip_entrypoint (struct gdbarch *gdbarch,
|
||
+ gdbarch_skip_entrypoint_ftype skip_entrypoint)
|
||
+{
|
||
+ gdbarch->skip_entrypoint = skip_entrypoint;
|
||
+}
|
||
+
|
||
+int
|
||
gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs)
|
||
{
|
||
gdb_assert (gdbarch != NULL);
|
||
--- a/gdb/gdbarch.h
|
||
+++ b/gdb/gdbarch.h
|
||
@@ -487,6 +487,12 @@ typedef CORE_ADDR (gdbarch_skip_main_pro
|
||
extern CORE_ADDR gdbarch_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR ip);
|
||
extern void set_gdbarch_skip_main_prologue (struct gdbarch *gdbarch, gdbarch_skip_main_prologue_ftype *skip_main_prologue);
|
||
|
||
+extern int gdbarch_skip_entrypoint_p (struct gdbarch *gdbarch);
|
||
+
|
||
+typedef CORE_ADDR (gdbarch_skip_entrypoint_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip);
|
||
+extern CORE_ADDR gdbarch_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR ip);
|
||
+extern void set_gdbarch_skip_entrypoint (struct gdbarch *gdbarch, gdbarch_skip_entrypoint_ftype *skip_entrypoint);
|
||
+
|
||
typedef int (gdbarch_inner_than_ftype) (CORE_ADDR lhs, CORE_ADDR rhs);
|
||
extern int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs);
|
||
extern void set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch_inner_than_ftype *inner_than);
|
||
--- a/gdb/gdbarch.sh
|
||
+++ b/gdb/gdbarch.sh
|
||
@@ -527,6 +527,7 @@ m:int:return_in_first_hidden_param_p:str
|
||
|
||
m:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0
|
||
M:CORE_ADDR:skip_main_prologue:CORE_ADDR ip:ip
|
||
+M:CORE_ADDR:skip_entrypoint:CORE_ADDR ip:ip
|
||
f:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs:0:0
|
||
m:const gdb_byte *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr::0:
|
||
# Return the adjusted address and kind to use for Z0/Z1 packets.
|
||
--- a/gdb/gdbtypes.c
|
||
+++ b/gdb/gdbtypes.c
|
||
@@ -107,8 +107,8 @@ const struct floatformat *floatformats_v
|
||
&floatformat_vax_d
|
||
};
|
||
const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = {
|
||
- &floatformat_ibm_long_double,
|
||
- &floatformat_ibm_long_double
|
||
+ &floatformat_ibm_long_double_big,
|
||
+ &floatformat_ibm_long_double_little
|
||
};
|
||
|
||
/* Should opaque types be resolved? */
|
||
--- a/gdb/infrun.c
|
||
+++ b/gdb/infrun.c
|
||
@@ -3139,6 +3139,10 @@ fill_in_stop_func (struct gdbarch *gdbar
|
||
ecs->stop_func_start
|
||
+= gdbarch_deprecated_function_start_offset (gdbarch);
|
||
|
||
+ if (gdbarch_skip_entrypoint_p (gdbarch))
|
||
+ ecs->stop_func_start = gdbarch_skip_entrypoint (gdbarch,
|
||
+ ecs->stop_func_start);
|
||
+
|
||
ecs->stop_func_filled_in = 1;
|
||
}
|
||
}
|
||
--- a/gdb/ppc-linux-tdep.c
|
||
+++ b/gdb/ppc-linux-tdep.c
|
||
@@ -44,6 +44,7 @@
|
||
#include "observer.h"
|
||
#include "auxv.h"
|
||
#include "elf/common.h"
|
||
+#include "elf/ppc64.h"
|
||
#include "exceptions.h"
|
||
#include "arch-utils.h"
|
||
#include "spu-tdep.h"
|
||
@@ -876,6 +877,43 @@ ppc_linux_core_read_description (struct
|
||
}
|
||
}
|
||
|
||
+/* If the ELF symbol has a local entry point, use it as SYMBOL_VALUE_ADDRESS
|
||
+ for the msymbol. This matches the DWARF function start if present. */
|
||
+
|
||
+static void
|
||
+ppc_elfv2_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
|
||
+{
|
||
+ elf_symbol_type *elf_sym = (elf_symbol_type *)sym;
|
||
+ switch (PPC64_LOCAL_ENTRY_OFFSET (elf_sym->internal_elf_sym.st_other))
|
||
+ {
|
||
+ default:
|
||
+ break;
|
||
+ case 8:
|
||
+ MSYMBOL_TARGET_FLAG_1 (msym) = 1;
|
||
+ break;
|
||
+ }
|
||
+}
|
||
+
|
||
+static CORE_ADDR
|
||
+ppc_elfv2_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||
+{
|
||
+ struct bound_minimal_symbol fun;
|
||
+ int local_entry_offset = 0;
|
||
+
|
||
+ fun = lookup_minimal_symbol_by_pc (pc);
|
||
+ if (fun.minsym == NULL)
|
||
+ return pc;
|
||
+
|
||
+ if (MSYMBOL_TARGET_FLAG_1 (fun.minsym))
|
||
+ local_entry_offset = 8;
|
||
+
|
||
+ if (SYMBOL_VALUE_ADDRESS (fun.minsym) <= pc
|
||
+ && pc < SYMBOL_VALUE_ADDRESS (fun.minsym) + local_entry_offset)
|
||
+ return SYMBOL_VALUE_ADDRESS (fun.minsym) + local_entry_offset;
|
||
+
|
||
+ return pc;
|
||
+}
|
||
+
|
||
/* Implementation of `gdbarch_stap_is_single_operand', as defined in
|
||
gdbarch.h. */
|
||
|
||
@@ -1332,13 +1370,23 @@ ppc_linux_init_abi (struct gdbarch_info
|
||
|
||
if (tdep->wordsize == 8)
|
||
{
|
||
- /* Handle PPC GNU/Linux 64-bit function pointers (which are really
|
||
- function descriptors). */
|
||
- set_gdbarch_convert_from_func_ptr_addr
|
||
- (gdbarch, ppc64_convert_from_func_ptr_addr);
|
||
+ if (tdep->elf_abi == POWERPC_ELF_V1)
|
||
+ {
|
||
+ /* Handle PPC GNU/Linux 64-bit function pointers (which are really
|
||
+ function descriptors). */
|
||
+ set_gdbarch_convert_from_func_ptr_addr
|
||
+ (gdbarch, ppc64_convert_from_func_ptr_addr);
|
||
|
||
- set_gdbarch_elf_make_msymbol_special (gdbarch,
|
||
- ppc64_elf_make_msymbol_special);
|
||
+ set_gdbarch_elf_make_msymbol_special
|
||
+ (gdbarch, ppc64_elf_make_msymbol_special);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ set_gdbarch_elf_make_msymbol_special
|
||
+ (gdbarch, ppc_elfv2_elf_make_msymbol_special);
|
||
+
|
||
+ set_gdbarch_skip_entrypoint (gdbarch, ppc_elfv2_skip_entrypoint);
|
||
+ }
|
||
|
||
/* Shared library handling. */
|
||
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
|
||
--- a/gdb/ppc-sysv-tdep.c
|
||
+++ b/gdb/ppc-sysv-tdep.c
|
||
@@ -610,42 +610,48 @@ ppc_sysv_abi_push_dummy_call (struct gdb
|
||
}
|
||
|
||
/* Handle the return-value conventions for Decimal Floating Point values
|
||
- in both ppc32 and ppc64, which are the same. */
|
||
-static int
|
||
+ in both ppc32 and ppc64, which are the same. INDEX specifies which
|
||
+ part of a multi-part return value is to be handled. */
|
||
+static void
|
||
get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype,
|
||
struct regcache *regcache, gdb_byte *readbuf,
|
||
- const gdb_byte *writebuf)
|
||
+ const gdb_byte *writebuf, int index)
|
||
{
|
||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||
+ int offset = index * TYPE_LENGTH (valtype);
|
||
|
||
gdb_assert (TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT);
|
||
|
||
/* 32-bit and 64-bit decimal floats in f1. */
|
||
if (TYPE_LENGTH (valtype) <= 8)
|
||
{
|
||
+ int regnum = tdep->ppc_fp0_regnum + 1 + index;
|
||
+
|
||
if (writebuf != NULL)
|
||
{
|
||
gdb_byte regval[MAX_REGISTER_SIZE];
|
||
const gdb_byte *p;
|
||
|
||
/* 32-bit decimal float is right aligned in the doubleword. */
|
||
- if (TYPE_LENGTH (valtype) == 4)
|
||
+ if (TYPE_LENGTH (valtype) == 4
|
||
+ && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
|
||
{
|
||
- memcpy (regval + 4, writebuf, 4);
|
||
+ memcpy (regval + 4, writebuf + offset, 4);
|
||
p = regval;
|
||
}
|
||
else
|
||
- p = writebuf;
|
||
+ p = writebuf + offset;
|
||
|
||
- regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, p);
|
||
+ regcache_cooked_write (regcache, regnum, p);
|
||
}
|
||
if (readbuf != NULL)
|
||
{
|
||
- regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf);
|
||
+ regcache_cooked_read (regcache, regnum, readbuf);
|
||
|
||
/* Left align 32-bit decimal float. */
|
||
- if (TYPE_LENGTH (valtype) == 4)
|
||
- memcpy (readbuf, readbuf + 4, 4);
|
||
+ if (TYPE_LENGTH (valtype) == 4
|
||
+ && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
|
||
+ memcpy (readbuf + offset, readbuf + offset + 4, 4);
|
||
}
|
||
}
|
||
/* 128-bit decimal floats in f2,f3. */
|
||
@@ -653,24 +659,27 @@ get_decimal_float_return_value (struct g
|
||
{
|
||
if (writebuf != NULL || readbuf != NULL)
|
||
{
|
||
- int i;
|
||
+ int i, regnum;
|
||
|
||
for (i = 0; i < 2; i++)
|
||
{
|
||
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
|
||
+ regnum = tdep->ppc_fp0_regnum + 2 + i + 2 * index;
|
||
+ else
|
||
+ regnum = tdep->ppc_fp0_regnum + 3 - i + 2 * index;
|
||
+
|
||
if (writebuf != NULL)
|
||
- regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 2 + i,
|
||
- writebuf + i * 8);
|
||
+ regcache_cooked_write (regcache, regnum,
|
||
+ writebuf + offset + i * 8);
|
||
if (readbuf != NULL)
|
||
- regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 2 + i,
|
||
- readbuf + i * 8);
|
||
+ regcache_cooked_read (regcache, regnum,
|
||
+ readbuf + offset + i * 8);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
/* Can't happen. */
|
||
internal_error (__FILE__, __LINE__, _("Unknown decimal float size."));
|
||
-
|
||
- return RETURN_VALUE_REGISTER_CONVENTION;
|
||
}
|
||
|
||
/* Handle the return-value conventions specified by the SysV 32-bit
|
||
@@ -802,8 +811,11 @@ do_ppc_sysv_return_value (struct gdbarch
|
||
return RETURN_VALUE_REGISTER_CONVENTION;
|
||
}
|
||
if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && !tdep->soft_float)
|
||
- return get_decimal_float_return_value (gdbarch, type, regcache, readbuf,
|
||
- writebuf);
|
||
+ {
|
||
+ get_decimal_float_return_value (gdbarch, type, regcache,
|
||
+ readbuf, writebuf, 0);
|
||
+ return RETURN_VALUE_REGISTER_CONVENTION;
|
||
+ }
|
||
else if ((TYPE_CODE (type) == TYPE_CODE_INT
|
||
|| TYPE_CODE (type) == TYPE_CODE_CHAR
|
||
|| TYPE_CODE (type) == TYPE_CODE_BOOL
|
||
@@ -1102,6 +1114,156 @@ convert_code_addr_to_desc_addr (CORE_ADD
|
||
return 1;
|
||
}
|
||
|
||
+/* Walk down the type tree of TYPE counting consecutive base elements.
|
||
+ If *FIELD_TYPE is NULL, then set it to the first valid floating point
|
||
+ or vector type. If a non-floating point or vector type is found, or
|
||
+ if a floating point or vector type that doesn't match a non-NULL
|
||
+ *FIELD_TYPE is found, then return -1, otherwise return the count in the
|
||
+ sub-tree. */
|
||
+
|
||
+static LONGEST
|
||
+ppc64_aggregate_candidate (struct type *type,
|
||
+ struct type **field_type)
|
||
+{
|
||
+ type = check_typedef (type);
|
||
+
|
||
+ switch (TYPE_CODE (type))
|
||
+ {
|
||
+ case TYPE_CODE_FLT:
|
||
+ case TYPE_CODE_DECFLOAT:
|
||
+ if (!*field_type)
|
||
+ *field_type = type;
|
||
+ if (TYPE_CODE (*field_type) == TYPE_CODE (type)
|
||
+ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type))
|
||
+ return 1;
|
||
+ break;
|
||
+
|
||
+ case TYPE_CODE_COMPLEX:
|
||
+ type = TYPE_TARGET_TYPE (type);
|
||
+ if (TYPE_CODE (type) == TYPE_CODE_FLT
|
||
+ || TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
|
||
+ {
|
||
+ if (!*field_type)
|
||
+ *field_type = type;
|
||
+ if (TYPE_CODE (*field_type) == TYPE_CODE (type)
|
||
+ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type))
|
||
+ return 2;
|
||
+ }
|
||
+ break;
|
||
+
|
||
+ case TYPE_CODE_ARRAY:
|
||
+ if (TYPE_VECTOR (type))
|
||
+ {
|
||
+ if (!*field_type)
|
||
+ *field_type = type;
|
||
+ if (TYPE_CODE (*field_type) == TYPE_CODE (type)
|
||
+ && TYPE_LENGTH (*field_type) == TYPE_LENGTH (type))
|
||
+ return 1;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ LONGEST count, low_bound, high_bound;
|
||
+
|
||
+ count = ppc64_aggregate_candidate
|
||
+ (TYPE_TARGET_TYPE (type), field_type);
|
||
+ if (count == -1)
|
||
+ return -1;
|
||
+
|
||
+ if (!get_array_bounds (type, &low_bound, &high_bound))
|
||
+ return -1;
|
||
+ count *= high_bound - low_bound;
|
||
+
|
||
+ /* There must be no padding. */
|
||
+ if (count == 0)
|
||
+ return TYPE_LENGTH (type) == 0 ? 0 : -1;
|
||
+ else if (TYPE_LENGTH (type) != count * TYPE_LENGTH (*field_type))
|
||
+ return -1;
|
||
+
|
||
+ return count;
|
||
+ }
|
||
+ break;
|
||
+
|
||
+ case TYPE_CODE_STRUCT:
|
||
+ case TYPE_CODE_UNION:
|
||
+ {
|
||
+ LONGEST count = 0;
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
|
||
+ {
|
||
+ LONGEST sub_count;
|
||
+
|
||
+ if (field_is_static (&TYPE_FIELD (type, i)))
|
||
+ continue;
|
||
+
|
||
+ sub_count = ppc64_aggregate_candidate
|
||
+ (TYPE_FIELD_TYPE (type, i), field_type);
|
||
+ if (sub_count == -1)
|
||
+ return -1;
|
||
+
|
||
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
|
||
+ count += sub_count;
|
||
+ else
|
||
+ count = max (count, sub_count);
|
||
+ }
|
||
+
|
||
+ /* There must be no padding. */
|
||
+ if (count == 0)
|
||
+ return TYPE_LENGTH (type) == 0 ? 0 : -1;
|
||
+ else if (TYPE_LENGTH (type) != count * TYPE_LENGTH (*field_type))
|
||
+ return -1;
|
||
+
|
||
+ return count;
|
||
+ }
|
||
+ break;
|
||
+
|
||
+ default:
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ return -1;
|
||
+}
|
||
+
|
||
+/* If an argument of type TYPE is a homogeneous float or vector aggregate
|
||
+ that shall be passed in FP/vector registers according to the ELFv2 ABI,
|
||
+ return the homogeneous element type in *ELT_TYPE and the number of
|
||
+ elements in *N_ELTS, and return non-zero. Otherwise, return zero. */
|
||
+
|
||
+static int
|
||
+ppc64_elfv2_abi_homogeneous_aggregate (struct type *type,
|
||
+ struct type **elt_type, int *n_elts)
|
||
+{
|
||
+ /* Complex types at the top level are treated separately. However,
|
||
+ complex types can be elements of homogeneous aggregates. */
|
||
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|
||
+ || TYPE_CODE (type) == TYPE_CODE_UNION
|
||
+ || (TYPE_CODE (type) == TYPE_CODE_ARRAY && !TYPE_VECTOR (type)))
|
||
+ {
|
||
+ struct type *field_type = NULL;
|
||
+ LONGEST field_count = ppc64_aggregate_candidate (type, &field_type);
|
||
+
|
||
+ if (field_count > 0)
|
||
+ {
|
||
+ int n_regs = ((TYPE_CODE (field_type) == TYPE_CODE_FLT
|
||
+ || TYPE_CODE (field_type) == TYPE_CODE_DECFLOAT)?
|
||
+ (TYPE_LENGTH (field_type) + 7) >> 3 : 1);
|
||
+
|
||
+ /* The ELFv2 ABI allows homogeneous aggregates to occupy
|
||
+ up to 8 registers. */
|
||
+ if (field_count * n_regs <= 8)
|
||
+ {
|
||
+ if (elt_type)
|
||
+ *elt_type = field_type;
|
||
+ if (n_elts)
|
||
+ *n_elts = (int) field_count;
|
||
+ return 1;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
/* Push a float in either registers, or in the stack. Using the ppc 64 bit
|
||
SysV ABI.
|
||
|
||
@@ -1143,6 +1305,8 @@ ppc64_sysv_abi_push_float (struct gdbarc
|
||
|
||
/* Write value in the stack's parameter save area. */
|
||
write_memory (gparam, p, 8);
|
||
+ if (greg <= 10)
|
||
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, p);
|
||
|
||
/* Floats and Doubles go in f1 .. f13. They also consume a left aligned
|
||
GREG, and can end up in memory. */
|
||
@@ -1154,8 +1318,6 @@ ppc64_sysv_abi_push_float (struct gdbarc
|
||
convert_typed_floating (val, type, regval, regtype);
|
||
regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval);
|
||
}
|
||
- if (greg <= 10)
|
||
- regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval);
|
||
}
|
||
else
|
||
{
|
||
@@ -1268,9 +1430,13 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
to their corresponding regions. */
|
||
refparam = align_down (sp - refparam_size, 16);
|
||
gparam = align_down (refparam - gparam_size, 16);
|
||
- /* Add in space for the TOC, link editor double word,
|
||
- compiler double word, LR save area, CR save area. */
|
||
- sp = align_down (gparam - 48, 16);
|
||
+ /* Add in space for the TOC, link editor double word (v1 only),
|
||
+ compiler double word (v1 only), LR save area, CR save area,
|
||
+ and backchain. */
|
||
+ if (tdep->elf_abi == POWERPC_ELF_V1)
|
||
+ sp = align_down (gparam - 48, 16);
|
||
+ else
|
||
+ sp = align_down (gparam - 32, 16);
|
||
}
|
||
|
||
/* If the function is returning a `struct', then there is an
|
||
@@ -1375,7 +1541,8 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
|
||
/* 32-bit decimal floats are right aligned in the
|
||
doubleword. */
|
||
- if (TYPE_LENGTH (type) == 4)
|
||
+ if (TYPE_LENGTH (type) == 4
|
||
+ && byte_order == BFD_ENDIAN_BIG)
|
||
{
|
||
memcpy (regval + 4, val, 4);
|
||
p = regval;
|
||
@@ -1407,10 +1574,21 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
{
|
||
/* Make sure freg is even. */
|
||
freg += freg & 1;
|
||
- regcache_cooked_write (regcache,
|
||
- tdep->ppc_fp0_regnum + freg, val);
|
||
- regcache_cooked_write (regcache,
|
||
- tdep->ppc_fp0_regnum + freg + 1, val + 8);
|
||
+
|
||
+ if (byte_order == BFD_ENDIAN_BIG)
|
||
+ {
|
||
+ regcache_cooked_write (regcache,
|
||
+ tdep->ppc_fp0_regnum + freg, val);
|
||
+ regcache_cooked_write (regcache,
|
||
+ tdep->ppc_fp0_regnum + freg + 1, val + 8);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ regcache_cooked_write (regcache,
|
||
+ tdep->ppc_fp0_regnum + freg + 1, val);
|
||
+ regcache_cooked_write (regcache,
|
||
+ tdep->ppc_fp0_regnum + freg, val + 8);
|
||
+ }
|
||
}
|
||
|
||
write_memory (gparam, val, TYPE_LENGTH (type));
|
||
@@ -1587,8 +1765,9 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
ULONGEST word = unpack_long (type, val);
|
||
/* Convert any function code addresses into
|
||
descriptors. */
|
||
- if (TYPE_CODE (type) == TYPE_CODE_PTR
|
||
- || TYPE_CODE (type) == TYPE_CODE_REF)
|
||
+ if (tdep->elf_abi == POWERPC_ELF_V1
|
||
+ && (TYPE_CODE (type) == TYPE_CODE_PTR
|
||
+ || TYPE_CODE (type) == TYPE_CODE_REF))
|
||
{
|
||
struct type *target_type;
|
||
target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
||
@@ -1613,6 +1792,9 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
}
|
||
else
|
||
{
|
||
+ struct type *elt_type;
|
||
+ int n_elts;
|
||
+
|
||
int byte;
|
||
for (byte = 0; byte < TYPE_LENGTH (type);
|
||
byte += tdep->wordsize)
|
||
@@ -1630,7 +1812,7 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
versions before 3.4 implemented this
|
||
incorrectly; see
|
||
<http://gcc.gnu.org/gcc-3.4/powerpc-abi.html>. */
|
||
- if (byte == 0)
|
||
+ if (byte_order == BFD_ENDIAN_BIG && byte == 0)
|
||
memcpy (regval + tdep->wordsize - len,
|
||
val + byte, len);
|
||
else
|
||
@@ -1649,7 +1831,7 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
value to memory. Fortunately, doing this
|
||
simplifies the code. */
|
||
int len = TYPE_LENGTH (type);
|
||
- if (len < tdep->wordsize)
|
||
+ if (byte_order == BFD_ENDIAN_BIG && len < tdep->wordsize)
|
||
write_memory (gparam + tdep->wordsize - len, val, len);
|
||
else
|
||
write_memory (gparam, val, len);
|
||
@@ -1705,6 +1887,132 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
}
|
||
}
|
||
}
|
||
+ /* In the ELFv2 ABI, homogeneous floating-point or vector
|
||
+ aggregates are passed in registers. */
|
||
+ if (tdep->elf_abi == POWERPC_ELF_V2
|
||
+ && ppc64_elfv2_abi_homogeneous_aggregate (type,
|
||
+ &elt_type, &n_elts))
|
||
+ {
|
||
+ int i;
|
||
+ for (i = 0; i < n_elts; i++)
|
||
+ {
|
||
+ const gdb_byte *elt_val
|
||
+ = val + i * TYPE_LENGTH (elt_type);
|
||
+
|
||
+ switch (TYPE_CODE (elt_type))
|
||
+ {
|
||
+ case TYPE_CODE_FLT:
|
||
+ if (TYPE_LENGTH (elt_type) <= 8)
|
||
+ {
|
||
+ if (write_pass && freg <= 13)
|
||
+ {
|
||
+ int fregnum = tdep->ppc_fp0_regnum + freg;
|
||
+ gdb_byte regval[MAX_REGISTER_SIZE];
|
||
+ struct type *regtype
|
||
+ = register_type (gdbarch, fregnum);
|
||
+ convert_typed_floating (elt_val, elt_type,
|
||
+ regval, regtype);
|
||
+ regcache_cooked_write (regcache,
|
||
+ fregnum, regval);
|
||
+ }
|
||
+ freg++;
|
||
+ }
|
||
+ else if (TYPE_LENGTH (elt_type) == 16
|
||
+ && (gdbarch_long_double_format (gdbarch)
|
||
+ == floatformats_ibm_long_double))
|
||
+ {
|
||
+ if (write_pass && freg <= 13)
|
||
+ {
|
||
+ int fregnum = tdep->ppc_fp0_regnum + freg;
|
||
+ regcache_cooked_write (regcache,
|
||
+ fregnum, elt_val);
|
||
+ if (freg <= 12)
|
||
+ regcache_cooked_write (regcache,
|
||
+ fregnum + 1,
|
||
+ elt_val + 8);
|
||
+ }
|
||
+ freg += 2;
|
||
+ }
|
||
+ break;
|
||
+
|
||
+ case TYPE_CODE_DECFLOAT:
|
||
+ if (TYPE_LENGTH (elt_type) <= 8)
|
||
+ {
|
||
+ if (write_pass && freg <= 13)
|
||
+ {
|
||
+ int fregnum = tdep->ppc_fp0_regnum + freg;
|
||
+ gdb_byte regval[MAX_REGISTER_SIZE];
|
||
+ const gdb_byte *p;
|
||
+
|
||
+ /* 32-bit decimal floats are right aligned
|
||
+ in the doubleword. */
|
||
+ if (TYPE_LENGTH (elt_type) == 4
|
||
+ && byte_order == BFD_ENDIAN_BIG)
|
||
+ {
|
||
+ memcpy (regval + 4, elt_val, 4);
|
||
+ p = regval;
|
||
+ }
|
||
+ else
|
||
+ p = elt_val;
|
||
+
|
||
+ regcache_cooked_write (regcache, fregnum, p);
|
||
+ }
|
||
+ freg++;
|
||
+ }
|
||
+ else if (TYPE_LENGTH (elt_type) == 16)
|
||
+ {
|
||
+ /* Make sure freg is even. */
|
||
+ freg += freg & 1;
|
||
+
|
||
+ if (write_pass && freg <= 12)
|
||
+ {
|
||
+ int fregnum = tdep->ppc_fp0_regnum + freg;
|
||
+ if (byte_order == BFD_ENDIAN_BIG)
|
||
+ {
|
||
+ regcache_cooked_write (regcache,
|
||
+ fregnum,
|
||
+ elt_val);
|
||
+ regcache_cooked_write (regcache,
|
||
+ fregnum + 1,
|
||
+ elt_val + 8);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ regcache_cooked_write (regcache,
|
||
+ fregnum + 1,
|
||
+ elt_val);
|
||
+ regcache_cooked_write (regcache,
|
||
+ fregnum,
|
||
+ elt_val + 8);
|
||
+ }
|
||
+ }
|
||
+ freg += 2;
|
||
+ }
|
||
+ break;
|
||
+
|
||
+ case TYPE_CODE_ARRAY:
|
||
+ gdb_assert (TYPE_VECTOR (type));
|
||
+
|
||
+ if (tdep->vector_abi == POWERPC_VEC_ALTIVEC
|
||
+ && TYPE_LENGTH (elt_type) == 16)
|
||
+ {
|
||
+ if (write_pass && vreg <= 13)
|
||
+ {
|
||
+ int vregnum = tdep->ppc_vr0_regnum + vreg;
|
||
+ regcache_cooked_write (regcache,
|
||
+ vregnum, elt_val);
|
||
+ }
|
||
+ vreg++;
|
||
+ }
|
||
+ break;
|
||
+
|
||
+ default:
|
||
+ internal_error (__FILE__, __LINE__,
|
||
+ _("Unknown element type."));
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
/* Always consume parameter stack space. */
|
||
gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
|
||
}
|
||
@@ -1733,24 +2041,31 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
||
breakpoint. */
|
||
regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
|
||
|
||
- /* Use the func_addr to find the descriptor, and use that to find
|
||
- the TOC. If we're calling via a function pointer, the pointer
|
||
- itself identifies the descriptor. */
|
||
- {
|
||
- struct type *ftype = check_typedef (value_type (function));
|
||
- CORE_ADDR desc_addr = value_as_address (function);
|
||
-
|
||
- if (TYPE_CODE (ftype) == TYPE_CODE_PTR
|
||
- || convert_code_addr_to_desc_addr (func_addr, &desc_addr))
|
||
- {
|
||
- /* The TOC is the second double word in the descriptor. */
|
||
- CORE_ADDR toc =
|
||
- read_memory_unsigned_integer (desc_addr + tdep->wordsize,
|
||
- tdep->wordsize, byte_order);
|
||
- regcache_cooked_write_unsigned (regcache,
|
||
- tdep->ppc_gp0_regnum + 2, toc);
|
||
- }
|
||
- }
|
||
+ /* In the ELFv1 ABI, use the func_addr to find the descriptor, and use
|
||
+ that to find the TOC. If we're calling via a function pointer,
|
||
+ the pointer itself identifies the descriptor. */
|
||
+ if (tdep->elf_abi == POWERPC_ELF_V1)
|
||
+ {
|
||
+ struct type *ftype = check_typedef (value_type (function));
|
||
+ CORE_ADDR desc_addr = value_as_address (function);
|
||
+
|
||
+ if (TYPE_CODE (ftype) == TYPE_CODE_PTR
|
||
+ || convert_code_addr_to_desc_addr (func_addr, &desc_addr))
|
||
+ {
|
||
+ /* The TOC is the second double word in the descriptor. */
|
||
+ CORE_ADDR toc =
|
||
+ read_memory_unsigned_integer (desc_addr + tdep->wordsize,
|
||
+ tdep->wordsize, byte_order);
|
||
+ regcache_cooked_write_unsigned (regcache,
|
||
+ tdep->ppc_gp0_regnum + 2, toc);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ /* In the ELFv2 ABI, we need to pass the target address in r12 since
|
||
+ we may be calling a global entry point. */
|
||
+ if (tdep->elf_abi == POWERPC_ELF_V2)
|
||
+ regcache_cooked_write_unsigned (regcache,
|
||
+ tdep->ppc_gp0_regnum + 12, func_addr);
|
||
|
||
return sp;
|
||
}
|
||
@@ -1775,6 +2090,8 @@ ppc64_sysv_abi_return_value (struct gdba
|
||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||
struct type *func_type = function ? value_type (function) : NULL;
|
||
int opencl_abi = func_type? ppc_sysv_use_opencl_abi (func_type) : 0;
|
||
+ struct type *elt_type;
|
||
+ int n_elts;
|
||
|
||
/* This function exists to support a calling convention that
|
||
requires floating-point registers. It shouldn't be used on
|
||
@@ -1799,8 +2116,11 @@ ppc64_sysv_abi_return_value (struct gdba
|
||
return RETURN_VALUE_REGISTER_CONVENTION;
|
||
}
|
||
if (TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT)
|
||
- return get_decimal_float_return_value (gdbarch, valtype, regcache, readbuf,
|
||
- writebuf);
|
||
+ {
|
||
+ get_decimal_float_return_value (gdbarch, valtype, regcache,
|
||
+ readbuf, writebuf, 0);
|
||
+ return RETURN_VALUE_REGISTER_CONVENTION;
|
||
+ }
|
||
/* Integers in r3. */
|
||
if ((TYPE_CODE (valtype) == TYPE_CODE_INT
|
||
|| TYPE_CODE (valtype) == TYPE_CODE_ENUM
|
||
@@ -2019,6 +2339,114 @@ ppc64_sysv_abi_return_value (struct gdba
|
||
}
|
||
}
|
||
return RETURN_VALUE_REGISTER_CONVENTION;
|
||
+ }
|
||
+ /* In the ELFv2 ABI, homogeneous floating-point or vector
|
||
+ aggregates are returned in registers. */
|
||
+ if (tdep->elf_abi == POWERPC_ELF_V2
|
||
+ && ppc64_elfv2_abi_homogeneous_aggregate (valtype, &elt_type, &n_elts))
|
||
+ {
|
||
+ int i;
|
||
+ for (i = 0; i < n_elts; i++)
|
||
+ {
|
||
+ int offset = i * TYPE_LENGTH (elt_type);
|
||
+
|
||
+ switch (TYPE_CODE (elt_type))
|
||
+ {
|
||
+ case TYPE_CODE_FLT:
|
||
+ if (TYPE_LENGTH (elt_type) <= 8)
|
||
+ {
|
||
+ int regnum = tdep->ppc_fp0_regnum + 1 + i;
|
||
+ gdb_byte regval[MAX_REGISTER_SIZE];
|
||
+ struct type *regtype = register_type (gdbarch, regnum);
|
||
+ if (writebuf != NULL)
|
||
+ {
|
||
+ convert_typed_floating (writebuf + offset, elt_type,
|
||
+ regval, regtype);
|
||
+ regcache_cooked_write (regcache, regnum, regval);
|
||
+ }
|
||
+ if (readbuf != NULL)
|
||
+ {
|
||
+ regcache_cooked_read (regcache, regnum, regval);
|
||
+ convert_typed_floating (regval, regtype,
|
||
+ readbuf + offset, elt_type);
|
||
+ }
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ int j, nregs = (TYPE_LENGTH (elt_type) + 7) / 8;
|
||
+ for (j = 0; j < nregs; j++)
|
||
+ {
|
||
+ int regnum = tdep->ppc_fp0_regnum + 1 + nregs * i + j;
|
||
+
|
||
+ if (writebuf != NULL)
|
||
+ regcache_cooked_write (regcache, regnum,
|
||
+ writebuf + offset + j * 8);
|
||
+ if (readbuf != NULL)
|
||
+ regcache_cooked_read (regcache, regnum,
|
||
+ readbuf + offset + j * 8);
|
||
+ }
|
||
+ }
|
||
+ break;
|
||
+
|
||
+ case TYPE_CODE_DECFLOAT:
|
||
+ get_decimal_float_return_value (gdbarch, elt_type, regcache,
|
||
+ readbuf, writebuf, i);
|
||
+ break;
|
||
+
|
||
+ case TYPE_CODE_ARRAY:
|
||
+ {
|
||
+ int regnum = tdep->ppc_vr0_regnum + 2 + i;
|
||
+ gdb_assert (TYPE_VECTOR (elt_type));
|
||
+
|
||
+ if (writebuf != NULL)
|
||
+ regcache_cooked_write (regcache, regnum, writebuf + offset);
|
||
+ if (readbuf != NULL)
|
||
+ regcache_cooked_read (regcache, regnum, readbuf + offset);
|
||
+ }
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ return RETURN_VALUE_REGISTER_CONVENTION;
|
||
+ }
|
||
+ /* In the ELFv2 ABI, aggregate types of up to 16 bytes are
|
||
+ returned in registers r3:r4. */
|
||
+ if (tdep->elf_abi == POWERPC_ELF_V2
|
||
+ && TYPE_LENGTH (valtype) <= 16
|
||
+ && (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
|
||
+ || TYPE_CODE (valtype) == TYPE_CODE_UNION
|
||
+ || (TYPE_CODE (valtype) == TYPE_CODE_ARRAY && !TYPE_VECTOR (valtype))))
|
||
+ {
|
||
+ int n_regs = (TYPE_LENGTH (valtype) + tdep->wordsize - 1) / tdep->wordsize;
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < n_regs; i++)
|
||
+ {
|
||
+ gdb_byte regval[MAX_REGISTER_SIZE];
|
||
+ int regnum = tdep->ppc_gp0_regnum + 3 + i;
|
||
+ int offset = i * tdep->wordsize;
|
||
+ int len = TYPE_LENGTH (valtype) - offset;
|
||
+ if (len > tdep->wordsize)
|
||
+ len = tdep->wordsize;
|
||
+
|
||
+ if (writebuf != NULL)
|
||
+ {
|
||
+ memset (regval, 0, sizeof regval);
|
||
+ if (byte_order == BFD_ENDIAN_BIG && offset == 0)
|
||
+ memcpy (regval + tdep->wordsize - len, writebuf, len);
|
||
+ else
|
||
+ memcpy (regval, writebuf + offset, len);
|
||
+ regcache_cooked_write (regcache, regnum, regval);
|
||
+ }
|
||
+ if (readbuf != NULL)
|
||
+ {
|
||
+ regcache_cooked_read (regcache, regnum, regval);
|
||
+ if (byte_order == BFD_ENDIAN_BIG && offset == 0)
|
||
+ memcpy (readbuf, regval + tdep->wordsize - len, len);
|
||
+ else
|
||
+ memcpy (readbuf + offset, regval, len);
|
||
+ }
|
||
+ }
|
||
+ return RETURN_VALUE_REGISTER_CONVENTION;
|
||
}
|
||
return RETURN_VALUE_STRUCT_CONVENTION;
|
||
}
|
||
--- a/gdb/ppc-tdep.h
|
||
+++ b/gdb/ppc-tdep.h
|
||
@@ -182,6 +182,15 @@ extern void ppc_collect_vsxregset (const
|
||
|
||
/* Private data that this module attaches to struct gdbarch. */
|
||
|
||
+/* ELF ABI version used by the inferior. */
|
||
+enum powerpc_elf_abi
|
||
+{
|
||
+ POWERPC_ELF_AUTO,
|
||
+ POWERPC_ELF_V1,
|
||
+ POWERPC_ELF_V2,
|
||
+ POWERPC_ELF_LAST
|
||
+};
|
||
+
|
||
/* Vector ABI used by the inferior. */
|
||
enum powerpc_vector_abi
|
||
{
|
||
@@ -197,6 +206,8 @@ struct gdbarch_tdep
|
||
int wordsize; /* Size in bytes of fixed-point word. */
|
||
int soft_float; /* Avoid FP registers for arguments? */
|
||
|
||
+ enum powerpc_elf_abi elf_abi; /* ELF ABI version. */
|
||
+
|
||
/* How to pass vector arguments. Never set to AUTO or LAST. */
|
||
enum powerpc_vector_abi vector_abi;
|
||
|
||
--- a/gdb/symtab.c
|
||
+++ b/gdb/symtab.c
|
||
@@ -2881,6 +2881,8 @@ skip_prologue_sal (struct symtab_and_lin
|
||
|
||
/* Skip "first line" of function (which is actually its prologue). */
|
||
pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
||
+ if (gdbarch_skip_entrypoint_p (gdbarch))
|
||
+ pc = gdbarch_skip_entrypoint (gdbarch, pc);
|
||
if (skip)
|
||
pc = gdbarch_skip_prologue (gdbarch, pc);
|
||
|
||
--- a/gdb/testsuite/gdb.arch/altivec-regs.exp
|
||
+++ b/gdb/testsuite/gdb.arch/altivec-regs.exp
|
||
@@ -118,7 +118,7 @@ gdb_test "info reg vscr" "vscr.*0x1\t1"
|
||
if {$endianness == "big"} {
|
||
set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = .0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1.."
|
||
} else {
|
||
- set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.."
|
||
+ set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.."
|
||
}
|
||
|
||
for {set i 0} {$i < 32} {incr i 1} {
|
||
--- a/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp
|
||
+++ b/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp
|
||
@@ -20,7 +20,7 @@
|
||
|
||
# Testcase for ppc decimal128 pseudo-registers.
|
||
|
||
-if ![istarget "powerpc64-*"] then {
|
||
+if ![istarget "powerpc64*-*"] then {
|
||
verbose "Skipping powerpc Decimal128 pseudo-registers testcase."
|
||
return
|
||
}
|
||
--- a/gdb/testsuite/gdb.arch/vsx-regs.exp
|
||
+++ b/gdb/testsuite/gdb.arch/vsx-regs.exp
|
||
@@ -58,19 +58,46 @@ if ![runto_main] then {
|
||
gdb_suppress_tests
|
||
}
|
||
|
||
+send_gdb "show endian\n"
|
||
+set endianness ""
|
||
+gdb_expect {
|
||
+ -re "(The target endianness is set automatically .currently )(big|little)( endian.*)$gdb_prompt $" {
|
||
+ pass "endianness"
|
||
+ set endianness $expect_out(2,string)
|
||
+ }
|
||
+ -re ".*$gdb_prompt $" {
|
||
+ fail "couldn't get endianness"
|
||
+ }
|
||
+ timeout { fail "(timeout) endianness" }
|
||
+}
|
||
+
|
||
# Data sets used throughout the test
|
||
|
||
-set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x1, 0x0., v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x0, 0x0., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x0, 0x0, 0x0., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0.."
|
||
+if {$endianness == "big"} {
|
||
+ set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x1, 0x0., v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x0, 0x0., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x0, 0x0, 0x0., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0.."
|
||
+
|
||
+ set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x1, 0x1., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
|
||
+
|
||
+ set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.."
|
||
|
||
-set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x1, 0x1., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
|
||
+ set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.."
|
||
|
||
-set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.."
|
||
+ set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
|
||
|
||
-set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.."
|
||
+ set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
|
||
+} else {
|
||
+ set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x0, 0x1., v4_float = .0x0, 0x0, 0xf99999a0, 0x1., v4_int32 = .0x0, 0x0, 0xcccccccc, 0x3ff4cccc., v8_int16 = .0x0, 0x0, 0x0, 0x0, 0xcccc, 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.."
|
||
|
||
-set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
|
||
+ set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x0, 0x0, 0xf99999a0, 0x1., v4_int32 = .0x1, 0x1, 0xcccccccc, 0x3ff4cccc., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0xcccc, 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.."
|
||
|
||
-set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
|
||
+ set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.."
|
||
+
|
||
+ set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.."
|
||
+
|
||
+ set vector_register3 ".uint128 = 0x00000001000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.."
|
||
+
|
||
+ set vector_register3_vr ".uint128 = 0x00000001000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.."
|
||
+}
|
||
|
||
set float_register ".raw 0xdeadbeefdeadbeef."
|
||
|
||
--- a/gdb/testsuite/gdb.base/sigbpt.exp
|
||
+++ b/gdb/testsuite/gdb.base/sigbpt.exp
|
||
@@ -82,7 +82,7 @@ gdb_test "break keeper"
|
||
set bowler_addrs bowler
|
||
set segv_addr none
|
||
gdb_test {display/i $pc}
|
||
-gdb_test "advance *bowler" "bowler.*" "advance to the bowler"
|
||
+gdb_test "advance bowler" "bowler.*" "advance to the bowler"
|
||
set test "stepping to fault"
|
||
set signame "SIGSEGV"
|
||
gdb_test_multiple "stepi" "$test" {
|
||
--- a/gdb/testsuite/gdb.base/step-bt.exp
|
||
+++ b/gdb/testsuite/gdb.base/step-bt.exp
|
||
@@ -32,7 +32,7 @@ gdb_start
|
||
gdb_reinitialize_dir $srcdir/$subdir
|
||
gdb_load ${binfile}
|
||
|
||
-gdb_test "break *hello" \
|
||
+gdb_test "break hello" \
|
||
"Breakpoint.*at.* file .*$srcfile, line .*" \
|
||
"breakpoint at first instruction of hello()"
|
||
|
||
--- a/include/elf/common.h
|
||
+++ b/include/elf/common.h
|
||
@@ -954,6 +954,7 @@
|
||
#define AT_BASE_PLATFORM 24 /* String identifying real platform,
|
||
may differ from AT_PLATFORM. */
|
||
#define AT_RANDOM 25 /* Address of 16 random bytes. */
|
||
+#define AT_HWCAP2 26 /* Extension of AT_HWCAP. */
|
||
#define AT_EXECFN 31 /* Filename of executable. */
|
||
/* Pointer to the global system page used for system calls and other
|
||
nice things. */
|
||
--- a/include/elf/ppc64.h
|
||
+++ b/include/elf/ppc64.h
|
||
@@ -164,6 +164,60 @@ END_RELOC_NUMBERS (R_PPC64_max)
|
||
#define IS_PPC64_TLS_RELOC(R) \
|
||
((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA)
|
||
|
||
+
|
||
+/* e_flags bits specifying ABI.
|
||
+ 1 for original function descriptor using ABI,
|
||
+ 2 for revised ABI without function descriptors,
|
||
+ 0 for unspecified or not using any features affected by the differences. */
|
||
+#define EF_PPC64_ABI 3
|
||
+
|
||
+/* The ELFv2 ABI uses three bits in the symbol st_other field of a
|
||
+ function definition to specify the number of instructions between a
|
||
+ function's global entry point and local entry point.
|
||
+ The global entry point is used when it is necessary to set up the
|
||
+ toc pointer (r2) for the function. Callers must enter the global
|
||
+ entry point with r12 set to the global entry point address. On
|
||
+ return from the function, r2 may have a different value to that
|
||
+ which it had on entry.
|
||
+ The local entry point is used when r2 is known to already be valid
|
||
+ for the function. There is no requirement on r12 when using the
|
||
+ local entry point, and on return r2 will contain the same value as
|
||
+ at entry.
|
||
+ A value of zero in these bits means that the function has a single
|
||
+ entry point with no requirement on r12 or r2, and that on return r2
|
||
+ will contain the same value as at entry.
|
||
+ Values of one and seven are reserved. */
|
||
+#define STO_PPC64_LOCAL_BIT 5
|
||
+#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
|
||
+
|
||
+// 3 bit other field to bytes.
|
||
+static inline unsigned int
|
||
+ppc64_decode_local_entry(unsigned int other)
|
||
+{
|
||
+ return ((1 << other) >> 2) << 2;
|
||
+}
|
||
+
|
||
+// bytes to field value.
|
||
+static inline unsigned int
|
||
+ppc64_encode_local_entry(unsigned int val)
|
||
+{
|
||
+ return (val >= 4 * 4
|
||
+ ? (val >= 8 * 4
|
||
+ ? (val >= 16 * 4 ? 6 : 5)
|
||
+ : 4)
|
||
+ : (val >= 2 * 4
|
||
+ ? 3
|
||
+ : (val >= 1 * 4 ? 2 : 0)));
|
||
+}
|
||
+
|
||
+/* st_other to number of bytes. */
|
||
+#define PPC64_LOCAL_ENTRY_OFFSET(other) \
|
||
+ ppc64_decode_local_entry (((other) & STO_PPC64_LOCAL_MASK) \
|
||
+ >> STO_PPC64_LOCAL_BIT)
|
||
+/* number of bytes to st_other. */
|
||
+#define PPC64_SET_LOCAL_ENTRY_OFFSET(val) \
|
||
+ ppc64_encode_local_entry (val) << STO_PPC64_LOCAL_BIT
|
||
+
|
||
/* Specify the start of the .glink section. */
|
||
#define DT_PPC64_GLINK DT_LOPROC
|
||
|