summaryrefslogtreecommitdiffstats
path: root/dwflpp.cxx
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-09-02 19:09:50 -0700
committerJosh Stone <jistone@redhat.com>2009-09-02 19:09:50 -0700
commitb74789646bfe59131327716357c8b7c1521fa14a (patch)
tree90647b22c781da3a38dc5be568ed846280b64193 /dwflpp.cxx
parent7a1921492e38221e1552b7698f001fa70d0e0e8b (diff)
downloadsystemtap-steved-b74789646bfe59131327716357c8b7c1521fa14a.tar.gz
systemtap-steved-b74789646bfe59131327716357c8b7c1521fa14a.tar.xz
systemtap-steved-b74789646bfe59131327716357c8b7c1521fa14a.zip
PR10572: Allow duplicate function names in a CU
We can't assume that a given function name will only appear once in a CU. In C++, two functions may have the same name in different classes or namespaces, or even in the same scope with overloaded parameters. Even in C, the compiler may generate multiple copies of a single function with different optimizations. We now use a multimap for function names, so we shouldn't miss any. * dwflpp.h (cu_type_cache_t, mod_cu_type_cache_t): New typedef to keep a normal map for the global_alias_cache. (cu_function_cache_t): Use a multimap for function names. * dwflpp.cxx (dwflpp::iterate_over_functions): Walk over the range of exactly-matching functions. * tapsets.cxx (query_dwarf_func): Don't abort after seeing an exact match -- there could be more to come.
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r--dwflpp.cxx30
1 files changed, 17 insertions, 13 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 3c6a106d..d55852ee 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -106,7 +106,7 @@ dwflpp::~dwflpp()
it != cu_inl_function_cache.end(); ++it)
delete it->second;
- for (mod_cu_function_cache_t::iterator it = global_alias_cache.begin();
+ for (mod_cu_type_cache_t::iterator it = global_alias_cache.begin();
it != global_alias_cache.end(); ++it)
delete it->second;
@@ -594,7 +594,7 @@ dwflpp::iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void *
int
dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg)
{
- cu_function_cache_t *cache = static_cast<cu_function_cache_t*>(arg);
+ cu_type_cache_t *cache = static_cast<cu_type_cache_t*>(arg);
const char *name = dwarf_diename(die);
if (!name)
@@ -616,10 +616,10 @@ dwflpp::declaration_resolve(const char *name)
if (!name)
return NULL;
- cu_function_cache_t *v = global_alias_cache[cu->addr];
+ cu_type_cache_t *v = global_alias_cache[cu->addr];
if (v == 0) // need to build the cache, just once per encountered module/cu
{
- v = new cu_function_cache_t;
+ v = new cu_type_cache_t;
global_alias_cache[cu->addr] = v;
iterate_over_globals(global_alias_caching_callback, v);
if (sess.verbose > 4)
@@ -650,8 +650,7 @@ dwflpp::cu_function_caching_callback (Dwarf_Die* func, void *arg)
if (!name)
return DWARF_CB_OK;
- string function_name = name;
- (*v)[function_name] = * func;
+ v->insert(make_pair(string(name), *func));
return DWARF_CB_OK;
}
@@ -677,14 +676,19 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query *
mod_info->update_symtab(v);
}
- cu_function_cache_t::iterator it = v->find(function);
- if (it != v->end())
+ cu_function_cache_t::iterator it;
+ cu_function_cache_range_t range = v->equal_range(function);
+ if (range.first != range.second)
{
- Dwarf_Die& die = it->second;
- if (sess.verbose > 4)
- clog << "function cache " << module_name << ":" << cu_name()
- << " hit " << function << endl;
- return (*callback)(& die, q);
+ for (it = range.first; it != range.second; ++it)
+ {
+ Dwarf_Die& die = it->second;
+ if (sess.verbose > 4)
+ clog << "function cache " << module_name << ":" << cu_name()
+ << " hit " << function << endl;
+ rc = (*callback)(& die, q);
+ if (rc != DWARF_CB_OK) break;
+ }
}
else if (name_has_wildcard (function))
{