From 06de3a04b52063f30e57bb4a822569f637de147a Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Fri, 14 Feb 2014 15:24:00 -0500 Subject: [PATCH] template-ify iterate_over_modules() --- dwflpp.cxx | 12 +++++++----- dwflpp.h | 36 ++++++++++++++++++++++++++++++++---- tapsets.cxx | 16 +++++++--------- translate.cxx | 6 +++--- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index 2730096fc..3b6585f5d 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -390,11 +390,13 @@ dwflpp::setup_user(const vector& modules, bool debuginfo_needed) dwfl_ptr.get()->dwfl); } -void -dwflpp::iterate_over_modules(int (* callback)(Dwfl_Module *, void **, - const char *, Dwarf_Addr, - void *), - void *data) +template<> void +dwflpp::iterate_over_modules(int (*callback)(Dwfl_Module*, + void**, + const char*, + Dwarf_Addr, + void*), + void *data) { dwfl_getmodules (dwfl_ptr.get()->dwfl, callback, data, 0); diff --git a/dwflpp.h b/dwflpp.h index 839cfb79c..8e5b6685e 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -203,10 +203,28 @@ struct dwflpp bool function_name_matches(const std::string& pattern); bool function_scope_matches(const std::vector& scopes); - void iterate_over_modules(int (* callback)(Dwfl_Module *, void **, - const char *, Dwarf_Addr, - void *), - void *data); + template + void iterate_over_modules(int (* callback)(Dwfl_Module*, + void**, + const char*, + Dwarf_Addr, + T*), + T *data) + { + /* We're using templates here to enforce type-safety between the data arg + * we're requested to pass to callback, and the data arg that the callback + * actually takes. Rather than putting the implementation here, we simply + * call the specialization, which does the real work. + * As a result, we need to cast the data arg in the callback signature + * and the one passed to void* (which is what elfutils also works with). + * */ + iterate_over_modules((int (*)(Dwfl_Module*, + void**, + const char*, + Dwarf_Addr, + void *))callback, + (void*)data); + } void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg), void * data, bool want_types); @@ -379,6 +397,8 @@ private: static int global_alias_caching_callback(Dwarf_Die *die, bool has_inner_types, const std::string& prefix, void *arg); static int global_alias_caching_callback_cus(Dwarf_Die *die, void *arg); + + static int iterate_over_globals (Dwarf_Die *, int (* callback)(Dwarf_Die *, bool, const std::string&, void *), @@ -475,6 +495,14 @@ public: Dwarf_Addr pr15123_retry_addr (Dwarf_Addr pc, Dwarf_Die* var); }; +template<> void +dwflpp::iterate_over_modules(int (*callback)(Dwfl_Module*, + void**, + const char*, + Dwarf_Addr, + void*), + void *data); + #endif // DWFLPP_H /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ diff --git a/tapsets.cxx b/tapsets.cxx index 31c4d6f7e..80047e329 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2139,10 +2139,8 @@ query_module (Dwfl_Module *mod, void **, const char *name, Dwarf_Addr addr, - void *arg) + base_query *q) { - base_query *q = static_cast(arg); - try { module_info* mi = q->sess.module_cache->cache[name]; @@ -4207,7 +4205,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) } dwarf_cast_query q (*dw, module, *e, lvalue, userspace_p, result); - dw->iterate_over_modules(&query_module, &q); + dw->iterate_over_modules(&query_module, &q); } if (!result) @@ -4378,7 +4376,7 @@ dwarf_atvar_expanding_visitor::visit_atvar_op (atvar_op* e) } dwarf_atvar_query q (*dw, module, *e, userspace_p, lvalue, result, tick); - dw->iterate_over_modules(&query_module, &q); + dw->iterate_over_modules(&query_module, &q); if (result) { @@ -6532,7 +6530,7 @@ sdt_query::handle_probe_entry() // V1 probes always need dwarf info // V2+ probes need dwarf info in case of a variable reference if (have_debuginfo_uprobe(need_debug_info)) - dw.iterate_over_modules(&query_module, &q); + dw.iterate_over_modules(&query_module, &q); // For V2+ probes, if variable references weren't used or failed (PR14369), // then try with the more direct approach. Unresolved $vars might still @@ -7426,7 +7424,7 @@ dwarf_builder::build(systemtap_session & sess, if (get_param(parameters, TOK_MARK, dummy_mark_name)) { sdt_query sdtq(base, location, *dw, filled_parameters, finished_results, user_lib); - dw->iterate_over_modules(&query_module, &sdtq); + dw->iterate_over_modules(&query_module, &sdtq); // We need to update modules_seen with the modules we've visited modules_seen.insert(sdtq.visited_modules.begin(), @@ -7475,7 +7473,7 @@ dwarf_builder::build(systemtap_session & sess, return; } - dw->iterate_over_modules(&query_module, &q); + dw->iterate_over_modules(&query_module, &q); // We need to update modules_seen with the modules we've visited modules_seen.insert(q.visited_modules.begin(), @@ -10748,7 +10746,7 @@ tracepoint_builder::build(systemtap_session& s, tracepoint_query q(*dw, tracepoint, base, location, finished_results); unsigned results_pre = finished_results.size(); - dw->iterate_over_modules(&query_module, &q); + dw->iterate_over_modules(&query_module, &q); unsigned results_post = finished_results.size(); // Did we fail to find a match? Let's suggest something! diff --git a/translate.cxx b/translate.cxx index 7ef4c86e0..1214dd0f9 100644 --- a/translate.cxx +++ b/translate.cxx @@ -6376,9 +6376,9 @@ query_module (Dwfl_Module *mod, void **, const char *, Dwarf_Addr, - void *arg) + struct dwflpp *dwflpp) { - ((struct dwflpp*)arg)->focus_on_module(mod, NULL); + dwflpp->focus_on_module(mod, NULL); return DWARF_CB_OK; } @@ -6397,7 +6397,7 @@ add_unwindsym_ldd (systemtap_session &s) if (! is_user_module (modname)) continue; struct dwflpp *mod_dwflpp = new dwflpp(s, modname, false); - mod_dwflpp->iterate_over_modules (&query_module, mod_dwflpp); + mod_dwflpp->iterate_over_modules(&query_module, mod_dwflpp); if (mod_dwflpp->module) // existing binary { assert (mod_dwflpp->module_name != ""); -- 2.43.5