summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2021-05-01 18:00:49 +0200
committerMark Wielaard <mark@klomp.org>2021-05-06 23:16:10 +0200
commit09184fc04f3cd54600dee562ea48d281d2087e21 (patch)
treeab620de090e56913da292d0cc8d600f998f7277b
parent5f72c51a7e5c02be833d78c8412a8083f2212dcf (diff)
downloadelfutils-09184fc04f3cd54600dee562ea48d281d2087e21.tar.gz
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 <mark@klomp.org>
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/libdw_form.c6
2 files changed, 10 insertions, 1 deletions
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 <mark@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 <osandov@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;