summaryrefslogtreecommitdiffstats
path: root/src/libdw/dwarf_getattrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libdw/dwarf_getattrs.c')
-rw-r--r--src/libdw/dwarf_getattrs.c100
1 files changed, 37 insertions, 63 deletions
diff --git a/src/libdw/dwarf_getattrs.c b/src/libdw/dwarf_getattrs.c
index 051dc25f..0da8b5ba 100644
--- a/src/libdw/dwarf_getattrs.c
+++ b/src/libdw/dwarf_getattrs.c
@@ -1,52 +1,31 @@
/* Get attributes of the DIE.
- Copyright (C) 2004, 2005, 2008, 2009 Red Hat, Inc.
- This file is part of Red Hat elfutils.
+ Copyright (C) 2004, 2005, 2008, 2009, 2014 Red Hat, Inc.
+ This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2004.
- Red Hat elfutils is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by the
- Free Software Foundation; version 2 of the License.
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
- Red Hat elfutils is distributed in the hope that it will be useful, but
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with Red Hat elfutils; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
-
- In addition, as a special exception, Red Hat, Inc. gives You the
- additional right to link the code of Red Hat elfutils with code licensed
- under any Open Source Initiative certified open source license
- (http://www.opensource.org/licenses/index.php) which requires the
- distribution of source code with any binary distribution and to
- distribute linked combinations of the two. Non-GPL Code permitted under
- this exception must only link to the code of Red Hat elfutils through
- those well defined interfaces identified in the file named EXCEPTION
- found in the source code files (the "Approved Interfaces"). The files
- of Non-GPL Code may instantiate templates or use macros or inline
- functions from the Approved Interfaces without causing the resulting
- work to be covered by the GNU General Public License. Only Red Hat,
- Inc. may make changes or additions to the list of Approved Interfaces.
- Red Hat's grant of this exception is conditioned upon your not adding
- any new exceptions. If you wish to add a new Approved Interface or
- exception, please contact Red Hat. You must obey the GNU General Public
- License in all respects for all of the Red Hat elfutils code and other
- code used in conjunction with Red Hat elfutils except the Non-GPL Code
- covered by this exception. If you modify this file, you may extend this
- exception to your version of the file, but you are not obligated to do
- so. If you do not wish to provide this exception without modification,
- you must delete this exception statement from your version and license
- this file solely under the GPL without exception.
-
- Red Hat elfutils is an included package of the Open Invention Network.
- An included package of the Open Invention Network is a package for which
- Open Invention Network licensees cross-license their patents. No patent
- license is granted, either expressly or impliedly, by designation as an
- included package. Should you wish to participate in the Open Invention
- Network licensing program, please visit www.openinventionnetwork.com
- <http://www.openinventionnetwork.com>. */
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -65,17 +44,12 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
if (unlikely (offset == 1))
return 1;
- const unsigned char *die_addr = die->addr;
+ const unsigned char *die_addr;
- /* Get the abbreviation code. */
- unsigned int u128;
- get_uleb128 (u128, die_addr);
+ /* Find the abbreviation entry. */
+ Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &die_addr);
- if (die->abbrev == NULL)
- /* Find the abbreviation. */
- die->abbrev = __libdw_findabbrev (die->cu, u128);
-
- if (unlikely (die->abbrev == DWARF_END_ABBREV))
+ if (unlikely (abbrevp == DWARF_END_ABBREV))
{
invalid_dwarf:
__libdw_seterrno (DWARF_E_INVALID_DWARF);
@@ -83,26 +57,28 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
}
/* This is where the attributes start. */
- const unsigned char *attrp = die->abbrev->attrp;
- const unsigned char *const offset_attrp = die->abbrev->attrp + offset;
+ const unsigned char *attrp = abbrevp->attrp;
+ 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
- >= ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
- + dbg->sectiondata[IDX_debug_abbrev]->d_size)))
+ if (unlikely (attrp >= endp))
goto invalid_dwarf;
/* Get attribute name and form. */
Dwarf_Attribute attr;
const unsigned char *remembered_attrp = attrp;
- // XXX Fix bound checks
- get_uleb128 (attr.code, attrp);
- get_uleb128 (attr.form, attrp);
+ get_uleb128 (attr.code, attrp, endp);
+ if (unlikely (attrp >= endp))
+ goto invalid_dwarf;
+ get_uleb128 (attr.form, attrp, endp);
/* We can stop if we found the attribute with value zero. */
if (attr.code == 0 && attr.form == 0)
@@ -125,20 +101,18 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
/* Return the offset of the start of the attribute, so that
dwarf_getattrs() can be restarted from this point if the
caller so desires. */
- return remembered_attrp - die->abbrev->attrp;
+ return remembered_attrp - abbrevp->attrp;
}
/* Skip over the rest of this attribute (if there is any). */
if (attr.form != 0)
{
- size_t len = __libdw_form_val_len (dbg, die->cu, attr.form,
- die_addr);
-
+ size_t len = __libdw_form_val_len (die->cu, attr.form, die_addr);
if (unlikely (len == (size_t) -1l))
/* Something wrong with the file. */
return -1l;
- // XXX We need better boundary checks.
+ // __libdw_form_val_len will have done a bounds check.
die_addr += len;
}
}