Do not separately read type units

Currently, the DWARF reader has a separate pass to read type units --
create_all_type_units.  While working on other patches, I discovered
that this caused DWARF 5 type units to be read twice, once by
create_all_comp_units and once by create_all_type_units.

There's no need any more (if there ever was) to treat type units
differently from CUs.  So, this patch removes create_all_type_units
and unifies the code paths.

Note that the DWO code still has a second pass.  I haven't looked into
this code yet; perhaps it can also be simplified.

Regression tested using the debug-types board file on x86-64 Fedora 32.

gdb/ChangeLog
2021-04-30  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (dwarf2_initialize_objfile): Update.
	(add_signatured_type_cu_to_table): Remove.
	(create_debug_type_hash_table): Assume dwo_file is non-null.
	(create_debug_types_hash_table): Update comment.
	(create_all_type_units): Remove.
	(sort_tu_by_abbrev_offset): Update comment.
	(build_type_psymtabs): Rename from build_type_psymtabs_1.
	(build_type_psymtabs): Remove.
	(process_skeletonless_type_unit, dwarf2_build_psymtabs_hard):
	Update.
	(read_comp_units_from_section): Add types_htab, section_kind
	parameters.
	(create_all_comp_units): Read type units.
This commit is contained in:
Tom Tromey
2021-04-30 14:07:58 -06:00
parent 91eea9cc48
commit b8efb248a8
2 changed files with 68 additions and 132 deletions

View File

@ -1,3 +1,19 @@
2021-04-30 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (dwarf2_initialize_objfile): Update.
(add_signatured_type_cu_to_table): Remove.
(create_debug_type_hash_table): Assume dwo_file is non-null.
(create_debug_types_hash_table): Update comment.
(create_all_type_units): Remove.
(sort_tu_by_abbrev_offset): Update comment.
(build_type_psymtabs): Rename from build_type_psymtabs_1.
(build_type_psymtabs): Remove.
(process_skeletonless_type_unit, dwarf2_build_psymtabs_hard):
Update.
(read_comp_units_from_section): Add types_htab, section_kind
parameters.
(create_all_comp_units): Read type units.
2021-04-30 Tom Tromey <tom@tromey.com> 2021-04-30 Tom Tromey <tom@tromey.com>
* dwarf2/read.h (struct tu_stats) <nr_tus>: New member. * dwarf2/read.h (struct tu_stats) <nr_tus>: New member.

View File

@ -1689,8 +1689,6 @@ static struct type *set_die_type (struct die_info *, struct type *,
static void create_all_comp_units (dwarf2_per_objfile *per_objfile); static void create_all_comp_units (dwarf2_per_objfile *per_objfile);
static int create_all_type_units (dwarf2_per_objfile *per_objfile);
static void load_full_comp_unit (dwarf2_per_cu_data *per_cu, static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile, dwarf2_per_objfile *per_objfile,
dwarf2_cu *existing_cu, dwarf2_cu *existing_cu,
@ -5656,7 +5654,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
per_bfd->using_index = 1; per_bfd->using_index = 1;
create_all_comp_units (per_objfile); create_all_comp_units (per_objfile);
create_all_type_units (per_objfile);
per_bfd->quick_file_names_table per_bfd->quick_file_names_table
= create_quick_file_names_table (per_bfd->all_comp_units.size ()); = create_quick_file_names_table (per_bfd->all_comp_units.size ());
per_objfile->resize_symtabs (); per_objfile->resize_symtabs ();
@ -6002,20 +5999,6 @@ allocate_signatured_type_table ()
NULL, xcalloc, xfree)); NULL, xcalloc, xfree));
} }
/* A helper function to add a signatured type CU to a table. */
static int
add_signatured_type_cu_to_table (void **slot, void *datum)
{
struct signatured_type *sigt = (struct signatured_type *) *slot;
std::vector<std::unique_ptr<dwarf2_per_cu_data>> *all_comp_units
= (std::vector<std::unique_ptr<dwarf2_per_cu_data>> *) datum;
all_comp_units->emplace_back (sigt);
return 1;
}
/* A helper for create_debug_types_hash_table. Read types from SECTION /* A helper for create_debug_types_hash_table. Read types from SECTION
and fill them into TYPES_HTAB. It will process only type units, and fill them into TYPES_HTAB. It will process only type units,
therefore DW_UT_type. */ therefore DW_UT_type. */
@ -6031,9 +6014,7 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
bfd *abfd; bfd *abfd;
const gdb_byte *info_ptr, *end_ptr; const gdb_byte *info_ptr, *end_ptr;
abbrev_section = (dwo_file != NULL abbrev_section = &dwo_file->sections.abbrev;
? &dwo_file->sections.abbrev
: &per_objfile->per_bfd->abbrev);
dwarf_read_debug_printf ("Reading %s for %s", dwarf_read_debug_printf ("Reading %s for %s",
section->get_name (), section->get_name (),
@ -6087,68 +6068,25 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
} }
if (types_htab == NULL) if (types_htab == NULL)
{ types_htab = allocate_dwo_unit_table ();
if (dwo_file)
types_htab = allocate_dwo_unit_table ();
else
types_htab = allocate_signatured_type_table ();
}
if (dwo_file) dwo_tu = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, dwo_unit);
{ dwo_tu->dwo_file = dwo_file;
dwo_tu = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, dwo_unit); dwo_tu->signature = header.signature;
dwo_tu->dwo_file = dwo_file; dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu;
dwo_tu->signature = header.signature; dwo_tu->section = section;
dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu; dwo_tu->sect_off = sect_off;
dwo_tu->section = section; dwo_tu->length = length;
dwo_tu->sect_off = sect_off;
dwo_tu->length = length;
}
else
{
/* N.B.: type_offset is not usable if this type uses a DWO file.
The real type_offset is in the DWO file. */
dwo_tu = NULL;
sig_type = per_objfile->per_bfd->allocate_signatured_type ();
sig_type->signature = header.signature;
sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
sig_type->is_debug_types = 1;
sig_type->section = section;
sig_type->sect_off = sect_off;
sig_type->length = length;
}
slot = htab_find_slot (types_htab.get (), slot = htab_find_slot (types_htab.get (), dwo_tu, INSERT);
(dwo_file
? (void *) dwo_tu
: (void *) sig_type.get ()),
INSERT);
gdb_assert (slot != NULL); gdb_assert (slot != NULL);
if (*slot != NULL) if (*slot != NULL)
{ complaint (_("debug type entry at offset %s is duplicate to"
sect_offset dup_sect_off; " the entry at offset %s, signature %s"),
sect_offset_str (sect_off),
if (dwo_file) sect_offset_str (dwo_tu->sect_off),
{ hex_string (header.signature));
const struct dwo_unit *dup_tu *slot = dwo_tu;
= (const struct dwo_unit *) *slot;
dup_sect_off = dup_tu->sect_off;
}
else
{
const struct signatured_type *dup_tu
= (const struct signatured_type *) *slot;
dup_sect_off = dup_tu->sect_off;
}
complaint (_("debug type entry at offset %s is duplicate to"
" the entry at offset %s, signature %s"),
sect_offset_str (sect_off), sect_offset_str (dup_sect_off),
hex_string (header.signature));
}
*slot = dwo_file ? (void *) dwo_tu : (void *) sig_type.release ();
dwarf_read_debug_printf_v (" offset %s, signature %s", dwarf_read_debug_printf_v (" offset %s, signature %s",
sect_offset_str (sect_off), sect_offset_str (sect_off),
@ -6160,8 +6098,7 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
/* Create the hash table of all entries in the .debug_types /* Create the hash table of all entries in the .debug_types
(or .debug_types.dwo) section(s). (or .debug_types.dwo) section(s).
If reading a DWO file, then DWO_FILE is a pointer to the DWO file object, DWO_FILE is a pointer to the DWO file object.
otherwise it is NULL.
The result is a pointer to the hash table or NULL if there are no types. The result is a pointer to the hash table or NULL if there are no types.
@ -6178,35 +6115,6 @@ create_debug_types_hash_table (dwarf2_per_objfile *per_objfile,
rcuh_kind::TYPE); rcuh_kind::TYPE);
} }
/* Create the hash table of all entries in the .debug_types section,
and update all_comp_units.
The result is zero if there is an error (e.g. missing .debug_types section),
otherwise non-zero. */
static int
create_all_type_units (dwarf2_per_objfile *per_objfile)
{
htab_up types_htab;
create_debug_type_hash_table (per_objfile, NULL, &per_objfile->per_bfd->info,
types_htab, rcuh_kind::COMPILE);
create_debug_types_hash_table (per_objfile, NULL, per_objfile->per_bfd->types,
types_htab);
if (types_htab == NULL)
{
per_objfile->per_bfd->signatured_types = NULL;
return 0;
}
per_objfile->per_bfd->signatured_types = std::move (types_htab);
htab_traverse_noresize (per_objfile->per_bfd->signatured_types.get (),
add_signatured_type_cu_to_table,
&per_objfile->per_bfd->all_comp_units);
return 1;
}
/* Add an entry for signature SIG to dwarf2_per_objfile->per_bfd->signatured_types. /* Add an entry for signature SIG to dwarf2_per_objfile->per_bfd->signatured_types.
If SLOT is non-NULL, it is the entry to use in the hash table. If SLOT is non-NULL, it is the entry to use in the hash table.
Otherwise we find one. */ Otherwise we find one. */
@ -7447,7 +7355,7 @@ struct tu_abbrev_offset
sect_offset abbrev_offset; sect_offset abbrev_offset;
}; };
/* Helper routine for build_type_psymtabs_1, passed to std::sort. */ /* Helper routine for build_type_psymtabs, passed to std::sort. */
static bool static bool
sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a, sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a,
@ -7457,7 +7365,6 @@ sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a,
} }
/* Efficiently read all the type units. /* Efficiently read all the type units.
This does the bulk of the work for build_type_psymtabs.
The efficiency is because we sort TUs by the abbrev table they use and The efficiency is because we sort TUs by the abbrev table they use and
only read each abbrev table once. In one program there are 200K TUs only read each abbrev table once. In one program there are 200K TUs
@ -7475,7 +7382,7 @@ sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a,
dwarf2_per_objfile->per_bfd->type_unit_groups. */ dwarf2_per_objfile->per_bfd->type_unit_groups. */
static void static void
build_type_psymtabs_1 (dwarf2_per_objfile *per_objfile) build_type_psymtabs (dwarf2_per_objfile *per_objfile)
{ {
struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats; struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
abbrev_table_up abbrev_table; abbrev_table_up abbrev_table;
@ -7602,18 +7509,6 @@ build_type_psymtab_dependencies (void **slot, void *info)
return 1; return 1;
} }
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
Build partial symbol tables for the .debug_types comp-units. */
static void
build_type_psymtabs (dwarf2_per_objfile *per_objfile)
{
if (! create_all_type_units (per_objfile))
return;
build_type_psymtabs_1 (per_objfile);
}
/* Traversal function for process_skeletonless_type_unit. /* Traversal function for process_skeletonless_type_unit.
Read a TU in a DWO file and build partial symbols for it. */ Read a TU in a DWO file and build partial symbols for it. */
@ -7637,13 +7532,13 @@ process_skeletonless_type_unit (void **slot, void *info)
if (*slot != NULL) if (*slot != NULL)
return 1; return 1;
/* This does the job that create_all_type_units would have done for /* This does the job that create_all_comp_units would have done for
this TU. */ this TU. */
entry = add_type_unit (per_objfile, dwo_unit->signature, slot); entry = add_type_unit (per_objfile, dwo_unit->signature, slot);
fill_in_sig_entry_from_dwo_entry (per_objfile, entry, dwo_unit); fill_in_sig_entry_from_dwo_entry (per_objfile, entry, dwo_unit);
*slot = entry; *slot = entry;
/* This does the job that build_type_psymtabs_1 would have done. */ /* This does the job that build_type_psymtabs would have done. */
cutu_reader reader (entry, per_objfile, nullptr, nullptr, false); cutu_reader reader (entry, per_objfile, nullptr, nullptr, false);
if (!reader.dummy_p) if (!reader.dummy_p)
build_type_psymtabs_reader (&reader, reader.info_ptr, build_type_psymtabs_reader (&reader, reader.info_ptr,
@ -7725,9 +7620,8 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
read_in_chain. Make sure to free them when we're done. */ read_in_chain. Make sure to free them when we're done. */
free_cached_comp_units freer (per_objfile); free_cached_comp_units freer (per_objfile);
build_type_psymtabs (per_objfile);
create_all_comp_units (per_objfile); create_all_comp_units (per_objfile);
build_type_psymtabs (per_objfile);
/* Create a temporary address map on a temporary obstack. We later /* Create a temporary address map on a temporary obstack. We later
copy this to the final obstack. */ copy this to the final obstack. */
@ -7800,7 +7694,9 @@ static void
read_comp_units_from_section (dwarf2_per_objfile *per_objfile, read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
struct dwarf2_section_info *section, struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section, struct dwarf2_section_info *abbrev_section,
unsigned int is_dwz) unsigned int is_dwz,
htab_up &types_htab,
rcuh_kind section_kind)
{ {
const gdb_byte *info_ptr; const gdb_byte *info_ptr;
struct objfile *objfile = per_objfile->objfile; struct objfile *objfile = per_objfile->objfile;
@ -7822,17 +7718,31 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
comp_unit_head cu_header; comp_unit_head cu_header;
read_and_check_comp_unit_head (per_objfile, &cu_header, section, read_and_check_comp_unit_head (per_objfile, &cu_header, section,
abbrev_section, info_ptr, abbrev_section, info_ptr,
rcuh_kind::COMPILE); section_kind);
/* Save the compilation unit for later lookup. */ /* Save the compilation unit for later lookup. */
if (cu_header.unit_type != DW_UT_type) if (cu_header.unit_type != DW_UT_type)
this_cu = per_objfile->per_bfd->allocate_per_cu (); this_cu = per_objfile->per_bfd->allocate_per_cu ();
else else
{ {
if (types_htab == nullptr)
types_htab = allocate_signatured_type_table ();
auto sig_type = per_objfile->per_bfd->allocate_signatured_type (); auto sig_type = per_objfile->per_bfd->allocate_signatured_type ();
signatured_type *sig_ptr = sig_type.get ();
sig_type->signature = cu_header.signature; sig_type->signature = cu_header.signature;
sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu; sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
this_cu = std::move (sig_type); this_cu = std::move (sig_type);
void **slot = htab_find_slot (types_htab.get (), sig_ptr, INSERT);
gdb_assert (slot != nullptr);
if (*slot != nullptr)
complaint (_("debug type entry at offset %s is duplicate to"
" the entry at offset %s, signature %s"),
sect_offset_str (sect_off),
sect_offset_str (sig_ptr->sect_off),
hex_string (sig_ptr->signature));
*slot = sig_ptr;
} }
this_cu->is_debug_types = (cu_header.unit_type == DW_UT_type); this_cu->is_debug_types = (cu_header.unit_type == DW_UT_type);
this_cu->sect_off = sect_off; this_cu->sect_off = sect_off;
@ -7851,12 +7761,22 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
static void static void
create_all_comp_units (dwarf2_per_objfile *per_objfile) create_all_comp_units (dwarf2_per_objfile *per_objfile)
{ {
htab_up types_htab;
read_comp_units_from_section (per_objfile, &per_objfile->per_bfd->info, read_comp_units_from_section (per_objfile, &per_objfile->per_bfd->info,
&per_objfile->per_bfd->abbrev, 0); &per_objfile->per_bfd->abbrev, 0,
types_htab, rcuh_kind::COMPILE);
for (dwarf2_section_info &section : per_objfile->per_bfd->types)
read_comp_units_from_section (per_objfile, &section,
&per_objfile->per_bfd->abbrev, 0,
types_htab, rcuh_kind::TYPE);
dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd); dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
if (dwz != NULL) if (dwz != NULL)
read_comp_units_from_section (per_objfile, &dwz->info, &dwz->abbrev, 1); read_comp_units_from_section (per_objfile, &dwz->info, &dwz->abbrev, 1,
types_htab, rcuh_kind::COMPILE);
per_objfile->per_bfd->signatured_types = std::move (types_htab);
} }
/* Process all loaded DIEs for compilation unit CU, starting at /* Process all loaded DIEs for compilation unit CU, starting at