]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Handle DW_FORM_sec_offset in dwarf_formudata.
authorMark Wielaard <mjw@redhat.com>
Tue, 31 Jan 2012 18:22:03 +0000 (19:22 +0100)
committerMark Wielaard <mjw@redhat.com>
Tue, 31 Jan 2012 22:28:32 +0000 (23:28 +0100)
libdw/ChangeLog
libdw/dwarf_formudata.c
src/ChangeLog
src/readelf.c

index cfc5c894eee48d75521bb86b7944354d6e6143e9..98b67f4a7ea1e7e06c924b781f17a75311c9fb07 100644 (file)
@@ -1,3 +1,7 @@
+2012-01-31  Mark Wielaard  <mjw@redhat.com>
+
+       * dwarf_formudata.c (dwarf_formudata): Handle DW_FORM_sec_offset.
+
 2011-11-31  Mark Wielaard  <mjw@redhat.com>
 
        * Makefile.am (known-dwarf.h): Run gawk on config/known-dwarf.awk.
index 573a5783a9c5362061e74e6281e1c5162129d567..07efbe0b2f8bc284b0bfefdf60e39f5e1eae27c1 100644 (file)
@@ -1,5 +1,5 @@
 /* Return unsigned constant represented by attribute.
-   Copyright (C) 2003-2010 Red Hat, Inc.
+   Copyright (C) 2003-2012 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -134,11 +134,83 @@ dwarf_formudata (attr, return_uval)
 
     case DW_FORM_data4:
     case DW_FORM_data8:
-      if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
-                               attr->valp,
-                               attr->form == DW_FORM_data4 ? 4 : 8,
-                               return_uval))
-       return -1;
+    case DW_FORM_sec_offset:
+      /* Before DWARF4 data4 and data8 are pure constants unless the
+        attribute also allows offsets (*ptr classes), since DWARF4
+        they are always just constants (start_scope is special though,
+        since it only could express a rangelist since DWARF4).  */
+      if (attr->form == DW_FORM_sec_offset
+         || (attr->cu->version < 4 && attr->code != DW_AT_start_scope))
+       {
+         switch (attr->code)
+           {
+           case DW_AT_data_member_location:
+           case DW_AT_frame_base:
+           case DW_AT_location:
+           case DW_AT_return_addr:
+           case DW_AT_segment:
+           case DW_AT_static_link:
+           case DW_AT_string_length:
+           case DW_AT_use_location:
+           case DW_AT_vtable_elem_location:
+             /* loclistptr */
+             if (__libdw_formptr (attr, IDX_debug_loc,
+                                  DWARF_E_NO_LOCLIST, NULL,
+                                  return_uval) == NULL)
+               return -1;
+             break;
+
+           case DW_AT_macro_info:
+             /* macptr */
+             if (__libdw_formptr (attr, IDX_debug_macinfo,
+                                  DWARF_E_NO_ENTRY, NULL,
+                                  return_uval) == NULL)
+               return -1;
+             break;
+
+           case DW_AT_ranges:
+           case DW_AT_start_scope:
+             /* rangelistptr */
+             if (__libdw_formptr (attr, IDX_debug_ranges,
+                                  DWARF_E_NO_DEBUG_RANGES, NULL,
+                                  return_uval) == NULL)
+               return -1;
+             break;
+
+           case DW_AT_stmt_list:
+             /* lineptr */
+             if (__libdw_formptr (attr, IDX_debug_line,
+                                  DWARF_E_NO_DEBUG_LINE, NULL,
+                                  return_uval) == NULL)
+               return -1;
+             break;
+
+           default:
+             /* sec_offset can only be used by one of the above attrs.  */
+             if (attr->form == DW_FORM_sec_offset)
+               {
+                 __libdw_seterrno (DWARF_E_INVALID_DWARF);
+                 return -1;
+               }
+
+             /* Not one of the special attributes, just a constant.  */
+             if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
+                                       attr->valp,
+                                       attr->form == DW_FORM_data4 ? 4 : 8,
+                                       return_uval))
+               return -1;
+             break;
+           }
+       }
+      else
+       {
+         /* We are dealing with a constant data4 or data8.  */
+         if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
+                                   attr->valp,
+                                   attr->form == DW_FORM_data4 ? 4 : 8,
+                                   return_uval))
+           return -1;
+       }
       break;
 
     case DW_FORM_sdata:
index de6031f11cb89d689f5251be5f2a23bbbb326023..ff19b484fda16ea0ba376f88a5d27ac41bff6789 100644 (file)
@@ -1,3 +1,7 @@
+2012-01-31  Mark Wielaard  <mjw@redhat.com>
+
+       * readelf.c (attr_callback): Don't special case DW_FORM_sec_offset.
+
 2012-01-21  Ulrich Drepper  <drepper@gmail.com>
 
        * addr2line.c: Update copyright year.
index 10e25e3a09b1b94307251809eabea75e11e13222..88766889b286397ef274348262ca0537e795a8cf 100644 (file)
@@ -5612,9 +5612,6 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
       break;
 
     case DW_FORM_sec_offset:
-      attrp->form = cbargs->offset_size == 8 ? DW_FORM_data8 : DW_FORM_data4;
-      /* Fall through.  */
-
     case DW_FORM_udata:
     case DW_FORM_sdata:
     case DW_FORM_data8: