+2020-09-29 Tom Tromey <tom@tromey.com>
+
+ * dwarf2/read.c (read_cutu_die_from_dwo): Use OBSTACK_ZALLOC.
+ (read_attribute_reprocess, read_attribute_value): Update.
+ (read_attribute): Clear requires_reprocessing.
+ * dwarf2/attribute.h (struct attribute) <as_unsigned_reprocess,
+ form_requires_reprocessing>: New methods.
+ <string_init>: Clear requires_reprocessing.
+ <set_unsigned_reprocess>: New method.
+ <name>: Shrink by one bit.
+ <requires_reprocessing>: New member.
+ * dwarf2/attribute.c (attribute::form_requires_reprocessing): New
+ method.
+
2020-09-29 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (read_attribute_value): Update.
|| form == DW_FORM_ref8
|| form == DW_FORM_ref_udata);
}
+
+/* See attribute.h. */
+
+bool
+attribute::form_requires_reprocessing () const
+{
+ return (form == DW_FORM_strx1
+ || form == DW_FORM_strx2
+ || form == DW_FORM_strx3
+ || form == DW_FORM_strx4
+ || form == DW_FORM_GNU_str_index
+ || form == DW_FORM_addrx
+ || form == DW_FORM_GNU_addr_index);
+}
return u.snd;
}
+ /* Return the unsigned value, but only for attributes requiring
+ reprocessing. */
+ ULONGEST as_unsigned_reprocess () const
+ {
+ gdb_assert (form_requires_reprocessing ());
+ gdb_assert (requires_reprocessing);
+ return u.unsnd;
+ }
+
/* 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.
/* Check if the attribute's form is an unsigned integer form. */
bool form_is_unsigned () const;
+ /* Check if the attribute's form is a form that requires
+ "reprocessing". */
+ bool form_requires_reprocessing () const;
+
/* Return DIE offset of this attribute. Return 0 with complaint if
the attribute is not of the required kind. */
gdb_assert (form_is_string ());
u.str = str;
string_is_canonical = 0;
+ requires_reprocessing = 0;
}
/* Set the canonical string value for this attribute. */
u.unsnd = unsnd;
}
+ /* Temporarily set this attribute to an unsigned integer. This is
+ used only for those forms that require reprocessing. */
+ void set_unsigned_reprocess (ULONGEST unsnd)
+ {
+ gdb_assert (form_requires_reprocessing ());
+ u.unsnd = unsnd;
+ requires_reprocessing = 1;
+ }
+
+
+ ENUM_BITFIELD(dwarf_attribute) name : 15;
+
+ /* A boolean that is used for forms that require reprocessing. A
+ form may require data not directly available in the attribute.
+ E.g., DW_FORM_strx requires the corresponding
+ DW_AT_str_offsets_base. In this case, the processing for the
+ attribute must be done in two passes. In the first past, this
+ flag is set and the value is an unsigned. In the second pass,
+ the unsigned value is turned into the correct value for the form,
+ and this flag is cleared. This flag is unused for other
+ forms. */
+ unsigned int requires_reprocessing : 1;
- ENUM_BITFIELD(dwarf_attribute) name : 16;
ENUM_BITFIELD(dwarf_form) form : 15;
/* Has u.str already been updated by dwarf2_canonicalize_name? This
else if (stub_comp_dir != NULL)
{
/* Reconstruct the comp_dir attribute to simplify the code below. */
- comp_dir = XOBNEW (&cu->comp_unit_obstack, struct attribute);
+ comp_dir = OBSTACK_ZALLOC (&cu->comp_unit_obstack, struct attribute);
comp_dir->name = DW_AT_comp_dir;
comp_dir->form = DW_FORM_string;
comp_dir->set_string_noncanonical (stub_comp_dir);
{
case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
- DW_ADDR (attr) = read_addr_index (cu, DW_UNSND (attr));
+ DW_ADDR (attr) = read_addr_index (cu, attr->as_unsigned_reprocess ());
break;
case DW_FORM_loclistx:
DW_UNSND (attr) = read_loclist_index (cu, DW_UNSND (attr));
case DW_FORM_strx4:
case DW_FORM_GNU_str_index:
{
- unsigned int str_index = DW_UNSND (attr);
+ unsigned int str_index = attr->as_unsigned_reprocess ();
gdb_assert (!attr->canonical_string_p ());
if (reader->dwo_file != NULL)
attr->set_string_noncanonical (read_dwo_str_index (reader,
case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
*need_reprocess = true;
- DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ attr->set_unsigned_reprocess (read_unsigned_leb128 (abfd, info_ptr,
+ &bytes_read));
info_ptr += bytes_read;
break;
case DW_FORM_strx:
info_ptr += bytes_read;
}
*need_reprocess = true;
- DW_UNSND (attr) = str_index;
+ attr->set_unsigned_reprocess (str_index);
}
break;
default:
{
attr->name = abbrev->name;
attr->string_is_canonical = 0;
+ attr->requires_reprocessing = 0;
return read_attribute_value (reader, attr, abbrev->form,
abbrev->implicit_const, info_ptr,
need_reprocess);