diff options
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r-- | gdb/dwarf2/attribute.c | 40 | ||||
-rw-r--r-- | gdb/dwarf2/attribute.h | 32 | ||||
-rw-r--r-- | gdb/dwarf2/comp-unit-head.c | 23 | ||||
-rw-r--r-- | gdb/dwarf2/comp-unit-head.h | 7 | ||||
-rw-r--r-- | gdb/dwarf2/cooked-indexer.c | 4 | ||||
-rw-r--r-- | gdb/dwarf2/cu.h | 9 | ||||
-rw-r--r-- | gdb/dwarf2/die.c | 3 | ||||
-rw-r--r-- | gdb/dwarf2/dwz.c | 193 | ||||
-rw-r--r-- | gdb/dwarf2/dwz.h | 25 | ||||
-rw-r--r-- | gdb/dwarf2/macro.c | 1 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 485 | ||||
-rw-r--r-- | gdb/dwarf2/read.h | 44 | ||||
-rw-r--r-- | gdb/dwarf2/section.h | 13 |
13 files changed, 555 insertions, 324 deletions
diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c index 1278f97..8ff0353 100644 --- a/gdb/dwarf2/attribute.c +++ b/gdb/dwarf2/attribute.c @@ -73,7 +73,8 @@ attribute::form_is_string () const || form == DW_FORM_strx3 || form == DW_FORM_strx4 || form == DW_FORM_GNU_str_index - || form == DW_FORM_GNU_strp_alt); + || form == DW_FORM_GNU_strp_alt + || form == DW_FORM_strp_sup); } /* See attribute.h. */ @@ -185,11 +186,43 @@ attribute::unsigned_constant () const /* See attribute.h. */ +std::optional<LONGEST> +attribute::signed_constant () const +{ + if (form_is_strictly_signed ()) + return u.snd; + + switch (form) + { + case DW_FORM_data8: + case DW_FORM_udata: + /* Not sure if DW_FORM_udata should be handled or not. Anyway + for DW_FORM_data8, there's no need to sign-extend. */ + return u.snd; + + case DW_FORM_data1: + return sign_extend (u.unsnd, 8); + case DW_FORM_data2: + return sign_extend (u.unsnd, 16); + case DW_FORM_data4: + return sign_extend (u.unsnd, 32); + } + + /* For DW_FORM_data16 see attribute::form_is_constant. */ + complaint (_("Attribute value is not a constant (%s)"), + dwarf_form_name (form)); + return {}; +} + +/* See attribute.h. */ + bool attribute::form_is_unsigned () const { return (form == DW_FORM_ref_addr || form == DW_FORM_GNU_ref_alt + || form == DW_FORM_ref_sup4 + || form == DW_FORM_ref_sup8 || form == DW_FORM_data2 || form == DW_FORM_data4 || form == DW_FORM_data8 @@ -293,5 +326,8 @@ attribute::as_boolean () const return true; else if (form == DW_FORM_flag) return u.unsnd != 0; - return constant_value (0) != 0; + /* Using signed_constant here will work even for the weird case + where a negative value is provided. Probably doesn't matter but + also seems harmless. */ + return signed_constant ().value_or (0) != 0; } diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h index 70edff3..31ff018 100644 --- a/gdb/dwarf2/attribute.h +++ b/gdb/dwarf2/attribute.h @@ -114,6 +114,15 @@ struct attribute returned. */ std::optional<ULONGEST> unsigned_constant () const; + /* Return a signed constant value. This only handles constant forms + (i.e., form_is_constant -- and not the extended list of + "unsigned" forms) and assumes a signed value is desired. This + function will sign-extend DW_FORM_data* values. + + If non-constant form is used, then complaint is issued and an + empty value is returned. */ + std::optional<LONGEST> signed_constant () const; + /* Return non-zero if ATTR's value falls in the 'constant' class, or zero otherwise. When this function returns true, you can apply the constant_value method to it. @@ -144,7 +153,9 @@ struct attribute || form == DW_FORM_ref4 || form == DW_FORM_ref8 || form == DW_FORM_ref_udata - || form == DW_FORM_GNU_ref_alt); + || form == DW_FORM_GNU_ref_alt + || form == DW_FORM_ref_sup4 + || form == DW_FORM_ref_sup8); } /* Check if the attribute's form is a DW_FORM_block* @@ -164,10 +175,29 @@ struct attribute false. */ bool form_is_strictly_signed () const; + /* Check if the attribute's form is an unsigned constant form. This + only returns true for forms that are strictly unsigned -- that + is, for a context-dependent form like DW_FORM_data1, this returns + false. */ + bool form_is_strictly_unsigned () const + { + return form == DW_FORM_udata; + } + /* Check if the attribute's form is a form that requires "reprocessing". */ bool form_requires_reprocessing () const; + /* Check if attribute's form refers to the separate "dwz" file. + This is only useful for references to the .debug_info section, + not to the supplementary .debug_str section. */ + bool form_is_alt () const + { + return (form == DW_FORM_GNU_ref_alt + || form == DW_FORM_ref_sup4 + || form == DW_FORM_ref_sup8); + } + /* Return DIE offset of this attribute. Return 0 with complaint if the attribute is not of the required kind. */ diff --git a/gdb/dwarf2/comp-unit-head.c b/gdb/dwarf2/comp-unit-head.c index 8ec8897..a35d664 100644 --- a/gdb/dwarf2/comp-unit-head.c +++ b/gdb/dwarf2/comp-unit-head.c @@ -26,7 +26,6 @@ #include "dwarf2/comp-unit-head.h" #include "dwarf2/leb.h" -#include "dwarf2/read.h" #include "dwarf2/section.h" #include "dwarf2/stringify.h" #include "dwarf2/error.h" @@ -149,15 +148,13 @@ read_comp_unit_head (struct comp_unit_head *cu_header, Perform various error checking on the header. */ static void -error_check_comp_unit_head (dwarf2_per_objfile *per_objfile, - struct comp_unit_head *header, - struct dwarf2_section_info *section, - struct dwarf2_section_info *abbrev_section) +error_check_comp_unit_head (comp_unit_head *header, + dwarf2_section_info *section, + dwarf2_section_info *abbrev_section) { const char *filename = section->get_file_name (); - if (to_underlying (header->abbrev_sect_off) - >= abbrev_section->get_size (per_objfile->objfile)) + if (to_underlying (header->abbrev_sect_off) >= abbrev_section->size) error (_(DWARF_ERROR_PREFIX "bad offset (%s) in compilation unit header " "(offset %s + 6) [in module %s]"), @@ -179,12 +176,10 @@ error_check_comp_unit_head (dwarf2_per_objfile *per_objfile, /* See comp-unit-head.h. */ const gdb_byte * -read_and_check_comp_unit_head (dwarf2_per_objfile *per_objfile, - struct comp_unit_head *header, - struct dwarf2_section_info *section, - struct dwarf2_section_info *abbrev_section, - const gdb_byte *info_ptr, - rcuh_kind section_kind) +read_and_check_comp_unit_head (comp_unit_head *header, + dwarf2_section_info *section, + dwarf2_section_info *abbrev_section, + const gdb_byte *info_ptr, rcuh_kind section_kind) { const gdb_byte *beg_of_comp_unit = info_ptr; @@ -194,7 +189,7 @@ read_and_check_comp_unit_head (dwarf2_per_objfile *per_objfile, header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit); - error_check_comp_unit_head (per_objfile, header, section, abbrev_section); + error_check_comp_unit_head (header, section, abbrev_section); return info_ptr; } diff --git a/gdb/dwarf2/comp-unit-head.h b/gdb/dwarf2/comp-unit-head.h index 5134893..ea09153 100644 --- a/gdb/dwarf2/comp-unit-head.h +++ b/gdb/dwarf2/comp-unit-head.h @@ -129,11 +129,8 @@ extern const gdb_byte *read_comp_unit_head The contents of the header are stored in HEADER. The result is a pointer to the start of the first DIE. */ extern const gdb_byte *read_and_check_comp_unit_head - (dwarf2_per_objfile *per_objfile, - struct comp_unit_head *header, - struct dwarf2_section_info *section, - struct dwarf2_section_info *abbrev_section, - const gdb_byte *info_ptr, + (comp_unit_head *header, dwarf2_section_info *section, + dwarf2_section_info *abbrev_section, const gdb_byte *info_ptr, rcuh_kind section_kind); #endif /* GDB_DWARF2_COMP_UNIT_HEAD_H */ diff --git a/gdb/dwarf2/cooked-indexer.c b/gdb/dwarf2/cooked-indexer.c index 1f3a235..b8b66cf 100644 --- a/gdb/dwarf2/cooked-indexer.c +++ b/gdb/dwarf2/cooked-indexer.c @@ -222,7 +222,7 @@ cooked_indexer::scan_attributes (dwarf2_per_cu *scanning_per_cu, case DW_AT_abstract_origin: case DW_AT_extension: origin_offset = attr.get_ref_die_offset (); - origin_is_dwz = attr.form == DW_FORM_GNU_ref_alt; + origin_is_dwz = attr.form_is_alt (); break; case DW_AT_external: @@ -423,7 +423,7 @@ cooked_indexer::index_imported_unit (cutu_reader *reader, if (attr.name == DW_AT_import) { sect_off = attr.get_ref_die_offset (); - is_dwz = (attr.form == DW_FORM_GNU_ref_alt + is_dwz = (attr.form_is_alt () || reader->cu ()->per_cu->is_dwz); } } diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h index 5683291..6eda19b 100644 --- a/gdb/dwarf2/cu.h +++ b/gdb/dwarf2/cu.h @@ -99,6 +99,15 @@ struct dwarf2_cu void add_dependence (dwarf2_per_cu *ref_per_cu) { m_dependencies.emplace (ref_per_cu); } + /* Find the DIE at section offset SECT_OFF. + + Return nullptr if not found. */ + die_info *find_die (sect_offset sect_off) const + { + auto it = die_hash.find (sect_off); + return it != die_hash.end () ? *it : nullptr; + } + /* The header of the compilation unit. */ struct comp_unit_head header; diff --git a/gdb/dwarf2/die.c b/gdb/dwarf2/die.c index 8c3d2ca..7ed18bf 100644 --- a/gdb/dwarf2/die.c +++ b/gdb/dwarf2/die.c @@ -90,6 +90,8 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f); break; case DW_FORM_GNU_ref_alt: + case DW_FORM_ref_sup4: + case DW_FORM_ref_sup8: gdb_printf (f, "alt ref address: "); gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f); break; @@ -123,6 +125,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) case DW_FORM_strx: case DW_FORM_GNU_str_index: case DW_FORM_GNU_strp_alt: + case DW_FORM_strp_sup: gdb_printf (f, "string: \"%s\" (%s canonicalized)", die->attrs[i].as_string () ? die->attrs[i].as_string () : "", diff --git a/gdb/dwarf2/dwz.c b/gdb/dwarf2/dwz.c index e5e18a1..583103b 100644 --- a/gdb/dwarf2/dwz.c +++ b/gdb/dwarf2/dwz.c @@ -21,6 +21,7 @@ #include "build-id.h" #include "debuginfod-support.h" +#include "dwarf2/leb.h" #include "dwarf2/read.h" #include "dwarf2/sect-names.h" #include "filenames.h" @@ -34,15 +35,17 @@ const char * dwz_file::read_string (struct objfile *objfile, LONGEST str_offset) { - str.read (objfile); + /* This must be true because the sections are read in when the + dwz_file is created. */ + gdb_assert (str.readin); if (str.buffer == NULL) - error (_("DW_FORM_GNU_strp_alt used without .debug_str " + error (_("supplementary DWARF file missing .debug_str " "section [in module %s]"), this->filename ()); if (str_offset >= str.size) - error (_("DW_FORM_GNU_strp_alt pointing outside of " - ".debug_str section [in module %s]"), + error (_("invalid string reference to supplementary DWARF file " + "[in module %s]"), this->filename ()); gdb_assert (HOST_CHAR_BIT == 8); if (str.buffer[str_offset] == '\0') @@ -85,6 +88,139 @@ locate_dwz_sections (struct objfile *objfile, bfd *abfd, asection *sectp, } } +/* Helper that throws an exception when reading the .debug_sup + section. */ + +static void +debug_sup_failure (const char *text, bfd *abfd) +{ + error (_("%s [in modules %s]"), text, bfd_get_filename (abfd)); +} + +/* Look for the .debug_sup section and read it. If the section does + not exist, this returns false. If the section does exist but fails + to parse for some reason, an exception is thrown. Otherwise, if + everything goes well, this returns true and fills in the out + parameters. */ + +static bool +get_debug_sup_info (bfd *abfd, + std::string *filename, + size_t *buildid_len, + gdb::unique_xmalloc_ptr<bfd_byte> *buildid) +{ + asection *sect = bfd_get_section_by_name (abfd, ".debug_sup"); + if (sect == nullptr) + return false; + + bfd_byte *contents; + if (!bfd_malloc_and_get_section (abfd, sect, &contents)) + debug_sup_failure (_("could not read .debug_sup section"), abfd); + + gdb::unique_xmalloc_ptr<bfd_byte> content_holder (contents); + bfd_size_type size = bfd_section_size (sect); + + /* Version of this section. */ + if (size < 4) + debug_sup_failure (_(".debug_sup section too short"), abfd); + unsigned int version = read_2_bytes (abfd, contents); + contents += 2; + size -= 2; + if (version != 5) + debug_sup_failure (_(".debug_sup has wrong version number"), abfd); + + /* Skip the is_supplementary value. We already ensured there were + enough bytes, above. */ + ++contents; + --size; + + /* The spec says that in the supplementary file, this must be \0, + but it doesn't seem very important. */ + const char *fname = (const char *) contents; + size_t len = strlen (fname) + 1; + if (filename != nullptr) + *filename = fname; + contents += len; + size -= len; + + if (size == 0) + debug_sup_failure (_(".debug_sup section missing ID"), abfd); + + unsigned int bytes_read; + *buildid_len = read_unsigned_leb128 (abfd, contents, &bytes_read); + contents += bytes_read; + size -= bytes_read; + + if (size < *buildid_len) + debug_sup_failure (_("extra data after .debug_sup section ID"), abfd); + + if (*buildid_len != 0) + buildid->reset ((bfd_byte *) xmemdup (contents, *buildid_len, + *buildid_len)); + + return true; +} + +/* Validate that ABFD matches the given BUILDID. If DWARF5 is true, + then this is done by examining the .debug_sup data. */ + +static bool +verify_id (bfd *abfd, size_t len, const bfd_byte *buildid, bool dwarf5) +{ + if (!bfd_check_format (abfd, bfd_object)) + return false; + + if (dwarf5) + { + size_t new_len; + gdb::unique_xmalloc_ptr<bfd_byte> new_id; + + if (!get_debug_sup_info (abfd, nullptr, &new_len, &new_id)) + return false; + return (len == new_len + && memcmp (buildid, new_id.get (), len) == 0); + } + else + return build_id_verify (abfd, len, buildid); +} + +/* Find either the .debug_sup or .gnu_debugaltlink section and return + its contents. Returns true on success and sets out parameters, or + false if nothing is found. */ + +static bool +read_alt_info (bfd *abfd, std::string *filename, + size_t *buildid_len, + gdb::unique_xmalloc_ptr<bfd_byte> *buildid, + bool *dwarf5) +{ + if (get_debug_sup_info (abfd, filename, buildid_len, buildid)) + { + *dwarf5 = true; + return true; + } + + bfd_size_type buildid_len_arg; + bfd_set_error (bfd_error_no_error); + bfd_byte *buildid_out; + gdb::unique_xmalloc_ptr<char> new_filename + (bfd_get_alt_debug_link_info (abfd, &buildid_len_arg, + &buildid_out)); + if (new_filename == nullptr) + { + if (bfd_get_error () == bfd_error_no_error) + return false; + error (_("could not read '.gnu_debugaltlink' section: %s"), + bfd_errmsg (bfd_get_error ())); + } + *filename = new_filename.get (); + + *buildid_len = buildid_len_arg; + buildid->reset (buildid_out); + *dwarf5 = false; + return true; +} + /* Attempt to find a .dwz file (whose full path is represented by FILENAME) in all of the specified debug file directories provided. @@ -93,7 +229,7 @@ locate_dwz_sections (struct objfile *objfile, bfd *abfd, asection *sectp, static gdb_bfd_ref_ptr dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid, - size_t buildid_len) + size_t buildid_len, bool dwarf5) { /* Let's assume that the path represented by FILENAME has the "/.dwz/" subpath in it. This is what (most) GNU/Linux @@ -161,7 +297,7 @@ dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid, if (dwz_bfd == nullptr) continue; - if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) + if (!verify_id (dwz_bfd.get (), buildid_len, buildid, dwarf5)) { dwz_bfd.reset (nullptr); continue; @@ -177,11 +313,8 @@ dwz_search_other_debugdirs (std::string &filename, bfd_byte *buildid, /* See dwz.h. */ void -dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile) +dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile) { - bfd_size_type buildid_len_arg; - size_t buildid_len; - bfd_byte *buildid; dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; /* This may query the user via the debuginfod support, so it may @@ -193,24 +326,17 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile) /* Set this early, so that on error it remains NULL. */ per_bfd->dwz_file.emplace (nullptr); - bfd_set_error (bfd_error_no_error); - gdb::unique_xmalloc_ptr<char> data - (bfd_get_alt_debug_link_info (per_bfd->obfd, - &buildid_len_arg, &buildid)); - if (data == NULL) + size_t buildid_len; + gdb::unique_xmalloc_ptr<bfd_byte> buildid; + std::string filename; + bool dwarf5; + if (!read_alt_info (per_bfd->obfd, &filename, &buildid_len, &buildid, + &dwarf5)) { - if (bfd_get_error () == bfd_error_no_error) - return; - error (_("could not read '.gnu_debugaltlink' section: %s"), - bfd_errmsg (bfd_get_error ())); + /* Nothing found, nothing to do. */ + return; } - gdb::unique_xmalloc_ptr<bfd_byte> buildid_holder (buildid); - - buildid_len = (size_t) buildid_len_arg; - - std::string filename = data.get (); - if (!IS_ABSOLUTE_PATH (filename.c_str ())) { gdb::unique_xmalloc_ptr<char> abs = gdb_realpath (per_bfd->filename ()); @@ -223,25 +349,26 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile) gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename.c_str (), gnutarget)); if (dwz_bfd != NULL) { - if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) + if (!verify_id (dwz_bfd.get (), buildid_len, buildid.get (), dwarf5)) dwz_bfd.reset (nullptr); } if (dwz_bfd == NULL) - dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid); + dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid.get ()); if (dwz_bfd == nullptr) { /* If the user has provided us with different debug file directories, we can try them in order. */ - dwz_bfd = dwz_search_other_debugdirs (filename, buildid, buildid_len); + dwz_bfd = dwz_search_other_debugdirs (filename, buildid.get (), + buildid_len, dwarf5); } if (dwz_bfd == nullptr) { gdb::unique_xmalloc_ptr<char> alt_filename; scoped_fd fd - = debuginfod_debuginfo_query (buildid, buildid_len, + = debuginfod_debuginfo_query (buildid.get (), buildid_len, per_bfd->filename (), &alt_filename); if (fd.get () >= 0) @@ -252,16 +379,18 @@ dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile) if (dwz_bfd == nullptr) warning (_("File \"%s\" from debuginfod cannot be opened as bfd"), alt_filename.get ()); - else if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) + else if (!verify_id (dwz_bfd.get (), buildid_len, buildid.get (), + dwarf5)) dwz_bfd.reset (nullptr); } } if (dwz_bfd == NULL) - error (_("could not find '.gnu_debugaltlink' file for %s"), + error (_("could not find supplementary DWARF file (%s) for %s"), + filename.c_str (), per_bfd->filename ()); - auto result = std::make_unique<dwz_file> (std::move (dwz_bfd)); + dwz_file_up result (new dwz_file (std::move (dwz_bfd))); for (asection *sec : gdb_bfd_sections (result->dwz_bfd)) locate_dwz_sections (per_objfile->objfile, result->dwz_bfd.get (), diff --git a/gdb/dwarf2/dwz.h b/gdb/dwarf2/dwz.h index 9f69123..372f7e6 100644 --- a/gdb/dwarf2/dwz.h +++ b/gdb/dwarf2/dwz.h @@ -31,10 +31,12 @@ struct dwarf2_per_objfile; struct dwz_file { - dwz_file (gdb_bfd_ref_ptr &&bfd) - : dwz_bfd (std::move (bfd)) - { - } + /* Open the separate '.dwz' debug file, if needed. This will set + the appropriate field in the per-BFD structure. If the DWZ file + exists, the relevant sections are read in as well. Throws an + exception if the .gnu_debugaltlink or .debug_sup section exists + but is invalid or if the file cannot be found. */ + static void read_dwz_file (dwarf2_per_objfile *per_objfile); const char *filename () const { @@ -64,16 +66,15 @@ struct dwz_file return a pointer to the string. */ const char *read_string (struct objfile *objfile, LONGEST str_offset); -}; -using dwz_file_up = std::unique_ptr<dwz_file>; +private: -/* Open the separate '.dwz' debug file, if needed. This just sets the - appropriate field in the per-BFD structure. If the DWZ file - exists, the relevant sections are read in as well. Throws an error - if the .gnu_debugaltlink section exists but the file cannot be - found. */ + explicit dwz_file (gdb_bfd_ref_ptr &&bfd) + : dwz_bfd (std::move (bfd)) + { + } +}; -extern void dwarf2_read_dwz_file (dwarf2_per_objfile *per_objfile); +using dwz_file_up = std::unique_ptr<dwz_file>; #endif /* GDB_DWARF2_DWZ_H */ diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c index 9b8f093..1dc3a9e 100644 --- a/gdb/dwarf2/macro.c +++ b/gdb/dwarf2/macro.c @@ -259,6 +259,7 @@ skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end, case DW_FORM_sec_offset: case DW_FORM_strp: case DW_FORM_GNU_strp_alt: + case DW_FORM_strp_sup: bytes += offset_size; break; diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 6e96afe..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. */ @@ -1039,14 +1045,7 @@ static struct dwo_unit *lookup_dwo_unit_in_dwp (dwarf2_per_bfd *per_bfd, struct dwp_file *dwp_file, const char *comp_dir, ULONGEST signature, int is_debug_types); -static struct dwp_file *get_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 open_and_init_dwp_file (dwarf2_per_objfile *per_objfile); static void queue_and_load_all_dwo_tus (dwarf2_cu *cu); @@ -1289,7 +1288,16 @@ 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) + { + warning (_("%s"), err.what ()); + } + + try + { + open_and_init_dwp_file (per_objfile); } catch (const gdb_exception_error &err) { @@ -1632,7 +1640,7 @@ dw2_do_instantiate_symtab (dwarf2_per_cu *per_cu, && per_objfile->per_bfd->index_table != NULL && !per_objfile->per_bfd->index_table->version_check () /* DWP files aren't supported yet. */ - && get_dwp_file (per_objfile) == NULL) + && per_objfile->per_bfd->dwp_file == nullptr) queue_and_load_all_dwo_tus (cu); } @@ -2383,16 +2391,16 @@ read_abbrev_offset (dwarf2_per_objfile *per_objfile, return (sect_offset) read_offset (abfd, info_ptr, offset_size); } -/* A helper for create_debug_types_hash_table. Read types from SECTION +/* A helper for create_dwo_debug_types_hash_table. Read types from SECTION and fill them into DWO_FILE's type unit hash table. It will process only type units, therefore DW_UT_type. */ -static void -create_debug_type_hash_table (dwarf2_per_objfile *per_objfile, - 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 objfile *objfile = per_objfile->objfile; struct dwarf2_section_info *abbrev_section; bfd *abfd; const gdb_byte *info_ptr, *end_ptr; @@ -2403,7 +2411,6 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile, section->get_name (), abbrev_section->get_file_name ()); - section->read (objfile); info_ptr = section->buffer; if (info_ptr == NULL) @@ -2432,8 +2439,8 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile, /* We need to read the type's signature in order to build the hash table, but we don't need anything else just yet. */ - ptr = read_and_check_comp_unit_head (per_objfile, &header, section, - abbrev_section, ptr, section_kind); + ptr = read_and_check_comp_unit_head (&header, section, abbrev_section, + ptr, section_kind); length = header.get_length_with_initial (); @@ -2447,8 +2454,7 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile, continue; } - dwo_unit *dwo_tu - = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, dwo_unit); + dwo_unit *dwo_tu = OBSTACK_ZALLOC (&per_bfd->obstack, dwo_unit); dwo_tu->dwo_file = dwo_file; dwo_tu->signature = header.signature; dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu; @@ -2478,14 +2484,14 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile, Note: This function processes DWO files only, not DWP files. */ -static void -create_debug_types_hash_table - (dwarf2_per_objfile *per_objfile, dwo_file *dwo_file, +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) { for (dwarf2_section_info §ion : type_sections) - create_debug_type_hash_table (per_objfile, dwo_file, §ion, - rcuh_kind::TYPE); + create_dwo_debug_type_hash_table (per_bfd, dwo_file, §ion, + rcuh_kind::TYPE); } /* Add an entry for signature SIG to per_bfd->signatured_types. */ @@ -2610,7 +2616,7 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) { dwarf2_per_objfile *per_objfile = cu->per_objfile; dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; - struct dwp_file *dwp_file = get_dwp_file (per_objfile); + dwp_file *dwp_file = per_objfile->per_bfd->dwp_file.get (); gdb_assert (cu->dwo_unit); gdb_assert (dwp_file != NULL); @@ -2652,7 +2658,7 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) { /* We're in a DWO/DWP file, and we're using .gdb_index. These cases require special processing. */ - if (get_dwp_file (per_objfile) == NULL) + if (per_objfile->per_bfd->dwp_file == nullptr) return lookup_dwo_signatured_type (cu, sig); else return lookup_dwp_signatured_type (cu, sig); @@ -2712,9 +2718,8 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit, die_info *stub_comp_unit_die, const char *stub_comp_dir) { - dwarf2_per_objfile *per_objfile = cu->per_objfile; dwarf2_per_cu *per_cu = cu->per_cu; - struct objfile *objfile = per_objfile->objfile; + struct objfile *objfile = cu->per_objfile->objfile; bfd *abfd; struct dwarf2_section_info *dwo_abbrev_section; @@ -2790,9 +2795,10 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit, { signatured_type *sig_type = (struct signatured_type *) per_cu; - m_info_ptr = read_and_check_comp_unit_head (per_objfile, &cu->header, - section, dwo_abbrev_section, + m_info_ptr = read_and_check_comp_unit_head (&cu->header, section, + dwo_abbrev_section, m_info_ptr, rcuh_kind::TYPE); + /* This is not an assert because it can be caused by bad debug info. */ if (sig_type->signature != cu->header.signature) { @@ -2818,7 +2824,7 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit, else { m_info_ptr - = read_and_check_comp_unit_head (per_objfile, &cu->header, section, + = read_and_check_comp_unit_head (&cu->header, section, dwo_abbrev_section, m_info_ptr, rcuh_kind::COMPILE); gdb_assert (dwo_unit->sect_off == cu->header.sect_off); @@ -2873,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. */ @@ -3047,7 +3054,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu, if (this_cu.is_debug_types) { m_info_ptr - = read_and_check_comp_unit_head (&per_objfile, &cu->header, section, + = read_and_check_comp_unit_head (&cu->header, section, abbrev_section, m_info_ptr, rcuh_kind::TYPE); @@ -3070,7 +3077,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu, else { m_info_ptr - = read_and_check_comp_unit_head (&per_objfile, &cu->header, section, + = read_and_check_comp_unit_head (&cu->header, section, abbrev_section, m_info_ptr, rcuh_kind::COMPILE); @@ -3204,12 +3211,11 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu, m_info_ptr = section->buffer + to_underlying (this_cu.sect_off); const gdb_byte *begin_info_ptr = m_info_ptr; - m_info_ptr - = read_and_check_comp_unit_head (&per_objfile, &m_new_cu->header, section, - abbrev_section, m_info_ptr, - (this_cu.is_debug_types - ? rcuh_kind::TYPE - : rcuh_kind::COMPILE)); + m_info_ptr = read_and_check_comp_unit_head (&m_new_cu->header, section, + abbrev_section, m_info_ptr, + (this_cu.is_debug_types + ? rcuh_kind::TYPE + : rcuh_kind::COMPILE)); m_new_cu->str_offsets_base = parent_cu.str_offsets_base; m_new_cu->addr_base = parent_cu.addr_base; @@ -3510,7 +3516,7 @@ process_skeletonless_type_units (dwarf2_per_objfile *per_objfile, cooked_index_worker_result *storage) { /* Skeletonless TUs in DWP files without .gdb_index is not supported yet. */ - if (get_dwp_file (per_objfile) == nullptr) + if (per_objfile->per_bfd->dwp_file == nullptr) for (const dwo_file_up &file : per_objfile->per_bfd->dwo_files) for (dwo_unit *unit : file->tus) process_skeletonless_type_unit (unit, per_objfile, storage); @@ -3692,6 +3698,7 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile, { const gdb_byte *info_ptr; struct objfile *objfile = per_objfile->objfile; + dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; dwarf_read_debug_printf ("Reading %s for %s", section->get_name (), @@ -3708,20 +3715,19 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile, sect_offset sect_off = (sect_offset) (info_ptr - section->buffer); comp_unit_head cu_header; - read_and_check_comp_unit_head (per_objfile, &cu_header, section, - abbrev_section, info_ptr, - section_kind); + read_and_check_comp_unit_head (&cu_header, section, abbrev_section, + info_ptr, section_kind); unsigned int length = cu_header.get_length_with_initial (); /* Save the compilation unit for later lookup. */ if (cu_header.unit_type != DW_UT_type) - this_cu - = per_objfile->per_bfd->allocate_per_cu (section, sect_off, length, is_dwz); + this_cu = per_bfd->allocate_per_cu (section, sect_off, length, is_dwz); else { - auto sig_type = per_objfile->per_bfd->allocate_signatured_type - (section, sect_off, length, is_dwz, cu_header.signature); + auto sig_type + = per_bfd->allocate_signatured_type (section, sect_off, length, + is_dwz, cu_header.signature); signatured_type *sig_ptr = sig_type.get (); sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu; this_cu.reset (sig_type.release ()); @@ -3737,7 +3743,7 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile, } info_ptr = info_ptr + this_cu->length (); - per_objfile->per_bfd->all_units.push_back (std::move (this_cu)); + per_bfd->all_units.push_back (std::move (this_cu)); } } @@ -3896,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: @@ -3913,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: @@ -5023,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, @@ -6307,16 +6316,14 @@ 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_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; - struct objfile *objfile = per_objfile->objfile; dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; const gdb_byte *info_ptr, *end_ptr; auto §ion = dwo_file.sections.info; - section.read (objfile); info_ptr = section.buffer; if (info_ptr == NULL) @@ -6342,6 +6349,12 @@ create_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file) if (reader.is_dummy()) continue; + /* DWARF 5 .debug_info.dwo sections may contain some type units. Skip + everything that is not a compile unit. */ + if (const auto ut = reader.cu ()->header.unit_type; + ut != DW_UT_compile && ut != DW_UT_split_compile) + continue; + std::optional<ULONGEST> signature = lookup_dwo_id (reader.cu (), reader.top_level_die ()); if (!signature.has_value ()) @@ -6530,27 +6543,18 @@ create_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file) Note: This function processes DWP files only, not DWO files. */ static struct dwp_hash_table * -create_dwp_hash_table (dwarf2_per_objfile *per_objfile, - struct dwp_file *dwp_file, int is_debug_types) +create_dwp_hash_table (dwarf2_per_bfd *per_bfd, struct dwp_file *dwp_file, + dwarf2_section_info &index) { - struct objfile *objfile = per_objfile->objfile; bfd *dbfd = dwp_file->dbfd.get (); - const gdb_byte *index_ptr, *index_end; - struct dwarf2_section_info *index; uint32_t version, nr_columns, nr_units, nr_slots; struct dwp_hash_table *htab; - if (is_debug_types) - index = &dwp_file->sections.tu_index; - else - index = &dwp_file->sections.cu_index; - - if (index->empty ()) + if (index.empty ()) return NULL; - index->read (objfile); - index_ptr = index->buffer; - index_end = index_ptr + index->size; + const gdb_byte *index_ptr = index.buffer; + const gdb_byte *index_end = index_ptr + index.size; /* For Version 5, the version is really 2 bytes of data & 2 bytes of padding. For now it's safe to just read 4 bytes (particularly as it's difficult to @@ -6581,7 +6585,7 @@ create_dwp_hash_table (dwarf2_per_objfile *per_objfile, pulongest (nr_slots), dwp_file->name); } - htab = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, struct dwp_hash_table); + htab = OBSTACK_ZALLOC (&per_bfd->obstack, struct dwp_hash_table); htab->version = version; htab->nr_columns = nr_columns; htab->nr_units = nr_units; @@ -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,11 +7610,12 @@ 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; gdb_bfd_ref_ptr dbfd = open_dwo_file (per_objfile->per_bfd, dwo_name, comp_dir); @@ -7627,17 +7632,18 @@ 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_cus_hash_table (cu, *dwo_file); + create_dwo_cus_hash_table (cu, *dwo_file); if (cu->header.version < 5) - create_debug_types_hash_table (per_objfile, dwo_file.get (), - dwo_file->sections.types); + create_dwo_debug_types_hash_table (per_bfd, dwo_file.get (), + dwo_file->sections.types); else - create_debug_type_hash_table (per_objfile, dwo_file.get (), - &dwo_file->sections.info, rcuh_kind::COMPILE); + create_dwo_debug_type_hash_table (per_bfd, dwo_file.get (), + &dwo_file->sections.info, + rcuh_kind::COMPILE); dwarf_read_debug_printf ("DWO file found: %s", dwo_name); @@ -7803,10 +7809,9 @@ open_dwp_file (dwarf2_per_bfd *per_bfd, const char *file_name) } /* Initialize the use of the DWP file for the current objfile. - By convention the name of the DWP file is ${objfile}.dwp. - The result is NULL if it can't be found. */ + By convention the name of the DWP file is ${objfile}.dwp. */ -static dwp_file_up +static void open_and_init_dwp_file (dwarf2_per_objfile *per_objfile) { struct objfile *objfile = per_objfile->objfile; @@ -7844,7 +7849,7 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile) { dwarf_read_debug_printf ("DWP file not found: %s", dwp_name.c_str ()); - return dwp_file_up (); + return; } const char *name = bfd_get_filename (dbfd.get ()); @@ -7858,9 +7863,10 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile) dwarf2_locate_common_dwp_sections (objfile, dwp_file->dbfd.get (), sec, dwp_file.get ()); - dwp_file->cus = create_dwp_hash_table (per_objfile, dwp_file.get (), 0); - - dwp_file->tus = create_dwp_hash_table (per_objfile, dwp_file.get (), 1); + dwp_file->cus = create_dwp_hash_table (per_bfd, dwp_file.get (), + dwp_file->sections.cu_index); + dwp_file->tus = create_dwp_hash_table (per_bfd, dwp_file.get (), + dwp_file->sections.tu_index); /* The DWP file version is stored in the hash table. Oh well. */ if (dwp_file->cus && dwp_file->tus @@ -7900,20 +7906,8 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile) bfd_cache_close (dwp_file->dbfd.get ()); - return dwp_file; -} - -/* Wrapper around open_and_init_dwp_file, only open it once. */ - -static struct dwp_file * -get_dwp_file (dwarf2_per_objfile *per_objfile) -{ - if (!per_objfile->per_bfd->dwp_checked) - { - per_objfile->per_bfd->dwp_file = open_and_init_dwp_file (per_objfile); - per_objfile->per_bfd->dwp_checked = 1; - } - return per_objfile->per_bfd->dwp_file.get (); + /* Everything worked, install this dwp_file in the per_bfd. */ + per_objfile->per_bfd->dwp_file = std::move (dwp_file); } /* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit. @@ -7932,22 +7926,23 @@ get_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; struct objfile *objfile = per_objfile->objfile; const char *kind = is_debug_types ? "TU" : "CU"; - struct dwp_file *dwp_file; /* First see if there's a DWP file. If we have a DWP file but didn't find the DWO inside it, don't look for the original DWO file. It makes gdb behave differently depending on whether one is debugging in the build tree. */ - dwp_file = get_dwp_file (per_objfile); + dwp_file *dwp_file = per_objfile->per_bfd->dwp_file.get (); + if (dwp_file != NULL) { const struct dwp_hash_table *dwp_htab = @@ -8048,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); @@ -8060,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); @@ -8104,7 +8100,7 @@ queue_and_load_all_dwo_tus (dwarf2_cu *cu) gdb_assert (cu != nullptr); gdb_assert (!cu->per_cu->is_debug_types); - gdb_assert (get_dwp_file (cu->per_objfile) == nullptr); + gdb_assert (cu->per_objfile->per_bfd->dwp_file == nullptr); dwo_unit = cu->dwo_unit; gdb_assert (dwo_unit != NULL); @@ -9933,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 () @@ -9951,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; } } @@ -9973,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: @@ -10022,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)); } } @@ -10091,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); @@ -10100,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 @@ -10107,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 { @@ -10118,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 ()) @@ -10126,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 { @@ -10279,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 @@ -11099,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; @@ -11244,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); @@ -11575,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) @@ -11607,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); @@ -11628,13 +11644,10 @@ update_enumeration_type_from_children (struct die_info *die, if (!fields.empty ()) type->copy_fields (fields); else - flag_enum = 0; + flag_enum = false; - if (unsigned_enum) - type->set_is_unsigned (true); - - 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 @@ -11678,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); @@ -11692,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 @@ -11704,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 ()); @@ -11724,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; } @@ -12074,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. */ @@ -12298,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 @@ -12613,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; @@ -12725,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); @@ -12889,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 @@ -12910,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 { @@ -13227,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 @@ -13409,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)); @@ -13628,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")); @@ -13779,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; } } } @@ -14107,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. @@ -14195,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); @@ -14927,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; @@ -14982,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 @@ -17179,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) @@ -17193,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 @@ -17264,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 (); @@ -17287,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: @@ -17470,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 @@ -18238,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. @@ -18254,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 @@ -18473,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. */ { @@ -18501,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: @@ -18615,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. */ @@ -18625,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; @@ -19182,7 +19195,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym, /* .debug_loc{,.dwo} may not exist at all, or the offset may be outside the section. If so, fall through to the complaint in the other branch. */ - && attr->as_unsigned () < section->get_size (objfile)) + && attr->as_unsigned () < section->size) { struct dwarf2_loclist_baton *baton; diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 3177b19..f3e043c 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -533,9 +533,9 @@ struct dwarf2_per_bfd } /* Return the separate '.dwz' debug file. If there is no - .gnu_debugaltlink section in the file, then the result depends on - REQUIRE: if REQUIRE is true, error out; if REQUIRE is false, - return nullptr. */ + .gnu_debugaltlink or .debug_sup section in the file, then the + result depends on REQUIRE: if REQUIRE is true, error out; if + REQUIRE is false, return nullptr. */ struct dwz_file *get_dwz_file (bool require = false) { gdb_assert (!require || this->dwz_file.has_value ()); @@ -546,7 +546,7 @@ struct dwarf2_per_bfd { result = this->dwz_file->get (); if (require && result == nullptr) - error (_("could not read '.gnu_debugaltlink' section")); + error (_("could not find supplementary DWARF file")); } return result; @@ -634,9 +634,6 @@ public: /* Set of dwo_file objects. */ dwo_file_up_set dwo_files; - /* True if we've checked for whether there is a DWP file. */ - bool dwp_checked = false; - /* The DWP file if there is one, or NULL. */ dwp_file_up dwp_file; @@ -1028,6 +1025,39 @@ private: const char *read_dwo_str_index (ULONGEST str_index); + gdb_bfd_ref_ptr open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name, + const char *comp_dir); + + dwo_file_up open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name, + const char *comp_dir); + + void locate_dwo_sections (struct objfile *objfile, bfd *abfd, asection *sectp, + struct dwo_sections *dwo_sections); + + void create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file); + + void create_dwo_debug_types_hash_table + (dwarf2_per_bfd *per_bfd, dwo_file *dwo_file, + gdb::array_view<dwarf2_section_info> type_sections); + + void create_dwo_debug_type_hash_table (dwarf2_per_bfd *per_bfd, + dwo_file *dwo_file, + dwarf2_section_info *section, + rcuh_kind section_kind); + + dwo_unit *lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, + const char *comp_dir, ULONGEST signature, + int is_debug_types); + + dwo_unit *lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, + const char *comp_dir, ULONGEST signature); + + dwo_unit *lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name, + const char *comp_dir); + + dwo_unit *lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, + const char *dwo_name); + /* The bfd of die_section. */ bfd *m_abfd; diff --git a/gdb/dwarf2/section.h b/gdb/dwarf2/section.h index 85da485..b9d3c31 100644 --- a/gdb/dwarf2/section.h +++ b/gdb/dwarf2/section.h @@ -81,19 +81,6 @@ struct dwarf2_section_info If the section is compressed, uncompress it before returning. */ void read (struct objfile *objfile); - /* A helper function that returns the size of a section in a safe way. - If you are positive that the section has been read before using the - size, then it is safe to refer to the dwarf2_section_info object's - "size" field directly. In other cases, you must call this - function, because for compressed sections the size field is not set - correctly until the section has been read. */ - bfd_size_type get_size (struct objfile *objfile) - { - if (!readin) - read (objfile); - return size; - } - /* Issue a complaint that something was outside the bounds of this buffer. */ void overflow_complaint () const; |