aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/dwarf2/attribute.c14
-rw-r--r--gdb/dwarf2/attribute.h37
-rw-r--r--gdb/dwarf2/read.c12
4 files changed, 71 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ea0a4ae..d02fd7d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,19 @@
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.
* dwarf2/attribute.h (struct attribute) <form_is_unsigned,
set_unsigned>: New methods.
diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c
index 69c59cc..5d9c559 100644
--- a/gdb/dwarf2/attribute.c
+++ b/gdb/dwarf2/attribute.c
@@ -182,3 +182,17 @@ attribute::form_is_unsigned () const
|| 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);
+}
diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index 3067e2a..b2c824f 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -73,6 +73,15 @@ struct attribute
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.
@@ -127,6 +136,10 @@ struct attribute
/* 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. */
@@ -162,6 +175,7 @@ struct attribute
gdb_assert (form_is_string ());
u.str = str;
string_is_canonical = 0;
+ requires_reprocessing = 0;
}
/* Set the canonical string value for this attribute. */
@@ -200,8 +214,29 @@ struct 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
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index c572ed4..57b667e 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6869,7 +6869,7 @@ read_cutu_die_from_dwo (dwarf2_cu *cu,
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);
@@ -19640,7 +19640,7 @@ read_attribute_reprocess (const struct die_reader_specs *reader,
{
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));
@@ -19655,7 +19655,7 @@ read_attribute_reprocess (const struct die_reader_specs *reader,
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,
@@ -19879,7 +19879,8 @@ read_attribute_value (const struct die_reader_specs *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:
@@ -19916,7 +19917,7 @@ read_attribute_value (const struct die_reader_specs *reader,
info_ptr += bytes_read;
}
*need_reprocess = true;
- DW_UNSND (attr) = str_index;
+ attr->set_unsigned_reprocess (str_index);
}
break;
default:
@@ -19957,6 +19958,7 @@ read_attribute (const struct die_reader_specs *reader,
{
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);