You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
4.5 KiB
118 lines
4.5 KiB
commit d4094b6a8883ae481c7644c5a210254efe92e9ad |
|
Author: Ulrich Weigand <ulrich.weigand@de.ibm.com> |
|
Date: Tue Feb 4 18:40:16 2014 +0100 |
|
|
|
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. |
|
|
|
Index: gdb-7.6.1/gdb/ppc-linux-tdep.c |
|
=================================================================== |
|
--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c |
|
+++ gdb-7.6.1/gdb/ppc-linux-tdep.c |
|
@@ -1331,13 +1331,16 @@ 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); |
|
+ } |
|
|
|
/* Shared library handling. */ |
|
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); |
|
Index: gdb-7.6.1/gdb/ppc-sysv-tdep.c |
|
=================================================================== |
|
--- gdb-7.6.1.orig/gdb/ppc-sysv-tdep.c |
|
+++ gdb-7.6.1/gdb/ppc-sysv-tdep.c |
|
@@ -1351,8 +1351,9 @@ ppc64_sysv_abi_push_param (struct gdbarc |
|
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)); |
|
@@ -1552,24 +1553,32 @@ 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; |
|
}
|
|
|