From 3690dd376bc19907f4c229fc3471b9898386d32c Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Thu, 13 Dec 2007 19:02:51 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 11 +++++++++ gdb/dwarf2read.c | 64 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e0428ed62b..23c38e63ea 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2007-12-13 Jim Blandy + + * 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 Remove unused support for target-based exception catching. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index eb2564efff..ec0e645cac 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. */