From 5f8ca04fbb0682ff8647b4df5de68cd1042e312d Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 29 Sep 2009 00:12:26 +0200 Subject: Factor out duplicated code to setup user/module Dwfl from dwflpp/translate. * setupdwfl.h: Add setup_dwfl_user() and is_user_module(). * setupdwfl.cxx: Likewise. * dwflpp.cxx (setup_user): Use setup_dwfl_user(). * translate.cxx (emit_symbol_data): Likewise and is_user_module(). * tapsets.cxx (dwarf_cast_expanding_visitor::visit_cast_op): Use is_user_module(). --- setupdwfl.cxx | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'setupdwfl.cxx') diff --git a/setupdwfl.cxx b/setupdwfl.cxx index 49667152..33d481ef 100644 --- a/setupdwfl.cxx +++ b/setupdwfl.cxx @@ -25,6 +25,12 @@ static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build"; static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH"); static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr); +// NB: kernel_build_tree doesn't enter into this, as it's for +// kernel-side modules only. +static const char *debuginfo_usr_path_arr = "+:.debug:/usr/lib/debug"; +static const char *debuginfo_usr_path = (debuginfo_env_arr + ?: debuginfo_usr_path_arr); + static const Dwfl_Callbacks kernel_callbacks = { dwfl_linux_kernel_find_elf, @@ -33,6 +39,15 @@ static const Dwfl_Callbacks kernel_callbacks = (char **) & debuginfo_path }; +static const Dwfl_Callbacks user_callbacks = + { + NULL, + dwfl_standard_find_debuginfo, + NULL, /* ET_REL not supported for user space, only ET_EXEC and ET_DYN. + dwfl_offline_section_address, */ + (char **) & debuginfo_usr_path + }; + using namespace std; // Setup in setup_dwfl_kernel(), for use in setup_dwfl_report_kernel_p(). @@ -191,3 +206,53 @@ setup_dwfl_kernel(const std::set &names, offline_search_names = names; return setup_dwfl_kernel(found, s); } + +Dwfl* +setup_dwfl_user(const std::string &name) +{ + Dwfl *dwfl = dwfl_begin (&user_callbacks); + dwfl_assert("dwfl_begin", dwfl); + dwfl_report_begin (dwfl); + + // XXX: should support buildid-based naming + const char *cname = name.c_str(); + Dwfl_Module *mod = dwfl_report_offline (dwfl, cname, cname, -1); + dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL)); + if (! mod) + { + dwfl_end(dwfl); + dwfl = NULL; + } + return dwfl; +} + +Dwfl* +setup_dwfl_user(std::vector::const_iterator &begin, + const std::vector::const_iterator &end, + bool all_needed) +{ + Dwfl *dwfl = dwfl_begin (&user_callbacks); + dwfl_assert("dwfl_begin", dwfl); + dwfl_report_begin (dwfl); + + // XXX: should support buildid-based naming + while (begin != end && dwfl != NULL) + { + const char *cname = (*begin).c_str(); + Dwfl_Module *mod = dwfl_report_offline (dwfl, cname, cname, -1); + if (! mod && all_needed) + { + dwfl_end(dwfl); + dwfl = NULL; + } + begin++; + } + if (dwfl) + dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL)); + return dwfl; +} + +bool is_user_module(const std::string &m) +{ + return m[0] == '/' && m.rfind(".ko", m.length() - 1) != m.length() - 3; +} -- cgit