From: Daniel Jacobowitz Date: Wed, 14 May 2008 18:14:34 +0000 (+0000) Subject: * elfread.c (elf_symtab_read): Create trampolines for @plt symbols. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2eaf8d2a141aefdad8ad7f61c9a9f84a38019044;p=binutils-gdb.git * elfread.c (elf_symtab_read): Create trampolines for @plt symbols. * minsyms.c (lookup_minimal_symbol_by_pc_section_1): Renamed from lookup_minimal_symbol_by_pc_section. Prefer trampolines if requested. (lookup_minimal_symbol_by_pc_section): Use lookup_minimal_symbol_by_pc_section_1. (lookup_solib_trampoline_symbol_by_pc): Likewise. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 98330131638..e7ff47bfb11 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2008-05-14 Daniel Jacobowitz + + * elfread.c (elf_symtab_read): Create trampolines for @plt symbols. + * minsyms.c (lookup_minimal_symbol_by_pc_section_1): Renamed from + lookup_minimal_symbol_by_pc_section. Prefer trampolines if requested. + (lookup_minimal_symbol_by_pc_section): Use + lookup_minimal_symbol_by_pc_section_1. + (lookup_solib_trampoline_symbol_by_pc): Likewise. + 2008-05-13 Joel Brobecker * findcmd.c: Add #include "gdb_stdint.h". diff --git a/gdb/elfread.c b/gdb/elfread.c index 76af9dcd7c3..363702a99fc 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -521,6 +521,33 @@ elf_symtab_read (struct objfile *objfile, int type, if (msym != NULL) msym->filename = filesymname; gdbarch_elf_make_msymbol_special (gdbarch, sym, msym); + + /* For @plt symbols, also record a trampoline to the + destination symbol. The @plt symbol will be used in + disassembly, and the trampoline will be used when we are + trying to find the target. */ + if (msym && ms_type == mst_text && type == ST_SYNTHETIC) + { + int len = strlen (sym->name); + + if (len > 4 && strcmp (sym->name + len - 4, "@plt") == 0) + { + char *base_name = alloca (len - 4 + 1); + struct minimal_symbol *mtramp; + + memcpy (base_name, sym->name, len - 4); + base_name[len - 4] = '\0'; + mtramp = record_minimal_symbol (base_name, symaddr, + mst_solib_trampoline, + sym->section, objfile); + if (mtramp) + { + MSYMBOL_SIZE (mtramp) = MSYMBOL_SIZE (msym); + mtramp->filename = filesymname; + gdbarch_elf_make_msymbol_special (gdbarch, sym, mtramp); + } + } + } } } } diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 8dceb0d7f5e..f1a6c486b44 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -377,10 +377,15 @@ lookup_minimal_symbol_solib_trampoline (const char *name, ALL the minimal symbol tables before deciding on the symbol that comes closest to the specified PC. This is because objfiles can overlap, for example objfile A has .text at 0x100 and .data at - 0x40000 and objfile B has .text at 0x234 and .data at 0x40048. */ + 0x40000 and objfile B has .text at 0x234 and .data at 0x40048. -struct minimal_symbol * -lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) + If WANT_TRAMPOLINE is set, prefer mst_solib_trampoline symbols when + there are text and trampoline symbols at the same address. + Otherwise prefer mst_text symbols. */ + +static struct minimal_symbol * +lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section, + int want_trampoline) { int lo; int hi; @@ -389,7 +394,11 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) struct minimal_symbol *msymbol; struct minimal_symbol *best_symbol = NULL; struct obj_section *pc_section; + enum minimal_symbol_type want_type, other_type; + want_type = want_trampoline ? mst_solib_trampoline : mst_text; + other_type = want_trampoline ? mst_text : mst_solib_trampoline; + /* PC has to be in a known section. This ensures that anything beyond the end of the last segment doesn't appear to be part of the last function in the last segment. */ @@ -506,6 +515,24 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) continue; } + /* If we are looking for a trampoline and this is a + text symbol, or the other way around, check the + preceeding symbol too. If they are otherwise + identical prefer that one. */ + if (hi > 0 + && MSYMBOL_TYPE (&msymbol[hi]) == other_type + && MSYMBOL_TYPE (&msymbol[hi - 1]) == want_type + && (MSYMBOL_SIZE (&msymbol[hi]) + == MSYMBOL_SIZE (&msymbol[hi - 1])) + && (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) + == SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1])) + && (SYMBOL_BFD_SECTION (&msymbol[hi]) + == SYMBOL_BFD_SECTION (&msymbol[hi - 1]))) + { + hi--; + continue; + } + /* If the minimal symbol has a zero size, save it but keep scanning backwards looking for one with a non-zero size. A zero size may mean that the @@ -586,6 +613,12 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) return (best_symbol); } +struct minimal_symbol * +lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) +{ + return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0); +} + /* Backward compatibility: search through the minimal symbol table for a matching PC (no section given) */ @@ -1039,7 +1072,13 @@ msymbols_sort (struct objfile *objfile) struct minimal_symbol * lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc) { - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc); + struct obj_section *section = find_pc_section (pc); + struct minimal_symbol *msymbol; + + if (section == NULL) + return NULL; + msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section->the_bfd_section, + 1); if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) return msymbol;