summaryrefslogtreecommitdiff
path: root/libdw/dwarf_child.c
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2021-04-23 16:36:15 -0700
committerMark Wielaard <mark@klomp.org>2021-05-01 16:49:48 +0200
commitd63b26b8d21fb554049789290cd245cbe0446735 (patch)
tree7df73b0070538294d2d09f32a9dfd600139d72c4 /libdw/dwarf_child.c
parent6c8b68b0245c8754997b4c4b0ff4ba24974e3fdd (diff)
downloadelfutils-d63b26b8d21fb554049789290cd245cbe0446735.tar.gz
libdw: handle DW_FORM_indirect when reading attributes
Whenever we encounter an attribute with DW_FORM_indirect, we need to read its true form from the DIE data. Then, we can continue normally. This adds support to the most obvious places: __libdw_find_attr() and dwarf_getattrs(). There may be more places that need to be updated. I encountered this when inspecting a file that was processed by our BOLT tool: https://github.com/facebookincubator/BOLT. This also adds a couple of test cases using a file generated by that tool. Signed-off-by: Omar Sandoval <osandov@fb.com>
Diffstat (limited to 'libdw/dwarf_child.c')
-rw-r--r--libdw/dwarf_child.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c
index 2e39d834..c8c8bb61 100644
--- a/libdw/dwarf_child.c
+++ b/libdw/dwarf_child.c
@@ -53,6 +53,8 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
return NULL;
}
+ const unsigned char *endp = die->cu->endp;
+
/* Search the name attribute. Attribute has been checked when
Dwarf_Abbrev was created, we can read unchecked. */
const unsigned char *attrp = abbrevp->attrp;
@@ -69,6 +71,17 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
if (attr_name == 0 && attr_form == 0)
break;
+ if (attr_form == DW_FORM_indirect)
+ {
+ get_uleb128 (attr_form, readp, endp);
+ if (attr_form == DW_FORM_indirect ||
+ attr_form == DW_FORM_implicit_const)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return NULL;
+ }
+ }
+
/* Is this the name attribute? */
if (attr_name == search_name && search_name != INVALID)
{