aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorJim Blandy <jimb@codesourcery.com>2007-12-13 19:02:51 +0000
committerJim Blandy <jimb@codesourcery.com>2007-12-13 19:02:51 +0000
commit3690dd376bc19907f4c229fc3471b9898386d32c (patch)
tree48365d4042e79d418e22c74b6c10fe1aeb5fc9d7 /gdb/dwarf2read.c
parentdfdfb3ca984ae5d2775c942705e79794d0c82d8c (diff)
downloadgdb-3690dd376bc19907f4c229fc3471b9898386d32c.zip
gdb-3690dd376bc19907f4c229fc3471b9898386d32c.tar.gz
gdb-3690dd376bc19907f4c229fc3471b9898386d32c.tar.bz2
* 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.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c64
1 files changed, 58 insertions, 6 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index eb2564e..ec0e645 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1027,6 +1027,10 @@ static void dwarf_decode_macros (struct line_header *, unsigned int,
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);
@@ -3474,8 +3478,16 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
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;
@@ -3794,7 +3806,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
{
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 ();
}
@@ -4510,7 +4522,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
{
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 ();
}
@@ -5673,7 +5685,7 @@ read_partial_die (struct partial_die_info *part_die,
{
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 ();
}
@@ -9722,6 +9734,46 @@ attr_form_is_block (struct attribute *attr)
|| 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)
@@ -9733,7 +9785,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
if (objfile->separate_debug_objfile_backlink)
objfile = objfile->separate_debug_objfile_backlink;
- if ((attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+ if (attr_form_is_section_offset (attr)
/* ".debug_loc" may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
other branch. */