From 063906a93ee3ea5b976f43e2dd1f73d29605fa4c Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 17 Nov 2009 22:20:32 +0100 Subject: Search other CUs of the module when resolving declarations. * dwflpp.h (declaration_resolve_other_cus): New method. (iterate_over_globals): Mark as static and takes a CU to iterate over. (global_alias_caching_callback_cus): New method. * dwflpp.cxx (global_alias_caching_callback_cus): New method. (declaration_resolve_other_cus): New method. (declaration_resolve): Call iterate_over_globals() with current cu. Call declaration_resolve_other_cus() when name not found. (iterate_over_globals): Takes cu_die to iterate over as argument. --- dwflpp.cxx | 48 ++++++++++++++++++++++++++++++++++++++---------- dwflpp.h | 7 +++++-- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index fdbcddf4..0e8a352d 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -721,6 +721,37 @@ dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg) return DWARF_CB_OK; } +int +dwflpp::global_alias_caching_callback_cus(Dwarf_Die *die, void *arg) +{ + mod_cu_type_cache_t *global_alias_cache; + global_alias_cache = &static_cast(arg)->global_alias_cache; + + cu_type_cache_t *v = (*global_alias_cache)[die->addr]; + if (v != 0) + return DWARF_CB_OK; + + v = new cu_type_cache_t; + (*global_alias_cache)[die->addr] = v; + iterate_over_globals(die, global_alias_caching_callback, v); + + return DWARF_CB_OK; +} + +Dwarf_Die * +dwflpp::declaration_resolve_other_cus(const char *name) +{ + iterate_over_cus(global_alias_caching_callback_cus, this); + for (mod_cu_type_cache_t::iterator i = global_alias_cache.begin(); + i != global_alias_cache.end(); ++i) + { + cu_type_cache_t *v = (*i).second; + if (v->find(name) != v->end()) + return & ((*v)[name]); + } + + return NULL; +} Dwarf_Die * dwflpp::declaration_resolve(const char *name) @@ -733,7 +764,7 @@ dwflpp::declaration_resolve(const char *name) { v = new cu_type_cache_t; global_alias_cache[cu->addr] = v; - iterate_over_globals(global_alias_caching_callback, v); + iterate_over_globals(cu, global_alias_caching_callback, v); if (sess.verbose > 4) clog << "global alias cache " << module_name << ":" << cu_name() << " size " << v->size() << endl; @@ -744,11 +775,8 @@ dwflpp::declaration_resolve(const char *name) // forward-declared pointer type only, where the actual definition // may only be in vmlinux or the application. - // XXX: it is probably desirable to search other CU's declarations - // in the same module. - if (v->find(name) == v->end()) - return NULL; + return declaration_resolve_other_cus(name); return & ((*v)[name]); } @@ -839,17 +867,17 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * /* 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 -dwflpp::iterate_over_globals (int (* callback)(Dwarf_Die *, void *), +dwflpp::iterate_over_globals (Dwarf_Die *cu_die, + int (* callback)(Dwarf_Die *, void *), void * data) { int rc = DWARF_CB_OK; Dwarf_Die die; - assert (module); - assert (cu); - assert (dwarf_tag(cu) == DW_TAG_compile_unit); + assert (cu_die); + assert (dwarf_tag(cu_die) == DW_TAG_compile_unit); - if (dwarf_child(cu, &die) != 0) + if (dwarf_child(cu_die, &die) != 0) return rc; do diff --git a/dwflpp.h b/dwflpp.h index b3f71eb2..cdc6ad98 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -213,6 +213,7 @@ struct dwflpp std::vector getscopes(Dwarf_Addr pc); Dwarf_Die *declaration_resolve(const char *name); + Dwarf_Die *declaration_resolve_other_cus(const char *name); mod_cu_function_cache_t cu_function_cache; @@ -319,8 +320,10 @@ private: */ mod_cu_type_cache_t global_alias_cache; static int global_alias_caching_callback(Dwarf_Die *die, void *arg); - int iterate_over_globals (int (* callback)(Dwarf_Die *, void *), - void * data); + static int global_alias_caching_callback_cus(Dwarf_Die *die, void *arg); + static int iterate_over_globals (Dwarf_Die *, + int (* callback)(Dwarf_Die *, void *), + void * data); static int cu_function_caching_callback (Dwarf_Die* func, void *arg); -- cgit