aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r--gdb/dwarf2/cu.h11
-rw-r--r--gdb/dwarf2/dwz.c60
-rw-r--r--gdb/dwarf2/loc.c2
-rw-r--r--gdb/dwarf2/loc.h3
-rw-r--r--gdb/dwarf2/read.c200
-rw-r--r--gdb/dwarf2/read.h3
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 &section,