This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[PATCH v3 1/2] systemtap/tapsets.cxx: Adjusted for multiple static functions
- From: Hemant Kumar <hemant at linux dot vnet dot ibm dot com>
- To: systemtap at sourceware dot org
- Cc: mjw at redhat dot com, naveen dot n dot rao at linux dot vnet dot ibm dot com, ulrich dot weigand at de dot ibm dot com, uweigand at gcc dot gnu dot org, anton at samba dot org, fche at redhat dot com, Hemant Kumar <hemant at linux dot vnet dot ibm dot com>
- Date: Fri, 27 Mar 2015 19:12:15 +0530
- Subject: [PATCH v3 1/2] systemtap/tapsets.cxx: Adjusted for multiple static functions
- Authentication-results: sourceware.org; auth=none
There can be multiple static functions in an ELF (although in different
compilation units). But the existing lookup_symbol() code doesn't take
care of this. This patch changes the already existing map between
a function name to its descriptor to a map between a function name
to a list of descriptors(func_info), so that multiple static functions
can be accomodated in this map.
So, now whenever lookup_symbol will be called, a list of func_info *
will be sent instead of a single descriptor corresponding to the
function name.
We also need to fix other areas in the code where lookup_symbol() and
lookup_symbol_address() are being called so as to look for a list
instead of a single value.
Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
---
tapsets.cxx | 95 ++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 65 insertions(+), 30 deletions(-)
diff --git a/tapsets.cxx b/tapsets.cxx
index 443fb2e..326ba6a 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -395,7 +395,7 @@ struct
symbol_table
{
module_info *mod_info; // associated module
- map<string, func_info*> map_by_name;
+ map<string, list <func_info*> > map_by_name;
multimap<Dwarf_Addr, func_info*> map_by_addr;
map<string, Dwarf_Addr> globals;
map<string, Dwarf_Addr> locals;
@@ -410,8 +410,8 @@ symbol_table
void prepare_section_rejection(Dwfl_Module *mod);
bool reject_section(GElf_Word section);
void purge_syscall_stubs();
- func_info *lookup_symbol(const string& name);
- Dwarf_Addr lookup_symbol_address(const string& name);
+ list <func_info*> *lookup_symbol(const string& name);
+ list <Dwarf_Addr> *lookup_symbol_address(const string& name);
func_info *get_func_containing_address(Dwarf_Addr addr);
func_info *get_first_func();
@@ -1113,9 +1113,16 @@ dwarf_query::query_module_symtab()
}
else
{
- fi = sym_table->lookup_symbol(function_str_val);
- if (fi && !fi->descriptor && null_die(&fi->die))
- query_symtab_func_info(*fi, this);
+ list<func_info*> *fis = new list<func_info*>;
+ fis = sym_table->lookup_symbol(function_str_val);
+ if (!fis || fis->empty())
+ return;
+ for (list<func_info*>::iterator it=fis->begin(); it!=fis->end(); ++it)
+ {
+ fi = *it;
+ if (fi && !fi->descriptor && null_die(&fi->die))
+ query_symtab_func_info(*fi, this);
+ }
}
}
}
@@ -7484,8 +7491,8 @@ suggest_dwarf_functions(systemtap_session& sess,
// add all function symbols in cache
if (module->symtab_status != info_present || module->sym_table == NULL)
continue;
- map<string, func_info*>& modfuncs = module->sym_table->map_by_name;
- for (map<string, func_info*>::const_iterator itfuncs = modfuncs.begin();
+ map<string, list<func_info*> >& modfuncs = module->sym_table->map_by_name;
+ for (map<string, list <func_info*> >::const_iterator itfuncs = modfuncs.begin();
itfuncs != modfuncs.end(); ++itfuncs)
funcs.insert(itfuncs->first);
}
@@ -8072,7 +8079,21 @@ symbol_table::add_symbol(const char *name, bool weak, bool descriptor,
fi->name = name;
fi->weak = weak;
fi->descriptor = descriptor;
- map_by_name[fi->name] = fi;
+
+ if (map_by_name[fi->name].empty())
+ map_by_name[fi->name].push_back(fi);
+ else /* Check if its a duplicate entry ? */
+ {
+ list<func_info*>::iterator it=map_by_name[fi->name].begin();
+ for (; it!=map_by_name[fi->name].end(); ++it)
+ {
+ if (fi->addr == (*it)->addr)
+ break;
+ }
+ if (it == map_by_name[fi->name].end())
+ map_by_name[fi->name].push_back(fi);
+ }
+
// TODO: Use a multimap in case there are multiple static
// functions with the same name?
map_by_addr.insert(make_pair(addr, fi));
@@ -8194,22 +8215,29 @@ symbol_table::get_first_func()
return (iter)->second;
}
-func_info *
+list <func_info*> *
symbol_table::lookup_symbol(const string& name)
{
- map<string, func_info*>::iterator i = map_by_name.find(name);
+ map<string, list <func_info*> >::iterator i = map_by_name.find(name);
if (i == map_by_name.end())
return NULL;
- return i->second;
+ return &i->second;
}
-Dwarf_Addr
+list <Dwarf_Addr> *
symbol_table::lookup_symbol_address(const string& name)
{
- func_info *fi = lookup_symbol(name);
- if (fi)
- return fi->addr;
- return 0;
+ list<func_info*> *fis = new list<func_info*>;
+ list<Dwarf_Addr> *addrs = new list<Dwarf_Addr>;
+
+ fis = lookup_symbol(name);
+ if (!fis || fis->empty())
+ return NULL;
+ for (list<func_info*>::iterator it=fis->begin(); it!=fis->end(); ++it)
+ {
+ addrs->push_back((*it)->addr);
+ }
+ return addrs;
}
// This is the kernel symbol table. The kernel macro cond_syscall creates
@@ -8223,9 +8251,12 @@ symbol_table::lookup_symbol_address(const string& name)
void
symbol_table::purge_syscall_stubs()
{
- Dwarf_Addr stub_addr = lookup_symbol_address("sys_ni_syscall");
- if (stub_addr == 0)
+ list<Dwarf_Addr> *addrs = lookup_symbol_address("sys_ni_syscall");
+ if (!addrs || addrs->empty())
return;
+ /* Highly unlikely that multiple functions named "sys_ni_syscall" may exist */
+ Dwarf_Addr stub_addr = addrs->front();
+
range_t purge_range = map_by_addr.equal_range(stub_addr);
for (iterator_t iter = purge_range.first;
iter != purge_range.second;
@@ -8299,21 +8330,25 @@ module_info::update_symtab(cu_function_cache_t *funcs)
// missing, so we may also need to try matching by address. See also the
// notes about _Z in dwflpp::iterate_over_functions().
- func_info *fi = sym_table->lookup_symbol(func->first);
- if (!fi)
+ list<func_info*> *fis = sym_table->lookup_symbol(func->first);
+ if (!fis || fis->empty())
continue;
- // iterate over all functions at the same address
- symbol_table::range_t er = sym_table->map_by_addr.equal_range(fi->addr);
- for (symbol_table::iterator_t it = er.first; it != er.second; ++it)
+ for (list<func_info*>::iterator fi=fis->begin(); fi!=fis->end(); ++fi)
{
- // update this function with the dwarf die
- it->second->die = func->second;
+ // iterate over all functions at the same address
+ symbol_table::range_t er = sym_table->map_by_addr.equal_range((*fi)->addr);
- // if this function is a new alias, then
- // save it to merge into the function cache
- if (it->second != fi)
- new_funcs.insert(make_pair(it->second->name, it->second->die));
+ for (symbol_table::iterator_t it = er.first; it != er.second; ++it)
+ {
+ // update this function with the dwarf die
+ it->second->die = func->second;
+
+ // if this function is a new alias, then
+ // save it to merge into the function cache
+ if (it->second != *fi)
+ new_funcs.insert(make_pair(it->second->name, it->second->die));
+ }
}
}
--
1.9.3