* 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.
This commit is contained in:
Daniel Jacobowitz 2008-05-14 18:14:34 +00:00
parent 86a4952b14
commit 2eaf8d2a14
3 changed files with 79 additions and 4 deletions

View File

@ -1,3 +1,12 @@
2008-05-14 Daniel Jacobowitz <dan@codesourcery.com>
* 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 <brobecker@adacore.com>
* findcmd.c: Add #include "gdb_stdint.h".

View File

@ -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);
}
}
}
}
}
}

View File

@ -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;