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.
This commit is contained in:
Ulrich Weigand 2014-02-04 18:40:16 +01:00
parent cd453cd072
commit d4094b6a88
3 changed files with 47 additions and 25 deletions

View File

@ -1,3 +1,13 @@
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> 2014-02-04 Ulrich Weigand  <uweigand@de.ibm.com>
* ppc-tdep.h (enum powerpc_elf_abi): New data type. * ppc-tdep.h (enum powerpc_elf_abi): New data type.

View File

@ -1339,13 +1339,16 @@ ppc_linux_init_abi (struct gdbarch_info info,
if (tdep->wordsize == 8) if (tdep->wordsize == 8)
{ {
/* Handle PPC GNU/Linux 64-bit function pointers (which are really if (tdep->elf_abi == POWERPC_ELF_V1)
function descriptors). */ {
set_gdbarch_convert_from_func_ptr_addr /* Handle PPC GNU/Linux 64-bit function pointers (which are really
(gdbarch, ppc64_convert_from_func_ptr_addr); function descriptors). */
set_gdbarch_convert_from_func_ptr_addr
(gdbarch, ppc64_convert_from_func_ptr_addr);
set_gdbarch_elf_make_msymbol_special (gdbarch, set_gdbarch_elf_make_msymbol_special
ppc64_elf_make_msymbol_special); (gdbarch, ppc64_elf_make_msymbol_special);
}
/* Shared library handling. */ /* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);

View File

@ -1352,8 +1352,9 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
word = unpack_long (type, val); word = unpack_long (type, val);
/* Convert any function code addresses into descriptors. */ /* Convert any function code addresses into descriptors. */
if (TYPE_CODE (type) == TYPE_CODE_PTR if (tdep->elf_abi == POWERPC_ELF_V1
|| TYPE_CODE (type) == TYPE_CODE_REF) && (TYPE_CODE (type) == TYPE_CODE_PTR
|| TYPE_CODE (type) == TYPE_CODE_REF))
{ {
struct type *target_type struct type *target_type
= check_typedef (TYPE_TARGET_TYPE (type)); = check_typedef (TYPE_TARGET_TYPE (type));
@ -1553,24 +1554,32 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch,
breakpoint. */ breakpoint. */
regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
/* Use the func_addr to find the descriptor, and use that to find /* In the ELFv1 ABI, use the func_addr to find the descriptor, and use
the TOC. If we're calling via a function pointer, the pointer that to find the TOC. If we're calling via a function pointer,
itself identifies the descriptor. */ 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); struct type *ftype = check_typedef (value_type (function));
CORE_ADDR desc_addr = value_as_address (function);
if (TYPE_CODE (ftype) == TYPE_CODE_PTR if (TYPE_CODE (ftype) == TYPE_CODE_PTR
|| convert_code_addr_to_desc_addr (func_addr, &desc_addr)) || convert_code_addr_to_desc_addr (func_addr, &desc_addr))
{ {
/* The TOC is the second double word in the descriptor. */ /* The TOC is the second double word in the descriptor. */
CORE_ADDR toc = CORE_ADDR toc =
read_memory_unsigned_integer (desc_addr + tdep->wordsize, read_memory_unsigned_integer (desc_addr + tdep->wordsize,
tdep->wordsize, byte_order); tdep->wordsize, byte_order);
regcache_cooked_write_unsigned (regcache,
tdep->ppc_gp0_regnum + 2, toc); 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; return sp;
} }