summaryrefslogtreecommitdiffstats
path: root/dwflpp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r--dwflpp.cxx60
1 files changed, 60 insertions, 0 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index c0def432..0b25f4d5 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -99,6 +99,7 @@ dwflpp::~dwflpp()
{
delete_map(module_cu_cache);
delete_map(cu_function_cache);
+ delete_map(mod_function_cache);
delete_map(cu_inl_function_cache);
delete_map(global_alias_cache);
delete_map(cu_die_parent_cache);
@@ -796,6 +797,14 @@ dwflpp::cu_function_caching_callback (Dwarf_Die* func, void *arg)
int
+dwflpp::mod_function_caching_callback (Dwarf_Die* cu, void *arg)
+{
+ dwarf_getfuncs (cu, cu_function_caching_callback, arg, 0);
+ return DWARF_CB_OK;
+}
+
+
+int
dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q),
base_query * q, const string& function)
{
@@ -855,6 +864,57 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query *
}
+int
+dwflpp::iterate_single_function (int (* callback)(Dwarf_Die * func, base_query * q),
+ base_query * q, const string& function)
+{
+ int rc = DWARF_CB_OK;
+ assert (module);
+
+ get_module_dwarf(false);
+ if (!module_dwarf)
+ return rc;
+
+ cu_function_cache_t *v = mod_function_cache[module_dwarf];
+ if (v == 0)
+ {
+ v = new cu_function_cache_t;
+ mod_function_cache[module_dwarf] = v;
+ iterate_over_cus (mod_function_caching_callback, v);
+ if (sess.verbose > 4)
+ clog << "module function cache " << module_name
+ << " size " << v->size() << endl;
+ }
+
+ cu_function_cache_t::iterator it;
+ cu_function_cache_range_t range = v->equal_range(function);
+ if (range.first != range.second)
+ {
+ for (it = range.first; it != range.second; ++it)
+ {
+ Dwarf_Die cu_mem;
+ Dwarf_Die& die = it->second;
+ if (sess.verbose > 4)
+ clog << "module function cache " << module_name
+ << " hit " << function << endl;
+
+ // since we're iterating out of cu-context, we need each focus
+ focus_on_cu(dwarf_diecu(&die, &cu_mem, NULL, NULL));
+
+ rc = (*callback)(& die, q);
+ if (rc != DWARF_CB_OK) break;
+ }
+ }
+
+ // undo the focus_on_cu
+ this->cu = NULL;
+ this->function_name.clear();
+ this->function = NULL;
+
+ return rc;
+}
+
+
/* This basically only goes one level down from the compile unit so it
* only picks up top level stuff (i.e. nothing in a lower scope) */
int