diff options
author | Mark Wielaard <mjw@redhat.com> | 2009-08-18 15:50:40 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2009-08-18 15:50:40 +0200 |
commit | 21c38ccc872a9b8c340e15545dc37ff8474f4109 (patch) | |
tree | c512c1eacd3af1dc28e2a8b613d663d87487a917 /loc2c-test.c | |
parent | 7544ffdf7dd029f40f9c8b59d156df841c6fb56c (diff) | |
download | systemtap-steved-21c38ccc872a9b8c340e15545dc37ff8474f4109.tar.gz systemtap-steved-21c38ccc872a9b8c340e15545dc37ff8474f4109.tar.xz systemtap-steved-21c38ccc872a9b8c340e15545dc37ff8474f4109.zip |
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.
Diffstat (limited to 'loc2c-test.c')
-rw-r--r-- | loc2c-test.c | 40 |
1 files 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; |