tsym->tok = t;
tsym->name = t->content;
tsym->target_name = "";
+ tsym->cu_name = "";
parse_target_symbol_components(tsym);
tsym->addressof = addressof;
return tsym;
tsym->name = t->content;
expect_op("(");
expect_unknown(tok_string, tsym->target_name);
+ size_t found_at = tsym->target_name.find("@");
+ if (found_at != string::npos)
+ tsym->cu_name = tsym->target_name.substr(found_at + 1);
+ else
+ tsym->cu_name = "";
expect_op(")");
parse_target_symbol_components(tsym);
tsym->addressof = addressof;
string target_symbol::sym_name ()
{
if (name == "@var")
- return target_name;
+ {
+ if (cu_name == "")
+ return target_name;
+ else
+ return target_name.substr(0, target_name.length() - cu_name.length() - 1);
+ }
else
return name.substr(1);
}
bool addressof;
std::string target_name;
+ std::string cu_name;
std::vector<component> components;
semantic_error* saved_conversion_error; // hand-made linked list
target_symbol(): addressof(false), saved_conversion_error (0) {}
void visit_cast_op (cast_op* e);
void visit_entry_op (entry_op* e);
private:
+ vector<Dwarf_Die>& getcuscope(target_symbol *e);
vector<Dwarf_Die>& getscopes(target_symbol *e);
};
provide (repl);
}
+vector<Dwarf_Die>&
+dwarf_var_expanding_visitor::getcuscope(target_symbol *e)
+{
+ Dwarf_Die *cu = NULL;
+
+ string prefixed_srcfile = string("*/") + e->cu_name;
+
+ Dwarf_Off off = 0;
+ size_t cuhl;
+ Dwarf_Off noff;
+ Dwarf_Off module_bias;
+ Dwarf *dw = dwfl_module_getdwarf(q.dw.module, &module_bias);
+ while (cu == NULL && dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
+ {
+ Dwarf_Die die_mem;
+ Dwarf_Die *die;
+ die = dwarf_offdie (dw, off + cuhl, &die_mem);
+ const char *cu_name = dwarf_diename (die);
+ if (fnmatch(prefixed_srcfile.c_str(), cu_name, 0) == 0)
+ cu = die;
+ off = noff;
+ }
+
+ if (cu == NULL)
+ throw semantic_error ("unable to find CU '" + e->cu_name + "'"
+ + " while searching for '" + e->target_name + "'",
+ e->tok);
+
+ vector<Dwarf_Die> *cu_scope = new vector<Dwarf_Die>;
+ Dwarf_Die die_cu = *cu;
+ cu_scope->push_back(die_cu);
+ return *cu_scope;
+}
vector<Dwarf_Die>&
dwarf_var_expanding_visitor::getscopes(target_symbol *e)
{
+ // "static globals" can only be found in the top-level CU.
+ if (e->name == "@var" && e->cu_name != "")
+ return this->getcuscope(e);
+
if (scopes.empty())
{
scopes = q.dw.getscopes(scope_die);
# Check each "global" value picks up the right one.
# See GCC PR51410 and Systemtap PR10622
-set ::result_string {getdistance value: 60
+set ::result_string {main value@main: 42
+getdistance value: 60
+getdistance value@main: 42
+getdistance value@speed: 6
+getdistance value@distance: 60
getspeed value: 6
-compare value: 42}
+getspeed value@main: 42
+getspeed value@speed: 6
+getspeed value@distance: 60
+compare value: 42
+compare value@main: 42
+compare value@speed: 6
+compare value@distance: 60
+main return value@main: 42}
# Only run on make installcheck and uprobes present.
if {! [installtest_p]} { untested "$test"; return }
probe process.function("getdistance")
{
printf("getdistance value: %d\n", $value);
+ printf("getdistance value@main: %d\n", @var("value@global_var_main.c"));
+ printf("getdistance value@speed: %d\n", @var("value@global_var_speed.c"));
+ printf("getdistance value@distance: %d\n", @var("value@global_var_distance.c"));
}
probe process.function("getspeed")
{
printf("getspeed value: %d\n", $value);
+ printf("getspeed value@main: %d\n", @var("value@global_var_main.c"));
+ printf("getspeed value@speed: %d\n", @var("value@global_var_speed.c"));
+ printf("getspeed value@distance: %d\n", @var("value@global_var_distance.c"));
}
probe process.function("compare_value")
{
printf("compare value: %d\n", $value);
-}
\ No newline at end of file
+ printf("compare value@main: %d\n", @var("value@global_var_main.c"));
+ printf("compare value@speed: %d\n", @var("value@global_var_speed.c"));
+ printf("compare value@distance: %d\n", @var("value@global_var_distance.c"));
+}
+
+probe process.function("main")
+{
+ // Global, not local.
+ printf("main value@main: %d\n", @var("value@global_var_main.c"));
+}
+
+probe process.function("main").return
+{
+ printf("main return value@main: %d\n", @var("value@global_var_main.c"));
+}