From 21c38ccc872a9b8c340e15545dc37ff8474f4109 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 18 Aug 2009 15:50:40 +0200 Subject: PR10533 loc2c doesn't resolve frame base correctly for inlined vars. 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. * loc2c-test.c (handle_variable): Switch "die branches" when searching for frame base and a DW_TAG_inlined_subroutine is encountered. --- loc2c-test.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/loc2c-test.c b/loc2c-test.c index a5f848ab..c1c1d263 100644 --- a/loc2c-test.c +++ b/loc2c-test.c @@ -73,7 +73,7 @@ get_location (Dwarf_Addr dwbias, Dwarf_Addr pc, Dwarf_Attribute *loc_attr, } static void -handle_variable (Dwarf_Die *scopes, int nscopes, int out, +handle_variable (Dwarf_Die *lscopes, int lnscopes, int out, Dwarf_Addr cubias, Dwarf_Die *vardie, Dwarf_Addr pc, Dwarf_Op *cfa_ops, char **fields) { @@ -82,13 +82,18 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, struct obstack pool; obstack_init (&pool); - /* Figure out the appropriate frame base for accessing this variable. - XXX not handling nested functions - XXX inlines botched - */ + /* Figure out the appropriate frame base for accessing this variable. + * XXX not handling nested functions + */ Dwarf_Attribute fb_attr_mem, *fb_attr = NULL; int inner; - for (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 + * 'out' scope that the variable was found in. + */ + Dwarf_Die *scopes = lscopes; + int nscopes = lnscopes; + for (inner = out; inner < nscopes && fb_attr == NULL; ++inner) { switch (dwarf_tag (&scopes[inner])) { @@ -96,14 +101,25 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, continue; case DW_TAG_subprogram: case DW_TAG_entry_point: - case DW_TAG_inlined_subroutine: /* XXX */ - if (inner >= out) - 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 (out != -1) + { + nscopes = dwarf_getscopes_die (&scopes[inner], &scopes); + if (nscopes == -1) + error (2, 0, _("cannot get die scopes inlined_subroutine: %s"), + dwarf_errmsg (-1)); + inner = 1; + out = -1; + } break; } - break; } Dwarf_Attribute attr_mem; -- cgit