summaryrefslogtreecommitdiffstats
path: root/translate.cxx
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2009-04-14 12:34:11 -0400
committerDave Brolley <brolley@redhat.com>2009-04-14 12:34:11 -0400
commit6c39ba6093aa0b3b86aa7e6f17a23ef322bd67cd (patch)
tree7491c5c2357768fafe21752c3a16436f23c51f70 /translate.cxx
parenta2422e707214a425e4e10ac5b7c39fc5ae4dea56 (diff)
parentb9c2e81cc7a62336ec1daf374cb3411add772ab4 (diff)
downloadsystemtap-steved-6c39ba6093aa0b3b86aa7e6f17a23ef322bd67cd.tar.gz
systemtap-steved-6c39ba6093aa0b3b86aa7e6f17a23ef322bd67cd.tar.xz
systemtap-steved-6c39ba6093aa0b3b86aa7e6f17a23ef322bd67cd.zip
Merge branch 'master' of git://sources.redhat.com/git/systemtap
Diffstat (limited to 'translate.cxx')
-rw-r--r--translate.cxx45
1 files changed, 29 insertions, 16 deletions
diff --git a/translate.cxx b/translate.cxx
index 95986924..971c1498 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4516,7 +4516,7 @@ dump_unwindsyms (Dwfl_Module *m,
// In the future, we'll also care about data symbols.
int syments = dwfl_module_getsymtab(m);
- assert(syments);
+ dwfl_assert ("Getting symbol table for " + modname, syments >= 0);
//extract build-id from debuginfo file
int build_id_len = 0;
@@ -4562,6 +4562,10 @@ dump_unwindsyms (Dwfl_Module *m,
}
}
+ // Use end as sanity check when resolving symbol addresses.
+ Dwarf_Addr end;
+ dwfl_module_info (m, NULL, NULL, &end, NULL, NULL, NULL, NULL);
+
// Look up the relocation basis for symbols
int n = dwfl_module_relocations (m);
@@ -4576,10 +4580,11 @@ dump_unwindsyms (Dwfl_Module *m,
Dwarf_Addr extra_offset = 0;
- for (int i = 1 /* XXX: why not 0? */ ; i < syments; ++i)
+ for (int i = 0; i < syments; ++i)
{
GElf_Sym sym;
- const char *name = dwfl_module_getsym(m, i, &sym, NULL);
+ GElf_Word shndxp;
+ const char *name = dwfl_module_getsym(m, i, &sym, &shndxp);
if (name)
{
// NB: Yey, we found the kernel's _stext value.
@@ -4602,17 +4607,15 @@ dump_unwindsyms (Dwfl_Module *m,
clog << "Found kernel _stext extra offset 0x" << hex << extra_offset << dec << endl;
}
- // We only need the function symbols to identify kernel-mode
- // PC's, so we omit undefined or "fake" absolute addresses.
- // These fake absolute addresses occur in some older i386
- // kernels to indicate they are vDSO symbols, not real
- // functions in the kernel. We also omit symbols that have
- // suspicious addresses (before base).
+ // We are only interested in "real" symbols.
+ // We omit symbols that have suspicious addresses (before base,
+ // or after end).
if ((GELF_ST_TYPE (sym.st_info) == STT_FUNC ||
GELF_ST_TYPE (sym.st_info) == STT_OBJECT) // PR10000: also need .data
- && !(sym.st_shndx == SHN_UNDEF
- || sym.st_shndx == SHN_ABS
- || sym.st_value < base))
+ && !(sym.st_shndx == SHN_UNDEF // Value undefined,
+ || shndxp == (GElf_Word) -1 // in a non-allocated section,
+ || sym.st_value >= end // beyond current module,
+ || sym.st_value < base)) // before first section.
{
Dwarf_Addr sym_addr = sym.st_value;
const char *secname = NULL;
@@ -4637,6 +4640,16 @@ dump_unwindsyms (Dwfl_Module *m,
{
// This is a symbol within a (possibly relocatable)
// kernel image.
+
+ // We only need the function symbols to identify kernel-mode
+ // PC's, so we omit undefined or "fake" absolute addresses.
+ // These fake absolute addresses occur in some older i386
+ // kernels to indicate they are vDSO symbols, not real
+ // functions in the kernel. We also omit symbols that have
+ if (GELF_ST_TYPE (sym.st_info) == STT_FUNC
+ && sym.st_shndx == SHN_ABS)
+ continue;
+
secname = "_stext";
// NB: don't subtract session.sym_stext, which could be inconveniently NULL.
// Instead, sym_addr will get compensated later via extra_offset.
@@ -4696,10 +4709,10 @@ dump_unwindsyms (Dwfl_Module *m,
// There would be only a small benefit to warning. A user
// likely can't do anything about this; backtraces for the
// affected module would just get all icky heuristicy.
-#if 0
- c->session.print_warning ("No unwind data for " + modname
- + ", " + dwfl_errmsg (-1));
-#endif
+ // So only report in verbose mode.
+ if (c->session.verbose > 2)
+ c->session.print_warning ("No unwind data for " + modname
+ + ", " + dwfl_errmsg (-1));
}
for (unsigned secidx = 0; secidx < seclist.size(); secidx++)