]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarf_getattrs.c: Correctly skip attribute values when restarting.
authorRoland McGrath <roland@redhat.com>
Mon, 26 Jan 2009 03:37:33 +0000 (19:37 -0800)
committerRoland McGrath <roland@redhat.com>
Mon, 26 Jan 2009 03:37:33 +0000 (19:37 -0800)
libdw/ChangeLog
libdw/dwarf_getattrs.c

index 6ee143f79e97f37b7204cfd94db289a117a09b05..89225e937a023f594754a8d73e7995bc9e201b4a 100644 (file)
@@ -1,3 +1,7 @@
+2009-01-25  Roland McGrath  <roland@redhat.com>
+
+       * dwarf_getattrs.c: Correctly skip attribute values when restarting.
+
 2009-01-23  Roland McGrath  <roland@redhat.com>
 
        * Makefile.am ($(srcdir)/known-dwarf.h): Target renamed back.
index 42f25ca06ba427c79bb21a71d0690f5a8d24c872..051dc25fdd7894064ba90f01bbd8de8d244a6637 100644 (file)
@@ -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 <drepper@redhat.com>, 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)