diff options
Diffstat (limited to 'gdb/ppc-linux-tdep.c')
-rw-r--r-- | gdb/ppc-linux-tdep.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 25008c0..6d3b2d8 100644 --- 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,55 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, } } + +/* Implementation of `gdbarch_elf_make_msymbol_special', as defined in + gdbarch.h. This implementation is used for the ELFv2 ABI only. */ + +static void +ppc_elfv2_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym) +{ + elf_symbol_type *elf_sym = (elf_symbol_type *)sym; + + /* If the symbol is marked as having a local entry point, set a target + flag in the msymbol. We currently only support local entry point + offsets of 8 bytes, which is the only entry point offset ever used + by current compilers. If/when other offsets are ever used, we will + have to use additional target flag bits to store them. */ + switch (PPC64_LOCAL_ENTRY_OFFSET (elf_sym->internal_elf_sym.st_other)) + { + default: + break; + case 8: + MSYMBOL_TARGET_FLAG_1 (msym) = 1; + break; + } +} + +/* Implementation of `gdbarch_skip_entrypoint', as defined in + gdbarch.h. This implementation is used for the ELFv2 ABI only. */ + +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; + + /* See ppc_elfv2_elf_make_msymbol_special for how local entry point + offset values are encoded. */ + 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. */ @@ -1349,6 +1399,13 @@ ppc_linux_init_abi (struct gdbarch_info info, 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); |