summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-07-09 22:44:13 -0400
committerFrank Ch. Eigler <fche@elastic.org>2008-07-09 22:44:13 -0400
commita00cc8c70d20f2f3429590b629d272c8db65b40f (patch)
tree6a90966d1a715c48db4ac35b891c46ef654f272f /tapsets.cxx
parentdf00639dbe262b8919bdf625f30d80e5b9b96346 (diff)
parent51a3785482396c9f653e3e7647945bfc24f7b160 (diff)
downloadsystemtap-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.cxx93
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";