diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 14 | ||||
-rw-r--r-- | gdb/dwarf2/attribute.c | 14 | ||||
-rw-r--r-- | gdb/dwarf2/attribute.h | 37 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 12 |
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); |