summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_child.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdw/dwarf_child.c')
-rw-r--r--libdw/dwarf_child.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c
index cc95fb3f..9446b880 100644
--- a/libdw/dwarf_child.c
+++ b/libdw/dwarf_child.c
@@ -1,5 +1,5 @@
/* Return child of current DIE.
- Copyright (C) 2003-2011, 2014 Red Hat, Inc.
+ Copyright (C) 2003-2011, 2014, 2017 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <[email protected]>, 2003.
@@ -43,36 +43,27 @@ internal_function
__libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
unsigned int *codep, unsigned int *formp)
{
- Dwarf *dbg = die->cu->dbg;
const unsigned char *readp;
/* Find the abbreviation entry. */
Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &readp);
if (unlikely (abbrevp == DWARF_END_ABBREV))
{
- invalid_dwarf:
__libdw_seterrno (DWARF_E_INVALID_DWARF);
return NULL;
}
- /* Search the name attribute. */
- unsigned char *const endp
- = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
- + dbg->sectiondata[IDX_debug_abbrev]->d_size);
-
+ /* Search the name attribute. Attribute has been checked when
+ Dwarf_Abbrev was created, we can read unchecked. */
const unsigned char *attrp = abbrevp->attrp;
while (1)
{
/* Get attribute name and form. */
- if (unlikely (attrp >= endp))
- goto invalid_dwarf;
unsigned int attr_name;
- get_uleb128 (attr_name, attrp, endp);
+ get_uleb128_unchecked (attr_name, attrp);
- if (unlikely (attrp >= endp))
- goto invalid_dwarf;
unsigned int attr_form;
- get_uleb128 (attr_form, attrp, endp);
+ get_uleb128_unchecked (attr_form, attrp);
/* We can stop if we found the attribute with value zero. */
if (attr_name == 0 && attr_form == 0)
@@ -86,7 +77,12 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
if (formp != NULL)
*formp = attr_form;
- return (unsigned char *) readp;
+ /* Normally the attribute data comes from the DIE/info,
+ except for implicit_form, where it comes from the abbrev. */
+ if (attr_form == DW_FORM_implicit_const)
+ return (unsigned char *) attrp;
+ else
+ return (unsigned char *) readp;
}
/* Skip over the rest of this attribute (if there is any). */
@@ -101,6 +97,13 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
// __libdw_form_val_len will have done a bounds check.
readp += len;
+
+ // If the value is in the abbrev data, skip it.
+ if (attr_form == DW_FORM_implicit_const)
+ {
+ int64_t attr_value __attribute__((__unused__));
+ get_sleb128_unchecked (attr_value, attrp);
+ }
}
}