aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/read.c')
-rw-r--r--gdb/dwarf2/read.c329
1 files changed, 176 insertions, 153 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 659c952..6b7f2c7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -622,15 +622,21 @@ struct variant_field
/* A variant can contain other variant parts. */
std::vector<variant_part_builder> variant_parts;
- /* If we see a DW_TAG_variant, then this will be set if this is the
- default branch. */
- bool default_branch = false;
/* If we see a DW_AT_discr_value, then this will be the discriminant
- value. */
- ULONGEST discriminant_value = 0;
+ value. Just the attribute is stored here, because we have to
+ defer deciding whether the value is signed or unsigned until the
+ end. */
+ const attribute *discriminant_attr = nullptr;
/* If we see a DW_AT_discr_list, then this is a pointer to the list
data. */
struct dwarf_block *discr_list_data = nullptr;
+
+ /* If both DW_AT_discr_value and DW_AT_discr_list are absent, then
+ this is the default branch. */
+ bool is_default () const
+ {
+ return discriminant_attr == nullptr && discr_list_data == nullptr;
+ }
};
/* This represents a DW_TAG_variant_part. */
@@ -1041,13 +1047,6 @@ static struct dwo_unit *lookup_dwo_unit_in_dwp
static void open_and_init_dwp_file (dwarf2_per_objfile *per_objfile);
-static struct dwo_unit *lookup_dwo_comp_unit
- (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature);
-
-static struct dwo_unit *lookup_dwo_type_unit
- (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir);
-
static void queue_and_load_all_dwo_tus (dwarf2_cu *cu);
static void process_cu_includes (dwarf2_per_objfile *per_objfile);
@@ -1289,7 +1288,7 @@ dwarf2_has_info (struct objfile *objfile,
BFD, to avoid races. */
try
{
- dwarf2_read_dwz_file (per_objfile);
+ dwz_file::read_dwz_file (per_objfile);
}
catch (const gdb_exception_error &err)
{
@@ -2396,10 +2395,11 @@ read_abbrev_offset (dwarf2_per_objfile *per_objfile,
and fill them into DWO_FILE's type unit hash table. It will process only
type units, therefore DW_UT_type. */
-static void
-create_dwo_debug_type_hash_table (dwarf2_per_bfd *per_bfd, dwo_file *dwo_file,
- dwarf2_section_info *section,
- rcuh_kind section_kind)
+void
+cutu_reader::create_dwo_debug_type_hash_table (dwarf2_per_bfd *per_bfd,
+ dwo_file *dwo_file,
+ dwarf2_section_info *section,
+ rcuh_kind section_kind)
{
struct dwarf2_section_info *abbrev_section;
bfd *abfd;
@@ -2484,8 +2484,8 @@ create_dwo_debug_type_hash_table (dwarf2_per_bfd *per_bfd, dwo_file *dwo_file,
Note: This function processes DWO files only, not DWP files. */
-static void
-create_dwo_debug_types_hash_table
+void
+cutu_reader::create_dwo_debug_types_hash_table
(dwarf2_per_bfd *per_bfd, dwo_file *dwo_file,
gdb::array_view<dwarf2_section_info> type_sections)
{
@@ -2879,8 +2879,9 @@ lookup_dwo_id (struct dwarf2_cu *cu, struct die_info* comp_unit_die)
Returns nullptr if the specified DWO unit cannot be found. */
-static struct dwo_unit *
-lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
+dwo_unit *
+cutu_reader::lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die,
+ const char *dwo_name)
{
#if CXX_STD_THREAD
/* We need a lock here to handle the DWO hash table. */
@@ -3901,11 +3902,13 @@ cutu_reader::skip_one_attribute (dwarf_form form, const gdb_byte *info_ptr)
case DW_FORM_data4:
case DW_FORM_ref4:
case DW_FORM_strx4:
+ case DW_FORM_ref_sup4:
return info_ptr + 4;
case DW_FORM_data8:
case DW_FORM_ref8:
case DW_FORM_ref_sig8:
+ case DW_FORM_ref_sup8:
return info_ptr + 8;
case DW_FORM_data16:
@@ -3918,6 +3921,7 @@ cutu_reader::skip_one_attribute (dwarf_form form, const gdb_byte *info_ptr)
case DW_FORM_sec_offset:
case DW_FORM_strp:
case DW_FORM_GNU_strp_alt:
+ case DW_FORM_strp_sup:
return info_ptr + m_cu->header.offset_size;
case DW_FORM_exprloc:
@@ -5028,7 +5032,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
if (attr != NULL)
{
sect_offset sect_off = attr->get_ref_die_offset ();
- bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+ bool is_dwz = attr->form_is_alt () || cu->per_cu->is_dwz;
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_cu *per_cu
= dwarf2_find_containing_comp_unit (sect_off, is_dwz,
@@ -6312,8 +6316,8 @@ lookup_dwo_file (dwarf2_per_bfd *per_bfd, const char *dwo_name,
/* Create the dwo_units for the CUs in a DWO_FILE.
Note: This function processes DWO files only, not DWP files. */
-static void
-create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file)
+void
+cutu_reader::create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
@@ -7520,9 +7524,9 @@ try_open_dwop_file (dwarf2_per_bfd *per_bfd, const char *file_name, int is_dwp,
Upon success, the canonicalized path of the file is stored in the bfd,
same as symfile_bfd_open. */
-static gdb_bfd_ref_ptr
-open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
- const char *comp_dir)
+gdb_bfd_ref_ptr
+cutu_reader::open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
+ const char *comp_dir)
{
if (IS_ABSOLUTE_PATH (file_name))
return try_open_dwop_file (per_bfd, file_name,
@@ -7557,9 +7561,9 @@ open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
/* This function is mapped across the sections and remembers the offset and
size of each of the DWO debugging sections we are interested in. */
-static void
-dwarf2_locate_dwo_sections (struct objfile *objfile, bfd *abfd,
- asection *sectp, dwo_sections *dwo_sections)
+void
+cutu_reader::locate_dwo_sections (struct objfile *objfile, bfd *abfd,
+ asection *sectp, dwo_sections *dwo_sections)
{
const struct dwop_section_names *names = &dwop_section_names;
@@ -7606,9 +7610,9 @@ dwarf2_locate_dwo_sections (struct objfile *objfile, bfd *abfd,
by PER_CU. This is for the non-DWP case.
The result is NULL if DWO_NAME can't be found. */
-static dwo_file_up
-open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
- const char *comp_dir)
+dwo_file_up
+cutu_reader::open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
@@ -7628,8 +7632,8 @@ open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
dwo_file->dbfd = std::move (dbfd);
for (asection *sec : gdb_bfd_sections (dwo_file->dbfd))
- dwarf2_locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (),
- sec, &dwo_file->sections);
+ this->locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (), sec,
+ &dwo_file->sections);
create_dwo_cus_hash_table (cu, *dwo_file);
@@ -7922,9 +7926,10 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
The result is a pointer to the dwo_unit object or NULL if we didn't find it
(dwo_id mismatch or couldn't find the DWO/DWP file). */
-static struct dwo_unit *
-lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature, int is_debug_types)
+dwo_unit *
+cutu_reader::lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir, ULONGEST signature,
+ int is_debug_types)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
@@ -8038,9 +8043,9 @@ lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
/* Lookup the DWO CU DWO_NAME/SIGNATURE referenced from THIS_CU.
See lookup_dwo_cutu_unit for details. */
-static struct dwo_unit *
-lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature)
+dwo_unit *
+cutu_reader::lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir, ULONGEST signature)
{
gdb_assert (!cu->per_cu->is_debug_types);
@@ -8050,8 +8055,9 @@ lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
/* Lookup the DWO TU DWO_NAME/SIGNATURE referenced from THIS_TU.
See lookup_dwo_cutu_unit for details. */
-static struct dwo_unit *
-lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir)
+dwo_unit *
+cutu_reader::lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir)
{
gdb_assert (cu->per_cu->is_debug_types);
@@ -9923,7 +9929,7 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
so if we see it, we can assume that a constant form is really
a constant and not a section offset. */
if (attr->form_is_constant ())
- *offset = attr->constant_value (0);
+ *offset = attr->unsigned_constant ().value_or (0);
else if (attr->form_is_section_offset ())
dwarf2_complex_location_expr_complaint ();
else if (attr->form_is_block ()
@@ -9941,7 +9947,7 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
if (attr != nullptr)
{
- *offset = attr->constant_value (0);
+ *offset = attr->unsigned_constant ().value_or (0);
return 1;
}
}
@@ -9963,7 +9969,7 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
{
if (attr->form_is_constant ())
{
- LONGEST offset = attr->constant_value (0);
+ LONGEST offset = attr->unsigned_constant ().value_or (0);
/* Work around this GCC 11 bug, where it would erroneously use -1
data member locations, instead of 0:
@@ -10012,7 +10018,7 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
{
attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
if (attr != nullptr)
- field->set_loc_bitpos (attr->constant_value (0));
+ field->set_loc_bitpos (attr->unsigned_constant ().value_or (0));
}
}
@@ -10081,7 +10087,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
/* Get bit size of field (zero if none). */
attr = dwarf2_attr (die, DW_AT_bit_size, cu);
if (attr != nullptr)
- fp->set_bitsize (attr->constant_value (0));
+ fp->set_bitsize (attr->unsigned_constant ().value_or (0));
else
fp->set_bitsize (0);
@@ -10090,6 +10096,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr != nullptr && attr->form_is_constant ())
{
+ ULONGEST bit_offset = attr->unsigned_constant ().value_or (0);
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* For big endian bits, the DW_AT_bit_offset gives the
@@ -10097,7 +10104,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
anonymous object to the MSB of the field. We don't
have to do anything special since we don't need to
know the size of the anonymous object. */
- fp->set_loc_bitpos (fp->loc_bitpos () + attr->constant_value (0));
+ fp->set_loc_bitpos (fp->loc_bitpos () + bit_offset);
}
else
{
@@ -10108,7 +10115,6 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
the field itself. The result is the bit offset of
the LSB of the field. */
int anonymous_size;
- int bit_offset = attr->constant_value (0);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr && attr->form_is_constant ())
@@ -10116,7 +10122,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
/* The size of the anonymous object containing
the bit field is explicit, so use the
indicated size (in bytes). */
- anonymous_size = attr->constant_value (0);
+ anonymous_size = attr->unsigned_constant ().value_or (0);
}
else
{
@@ -10269,13 +10275,19 @@ convert_variant_range (struct obstack *obstack, const variant_field &variant,
{
std::vector<discriminant_range> ranges;
- if (variant.default_branch)
+ if (variant.is_default ())
return {};
if (variant.discr_list_data == nullptr)
{
- discriminant_range r
- = {variant.discriminant_value, variant.discriminant_value};
+ ULONGEST value;
+
+ if (is_unsigned)
+ value = variant.discriminant_attr->unsigned_constant ().value_or (0);
+ else
+ value = variant.discriminant_attr->signed_constant ().value_or (0);
+
+ discriminant_range r = { value, value };
ranges.push_back (r);
}
else
@@ -11089,7 +11101,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
if (attr != nullptr)
{
if (attr->form_is_constant ())
- type->set_length (attr->constant_value (0));
+ type->set_length (attr->unsigned_constant ().value_or (0));
else
{
struct dynamic_prop prop;
@@ -11234,12 +11246,14 @@ handle_variant (struct die_info *die, struct type *type,
{
discr = dwarf2_attr (die, DW_AT_discr_list, cu);
if (discr == nullptr || discr->as_block ()->size == 0)
- variant.default_branch = true;
+ {
+ /* Nothing to do here -- default branch. */
+ }
else
variant.discr_list_data = discr->as_block ();
}
else
- variant.discriminant_value = discr->constant_value (0);
+ variant.discriminant_attr = discr;
for (die_info *variant_child : die->children ())
handle_struct_member_die (variant_child, type, fi, template_args, cu);
@@ -11565,25 +11579,30 @@ die_byte_order (die_info *die, dwarf2_cu *cu, enum bfd_endian *byte_order)
/* Assuming DIE is an enumeration type, and TYPE is its associated
type, update TYPE using some information only available in DIE's
- children. In particular, the fields are computed. */
+ children. In particular, the fields are computed. If IS_UNSIGNED
+ is set, the enumeration type's sign is already known (a true value
+ means unsigned), and so examining the constants to determine the
+ sign isn't needed; when this is unset, the enumerator constants are
+ read as signed values. */
static void
update_enumeration_type_from_children (struct die_info *die,
struct type *type,
- struct dwarf2_cu *cu)
+ struct dwarf2_cu *cu,
+ std::optional<bool> is_unsigned)
{
- int unsigned_enum = 1;
- int flag_enum = 1;
+ /* This is used to check whether the enum is signed or unsigned; for
+ simplicity, it is always correct regardless of whether
+ IS_UNSIGNED is set. */
+ bool unsigned_enum = is_unsigned.value_or (true);
+ bool flag_enum = true;
- auto_obstack obstack;
std::vector<struct field> fields;
for (die_info *child_die : die->children ())
{
struct attribute *attr;
LONGEST value;
- const gdb_byte *bytes;
- struct dwarf2_locexpr_baton *baton;
const char *name;
if (child_die->tag != DW_TAG_enumerator)
@@ -11597,19 +11616,26 @@ update_enumeration_type_from_children (struct die_info *die,
if (name == NULL)
name = "<anonymous enumerator>";
- dwarf2_const_value_attr (attr, type, name, &obstack, cu,
- &value, &bytes, &baton);
- if (value < 0)
- {
- unsigned_enum = 0;
- flag_enum = 0;
- }
+ /* Can't check UNSIGNED_ENUM here because that is
+ optimistic. */
+ if (is_unsigned.has_value () && *is_unsigned)
+ value = attr->unsigned_constant ().value_or (0);
else
{
- if (count_one_bits_ll (value) >= 2)
- flag_enum = 0;
+ /* Read as signed, either because we don't know the sign or
+ because we know it is definitely signed. */
+ value = attr->signed_constant ().value_or (0);
+
+ if (value < 0)
+ {
+ unsigned_enum = false;
+ flag_enum = false;
+ }
}
+ if (flag_enum && count_one_bits_ll (value) >= 2)
+ flag_enum = false;
+
struct field &field = fields.emplace_back ();
field.set_name (dwarf2_physname (name, child_die, cu));
field.set_loc_enumval (value);
@@ -11618,13 +11644,10 @@ update_enumeration_type_from_children (struct die_info *die,
if (!fields.empty ())
type->copy_fields (fields);
else
- flag_enum = 0;
-
- if (unsigned_enum)
- type->set_is_unsigned (true);
+ flag_enum = false;
- if (flag_enum)
- type->set_is_flag_enum (true);
+ type->set_is_unsigned (unsigned_enum);
+ type->set_is_flag_enum (flag_enum);
}
/* Given a DW_AT_enumeration_type die, set its type. We do not
@@ -11668,7 +11691,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
- type->set_length (attr->constant_value (0));
+ type->set_length (attr->unsigned_constant ().value_or (0));
else
type->set_length (0);
@@ -11682,6 +11705,11 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
if (die_is_declaration (die, cu))
type->set_is_stub (true);
+ /* If the underlying type is known, and is unsigned, then we'll
+ assume the enumerator constants are unsigned. Otherwise we have
+ to assume they are signed. */
+ std::optional<bool> is_unsigned;
+
/* If this type has an underlying type that is not a stub, then we
may use its attributes. We always use the "unsigned" attribute
in this situation, because ordinarily we guess whether the type
@@ -11694,7 +11722,8 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *underlying_type = type->target_type ();
underlying_type = check_typedef (underlying_type);
- type->set_is_unsigned (underlying_type->is_unsigned ());
+ is_unsigned = underlying_type->is_unsigned ();
+ type->set_is_unsigned (*is_unsigned);
if (type->length () == 0)
type->set_length (underlying_type->length ());
@@ -11714,7 +11743,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
Note that, as usual, this must come after set_die_type to avoid
infinite recursion when trying to compute the names of the
enumerators. */
- update_enumeration_type_from_children (die, type, cu);
+ update_enumeration_type_from_children (die, type, cu, is_unsigned);
return type;
}
@@ -12064,7 +12093,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_bit_stride, cu);
if (attr != NULL)
- bit_stride = attr->constant_value (0);
+ bit_stride = attr->unsigned_constant ().value_or (0);
/* Irix 6.2 native cc creates array types without children for
arrays with unspecified length. */
@@ -12288,7 +12317,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
if (member_loc->form_is_constant ())
{
- offset = member_loc->constant_value (0);
+ offset = member_loc->unsigned_constant ().value_or (0);
baton->size += 1 /* DW_OP_addr */ + cu->header.addr_size;
}
else
@@ -12603,7 +12632,8 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr_byte_size)
- byte_size = attr_byte_size->constant_value (cu_header->addr_size);
+ byte_size = (attr_byte_size->unsigned_constant ()
+ .value_or (cu_header->addr_size));
else
byte_size = cu_header->addr_size;
@@ -12715,7 +12745,8 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
type = lookup_reference_type (target_type, refcode);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
- type->set_length (attr->constant_value (cu_header->addr_size));
+ type->set_length (attr->unsigned_constant ()
+ .value_or (cu_header->addr_size));
else
type->set_length (cu_header->addr_size);
@@ -12879,9 +12910,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
len = dwarf2_attr (die, DW_AT_byte_size, cu);
if (len != nullptr && len->form_is_constant ())
{
- /* Pass 0 as the default as we know this attribute is constant
- and the default value will not be returned. */
- LONGEST sz = len->constant_value (0);
+ LONGEST sz = len->unsigned_constant ().value_or (0);
prop_type = objfile_int_type (objfile, sz, true);
}
else
@@ -12900,15 +12929,14 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
else if (attr != nullptr)
{
/* This DW_AT_string_length just contains the length with no
- indirection. There's no need to create a dynamic property in this
- case. Pass 0 for the default value as we know it will not be
- returned in this case. */
- length = attr->constant_value (0);
+ indirection. There's no need to create a dynamic property in
+ this case. */
+ length = attr->unsigned_constant ().value_or (0);
}
else if ((attr = dwarf2_attr (die, DW_AT_byte_size, cu)) != nullptr)
{
/* We don't currently support non-constant byte sizes for strings. */
- length = attr->constant_value (1);
+ length = attr->unsigned_constant ().value_or (1);
}
else
{
@@ -13217,10 +13245,10 @@ get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr)
? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE,
true);
}
- else if (attr->form_is_unsigned ())
+ else if (attr->form_is_strictly_unsigned ())
*value = gdb_mpz (attr->as_unsigned ());
else
- *value = gdb_mpz (attr->constant_value (1));
+ *value = gdb_mpz (attr->signed_constant ().value_or (1));
}
/* Assuming DIE is a rational DW_TAG_constant, read the DIE's
@@ -13399,14 +13427,14 @@ finish_fixed_point_type (struct type *type, const char *suffix,
}
else if (attr->name == DW_AT_binary_scale)
{
- LONGEST scale_exp = attr->constant_value (0);
+ LONGEST scale_exp = attr->signed_constant ().value_or (0);
gdb_mpz &num_or_denom = scale_exp > 0 ? scale_num : scale_denom;
num_or_denom <<= std::abs (scale_exp);
}
else if (attr->name == DW_AT_decimal_scale)
{
- LONGEST scale_exp = attr->constant_value (0);
+ LONGEST scale_exp = attr->signed_constant ().value_or (0);
gdb_mpz &num_or_denom = scale_exp > 0 ? scale_num : scale_denom;
num_or_denom = gdb_mpz::pow (10, std::abs (scale_exp));
@@ -13618,7 +13646,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
}
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
- bits = attr->constant_value (0) * TARGET_CHAR_BIT;
+ bits = attr->unsigned_constant ().value_or (0) * TARGET_CHAR_BIT;
name = dwarf2_full_name (nullptr, die, cu);
if (!name)
complaint (_("DW_AT_name missing from DW_TAG_base_type"));
@@ -13769,22 +13797,28 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_bit_size, cu);
if (attr != nullptr && attr->form_is_constant ())
{
- unsigned real_bit_size = attr->constant_value (0);
+ unsigned real_bit_size = attr->unsigned_constant ().value_or (0);
if (real_bit_size >= 0 && real_bit_size <= 8 * type->length ())
{
attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
/* Only use the attributes if they make sense together. */
- if (attr == nullptr
- || (attr->form_is_constant ()
- && attr->constant_value (0) >= 0
- && (attr->constant_value (0) + real_bit_size
- <= 8 * type->length ())))
+ std::optional<ULONGEST> bit_offset;
+ if (attr == nullptr)
+ bit_offset = 0;
+ else if (attr->form_is_constant ())
+ {
+ bit_offset = attr->unsigned_constant ();
+ if (bit_offset.has_value ()
+ && *bit_offset + real_bit_size > 8 * type->length ())
+ bit_offset.reset ();
+ }
+ if (bit_offset.has_value ())
{
TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_size
= real_bit_size;
if (attr != nullptr)
TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_offset
- = attr->constant_value (0);
+ = *bit_offset;
}
}
}
@@ -14097,8 +14131,13 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
LONGEST bias = 0;
struct attribute *bias_attr = dwarf2_attr (die, DW_AT_GNU_bias, cu);
- if (bias_attr != nullptr && bias_attr->form_is_constant ())
- bias = bias_attr->constant_value (0);
+ if (bias_attr != nullptr)
+ {
+ if (base_type->is_unsigned ())
+ bias = (LONGEST) bias_attr->unsigned_constant ().value_or (0);
+ else
+ bias = bias_attr->signed_constant ().value_or (0);
+ }
/* Normally, the DWARF producers are expected to use a signed
constant form (Eg. DW_FORM_sdata) to express negative bounds.
@@ -14185,7 +14224,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
- range_type->set_length (attr->constant_value (0));
+ range_type->set_length (attr->unsigned_constant ().value_or (0));
maybe_set_alignment (cu, die, range_type);
@@ -14917,10 +14956,12 @@ cutu_reader::read_attribute_value (attribute *attr, unsigned form,
info_ptr += 2;
break;
case DW_FORM_data4:
+ case DW_FORM_ref_sup4:
attr->set_unsigned (read_4_bytes (m_abfd, info_ptr));
info_ptr += 4;
break;
case DW_FORM_data8:
+ case DW_FORM_ref_sup8:
attr->set_unsigned (read_8_bytes (m_abfd, info_ptr));
info_ptr += 8;
break;
@@ -14972,6 +15013,7 @@ cutu_reader::read_attribute_value (attribute *attr, unsigned form,
}
[[fallthrough]];
case DW_FORM_GNU_strp_alt:
+ case DW_FORM_strp_sup:
{
dwz_file *dwz = per_objfile->per_bfd->get_dwz_file (true);
LONGEST str_offset
@@ -17169,13 +17211,10 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
list was that this is unspecified. We choose to always zero-extend
because that is the interpretation long in use by GCC. */
-static gdb_byte *
-dwarf2_const_value_data (const struct attribute *attr, struct obstack *obstack,
- struct dwarf2_cu *cu, LONGEST *value, int bits)
+static void
+dwarf2_const_value_data (const struct attribute *attr, LONGEST *value,
+ int bits)
{
- struct objfile *objfile = cu->per_objfile->objfile;
- enum bfd_endian byte_order = bfd_big_endian (objfile->obfd.get ()) ?
- BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
LONGEST l = attr->constant_value (0);
if (bits < sizeof (*value) * 8)
@@ -17183,16 +17222,8 @@ dwarf2_const_value_data (const struct attribute *attr, struct obstack *obstack,
l &= ((LONGEST) 1 << bits) - 1;
*value = l;
}
- else if (bits == sizeof (*value) * 8)
- *value = l;
else
- {
- gdb_byte *bytes = (gdb_byte *) obstack_alloc (obstack, bits / 8);
- store_unsigned_integer (bytes, bits / 8, byte_order, l);
- return bytes;
- }
-
- return NULL;
+ *value = l;
}
/* Read a constant value from an attribute. Either set *VALUE, or if
@@ -17254,6 +17285,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
+ case DW_FORM_strp_sup:
/* The string is already allocated on the objfile obstack, point
directly to it. */
*bytes = (const gdb_byte *) attr->as_string ();
@@ -17277,16 +17309,16 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
converted to host endianness, so we just need to sign- or
zero-extend it as appropriate. */
case DW_FORM_data1:
- *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 8);
+ dwarf2_const_value_data (attr, value, 8);
break;
case DW_FORM_data2:
- *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 16);
+ dwarf2_const_value_data (attr, value, 16);
break;
case DW_FORM_data4:
- *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 32);
+ dwarf2_const_value_data (attr, value, 32);
break;
case DW_FORM_data8:
- *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 64);
+ dwarf2_const_value_data (attr, value, 64);
break;
case DW_FORM_sdata:
@@ -17460,7 +17492,7 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
/* First see if we have it cached. */
- if (attr->form == DW_FORM_GNU_ref_alt)
+ if (attr->form_is_alt ())
{
sect_offset sect_off = attr->get_ref_die_offset ();
dwarf2_per_cu *per_cu
@@ -18228,8 +18260,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
*ref_cu = target_cu;
- auto it = target_cu->die_hash.find (sect_off);
- return it != target_cu->die_hash.end () ? *it : nullptr;
+ return target_cu->find_die (sect_off);
}
/* Follow reference attribute ATTR of SRC_DIE.
@@ -18244,15 +18275,14 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
- if (attr->form != DW_FORM_GNU_ref_alt && src_die->sect_off == sect_off)
+ if (!attr->form_is_alt () && src_die->sect_off == sect_off)
{
/* Self-reference, we're done. */
return src_die;
}
die = follow_die_offset (sect_off,
- (attr->form == DW_FORM_GNU_ref_alt
- || cu->per_cu->is_dwz),
+ attr->form_is_alt () || cu->per_cu->is_dwz,
ref_cu);
if (!die)
error (_(DWARF_ERROR_PREFIX
@@ -18463,6 +18493,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
+ case DW_FORM_strp_sup:
/* The string is already allocated on the objfile obstack, point
directly to it. */
{
@@ -18491,31 +18522,23 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
zero-extend it as appropriate. */
case DW_FORM_data1:
type = die_type (die, cu);
- result = dwarf2_const_value_data (attr, obstack, cu, &value, 8);
- if (result == NULL)
- result = write_constant_as_bytes (obstack, byte_order,
- type, value, len);
+ dwarf2_const_value_data (attr, &value, 8);
+ result = write_constant_as_bytes (obstack, byte_order, type, value, len);
break;
case DW_FORM_data2:
type = die_type (die, cu);
- result = dwarf2_const_value_data (attr, obstack, cu, &value, 16);
- if (result == NULL)
- result = write_constant_as_bytes (obstack, byte_order,
- type, value, len);
+ dwarf2_const_value_data (attr, &value, 16);
+ result = write_constant_as_bytes (obstack, byte_order, type, value, len);
break;
case DW_FORM_data4:
type = die_type (die, cu);
- result = dwarf2_const_value_data (attr, obstack, cu, &value, 32);
- if (result == NULL)
- result = write_constant_as_bytes (obstack, byte_order,
- type, value, len);
+ dwarf2_const_value_data (attr, &value, 32);
+ result = write_constant_as_bytes (obstack, byte_order, type, value, len);
break;
case DW_FORM_data8:
type = die_type (die, cu);
- result = dwarf2_const_value_data (attr, obstack, cu, &value, 64);
- if (result == NULL)
- result = write_constant_as_bytes (obstack, byte_order,
- type, value, len);
+ dwarf2_const_value_data (attr, &value, 64);
+ result = write_constant_as_bytes (obstack, byte_order, type, value, len);
break;
case DW_FORM_sdata:
@@ -18605,8 +18628,8 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
gdb_assert (sig_cu != NULL);
gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
- if (auto die_it = sig_cu->die_hash.find (sig_type->type_offset_in_section);
- die_it != sig_cu->die_hash.end ())
+ if (die_info *die = sig_cu->find_die (sig_type->type_offset_in_section);
+ die != nullptr)
{
/* For .gdb_index version 7 keep track of included TUs.
http://sourceware.org/bugzilla/show_bug.cgi?id=15021. */
@@ -18615,7 +18638,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
(*ref_cu)->per_cu->imported_symtabs.push_back (sig_cu->per_cu);
*ref_cu = sig_cu;
- return *die_it;
+ return die;
}
return NULL;