From 8096dd7dbc7bc5712da58a6f9bcb90c0b74c10db Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 26 Aug 2009 20:09:48 -0700 Subject: [PATCH] Reorganize iterate_over_labels I noticed that iterate_over_labels was using a static variable as a recursion variable, which isn't a safe thing to do since it will only be initialized once. While fixing that, I also reorganized the function quite a bit. * dwflpp.cxx (dwflpp::iterate_over_labels): Take the current function as a parameter instead of using a static local. Rewrite some of the code as well to try to make it more obvious. * tapsets.cxx (add_label_name): Remove in favor of query_label. (query_label): New, to check decl_file and fix probe listing. (query_srcfile_label, query_cu): Adjust to iterate_over_labels change and start using query_label as the callback. --- dwflpp.cxx | 93 ++++++++++++++++++++++++----------------------------- dwflpp.h | 11 ++++--- tapsets.cxx | 47 ++++++++++++++++++--------- 3 files changed, 80 insertions(+), 71 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index 9ec7a7de9..7e9894e15 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -918,18 +918,18 @@ dwflpp::iterate_over_srcfile_lines (char const * srcfile, void dwflpp::iterate_over_labels (Dwarf_Die *begin_die, - const char *sym, - const char *symfunction, - void *data, + const string& sym, + const string& symfunction, + dwarf_query *q, void (* callback)(const string &, + const char *, const char *, int, Dwarf_Die *, Dwarf_Addr, - dwarf_query *)) + dwarf_query *), + const string& current_function) { - dwarf_query * q __attribute__ ((unused)) = static_cast(data) ; - get_module_dwarf(); Dwarf_Die die; @@ -937,63 +937,54 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die, if (res != 0) return; // die without children, bail out. - static string function_name = dwarf_diename (begin_die); + 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) { case DW_TAG_label: - if (name) - break; - else - continue; // Cannot handle unnamed label. + if (function_match && 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) + { + Dwarf_Die *scopes; + int nscopes = dwarf_getscopes_die (&die, &scopes); + if (nscopes > 1) + callback(current_function, name, file, dline, + &scopes[1], stmt_addr, q); + } + } break; + case DW_TAG_subprogram: - if (!dwarf_hasattr(&die, DW_AT_declaration) && name) - function_name = name; - else - continue; + if (dwarf_hasattr(&die, DW_AT_declaration) || !name) + break; case DW_TAG_inlined_subroutine: - if (name) - function_name = name; + if (name) + subfunction = true; default: if (dwarf_haschildren (&die)) - iterate_over_labels (&die, sym, symfunction, q, callback); - continue; - } - - if (strcmp(function_name.c_str(), symfunction) == 0 - || (name_has_wildcard(symfunction) - && function_name_matches (symfunction))) - { - } - else - continue; - if (strcmp(name, sym) == 0 - || (name_has_wildcard(sym) - && function_name_matches_pattern (name, sym))) - { - const char *file = dwarf_decl_file (&die); - - // Get the line number for this label - int dline; - dwarf_decl_line (&die, &dline); - - Dwarf_Addr stmt_addr; - if (dwarf_lowpc (&die, &stmt_addr) != 0) - continue; // Don't try to be smart. Just drop no addr labels. - - Dwarf_Die *scopes; - int nscopes = 0; - nscopes = dwarf_getscopes_die (&die, &scopes); - if (nscopes > 1) - { - callback(function_name.c_str(), file, - dline, &scopes[1], stmt_addr, q); - add_label_name(q, name); - } + iterate_over_labels (&die, sym, symfunction, q, callback, + subfunction ? name : current_function); + break; } } while (dwarf_siblingof (&die, &die) == 0); diff --git a/dwflpp.h b/dwflpp.h index 1c7c9215a..073b9bfc8 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -78,7 +78,6 @@ typedef std::vector inline_instance_map_t; /* XXX FIXME functions that dwflpp needs from tapsets.cxx */ func_info_map_t *get_filtered_functions(dwarf_query *q); inline_instance_map_t *get_filtered_inlines(dwarf_query *q); -void add_label_name(dwarf_query *q, const char *name); struct @@ -225,15 +224,17 @@ struct dwflpp void *data); void iterate_over_labels (Dwarf_Die *begin_die, - const char *sym, - const char *symfunction, - void *data, + const std::string& sym, + const std::string& symfunction, + dwarf_query *q, void (* callback)(const std::string &, + const char *, const char *, int, Dwarf_Die *, Dwarf_Addr, - dwarf_query *)); + dwarf_query *), + const std::string& current_function); void collect_srcfiles_matching (std::string const & pattern, std::set & filtered_srcfiles); diff --git a/tapsets.cxx b/tapsets.cxx index 9f21bb207..9651426e9 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -713,16 +713,6 @@ get_filtered_inlines(dwarf_query *q) } -void -add_label_name(dwarf_query *q, const char *name) -{ - // this is a kludge to let the listing mode show labels to the user - if (q->sess.listing_mode) - q->results.back()->locations[0]->components.push_back - (new probe_point::component(TOK_LABEL, new literal_string (name))); -} - - void dwarf_query::query_module_dwarf() { @@ -1113,6 +1103,33 @@ query_statement (string const & func, } } +static void +query_label (string const & func, + char const * label, + char const * file, + int line, + Dwarf_Die *scope_die, + Dwarf_Addr stmt_addr, + dwarf_query * q) +{ + size_t i = q->results.size(); + + // weed out functions whose decl_file isn't one of + // the source files that we actually care about + if ((q->has_statement_str || q->has_function_str) && + q->spec_type != function_alone && + q->filtered_srcfiles.count(file) == 0) + return; + + query_statement(func, file, line, scope_die, stmt_addr, q); + + // this is a kludge to let the listing mode show labels to the user + if (q->sess.listing_mode) + for (; i < q->results.size(); ++i) + q->results[i]->locations[0]->components.push_back + (new probe_point::component(TOK_LABEL, new literal_string (label))); +} + static void query_inline_instance_info (inline_instance_info & ii, dwarf_query * q) @@ -1184,8 +1201,8 @@ query_srcfile_label (const dwarf_line_t& line, void * arg) for (func_info_map_t::iterator i = q->filtered_functions.begin(); i != q->filtered_functions.end(); ++i) if (q->dw.die_has_pc (i->die, addr)) - q->dw.iterate_over_labels (&i->die, q->label_val.c_str(), q->function.c_str(), - q, query_statement); + q->dw.iterate_over_labels (&i->die, q->label_val, q->function, + q, query_label, i->name); } static void @@ -1280,7 +1297,7 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq) if ((q->has_statement_str || q->has_function_str) && q->spec_type != function_alone && q->filtered_srcfiles.count(dwarf_decl_file(func)?:"") == 0) - return DWARF_CB_OK; + return DWARF_CB_OK; try { @@ -1468,8 +1485,8 @@ query_cu (Dwarf_Die * cudie, void * arg) if (q->has_label) { if (q->line[0] == 0) // No line number specified - q->dw.iterate_over_labels (q->dw.cu, q->label_val.c_str(), q->function.c_str(), - q, query_statement); + q->dw.iterate_over_labels (q->dw.cu, q->label_val, q->function, + q, query_label, ""); else for (set::const_iterator i = q->filtered_srcfiles.begin(); i != q->filtered_srcfiles.end(); ++i) -- 2.43.5