This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v3 1/2] systemtap/tapsets.cxx: Adjusted for multiple static functions


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]