d745e52
commit 4809b16f7e629929a10ab8b15816b4f6f775aa82
d745e52
Author: Jim Blandy <jimb@codesourcery.com>
d745e52
Date:   Thu Dec 13 19:02:51 2007 +0000
d745e52
d745e52
commit 35fb264aa9a28b8d117df1e5a19fa3bfaf5a2cc8
d745e52
Author: Jim Blandy <jimb@codesourcery.com>
d745e52
Date:   Mon Dec 17 18:38:30 2007 +0000
d745e52
d745e52
Cherry-picked and backported these, since gdb would crash reading dwarf 3
d745e52
DW_AT_data_member_location that gcc generates now.
d745e52
-- Lubomir Rintel <lkundrak@v3.sk>
d745e52
d745e52
diff -urp gdb-6.1.orig/gdb/ChangeLog gdb-6.1/gdb/ChangeLog
d745e52
--- gdb-6.1.orig/gdb/ChangeLog	2009-08-08 17:04:24.836969960 +0200
d745e52
+++ gdb-6.1/gdb/ChangeLog	2009-08-08 17:00:21.682970174 +0200
d745e52
@@ -1,3 +1,14 @@
d745e52
+2007-12-13  Jim Blandy  <jimb@codesourcery.com>
d745e52
+
d745e52
+	* dwarf2read.c (attr_form_is_constant): New function.
d745e52
+	(dwarf2_add_field): Use it and attr_form_is_section_offset to
d745e52
+	recognize DW_AT_data_member_location attributes.  Use
d745e52
+	dwarf2_get_attr_constant_value when the attribute is a constant.
d745e52
+
d745e52
+	* dwarf2read.c (attr_form_is_section_offset): New function.
d745e52
+	(dwarf_add_member_fn, read_common_block, read_partial_die)
d745e52
+	(dwarf2_symbol_mark_computed): Use it, instead of writing it out.
d745e52
+
d745e52
 2004-04-03  GDB Administrator  <gdbadmin@sourceware.org>
d745e52
 
d745e52
 	GDB 6.1 released.
d745e52
diff -urp gdb-6.1.orig/gdb/dwarf2read.c gdb-6.1/gdb/dwarf2read.c
d745e52
--- gdb-6.1.orig/gdb/dwarf2read.c	2009-06-30 17:31:20.000000000 +0200
d745e52
+++ gdb-6.1/gdb/dwarf2read.c	2009-08-08 17:20:00.031969143 +0200
d745e52
@@ -922,6 +922,10 @@ static void dwarf_decode_macros (struct 
d745e52
 
d745e52
 static int attr_form_is_block (struct attribute *);
d745e52
 
d745e52
+static int attr_form_is_section_offset (struct attribute *);
d745e52
+
d745e52
+static int attr_form_is_constant (struct attribute *);
d745e52
+
d745e52
 static void
d745e52
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
d745e52
 			     struct dwarf2_cu *cu);
d745e52
@@ -2618,8 +2622,16 @@ dwarf2_add_field (struct field_info *fip
d745e52
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
d745e52
       if (attr)
d745e52
 	{
d745e52
-	  FIELD_BITPOS (*fp) =
d745e52
-	    decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
d745e52
+          if (attr_form_is_section_offset (attr))
d745e52
+            {
d745e52
+              dwarf2_complex_location_expr_complaint ();
d745e52
+              FIELD_BITPOS (*fp) = 0;
d745e52
+            }
d745e52
+          else if (attr_form_is_constant (attr))
d745e52
+            FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);
d745e52
+          else
d745e52
+            FIELD_BITPOS (*fp) =
d745e52
+              decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
d745e52
 	}
d745e52
       else
d745e52
 	FIELD_BITPOS (*fp) = 0;
d745e52
@@ -2939,7 +2951,7 @@ dwarf2_add_member_fn (struct field_info 
d745e52
         {
d745e52
           fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
d745e52
         }
d745e52
-      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
d745e52
+      else if (attr_form_is_section_offset (attr))
d745e52
         {
d745e52
 	  dwarf2_complex_location_expr_complaint ();
d745e52
         }
d745e52
@@ -3482,7 +3494,7 @@ read_common_block (struct die_info *die,
d745e52
         {
d745e52
           base = decode_locdesc (DW_BLOCK (attr), cu);
d745e52
         }
d745e52
-      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
d745e52
+      else if (attr_form_is_section_offset (attr))
d745e52
         {
d745e52
 	  dwarf2_complex_location_expr_complaint ();
d745e52
         }
d745e52
@@ -4392,7 +4404,7 @@ read_partial_die (struct partial_die_inf
d745e52
             {
d745e52
 	       part_die->locdesc = DW_BLOCK (&attr);
d745e52
             }
d745e52
-          else if (attr.form == DW_FORM_data4 || attr.form == DW_FORM_data8)
d745e52
+          else if (attr_form_is_section_offset (&attr))
d745e52
             {
d745e52
 	      dwarf2_complex_location_expr_complaint ();
d745e52
             }
d745e52
@@ -8030,11 +8042,51 @@ attr_form_is_block (struct attribute *at
d745e52
       || attr->form == DW_FORM_block);
d745e52
 }
d745e52
 
d745e52
+/* Return non-zero if ATTR's value is a section offset (classes
d745e52
+   lineptr, loclistptr, macptr or rangelistptr).  In this case,
d745e52
+   you may use DW_UNSND (attr) to retrieve the offset.  */
d745e52
+static int
d745e52
+attr_form_is_section_offset (struct attribute *attr)
d745e52
+{
d745e52
+  return (attr->form == DW_FORM_data4
d745e52
+          || attr->form == DW_FORM_data8);
d745e52
+}
d745e52
+
d745e52
+
d745e52
+/* Return non-zero if ATTR's value falls in the 'constant' class, or
d745e52
+   zero otherwise.  When this function returns true, you can apply
d745e52
+   dwarf2_get_attr_constant_value to it.
d745e52
+
d745e52
+   However, note that for some attributes you must check
d745e52
+   attr_form_is_section_offset before using this test.  DW_FORM_data4
d745e52
+   and DW_FORM_data8 are members of both the constant class, and of
d745e52
+   the classes that contain offsets into other debug sections
d745e52
+   (lineptr, loclistptr, macptr or rangelistptr).  The DWARF spec says
d745e52
+   that, if an attribute's can be either a constant or one of the
d745e52
+   section offset classes, DW_FORM_data4 and DW_FORM_data8 should be
d745e52
+   taken as section offsets, not constants.  */
d745e52
+static int
d745e52
+attr_form_is_constant (struct attribute *attr)
d745e52
+{
d745e52
+  switch (attr->form)
d745e52
+    {
d745e52
+    case DW_FORM_sdata:
d745e52
+    case DW_FORM_udata:
d745e52
+    case DW_FORM_data1:
d745e52
+    case DW_FORM_data2:
d745e52
+    case DW_FORM_data4:
d745e52
+    case DW_FORM_data8:
d745e52
+      return 1;
d745e52
+    default:
d745e52
+      return 0;
d745e52
+    }
d745e52
+}
d745e52
+
d745e52
 static void
d745e52
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
d745e52
 			     struct dwarf2_cu *cu)
d745e52
 {
d745e52
-  if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
d745e52
+  if (attr_form_is_section_offset (attr))
d745e52
     {
d745e52
       struct dwarf2_loclist_baton *baton;
d745e52
 
d745e52
diff -urp gdb-6.1.orig/gdb/ChangeLog gdb-6.1/gdb/ChangeLog
d745e52
--- gdb-6.1.orig/gdb/ChangeLog	2009-08-08 20:49:34.000000000 +0200
d745e52
+++ gdb-6.1/gdb/ChangeLog	2009-08-09 13:04:25.842288308 +0200
d745e52
@@ -1,3 +1,11 @@
d745e52
+2007-12-17  Jim Blandy  <jimb@codesourcery.com>
d745e52
+
d745e52
+	* dwarf2read.c (dwarf2_add_field): Correctly scale all byte
d745e52
+	offsets obtained from DW_AT_data_member_location before recording
d745e52
+	them in FIELD_BITPOS (*fp).
d745e52
+
d745e52
+	* dwarf2read.c (attr_form_is_section_offset): Doc fixes.
d745e52
+
d745e52
 2007-12-13  Jim Blandy  <jimb@codesourcery.com>
d745e52
 
d745e52
 	* dwarf2read.c (attr_form_is_constant): New function.
d745e52
diff -urp gdb-6.1.orig/gdb/dwarf2read.c gdb-6.1/gdb/dwarf2read.c
d745e52
--- gdb-6.1.orig/gdb/dwarf2read.c	2009-08-08 20:49:34.000000000 +0200
d745e52
+++ gdb-6.1/gdb/dwarf2read.c	2009-08-09 13:04:25.864291129 +0200
d745e52
@@ -2622,16 +2622,19 @@ dwarf2_add_field (struct field_info *fip
d745e52
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
d745e52
       if (attr)
d745e52
 	{
d745e52
+          int byte_offset;
d745e52
+
d745e52
           if (attr_form_is_section_offset (attr))
d745e52
             {
d745e52
               dwarf2_complex_location_expr_complaint ();
d745e52
-              FIELD_BITPOS (*fp) = 0;
d745e52
+              byte_offset = 0;
d745e52
             }
d745e52
           else if (attr_form_is_constant (attr))
d745e52
-            FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);
d745e52
+            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
d745e52
           else
d745e52
-            FIELD_BITPOS (*fp) =
d745e52
-              decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
d745e52
+            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
d745e52
+
d745e52
+          FIELD_BITPOS (*fp) = byte_offset * bits_per_byte;
d745e52
 	}
d745e52
       else
d745e52
 	FIELD_BITPOS (*fp) = 0;
d745e52
@@ -8042,9 +8045,14 @@ attr_form_is_block (struct attribute *at
d745e52
       || attr->form == DW_FORM_block);
d745e52
 }
d745e52
 
d745e52
-/* Return non-zero if ATTR's value is a section offset (classes
d745e52
-   lineptr, loclistptr, macptr or rangelistptr).  In this case,
d745e52
-   you may use DW_UNSND (attr) to retrieve the offset.  */
d745e52
+/* Return non-zero if ATTR's value is a section offset --- classes
d745e52
+   lineptr, loclistptr, macptr or rangelistptr --- or zero, otherwise.
d745e52
+   You may use DW_UNSND (attr) to retrieve such offsets.
d745e52
+
d745e52
+   Section 7.5.4, "Attribute Encodings", explains that no attribute
d745e52
+   may have a value that belongs to more than one of these classes; it
d745e52
+   would be ambiguous if we did, because we use the same forms for all
d745e52
+   of them.  */
d745e52
 static int
d745e52
 attr_form_is_section_offset (struct attribute *attr)
d745e52
 {