diff options
author | Omar Sandoval <osandov@fb.com> | 2021-04-23 16:36:15 -0700 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2021-05-01 16:49:48 +0200 |
commit | d63b26b8d21fb554049789290cd245cbe0446735 (patch) | |
tree | 7df73b0070538294d2d09f32a9dfd600139d72c4 /libdw/dwarf_child.c | |
parent | 6c8b68b0245c8754997b4c4b0ff4ba24974e3fdd (diff) | |
download | elfutils-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.c | 13 |
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) { |