diff options
| author | Roland McGrath <[email protected]> | 2009-01-25 19:37:33 -0800 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2009-01-25 19:37:33 -0800 |
| commit | d31505f6a07b91b23d62f9acd37e38658e790543 (patch) | |
| tree | 21796b930966c3901d4409ca764cd26381086313 | |
| parent | 11ed669865964b0ea98954c15557d99c0c55364e (diff) | |
dwarf_getattrs.c: Correctly skip attribute values when restarting.
| -rw-r--r-- | libdw/ChangeLog | 4 | ||||
| -rw-r--r-- | libdw/dwarf_getattrs.c | 33 |
2 files changed, 25 insertions, 12 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 6ee143f7..89225e93 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,7 @@ +2009-01-25 Roland McGrath <[email protected]> + + * dwarf_getattrs.c: Correctly skip attribute values when restarting. + 2009-01-23 Roland McGrath <[email protected]> * Makefile.am ($(srcdir)/known-dwarf.h): Target renamed back. diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c index 42f25ca0..051dc25f 100644 --- a/libdw/dwarf_getattrs.c +++ b/libdw/dwarf_getattrs.c @@ -1,5 +1,5 @@ /* Get attributes of the DIE. - Copyright (C) 2004, 2005, 2008 Red Hat, Inc. + Copyright (C) 2004, 2005, 2008, 2009 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper <[email protected]>, 2004. @@ -62,6 +62,9 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), if (die == NULL) return -1l; + if (unlikely (offset == 1)) + return 1; + const unsigned char *die_addr = die->addr; /* Get the abbreviation code. */ @@ -80,7 +83,8 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), } /* This is where the attributes start. */ - const unsigned char *attrp = die->abbrev->attrp + offset; + const unsigned char *attrp = die->abbrev->attrp; + const unsigned char *const offset_attrp = die->abbrev->attrp + offset; /* Go over the list of attributes. */ Dwarf *dbg = die->cu->dbg; @@ -108,16 +112,21 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), offset of an attribute. */ return 1l; - /* Fill in the rest. */ - attr.valp = (unsigned char *) die_addr; - attr.cu = die->cu; - - /* Now call the callback function. */ - if (callback (&attr, arg) != DWARF_CB_OK) - /* 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; + /* If we are not to OFFSET_ATTRP yet, we just have to skip + the values of the intervening attributes. */ + if (remembered_attrp >= offset_attrp) + { + /* Fill in the rest. */ + attr.valp = (unsigned char *) die_addr; + attr.cu = die->cu; + + /* Now call the callback function. */ + if (callback (&attr, arg) != DWARF_CB_OK) + /* 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; + } /* Skip over the rest of this attribute (if there is any). */ if (attr.form != 0) |
