diff options
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r-- | gdb/dwarf2/cu.h | 11 | ||||
-rw-r--r-- | gdb/dwarf2/dwz.c | 60 | ||||
-rw-r--r-- | gdb/dwarf2/loc.c | 2 | ||||
-rw-r--r-- | gdb/dwarf2/loc.h | 3 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 200 | ||||
-rw-r--r-- | gdb/dwarf2/read.h | 3 |
6 files changed, 126 insertions, 153 deletions
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h index 9f76789..5338dfe 100644 --- a/gdb/dwarf2/cu.h +++ b/gdb/dwarf2/cu.h @@ -27,8 +27,6 @@ #include "gdbsupport/unordered_set.h" #include "dwarf2/die.h" -struct field_info; - /* Type used for delaying computation of method physnames. See comments for compute_delayed_physnames. */ struct delayed_method_info @@ -401,15 +399,6 @@ public: .debug_str_offsets section (8 or 4, depending on the address size). */ std::optional<ULONGEST> str_offsets_base; - /* We may encounter a DIE where a property refers to a field in some - outer type. For example, in Ada, an array length may depend on a - field in some outer record. In this case, we need to be able to - stash a pointer to the 'struct field' into the appropriate - dynamic property baton. However, the fields aren't created until - the type has been fully processed, so we need a temporary - back-link to this object. */ - struct field_info *field_info = nullptr; - /* Mark used when releasing cached dies. */ bool m_mark : 1; diff --git a/gdb/dwarf2/dwz.c b/gdb/dwarf2/dwz.c index 583103b..1aa0d03 100644 --- a/gdb/dwarf2/dwz.c +++ b/gdb/dwarf2/dwz.c @@ -56,35 +56,37 @@ dwz_file::read_string (struct objfile *objfile, LONGEST str_offset) /* A helper function to find the sections for a .dwz file. */ static void -locate_dwz_sections (struct objfile *objfile, bfd *abfd, asection *sectp, - dwz_file *dwz_file) +locate_dwz_sections (objfile *objfile, dwz_file &dwz_file) { - dwarf2_section_info *sect = nullptr; + for (asection *sec : gdb_bfd_sections (dwz_file.dwz_bfd)) + { + dwarf2_section_info *sect = nullptr; - /* Note that we only support the standard ELF names, because .dwz + /* Note that we only support the standard ELF names, because .dwz is ELF-only (at the time of writing). */ - if (dwarf2_elf_names.abbrev.matches (sectp->name)) - sect = &dwz_file->abbrev; - else if (dwarf2_elf_names.info.matches (sectp->name)) - sect = &dwz_file->info; - else if (dwarf2_elf_names.str.matches (sectp->name)) - sect = &dwz_file->str; - else if (dwarf2_elf_names.line.matches (sectp->name)) - sect = &dwz_file->line; - else if (dwarf2_elf_names.macro.matches (sectp->name)) - sect = &dwz_file->macro; - else if (dwarf2_elf_names.gdb_index.matches (sectp->name)) - sect = &dwz_file->gdb_index; - else if (dwarf2_elf_names.debug_names.matches (sectp->name)) - sect = &dwz_file->debug_names; - else if (dwarf2_elf_names.types.matches (sectp->name)) - sect = &dwz_file->types; - - if (sect != nullptr) - { - sect->s.section = sectp; - sect->size = bfd_section_size (sectp); - sect->read (objfile); + if (dwarf2_elf_names.abbrev.matches (sec->name)) + sect = &dwz_file.abbrev; + else if (dwarf2_elf_names.info.matches (sec->name)) + sect = &dwz_file.info; + else if (dwarf2_elf_names.str.matches (sec->name)) + sect = &dwz_file.str; + else if (dwarf2_elf_names.line.matches (sec->name)) + sect = &dwz_file.line; + else if (dwarf2_elf_names.macro.matches (sec->name)) + sect = &dwz_file.macro; + else if (dwarf2_elf_names.gdb_index.matches (sec->name)) + sect = &dwz_file.gdb_index; + else if (dwarf2_elf_names.debug_names.matches (sec->name)) + sect = &dwz_file.debug_names; + else if (dwarf2_elf_names.types.matches (sec->name)) + sect = &dwz_file.types; + + if (sect != nullptr) + { + sect->s.section = sec; + sect->size = bfd_section_size (sec); + sect->read (objfile); + } } } @@ -341,7 +343,7 @@ dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile) { gdb::unique_xmalloc_ptr<char> abs = gdb_realpath (per_bfd->filename ()); - filename = ldirname (abs.get ()) + SLASH_STRING + filename; + filename = gdb_ldirname (abs.get ()) + SLASH_STRING + filename; } /* First try the file name given in the section. If that doesn't @@ -392,9 +394,7 @@ dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile) 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 (), - sec, result.get ()); + locate_dwz_sections (per_objfile->objfile, *result); gdb_bfd_record_inclusion (per_bfd->obfd, result->dwz_bfd.get ()); bfd_cache_close (result->dwz_bfd.get ()); diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index fa1b4eb..dee6127 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -1747,7 +1747,7 @@ dwarf2_evaluate_property (const dynamic_prop *prop, if (pinfo == NULL) error (_("cannot find reference address for offset property")); - struct field resolved_field = *baton->field; + struct field resolved_field = baton->field; resolve_dynamic_field (resolved_field, pinfo, initial_frame); /* Storage for memory if we need to read it. */ diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h index ebe5c31..ee88fd4 100644 --- a/gdb/dwarf2/loc.h +++ b/gdb/dwarf2/loc.h @@ -20,6 +20,7 @@ #ifndef GDB_DWARF2_LOC_H #define GDB_DWARF2_LOC_H +#include "gdbtypes.h" #include "dwarf2/expr.h" struct symbol_computed_ops; @@ -245,7 +246,7 @@ struct dwarf2_property_baton struct dwarf2_loclist_baton loclist; /* The location is stored in a field of PROPERTY_TYPE. */ - struct field *field; + struct field field; }; }; diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 71fa793..7de32bc 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -698,12 +698,6 @@ struct field_info we're reading. */ std::vector<variant_part_builder> variant_parts; - /* All the field batons that must be updated. This is only used - when a type's property depends on a field of this structure; for - example in Ada when an array's length may come from a field of an - enclosing record. */ - gdb::unordered_map<dwarf2_property_baton *, sect_offset> field_batons; - /* Return the total number of fields (including baseclasses). */ int nfields () const { @@ -5859,7 +5853,7 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu) && res.get_name () != nullptr && IS_ABSOLUTE_PATH (res.get_name ())) { - res.set_comp_dir (ldirname (res.get_name ())); + res.set_comp_dir (gdb_ldirname (res.get_name ())); res.set_name (make_unique_xstrdup (lbasename (res.get_name ()))); } @@ -7434,7 +7428,7 @@ try_open_dwop_file (dwarf2_per_bfd *per_bfd, const char *file_name, int is_dwp, search_path = per_bfd->captured_debug_dir.c_str (); /* Add the path for the executable binary to the list of search paths. */ - std::string objfile_dir = ldirname (per_bfd->filename ()); + std::string objfile_dir = gdb_ldirname (per_bfd->filename ()); search_path_holder.reset (concat (objfile_dir.c_str (), dirname_separator_string, search_path, nullptr)); @@ -7512,45 +7506,66 @@ cutu_reader::open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name, size of each of the DWO debugging sections we are interested in. */ void -cutu_reader::locate_dwo_sections (struct objfile *objfile, bfd *abfd, - asection *sectp, dwo_sections *dwo_sections) +cutu_reader::locate_dwo_sections (objfile *objfile, dwo_file &dwo_file) { const struct dwop_section_names *names = &dwop_section_names; + dwo_sections &dwo_sections = dwo_file.sections; + bool complained_about_macro_already = false; + + for (asection *sec : gdb_bfd_sections (dwo_file.dbfd)) + { + struct dwarf2_section_info *dw_sect = nullptr; + + if (names->abbrev_dwo.matches (sec->name)) + dw_sect = &dwo_sections.abbrev; + else if (names->info_dwo.matches (sec->name)) + dw_sect = &dwo_sections.infos.emplace_back (dwarf2_section_info {}); + else if (names->line_dwo.matches (sec->name)) + dw_sect = &dwo_sections.line; + else if (names->loc_dwo.matches (sec->name)) + dw_sect = &dwo_sections.loc; + else if (names->loclists_dwo.matches (sec->name)) + dw_sect = &dwo_sections.loclists; + else if (names->macinfo_dwo.matches (sec->name)) + dw_sect = &dwo_sections.macinfo; + else if (names->macro_dwo.matches (sec->name)) + { + /* gcc versions <= 13 generate multiple .debug_macro.dwo sections with + some unresolved links between them. It's not usable, so do as if + there were not there. */ + if (!complained_about_macro_already) + { + if (dwo_sections.macro.s.section == nullptr) + dw_sect = &dwo_sections.macro; + else + { + warning (_("Multiple .debug_macro.dwo sections found in " + "%s, ignoring them."), dwo_file.dbfd->filename); - struct dwarf2_section_info *dw_sect = nullptr; - - if (names->abbrev_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->abbrev; - else if (names->info_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->infos.emplace_back (dwarf2_section_info {}); - else if (names->line_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->line; - else if (names->loc_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->loc; - else if (names->loclists_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->loclists; - else if (names->macinfo_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->macinfo; - else if (names->macro_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->macro; - else if (names->rnglists_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->rnglists; - else if (names->str_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->str; - else if (names->str_offsets_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->str_offsets; - else if (names->types_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->types.emplace_back (dwarf2_section_info {}); - - if (dw_sect != nullptr) - { - /* Make sure we don't overwrite a section info that has been filled in + dwo_sections.macro = dwarf2_section_info {}; + complained_about_macro_already = true; + } + } + } + else if (names->rnglists_dwo.matches (sec->name)) + dw_sect = &dwo_sections.rnglists; + else if (names->str_dwo.matches (sec->name)) + dw_sect = &dwo_sections.str; + else if (names->str_offsets_dwo.matches (sec->name)) + dw_sect = &dwo_sections.str_offsets; + else if (names->types_dwo.matches (sec->name)) + dw_sect = &dwo_sections.types.emplace_back (dwarf2_section_info {}); + + if (dw_sect != nullptr) + { + /* Make sure we don't overwrite a section info that has been filled in already. */ - gdb_assert (!dw_sect->readin); + gdb_assert (!dw_sect->readin); - dw_sect->s.section = sectp; - dw_sect->size = bfd_section_size (sectp); - dw_sect->read (objfile); + dw_sect->s.section = sec; + dw_sect->size = bfd_section_size (sec); + dw_sect->read (objfile); + } } } @@ -7578,9 +7593,7 @@ cutu_reader::open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name, dwo_file->comp_dir = comp_dir; dwo_file->dbfd = std::move (dbfd); - for (asection *sec : gdb_bfd_sections (dwo_file->dbfd)) - this->locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (), sec, - &dwo_file->sections); + this->locate_dwo_sections (per_objfile->objfile, *dwo_file); /* There is normally just one .debug_info.dwo section in a DWO file. But when building with -fdebug-types-section, gcc produces multiple .debug_info.dwo @@ -7788,7 +7801,7 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile) struct objfile *backlink = objfile->separate_debug_objfile_backlink; const char *backlink_basename = lbasename (backlink->original_name); - dwp_name = ldirname (objfile->original_name) + SLASH_STRING + backlink_basename; + dwp_name = gdb_ldirname (objfile->original_name) + SLASH_STRING + backlink_basename; } else dwp_name = objfile->original_name; @@ -9966,6 +9979,29 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu, } } +/* A helper that computes the location of a field. The CU and the + DW_TAG_member DIE are passed in. The results are stored in + *FP. */ + +static void +compute_field_location (dwarf2_cu *cu, die_info *die, field *fp) +{ + /* Get type of field. */ + fp->set_type (die_type (die, cu)); + + fp->set_loc_bitpos (0); + + /* Get bit size of field (zero if none). */ + attribute *attr = dwarf2_attr (die, DW_AT_bit_size, cu); + if (attr != nullptr) + fp->set_bitsize (attr->unsigned_constant ().value_or (0)); + else + fp->set_bitsize (0); + + /* Get bit offset of field. */ + handle_member_location (die, cu, fp); +} + /* Add an aggregate field to the field list. */ static void @@ -10021,20 +10057,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } /* Data member other than a C++ static data member. */ - /* Get type of field. */ - fp->set_type (die_type (die, cu)); - - fp->set_loc_bitpos (0); - - /* Get bit size of field (zero if none). */ - attr = dwarf2_attr (die, DW_AT_bit_size, cu); - if (attr != nullptr) - fp->set_bitsize (attr->unsigned_constant ().value_or (0)); - else - fp->set_bitsize (0); - - /* Get bit offset of field. */ - handle_member_location (die, cu, fp); + compute_field_location (cu, die, fp); /* Get name of field. */ fieldname = dwarf2_name (die, cu); @@ -11222,45 +11245,14 @@ handle_struct_member_die (struct die_info *child_die, struct type *type, update_field_batons. If OFFSET is not found, NULL is returned. */ static dwarf2_property_baton * -find_field_create_baton (dwarf2_cu *cu, sect_offset offset) -{ - field_info *fi = cu->field_info; - /* Defensive programming in case we see unusual DWARF. */ - if (fi == nullptr) - return nullptr; - for (const auto &fld : fi->fields) - if (fld.offset == offset) - { - dwarf2_property_baton *result - = XOBNEW (&cu->per_objfile->objfile->objfile_obstack, - struct dwarf2_property_baton); - fi->field_batons[result] = offset; - return result; - } - return nullptr; -} - -/* Update all the stored field property batons. FI is the field info - for the structure being created. TYPE is the corresponding struct - type with its fields already filled in. This fills in the correct - field for each baton that was stored while processing this - type. */ - -static void -update_field_batons (field_info *fi, struct type *type) +find_field_create_baton (dwarf2_cu *cu, die_info *die) { - int n_bases = fi->baseclasses.size (); - for (auto &[baton, offset] : fi->field_batons) - { - for (int i = 0; i < fi->fields.size (); ++i) - { - if (fi->fields[i].offset == offset) - { - baton->field = &type->field (n_bases + i); - break; - } - } - } + dwarf2_property_baton *result + = XOBNEW (&cu->per_objfile->objfile->objfile_obstack, + struct dwarf2_property_baton); + memset (&result->field, 0, sizeof (result->field)); + compute_field_location (cu, die, &result->field); + return result; } /* Finish creating a structure or union type, including filling in its @@ -11284,9 +11276,6 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) struct field_info fi; std::vector<struct symbol *> template_args; - scoped_restore save_field_info - = make_scoped_restore (&cu->field_info, &fi); - for (die_info *child_die : die->children ()) handle_struct_member_die (child_die, type, &fi, &template_args, cu); @@ -11308,11 +11297,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) /* Attach fields and member functions to the type. */ if (fi.nfields () > 0) - { - dwarf2_attach_fields_to_type (&fi, type, cu); - update_field_batons (&fi, type); - } - + dwarf2_attach_fields_to_type (&fi, type, cu); if (!fi.fnfieldlists.empty ()) { dwarf2_attach_fn_fields_to_type (&fi, type, cu); @@ -13927,13 +13912,12 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, case DW_AT_data_member_location: case DW_AT_data_bit_offset: { - baton = find_field_create_baton (cu, target_die->sect_off); + baton = find_field_create_baton (cu, target_die); if (baton == nullptr) return 0; baton->property_type = read_type_die (target_die->parent, target_cu); - baton->field = nullptr; prop->set_field (baton); break; } diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 5b4c8f6..aaac5e7 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -1029,8 +1029,7 @@ private: 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 locate_dwo_sections (objfile *objfile, dwo_file &dwo_file); void create_dwo_unit_hash_tables (dwo_file &dwo_file, dwarf2_cu &skeleton_cu, dwarf2_section_info §ion, |