aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2008-05-14 18:14:34 +0000
committerDaniel Jacobowitz <drow@false.org>2008-05-14 18:14:34 +0000
commit2eaf8d2a141aefdad8ad7f61c9a9f84a38019044 (patch)
treeb71b0af640d0fabda31752ade90b5ba5c4192bf3
parent86a4952b1461aa668cb0fd55ececbb691eefdb12 (diff)
downloadgdb-2eaf8d2a141aefdad8ad7f61c9a9f84a38019044.zip
gdb-2eaf8d2a141aefdad8ad7f61c9a9f84a38019044.tar.gz
gdb-2eaf8d2a141aefdad8ad7f61c9a9f84a38019044.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog9
-rw-r--r--gdb/elfread.c27
-rw-r--r--gdb/minsyms.c47
3 files changed, 79 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9833013..e7ff47b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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".
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 76af9dc..363702a 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 8dceb0d..f1a6c48 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;