+2017-12-26 Mark Wielaard <mark@klomp.org>
+
+ * memory-access.h (__libdw_get_uleb128_unchecked): New function.
+ (get_uleb128_unchecked): New define.
+ * dwarf_child.c (__libdw_find_attr): Use get_uleb128_unchecked to
+ read attr name and form.
+ * dwarf_getabbrevattr.c (dwarf_getabbrevattr): Likewise.
+ * dwarf_getattrs.c (dwarf_getattrs): Likewise.
+ * dwarf_hasattr.c (dwarf_hasattr): Likewise.
+
2017-12-28 Mark Wielaard <mark@klomp.org>
* dwarf_offdie.c (__libdw_offdie): Check sectiondata exists.
/* 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 <drepper@redhat.com>, 2003.
__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)
/* Get specific attribute of abbreviation.
- Copyright (C) 2003, 2004, 2005, 2014 Red Hat, Inc.
+ Copyright (C) 2003, 2004, 2005, 2014, 2017 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2003.
{
start_attrp = attrp;
- /* Attribute code and form are encoded as ULEB128 values.i
- XXX We have no way to bounds check. */
- get_uleb128 (name, attrp, attrp + len_leb128 (name));
- get_uleb128 (form, attrp, attrp + len_leb128 (form));
+ /* Attribute code and form are encoded as ULEB128 values.
+ Already checked when Dwarf_Abbrev was created, read unchecked. */
+ get_uleb128_unchecked (name, attrp);
+ get_uleb128_unchecked (form, attrp);
/* If both values are zero the index is out of range. */
if (name == 0 && form == 0)
/* Get attributes of the DIE.
- Copyright (C) 2004, 2005, 2008, 2009, 2014 Red Hat, Inc.
+ Copyright (C) 2004, 2005, 2008, 2009, 2014, 2017 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2004.
if (unlikely (abbrevp == DWARF_END_ABBREV))
{
- invalid_dwarf:
__libdw_seterrno (DWARF_E_INVALID_DWARF);
return -1l;
}
const unsigned char *const offset_attrp = abbrevp->attrp + offset;
/* Go over the list of attributes. */
- Dwarf *dbg = die->cu->dbg;
- const unsigned char *endp;
- endp = ((const unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
- + dbg->sectiondata[IDX_debug_abbrev]->d_size);
while (1)
{
- /* Are we still in bounds? */
- if (unlikely (attrp >= endp))
- goto invalid_dwarf;
-
- /* Get attribute name and form. */
+ /* Get attribute name and form. Dwarf_Abbrev was checked when
+ created, so we can read unchecked. */
Dwarf_Attribute attr;
const unsigned char *remembered_attrp = attrp;
- get_uleb128 (attr.code, attrp, endp);
- if (unlikely (attrp >= endp))
- goto invalid_dwarf;
- get_uleb128 (attr.form, attrp, endp);
+ get_uleb128_unchecked (attr.code, attrp);
+ get_uleb128_unchecked (attr.form, attrp);
/* We can stop if we found the attribute with value zero. */
if (attr.code == 0 && attr.form == 0)
/* Check whether given DIE has specific attribute.
- Copyright (C) 2003, 2005, 2014 Red Hat, Inc.
+ Copyright (C) 2003, 2005, 2014, 2017 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2003.
Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
if (unlikely (abbrevp == DWARF_END_ABBREV))
{
- invalid_dwarf:
__libdw_seterrno (DWARF_E_INVALID_DWARF);
return 0;
}
- Dwarf *dbg = die->cu->dbg;
-
- /* 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. Dwarf_Abbrev was checked when created,
+ so we can read unchecked here. */
const unsigned char *attrp = abbrevp->attrp;
while (1)
{
- /* Are we still in bounds? This test needs to be refined. */
- if (unlikely (attrp >= endp))
- goto invalid_dwarf;
-
/* Get attribute name and form. */
unsigned int attr_name;
- get_uleb128 (attr_name, attrp, endp);
+ get_uleb128_unchecked (attr_name, attrp);
unsigned int attr_form;
- if (unlikely (attrp >= endp))
- goto invalid_dwarf;
- 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)
return UINT64_MAX;
}
+static inline uint64_t
+__libdw_get_uleb128_unchecked (const unsigned char **addrp)
+{
+ uint64_t acc = 0;
+
+ /* Unroll the first step to help the compiler optimize
+ for the common single-byte case. */
+ get_uleb128_step (acc, *addrp, 0);
+
+ const size_t max = len_leb128 (uint64_t);
+ for (size_t i = 1; i < max; ++i)
+ get_uleb128_step (acc, *addrp, i);
+ /* Other implementations set VALUE to UINT_MAX in this
+ case. So we better do this as well. */
+ return UINT64_MAX;
+}
+
/* Note, addr needs to me smaller than end. */
#define get_uleb128(var, addr, end) ((var) = __libdw_get_uleb128 (&(addr), end))
+#define get_uleb128_unchecked(var, addr) ((var) = __libdw_get_uleb128_unchecked (&(addr)))
/* The signed case is similar, but we sign-extend the result. */