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