summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx39
1 files changed, 39 insertions, 0 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index f9969434..ede2092f 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1635,6 +1635,7 @@ target_variable_flavour_calculating_visitor::visit_target_symbol (target_symbol
}
}
+
void
dwarf_query::add_probe_point(string const & funcname,
char const * filename,
@@ -1644,6 +1645,44 @@ dwarf_query::add_probe_point(string const & funcname,
{
dwarf_derived_probe *probe = NULL;
+ // Check whether the given address points into an .init section,
+ // which will have been unmapped by the kernel by the time we get to
+ // insert the probe. In this case, just ignore this call.
+ Dwarf_Addr baseaddr;
+ Elf* elf = dwfl_module_getelf (dw.module, & baseaddr);
+ Dwarf_Addr rel_addr = addr - baseaddr;
+ if (elf)
+ {
+ // Iterate through section headers to find which one
+ // contains the given rel_addr.
+ Elf_Scn* scn = 0;
+ size_t shstrndx;
+ dw.dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
+ while (scn = elf_nextscn (elf, scn))
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (! shdr) continue; // XXX error?
+
+ // check for address inclusion
+ GElf_Addr start = shdr->sh_addr;
+ GElf_Addr end = start + shdr->sh_size;
+ if (! (rel_addr >= start && rel_addr < end))
+ continue;
+
+ // check for section name
+ const char* name = elf_strptr (elf, shstrndx, shdr->sh_name);
+ if (name && strncmp (name, ".init.", 6) == 0)
+ {
+ if (sess.verbose)
+ clog << "skipping function '" << funcname << "' base 0x"
+ << hex << addr << dec << " is within section '"
+ << name << "'" << endl;
+ return;
+ }
+ }
+ }
+
if (probe_has_no_target_variables)
{
assert(probe_flavours.size() == 1);