diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-07-09 22:44:13 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-07-09 22:44:13 -0400 |
commit | a00cc8c70d20f2f3429590b629d272c8db65b40f (patch) | |
tree | 6a90966d1a715c48db4ac35b891c46ef654f272f /tapsets.cxx | |
parent | df00639dbe262b8919bdf625f30d80e5b9b96346 (diff) | |
parent | 51a3785482396c9f653e3e7647945bfc24f7b160 (diff) | |
download | systemtap-steved-a00cc8c70d20f2f3429590b629d272c8db65b40f.tar.gz systemtap-steved-a00cc8c70d20f2f3429590b629d272c8db65b40f.tar.xz systemtap-steved-a00cc8c70d20f2f3429590b629d272c8db65b40f.zip |
Merge commit 'origin/master' into pr6429-comp-unwindsyms
* commit 'origin/master':
fix shutdown race condition for scripts that might exit during begin probes
Fix PR 6732: Add runtime/autoconf-real-parent.c check for task_struct field.
clarify dejagnu test case name for empty-struct changes
add changelog entries for last two changes
Add test suite for declaration resolution
Fix semantic error: empty struct
Add hack to support git 1.6 in git_version.sh
Sync latest fix for git_version.sh from RadeonHD's tree
Slightly cleanup code of translate.cxx
PR2111: add general blurbage to stapprobes.5 on syscalls tapset
Use `uname -rvm` for checking system compatibility. Generate
Add section to stapex manual page on how installed examples are documented.
Install examples, demos and samples.
Install tutorial and langref manuals.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r-- | tapsets.cxx | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/tapsets.cxx b/tapsets.cxx index 56838140..7714715e 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1,6 +1,7 @@ // tapset resolution // Copyright (C) 2005-2008 Red Hat Inc. // Copyright (C) 2005-2007 Intel Corporation. +// Copyright (C) 2008 James.Bottomley@HansenPartnership.com // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General @@ -1157,6 +1158,47 @@ struct dwflpp // ----------------------------------------------------------------- + /* The global alias cache is used to resolve any DIE found in a + * module that is stubbed out with DW_AT_declaration with a defining + * DIE found in a different module. The current assumption is that + * this only applies to structures and unions, which have a global + * namespace (it deliberately only traverses program scope), so this + * cache is indexed by name. If other declaration lookups were + * added to it, it would have to be indexed by name and tag + */ + cu_function_cache_t global_alias_cache; + + static int global_alias_caching_callback(Dwarf_Die *die, void *arg) + { + dwflpp *dw = static_cast<struct dwflpp *>(arg); + const char *name = dwarf_diename(die); + + if (!name) + return DWARF_CB_OK; + + string structure_name = name; + + if (!dwarf_hasattr(die, DW_AT_declaration) && + dw->global_alias_cache.find(structure_name) == + dw->global_alias_cache.end()) + dw->global_alias_cache[structure_name] = *die; + + return DWARF_CB_OK; + } + + Dwarf_Die *declaration_resolve(Dwarf_Die *die) + { + const char *name = dwarf_diename(die); + + if (!name) + return NULL; + + if (global_alias_cache.find(name) == global_alias_cache.end()) + return NULL; + + return &global_alias_cache[name]; + } + mod_cu_function_cache_t cu_function_cache; static int cu_function_caching_callback (Dwarf_Die* func, void *arg) @@ -1169,6 +1211,16 @@ struct dwflpp int iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg), void * data); + int iterate_over_globals (int (* callback)(Dwarf_Die *, void *), + void * data); + + int update_alias_cache(void) + { + int rc; + + rc = iterate_over_globals(global_alias_caching_callback, this); + return rc; + } bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno); @@ -1834,6 +1886,14 @@ struct dwflpp case DW_TAG_structure_type: case DW_TAG_union_type: struct_die = *die; + if (dwarf_hasattr(die, DW_AT_declaration)) + { + Dwarf_Die *tmpdie = dwflpp::declaration_resolve(die); + if (tmpdie == NULL) + throw semantic_error ("unresolved struct " + + string (dwarf_diename_integrate (die) ?: "<anonymous>")); + *die_mem = *tmpdie; + } switch (dwarf_child (die, die_mem)) { case 1: /* No children. */ @@ -2517,6 +2577,37 @@ dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int linen return false; } +/* 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 *), + void * data) +{ + int rc = DWARF_CB_OK; + Dwarf_Die die; + + assert (module); + assert (cu); + assert (dwarf_tag(cu) == DW_TAG_compile_unit); + + if (dwarf_child(cu, &die) != 0) + return rc; + + do { + /* We're only currently looking for structures and unions, + * although other types of declarations exist */ + if (dwarf_tag(&die) != DW_TAG_structure_type && + dwarf_tag(&die) != DW_TAG_union_type) + continue; + + rc = (*callback)(&die, data); + if (rc != DWARF_CB_OK) + break; + + } while (dwarf_siblingof(&die, &die) == 0); + + return rc; +} int dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg), @@ -3505,6 +3596,8 @@ query_cu (Dwarf_Die * cudie, void * arg) { q->dw.focus_on_cu (cudie); + q->dw.update_alias_cache(); + if (false && q->sess.verbose>2) clog << "focused on CU '" << q->dw.cu_name << "', in module '" << q->dw.module_name << "'\n"; |