summaryrefslogtreecommitdiffstats
path: root/loc2c-test.c
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-08-18 15:50:40 +0200
committerMark Wielaard <mjw@redhat.com>2009-08-18 15:50:40 +0200
commit21c38ccc872a9b8c340e15545dc37ff8474f4109 (patch)
treec512c1eacd3af1dc28e2a8b613d663d87487a917 /loc2c-test.c
parent7544ffdf7dd029f40f9c8b59d156df841c6fb56c (diff)
downloadsystemtap-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.c40
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;