From f09d0d1e7fd437f6a3b8c21e4817de8af458c888 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 15 Sep 2009 18:15:20 -0700 Subject: Remove function comparison from label iteration We already have filtered functions and inlines, so just iterate in each of those to look for labels. * dwflpp.cxx (dwflpp::iterate_over_labels): Assume that the die we're looking at is already a matching function, and don't descend into inlined functions in this body. * tapsets.cxx (query_srcfile_label): Iterate through inlines too. (query_cu): Iterate over functions and inlines instead of the CU. --- dwflpp.cxx | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index dcf4182d..10127c61 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1138,7 +1138,7 @@ dwflpp::iterate_over_srcfile_lines (char const * srcfile, void dwflpp::iterate_over_labels (Dwarf_Die *begin_die, const string& sym, - const string& symfunction, + const string& function, dwarf_query *q, void (* callback)(const string &, const char *, @@ -1146,62 +1146,52 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die, int, Dwarf_Die *, Dwarf_Addr, - dwarf_query *), - const string& current_function) + dwarf_query *)) { get_module_dwarf(); Dwarf_Die die; + const char *name; int res = dwarf_child (begin_die, &die); if (res != 0) return; // die without children, bail out. - bool function_match = - (current_function == symfunction - || (name_has_wildcard(symfunction) - && function_name_matches_pattern (current_function, symfunction))); - do { - int tag = dwarf_tag(&die); - const char *name = dwarf_diename (&die); - bool subfunction = false; - - switch (tag) + switch (dwarf_tag(&die)) { case DW_TAG_label: - if (function_match && name && + name = dwarf_diename (&die); + if (name && (name == sym || (name_has_wildcard(sym) && function_name_matches_pattern (name, sym)))) { - // Get the file/line number for this label - int dline; - const char *file = dwarf_decl_file (&die); - dwarf_decl_line (&die, &dline); - // Don't try to be smart. Just drop no addr labels. Dwarf_Addr stmt_addr; if (dwarf_lowpc (&die, &stmt_addr) == 0) { + // Get the file/line number for this label + int dline; + const char *file = dwarf_decl_file (&die); + dwarf_decl_line (&die, &dline); + vector scopes = getscopes_die(&die); if (scopes.size() > 1) - callback(current_function, name, file, dline, + callback(function, name, file, dline, &scopes[1], stmt_addr, q); } } break; case DW_TAG_subprogram: - if (dwarf_hasattr(&die, DW_AT_declaration) || !name) - break; case DW_TAG_inlined_subroutine: - if (name) - subfunction = true; + // Stay within our filtered function + break; + default: if (dwarf_haschildren (&die)) - iterate_over_labels (&die, sym, symfunction, q, callback, - subfunction ? name : current_function); + iterate_over_labels (&die, sym, function, q, callback); break; } } -- cgit From 86598ebfa13479b4ba3b6b7a9de25c3e497ff57e Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 16 Sep 2009 12:22:04 +0200 Subject: Clean up dwflpp::translate_location workaround for DW_AT_data_member_location. Do the same workaround as loc2c-test.c does. Just treat a constant member location offset as a DW_OP_plus_uconst and call c_translate_location for it. Also Remove c_translate_add_offset. * dwflpp.cxx (dwflpp::translate_location): Check elfutils version and only do workaround for elfutils < 0.142. * loc2c.h (c_translate_add_offset): Removed. * loc2c.c (c_translate_add_offset): Likewise. --- dwflpp.cxx | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index 10127c61..ee13d0b2 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1674,21 +1674,20 @@ dwflpp::translate_location(struct obstack *pool, { /* DW_AT_data_member_location, can be either constant offsets - (struct member fields), or full blown location expressions. */ + (struct member fields), or full blown location expressions. + In older elfutils, dwarf_getlocation_addr would not handle the + constant for us, but newer ones do. For older ones, we work + it by faking an expression, which is what newer ones do. */ +#if !_ELFUTILS_PREREQ (0,142) if (dwarf_whatattr (attr) == DW_AT_data_member_location) { - unsigned int form = dwarf_whatform (attr); - if (form == DW_FORM_data1 || form == DW_FORM_data2 - || form == DW_FORM_sdata || form == DW_FORM_udata) - { - Dwarf_Sword off; - if (dwarf_formsdata (attr, &off) != 0) - throw semantic_error (string ("dwarf_formsdata failed, ") - + string (dwarf_errmsg (-1)), e->tok); - c_translate_add_offset (pool, 1, NULL, off, tail); - return *tail; - } + Dwarf_Op offset_loc = { .atom = DW_OP_plus_uconst }; + if (dwarf_formudata (attr, &offset_loc.number) == 0) + return c_translate_location (pool, &loc2c_error, this, + &loc2c_emit_address, 1, 0, pc, + &offset_loc, 1, NULL, NULL); } +#endif Dwarf_Op *expr; size_t len; -- cgit From 04ddd303348c0ffb71c6f57eacb2282bd1d61b3a Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 16 Sep 2009 17:38:53 -0700 Subject: Remove the unused function_name_final_match * dwflpp.cxx (dwflpp::function_name_final_match): Removed. --- dwflpp.cxx | 7 ------- 1 file changed, 7 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index ee13d0b2..68e6e97b 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -266,13 +266,6 @@ dwflpp::function_name_matches(const string& pattern) } -bool -dwflpp::function_name_final_match(const string& pattern) -{ - return module_name_final_match (pattern); -} - - static const char *offline_search_modname = NULL; static int offline_search_match_p = 0; -- cgit From 7d6d0afc24b43829511f3f1d0aeff0fefff56b54 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 16 Sep 2009 19:38:20 -0700 Subject: PR10461: Match C++ scopes for namespaces and classes The function spec for dwarf probes now supports scopes, so you can limit the probes to specific namespaces or classes. Multiple scopes can be specified, and they will be matched progressively outward. probe process("foo").function("std::vector<*>::*") { ... } probe process("foo").function("::global_function") { ... } * dwflpp.cxx (dwflpp::get_parent_scope): New, finds the containing scopes of the specified DIE. (dwflpp::function_scope_matches): New, checks that the scopes containing the function all match the given scope patterns. * tapsets.cxx (dwarf_query::parse_function_spec): Rewrite, now handles multiple scope separators too. (query_dwarf_func): Check that the functions scopes match. --- dwflpp.cxx | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index 68e6e97b..a73c3c4c 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -266,6 +266,33 @@ dwflpp::function_name_matches(const string& pattern) } +bool +dwflpp::function_scope_matches(const vector scopes) +{ + // walk up the containing scopes + Dwarf_Die* die = function; + for (int i = scopes.size() - 1; i >= 0; --i) + { + die = get_parent_scope(die); + + // check if this scope matches, and prepend it if so + // NB: a NULL die is the global scope, compared as "" + string name = dwarf_diename(die) ?: ""; + if (name_has_wildcard(scopes[i]) ? + function_name_matches_pattern(name, scopes[i]) : + name == scopes[i]) + function_name = name + "::" + function_name; + else + return false; + + // make sure there's no more if we're at the global scope + if (!die && i > 0) + return false; + } + return true; +} + + static const char *offline_search_modname = NULL; static int offline_search_match_p = 0; @@ -591,6 +618,9 @@ dwflpp::cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die) case DW_TAG_entry_point: case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: + case DW_TAG_namespace: + case DW_TAG_class_type: + case DW_TAG_structure_type: parents->insert(make_pair(child.addr, *die)); cache_die_parents(parents, &child); break; @@ -743,6 +773,34 @@ dwflpp::getscopes(Dwarf_Addr pc) } +Dwarf_Die* +dwflpp::get_parent_scope(Dwarf_Die* die) +{ + Dwarf_Die specification; + if (dwarf_attr_die(die, DW_AT_specification, &specification)) + die = &specification; + + cu_die_parent_cache_t *parents = get_die_parents(); + cu_die_parent_cache_t::iterator it = parents->find(die->addr); + while (it != parents->end()) + { + Dwarf_Die* scope = &it->second; + switch (dwarf_tag (scope)) + { + case DW_TAG_namespace: + case DW_TAG_class_type: + case DW_TAG_structure_type: + return scope; + + default: + break; + } + it = parents->find(scope->addr); + } + return NULL; +} + + int dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg) { -- cgit From bbc212e1244dbd30c2569cdd19d50ca36ca6612a Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Thu, 17 Sep 2009 14:25:28 +0800 Subject: Fix compilation error of dwflpp.cxx on gcc 4.1 * dwflpp.cxx(translate_location): Separate setting value from declaration and add missing parameter. --- dwflpp.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index a73c3c4c..ee3985cb 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1732,11 +1732,12 @@ dwflpp::translate_location(struct obstack *pool, #if !_ELFUTILS_PREREQ (0,142) if (dwarf_whatattr (attr) == DW_AT_data_member_location) { - Dwarf_Op offset_loc = { .atom = DW_OP_plus_uconst }; + Dwarf_Op offset_loc; + offset_loc.atom = DW_OP_plus_uconst; if (dwarf_formudata (attr, &offset_loc.number) == 0) return c_translate_location (pool, &loc2c_error, this, &loc2c_emit_address, 1, 0, pc, - &offset_loc, 1, NULL, NULL); + &offset_loc, 1, NULL, NULL, NULL); } #endif -- cgit From 24c7957b4dbddc8545d0e0c734377746a5ae6e60 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 17 Sep 2009 15:06:57 +0200 Subject: PR10417 Pass around attributes for supporting DW_OP_{implicit,stack}_value. Preparation for retrieving the Dwarf_Block that holds the value of an DW_OP_implicit_value. We need the Dwarf_Attribute that is associated with the location expression operants. Depends on new elfutils 0.143 functionality. Recognizes, but does not yet handle the new operants DW_OP_{implicit,stack}_value. * loc2c.h (c_translate_location): Take an Dwarf_Attribute. * loc2c.c (c_translate_location): Likewise and pass it on. (location_relative): Likewise. (location_from_address): Likewise. (translate): Likewise and capture Dwarf_Block. * loc2c-test.c (handle_variable): Pass in Dwarf_Attribute. * dwflpp.cxx (translate_location): Likewise. (literal_stmt_for_return): Pass in NULL to indicate no attribute. --- dwflpp.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index ee3985cb..f3015fcc 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1774,7 +1774,7 @@ dwflpp::translate_location(struct obstack *pool, return c_translate_location (pool, &loc2c_error, this, &loc2c_emit_address, 1, 0 /* PR9768 */, - pc, expr, len, tail, fb_attr, cfa_ops); + pc, attr, expr, len, tail, fb_attr, cfa_ops); } @@ -2397,7 +2397,7 @@ dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die, struct location *head = c_translate_location (&pool, &loc2c_error, this, &loc2c_emit_address, 1, 0 /* PR9768 */, - pc, locops, nlocops, + pc, NULL, locops, nlocops, &tail, NULL, NULL); /* Translate the ->bar->baz[NN] parts. */ -- cgit