From 7bce6f87482ece5b55db98b589666a2adac9cd1f Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 18 Aug 2009 21:54:54 +0200 Subject: PR10533 inlined vars are not always found (dwflpp). dwflpp::find_variable_and_frame_base switched too early to "pyshical view" of die tree. We need to lookup the var in the "syntactical view" of the die tree first. Then when we see a DW_TAG_inlined_subroutine while walking the syntactical die tree as returned by dwarf_getscopes for a given variable to retrieve the frame base, then we need to switch to walking the physical die tree where the subroutine is inlined. * dwflpp.cxx (find_variable_and_frame_base): Don't immediately go to die_scopes, but lookup var first based on pc. Then switch "die branches" when searching for frame base and a DW_TAG_inlined_subroutine is encountered. --- dwflpp.cxx | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index 6a697de7..73848429 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1414,14 +1414,6 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, assert (cu); nscopes = dwarf_getscopes_cached (pc, &scopes); - int sidx; - // if pc and scope_die are disjoint then we need dwarf_getscopes_die - for (sidx = 0; sidx < nscopes; sidx++) - if (scopes[sidx].addr == scope_die->addr) - break; - if (sidx == nscopes) - nscopes = dwarf_getscopes_die (scope_die, &scopes); - if (nscopes <= 0) { throw semantic_error ("unable to find any scopes containing " @@ -1454,7 +1446,13 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, e->tok); } - for (int inner = 0; inner < nscopes; ++inner) + /* We start out walking the "lexical scopes" as returned by + * as returned by dwarf_getscopes for the address, starting with the + * declaring_scope that the variable was found in. + */ + for (int inner = declaring_scope; + inner < nscopes && fb_attr == NULL; + ++inner) { switch (dwarf_tag (&scopes[inner])) { @@ -1462,14 +1460,28 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, continue; case DW_TAG_subprogram: case DW_TAG_entry_point: - case DW_TAG_inlined_subroutine: /* XXX */ - if (inner >= declaring_scope) - fb_attr = dwarf_attr_integrate (&scopes[inner], - DW_AT_frame_base, - fb_attr_mem); + fb_attr = dwarf_attr_integrate (&scopes[inner], + DW_AT_frame_base, + fb_attr_mem); + break; + case DW_TAG_inlined_subroutine: + /* Unless we already are going through the "pyshical die tree", + * we now need to start walking the die tree where this + * subroutine is inlined to find the appropriate frame base. */ + if (declaring_scope != -1) + { + nscopes = dwarf_getscopes_die (&scopes[inner], &scopes); + if (nscopes == -1) + throw semantic_error ("unable to get die scopes for '" + + local + "' in an inlined subroutines", + e->tok); + inner = 0; // zero is current scope, for look will increase. + declaring_scope = -1; + } break; } } + return fb_attr; } -- cgit