vector<Dwarf_Die> scopes = getscopes_die(&die);
if (scopes.size() > 1)
- callback(function, name, file, dline,
- &scopes[1], stmt_addr, q);
+ {
+ Dwarf_Die scope;
+ inner_die_containing_pc(scopes[1], stmt_addr, scope);
+ callback(function, name, file, dline,
+ &scope, stmt_addr, q);
+ }
}
}
break;
}
+void
+dwflpp::inner_die_containing_pc(Dwarf_Die& scope, Dwarf_Addr addr,
+ Dwarf_Die& result)
+{
+ if (!die_has_pc(scope, addr))
+ {
+ ostringstream msg;
+ msg << "dwflpp::inner_die_containing_pc internal error, '"
+ << (dwarf_diename(&scope) ?: "<unknown>")
+ << "' (dieoffset: " << lex_cast_hex(dwarf_dieoffset(&scope))
+ << ") doesn't contain address " << lex_cast_hex(addr);
+ throw semantic_error (msg.str());
+ }
+
+ Dwarf_Die child;
+ result = scope;
+ int rc = dwarf_child(&result, &child);
+ while (rc == 0)
+ {
+ switch (dwarf_tag (&child))
+ {
+ // lexical tags to recurse within the same starting scope
+ // NB: this intentionally doesn't cross into inlines!
+ case DW_TAG_lexical_block:
+ case DW_TAG_with_stmt:
+ case DW_TAG_catch_block:
+ case DW_TAG_try_block:
+ case DW_TAG_entry_point:
+ if (die_has_pc(child, addr))
+ {
+ result = child;
+ rc = dwarf_child(&result, &child);
+ continue;
+ }
+ }
+ rc = dwarf_siblingof(&child, &child);
+ }
+}
+
+
void
dwflpp::loc2c_error (void *, const char *fmt, ...)
{
void function_line (int *linep);
bool die_has_pc (Dwarf_Die & die, Dwarf_Addr pc);
+ void inner_die_containing_pc(Dwarf_Die& scope, Dwarf_Addr addr,
+ Dwarf_Die& result);
std::string literal_stmt_for_local (std::vector<Dwarf_Die>& scopes,
Dwarf_Addr pc,
if (q->sess.verbose>3)
clog << "function DIE lands on srcfile\n";
if (q->has_statement_str)
- query_statement (i->name, i->decl_file,
- lineno, // NB: not q->line !
- &(i->die), addr, q);
+ {
+ Dwarf_Die scope;
+ q->dw.inner_die_containing_pc(i->die, addr, scope);
+ query_statement (i->name, i->decl_file,
+ lineno, // NB: not q->line !
+ &scope, addr, q);
+ }
else
query_func_info (i->entrypc, *i, q);
}
if (q->sess.verbose>3)
clog << "inline instance DIE lands on srcfile\n";
if (q->has_statement_str)
- query_statement (i->name, i->decl_file,
- q->line[0], &(i->die), addr, q);
+ {
+ Dwarf_Die scope;
+ q->dw.inner_die_containing_pc(i->die, addr, scope);
+ query_statement (i->name, i->decl_file,
+ q->line[0], &scope, addr, q);
+ }
else
query_inline_instance_info (*i, q);
}
{
if (scopes.empty())
{
- // If the address is at the beginning of the scope_die, we can do a fast
- // getscopes from there. Otherwise we need to look it up by address.
- Dwarf_Addr entrypc;
- if (q.dw.die_entrypc(scope_die, &entrypc) && entrypc == addr)
- scopes = q.dw.getscopes(scope_die);
- else
- scopes = q.dw.getscopes(addr);
-
+ scopes = q.dw.getscopes(scope_die);
if (scopes.empty())
throw semantic_error ("unable to find any scopes containing "
+ lex_cast_hex(addr)