summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgraydon <graydon>2005-08-11 01:51:04 +0000
committergraydon <graydon>2005-08-11 01:51:04 +0000
commitc239d28c3bed8dd356246fad44afee340dc4f198 (patch)
treef1a01ee9d7493ab2de8345008716dc62249ca70b
parent319660888893154e17ebbe313501ede739a92dcd (diff)
downloadsystemtap-steved-c239d28c3bed8dd356246fad44afee340dc4f198.tar.gz
systemtap-steved-c239d28c3bed8dd356246fad44afee340dc4f198.tar.xz
systemtap-steved-c239d28c3bed8dd356246fad44afee340dc4f198.zip
2005-08-10 Graydon Hoare <graydon@redhat.com>
* tapsets.cxx (dwflpp::global_addr_of_line_in_cu): Implement next-line heuristic. (dwarf_query::get_number_param): Dwarf_Addr variant. (query_cu): Add line-selecting variant for function iteration.
-rw-r--r--ChangeLog7
-rw-r--r--tapsets.cxx94
2 files changed, 77 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index f05ab027..be2acee3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-08-10 Graydon Hoare <graydon@redhat.com>
+
+ * tapsets.cxx
+ (dwflpp::global_addr_of_line_in_cu): Implement next-line heuristic.
+ (dwarf_query::get_number_param): Dwarf_Addr variant.
+ (query_cu): Add line-selecting variant for function iteration.
+
2005-08-10 Frank Ch. Eigler <fche@elastic.org>
PR translator/1186
diff --git a/tapsets.cxx b/tapsets.cxx
index a7f3f241..1a619f1f 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -144,6 +144,18 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
// Dwarf derived probes.
// ------------------------------------------------------------------------
+static string TOK_PROCESS("process");
+static string TOK_KERNEL("kernel");
+static string TOK_MODULE("module");
+
+static string TOK_FUNCTION("function");
+static string TOK_RETURN("return");
+static string TOK_CALLEES("callees");
+
+static string TOK_STATEMENT("statement");
+static string TOK_LABEL("label");
+static string TOK_RELATIVE("relative");
+
template <typename OUT, typename IN> inline OUT
lex_cast(IN const & in)
{
@@ -282,6 +294,9 @@ dwflpp
assert(dwfl);
assert(module);
get_module_dwarf();
+ if (module_name == TOK_KERNEL)
+ return a;
+
if (sess.verbose)
clog << "module addr 0x" << hex << a
<< " + module start 0x" << hex << module_start
@@ -491,8 +506,9 @@ dwflpp
Dwarf_Addr global_addr_of_line_in_cu(int line)
{
Dwarf_Lines * lines;
- size_t nlines;
Dwarf_Addr addr;
+ size_t nlines;
+ int best_line = -1;
assert(module);
assert(cu);
@@ -503,17 +519,24 @@ dwflpp
int curr_line;
Dwarf_Line * line_rec = dwarf_onesrcline(lines, i);
dwflpp_assert("lineno", dwarf_lineno (line_rec, &curr_line));
- if (curr_line == line)
+
+ if (curr_line >= line && (best_line == -1 || curr_line < best_line))
{
+ best_line = curr_line;
dwflpp_assert("lineaddr", dwarf_lineaddr(line_rec, &addr));
- if (sess.verbose)
- clog << "line " << line
- << " of CU " << cu_name
- << " has module address " << addr
- << " in " << module_name << endl;
- return module_address_to_global(addr);
}
}
+
+ if (best_line != -1)
+ {
+ if (sess.verbose)
+ clog << "line " << best_line
+ << " (given query line " << line << ")"
+ << " of CU " << cu_name
+ << " has module address 0x" << hex << addr
+ << " in " << module_name << endl;
+ return module_address_to_global(addr);
+ }
if (sess.verbose)
clog << "WARNING: could not find line " << line
@@ -695,18 +718,6 @@ dwflpp
}
};
-static string TOK_PROCESS("process");
-static string TOK_KERNEL("kernel");
-static string TOK_MODULE("module");
-
-static string TOK_FUNCTION("function");
-static string TOK_RETURN("return");
-static string TOK_CALLEES("callees");
-
-static string TOK_STATEMENT("statement");
-static string TOK_LABEL("label");
-static string TOK_RELATIVE("relative");
-
enum
function_spec_type
@@ -769,6 +780,8 @@ dwarf_query
string const & k, string & v);
static bool get_number_param(map<string, literal *> const & params,
string const & k, long & v);
+ static bool get_number_param(map<string, literal *> const & params,
+ string const & k, Dwarf_Addr & v);
string pt_regs_member_for_regnum(uint8_t dwarf_regnum);
@@ -787,8 +800,8 @@ dwarf_query
bool has_statement_num;
string statement_str_val;
string function_str_val;
- long statement_num_val;
- long function_num_val;
+ Dwarf_Addr statement_num_val;
+ Dwarf_Addr function_num_val;
bool has_callees;
long callee_val;
@@ -866,6 +879,22 @@ dwarf_query::get_number_param(map<string, literal *> const & params,
return true;
}
+bool
+dwarf_query::get_number_param(map<string, literal *> const & params,
+ string const & k, Dwarf_Addr & v)
+{
+ map<string, literal *>::const_iterator i = params.find(k);
+ if (i == params.end())
+ return false;
+ if (i->second == NULL)
+ return false;
+ literal_number * ln = dynamic_cast<literal_number *>(i->second);
+ if (!ln)
+ return false;
+ v = static_cast<Dwarf_Addr>(ln->value);
+ return true;
+}
+
dwarf_query::dwarf_query(systemtap_session & sess,
probe * base_probe,
@@ -1013,7 +1042,7 @@ query_function(Dwarf_Func * func, void * arg)
Dwarf_Addr entry_addr;
if (q->has_statement_str || q->has_function_str)
- {
+ {
if (q->dw.function_name_matches(q->function))
{
if (q->sess.verbose)
@@ -1114,9 +1143,26 @@ query_cu (Dwarf_Die * cudie, void * arg)
// the remaining functions within the CU.
query_statement(q->dw.global_addr_of_line_in_cu(q->line), q);
}
+ else if (q->has_function_str
+ && (q->spec_type == function_file_and_line)
+ && q->dw.cu_name_matches(q->file))
+ {
+ // If we have a complete file:line *function* functor
+ // landing on this CU, we need to select only the functions
+ // which land on the line in question. We *could* check each
+ // function individually but the line->addr lookup is
+ // expensive, so we do it once here, then temporarily switch
+ // to a .function(addr) query for the remaining function
+ // iteration, switching back when we complete.
+ q->function_num_val = q->dw.global_addr_of_line_in_cu(q->line);
+ swap(q->has_function_str, q->has_function_num);
+ q->dw.iterate_over_functions(&query_function, q);
+ swap(q->has_function_str, q->has_function_num);
+ }
else
{
- // Otherwise we need to scan all the functions in this CU.
+ // Otherwise we need to scan all the functions in this CU,
+ // matching by function name or address, as requested.
q->dw.iterate_over_functions(&query_function, q);
}
return DWARF_CB_OK;