diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ba7ddd9d796..795e23f1292 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2014-02-04 Ulrich Weigand  + + * 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  * ppc-tdep.h (enum powerpc_elf_abi): New data type. diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index f28f360cbad..25008c010b7 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 8e460e5f675..b7fb4297d39 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); + /* 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); - } - } + 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; }