summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx58
1 files changed, 57 insertions, 1 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 8a78e04c..7b04f794 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -641,6 +641,8 @@ struct dwarf_query : public base_query
func_info_map_t filtered_functions;
bool choose_next_line;
Dwarf_Addr entrypc_for_next_line;
+
+ void query_module_functions ();
};
@@ -786,7 +788,13 @@ dwarf_query::query_module_dwarf()
// specifier, we have to scan over all the CUs looking for
// the function(s) in question
assert(has_function_str || has_statement_str);
- dw.iterate_over_cus(&query_cu, this);
+
+ // For simple cases, no wildcard and no source:line, we can do a very
+ // quick function lookup in a module-wide cache.
+ if (spec_type == function_alone && !dw.name_has_wildcard(function))
+ query_module_functions();
+ else
+ dw.iterate_over_cus(&query_cu, this);
}
}
@@ -1652,6 +1660,54 @@ query_cu (Dwarf_Die * cudie, void * arg)
}
+void
+dwarf_query::query_module_functions ()
+{
+ try
+ {
+ filtered_srcfiles.clear();
+ filtered_functions.clear();
+ filtered_inlines.clear();
+
+ // Collect all module functions so we know which CUs are interesting
+ int rc = dw.iterate_single_function(query_dwarf_func, this, function);
+ if (rc != DWARF_CB_OK)
+ {
+ query_done = true;
+ return;
+ }
+
+ set<void*> used_cus; // by cu->addr
+ vector<Dwarf_Die> cus;
+ Dwarf_Die cu_mem;
+
+ for (func_info_map_t::iterator i = filtered_functions.begin();
+ i != filtered_functions.end(); ++i)
+ if (dwarf_diecu(&i->die, &cu_mem, NULL, NULL) &&
+ used_cus.insert(cu_mem.addr).second)
+ cus.push_back(cu_mem);
+
+ for (inline_instance_map_t::iterator i = filtered_inlines.begin();
+ i != filtered_inlines.end(); ++i)
+ if (dwarf_diecu(&i->die, &cu_mem, NULL, NULL) &&
+ used_cus.insert(cu_mem.addr).second)
+ cus.push_back(cu_mem);
+
+ // Reset the dupes since we didn't actually collect them the first time
+ alias_dupes.clear();
+ inline_dupes.clear();
+
+ // Run the query again on the individual CUs
+ for (vector<Dwarf_Die>::iterator i = cus.begin(); i != cus.end(); ++i)
+ query_cu(&*i, this);
+ }
+ catch (const semantic_error& e)
+ {
+ sess.print_error (e);
+ }
+}
+
+
static void
validate_module_elf (Dwfl_Module *mod, const char *name, base_query *q)
{