Hi, On Sat, 2021-05-01 at 17:59 +0200, Mark Wielaard wrote: > There is __libdw_form_val_compute_len which already handles > DW_FORM_indirect: > > case DW_FORM_indirect: > get_uleb128 (u128, valp, endp); > // XXX Is this really correct? > result = __libdw_form_val_len (cu, u128, valp); > if (result != (size_t) -1) > result += valp - startp; > else > return (size_t) -1; > break; > > I believe the XXX question can be answered with: Yes, the result is the > size of the actual FORM data plus the size of the uleb128 encoding that > FORM (which is valp - startp). And it probably should check like your > code does that valp != DW_FORM_indirect && valp != > DW_FORM_implicit_const. I'll sent a patch to do that.
Patch attached. Cheers, Mark
From 73d0a32b44aa9bc641f0d5f0d79ee626d1ad2e4a Mon Sep 17 00:00:00 2001 From: Mark Wielaard <m...@klomp.org> Date: Sat, 1 May 2021 18:00:49 +0200 Subject: [PATCH] libdw: Document and handle DW_FORM_indirect in __libdw_form_val_compute_len Update the documentation in __libdw_form_val_compute_len for handling DW_FORM_indirect and make sure the indirect form isn't DW_FORM_indirect itself or DW_FORM_implicit_const. Signed-off-by: Mark Wielaard <m...@klomp.org> --- libdw/ChangeLog | 5 +++++ libdw/libdw_form.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index e3e467ee..aa3e5ee2 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2021-05-01 Mark Wielaard <m...@klomp.org> + + * libdw_form.c (__libdw_form_val_compute_len): Check indirect + form is not DW_FORM_indirect or DW_FORM_implicit_const. + 2021-04-23 Omar Sandoval <osan...@fb.com> * dwarf_child.c (__libdw_find_attr): Handle DW_FORM_indirect. diff --git a/libdw/libdw_form.c b/libdw/libdw_form.c index 584c8467..c83dfb39 100644 --- a/libdw/libdw_form.c +++ b/libdw/libdw_form.c @@ -116,8 +116,12 @@ __libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form, break; case DW_FORM_indirect: + /* The amount of data to skip in the DIE is the size of the actual + FORM data (which is __libdw_form_val_len) plus the size of the + uleb128 encoding that FORM (which is valp - startp). */ get_uleb128 (u128, valp, endp); - // XXX Is this really correct? + if (*valp == DW_FORM_indirect || *valp == DW_FORM_implicit_const) + return (size_t) -1; result = __libdw_form_val_len (cu, u128, valp); if (result != (size_t) -1) result += valp - startp; -- 2.18.4