* 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.
This commit is contained in:
Jim Blandy 2007-12-13 19:02:51 +00:00
parent dfdfb3ca98
commit 3690dd376b
2 changed files with 69 additions and 6 deletions

View File

@ -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.
2007-12-12 Jim Blandy <jimb@codesourcery.com>
Remove unused support for target-based exception catching.

View File

@ -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. */