This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: RFC: fix DW_AT_data_member_location buglet
>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
Jan> In the SET_FIELD_BITPOS case it is a problem the `bitpos' field is already
Jan> only `int' but that should be fixed one day anyway. I would prefer LONGEST
Jan> everywhere but sure GDB is far from 64-bit inferior compatibility.
I changed handle_data_member_location to use LONGEST. This still leaves
some narrowing (implicit) casts, but now at least they are more
consistently done by the callers, where actually needed.
This is what I am checking in.
Tom
ChangeLog:
2011-05-11 Tom Tromey <tromey@redhat.com>
* dwarf2read.c (handle_data_member_location): New function.
(dwarf2_add_field): Use it.
(read_common_block): Likewise.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.530
diff -u -r1.530 dwarf2read.c
--- dwarf2read.c 6 May 2011 15:06:46 -0000 1.530
+++ dwarf2read.c 11 May 2011 17:18:48 -0000
@@ -6365,6 +6365,41 @@
}
}
+/* Look for DW_AT_data_member_location. Set *OFFSET to the byte
+ offset. If the attribute was not found return 0, otherwise return
+ 1. If it was found but could not properly be handled, set *OFFSET
+ to 0. */
+
+static int
+handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
+ LONGEST *offset)
+{
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
+ if (attr != NULL)
+ {
+ *offset = 0;
+
+ /* Note that we do not check for a section offset first here.
+ This is because DW_AT_data_member_location is new in DWARF 4,
+ so if we see it, we can assume that a constant form is really
+ a constant and not a section offset. */
+ if (attr_form_is_constant (attr))
+ *offset = dwarf2_get_attr_constant_value (attr, 0);
+ else if (attr_form_is_section_offset (attr))
+ dwarf2_complex_location_expr_complaint ();
+ else if (attr_form_is_block (attr))
+ *offset = decode_locdesc (DW_BLOCK (attr), cu);
+ else
+ dwarf2_complex_location_expr_complaint ();
+
+ return 1;
+ }
+
+ return 0;
+}
+
/* Add an aggregate field to the field list. */
static void
@@ -6413,6 +6448,8 @@
if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
{
+ LONGEST offset;
+
/* Data member other than a C++ static data member. */
/* Get type of field. */
@@ -6432,22 +6469,8 @@
}
/* Get bit offset of field. */
- attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
- if (attr)
- {
- int byte_offset = 0;
-
- if (attr_form_is_section_offset (attr))
- dwarf2_complex_location_expr_complaint ();
- else if (attr_form_is_constant (attr))
- byte_offset = dwarf2_get_attr_constant_value (attr, 0);
- else if (attr_form_is_block (attr))
- byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
- else
- dwarf2_complex_location_expr_complaint ();
-
- SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
- }
+ if (handle_data_member_location (die, cu, &offset))
+ SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr)
{
@@ -6550,23 +6573,11 @@
}
else if (die->tag == DW_TAG_inheritance)
{
- /* C++ base class field. */
- attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
- if (attr)
- {
- int byte_offset = 0;
-
- if (attr_form_is_section_offset (attr))
- dwarf2_complex_location_expr_complaint ();
- else if (attr_form_is_constant (attr))
- byte_offset = dwarf2_get_attr_constant_value (attr, 0);
- else if (attr_form_is_block (attr))
- byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
- else
- dwarf2_complex_location_expr_complaint ();
+ LONGEST offset;
- SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
- }
+ /* C++ base class field. */
+ if (handle_data_member_location (die, cu, &offset))
+ SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
FIELD_BITSIZE (*fp) = 0;
FIELD_TYPE (*fp) = die_type (die, cu);
FIELD_NAME (*fp) = type_name_no_tag (fp->type);
@@ -7676,22 +7687,13 @@
child_die = die->child;
while (child_die && child_die->tag)
{
+ LONGEST offset;
+
sym = new_symbol (child_die, NULL, cu);
- attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
- if (sym != NULL && attr != NULL)
+ if (sym != NULL &&
+ handle_data_member_location (child_die, cu, &offset))
{
- CORE_ADDR byte_offset = 0;
-
- if (attr_form_is_section_offset (attr))
- dwarf2_complex_location_expr_complaint ();
- else if (attr_form_is_constant (attr))
- byte_offset = dwarf2_get_attr_constant_value (attr, 0);
- else if (attr_form_is_block (attr))
- byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
- else
- dwarf2_complex_location_expr_complaint ();
-
- SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset;
+ SYMBOL_VALUE_ADDRESS (sym) = base + offset;
add_symbol_to_list (sym, &global_symbols);
}
child_die = sibling_die (child_die);