aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2014-02-04 18:40:16 +0100
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2014-02-04 18:40:16 +0100
commitd4094b6a8883ae481c7644c5a210254efe92e9ad (patch)
treef90a336f9a968fe20137397c9710eee20c1599a5
parentcd453cd072004d26ede355b850b3831acffaeddd (diff)
downloadgdb-d4094b6a8883ae481c7644c5a210254efe92e9ad.zip
gdb-d4094b6a8883ae481c7644c5a210254efe92e9ad.tar.gz
gdb-d4094b6a8883ae481c7644c5a210254efe92e9ad.tar.bz2
PowerPC64 ELFv2 ABI: no function descriptors
This implements the most significant difference with the ELFv2 ABI: we no longer use function descriptors. The patch consists mostly of switching off code to deal with descriptors :-) In addition, when calling an inferior function, we no longer need to provide its TOC in r2. Instead, ELFv2 code expects to be called with r12 pointing to the code address itself. gdb/ChangeLog: * ppc-linux-tdep.c (ppc_linux_init_abi): Only call set_gdbarch_convert_from_func_ptr_addr and set_gdbarch_elf_make_msymbol_special for ELFv1. * ppc-sysv-tdep.c (ppc64_sysv_abi_push_param): Only handle function descriptors on ELFv1. (ppc64_sysv_abi_push_dummy_call): Likewise. On ELFv2, set up r12 at function entry.
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/ppc-linux-tdep.c15
-rw-r--r--gdb/ppc-sysv-tdep.c49
3 files changed, 48 insertions, 26 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ba7ddd9..795e23f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
2014-02-04 Ulrich Weigand  <uweigand@de.ibm.com>
+ * ppc-linux-tdep.c (ppc_linux_init_abi): Only call
+ set_gdbarch_convert_from_func_ptr_addr and
+ set_gdbarch_elf_make_msymbol_special for ELFv1.
+ * ppc-sysv-tdep.c (ppc64_sysv_abi_push_param): Only handle
+ function descriptors on ELFv1.
+ (ppc64_sysv_abi_push_dummy_call): Likewise. On ELFv2,
+ set up r12 at function entry.
+
+2014-02-04 Ulrich Weigand  <uweigand@de.ibm.com>
+
* ppc-tdep.h (enum powerpc_elf_abi): New data type.
(struct gdbarch_tdep): New member elf_abi.
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index f28f360..25008c0 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -1339,13 +1339,16 @@ ppc_linux_init_abi (struct gdbarch_info 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);
+ }
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 8e460e5..b7fb429 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -1352,8 +1352,9 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
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
= check_typedef (TYPE_TARGET_TYPE (type));
@@ -1553,24 +1554,32 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
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;
}