mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-25 14:01:00 +08:00
Revert past commits
I accidentally pushed my work-in-progress branch... revert that. Sorry for the noise :(. The list of commits reverted are: ae2a50a9ae15 attempt to revamp to the CU/TU list e9386435c94f gdb/dwarf: print DWARF CUs/TUs in "maint print objfiles" 6cbd64aa3eb0 gdb/dwarf: add dwarf_source_language_name 32a187da7622 libiberty: move DW_LANG_* definitions to dwarf2.def b3fa38aef59d gdb/dwarf: move index unit vectors to debug names reader and use them 30ba74418982 gdb/dwarf: track comp and type units count bedb4e09f292 gdb/dwarf: remove unnecessary braces b4f18de12c77 gdb/dwarf: use ranged for loop in some pots Change-Id: I80aed2847025f5b15c16c997680783b39858a703
This commit is contained in:
parent
ae2a50a9ae
commit
c19c928f7b
@ -696,7 +696,13 @@ struct cooked_index_functions : public dwarf2_base_index_functions
|
||||
dwarf2_base_index_functions::print_stats (objfile, print_bcache);
|
||||
}
|
||||
|
||||
void dump (struct objfile *objfile) override;
|
||||
void dump (struct objfile *objfile) override
|
||||
{
|
||||
cooked_index *index = wait (objfile, true);
|
||||
gdb_printf ("Cooked index in use:\n");
|
||||
gdb_printf ("\n");
|
||||
index->dump (objfile->arch ());
|
||||
}
|
||||
|
||||
void expand_all_symtabs (struct objfile *objfile) override
|
||||
{
|
||||
|
@ -84,17 +84,18 @@ tag_can_have_linkage_name (enum dwarf_tag tag)
|
||||
cutu_reader *
|
||||
cooked_indexer::ensure_cu_exists (cutu_reader *reader,
|
||||
dwarf2_per_objfile *per_objfile,
|
||||
const dwarf2_section_info §ion,
|
||||
sect_offset sect_off, bool for_scanning)
|
||||
sect_offset sect_off, bool is_dwz,
|
||||
bool for_scanning)
|
||||
{
|
||||
/* Lookups for type unit references are always in the CU, and
|
||||
cross-CU references will crash. */
|
||||
if (reader->cu ()->per_cu->section == §ion
|
||||
if (reader->cu ()->per_cu->is_dwz == is_dwz
|
||||
&& reader->cu ()->header.offset_in_cu_p (sect_off))
|
||||
return reader;
|
||||
|
||||
dwarf2_per_cu *per_cu
|
||||
= dwarf2_find_containing_unit (section, sect_off, per_objfile->per_bfd);
|
||||
= dwarf2_find_containing_comp_unit (sect_off, is_dwz,
|
||||
per_objfile->per_bfd);
|
||||
|
||||
/* When scanning, we only want to visit a given CU a single time.
|
||||
Doing this check here avoids self-imports as well. */
|
||||
@ -147,8 +148,10 @@ cooked_indexer::scan_attributes (dwarf2_per_cu *scanning_per_cu,
|
||||
bool *is_enum_class,
|
||||
bool for_specification)
|
||||
{
|
||||
bool origin_is_dwz = false;
|
||||
bool is_declaration = false;
|
||||
std::optional<section_and_offset> origin;
|
||||
sect_offset origin_offset {};
|
||||
|
||||
std::optional<unrelocated_addr> low_pc;
|
||||
std::optional<unrelocated_addr> high_pc;
|
||||
bool high_pc_relative = false;
|
||||
@ -215,8 +218,8 @@ cooked_indexer::scan_attributes (dwarf2_per_cu *scanning_per_cu,
|
||||
case DW_AT_specification:
|
||||
case DW_AT_abstract_origin:
|
||||
case DW_AT_extension:
|
||||
origin = { &get_section_for_ref (attr, reader->cu ()->per_cu),
|
||||
attr.get_ref_die_offset () };
|
||||
origin_offset = attr.get_ref_die_offset ();
|
||||
origin_is_dwz = attr.form == DW_FORM_GNU_ref_alt;
|
||||
break;
|
||||
|
||||
case DW_AT_external:
|
||||
@ -305,20 +308,20 @@ cooked_indexer::scan_attributes (dwarf2_per_cu *scanning_per_cu,
|
||||
|| (*linkage_name == nullptr
|
||||
&& tag_can_have_linkage_name (abbrev->tag))
|
||||
|| (*parent_entry == nullptr && m_language != language_c))
|
||||
&& origin.has_value ())
|
||||
&& origin_offset != sect_offset (0))
|
||||
{
|
||||
cutu_reader *new_reader
|
||||
= ensure_cu_exists (reader, reader->cu ()->per_objfile,
|
||||
*origin->section, origin->offset, false);
|
||||
= ensure_cu_exists (reader, reader->cu ()->per_objfile, origin_offset,
|
||||
origin_is_dwz, false);
|
||||
if (new_reader == nullptr)
|
||||
error (_(DWARF_ERROR_PREFIX
|
||||
"cannot follow reference to DIE at %s"
|
||||
" [in module %s]"),
|
||||
sect_offset_str (origin->offset),
|
||||
sect_offset_str (origin_offset),
|
||||
bfd_get_filename (reader->abfd ()));
|
||||
|
||||
const gdb_byte *new_info_ptr
|
||||
= (new_reader->buffer () + to_underlying (origin->offset));
|
||||
= (new_reader->buffer () + to_underlying (origin_offset));
|
||||
|
||||
if (*parent_entry == nullptr)
|
||||
{
|
||||
@ -342,7 +345,7 @@ cooked_indexer::scan_attributes (dwarf2_per_cu *scanning_per_cu,
|
||||
if (new_abbrev == nullptr)
|
||||
error (_(DWARF_ERROR_PREFIX
|
||||
"Unexpected null DIE at offset %s [in module %s]"),
|
||||
sect_offset_str (origin->offset),
|
||||
sect_offset_str (origin_offset),
|
||||
bfd_get_filename (new_reader->abfd ()));
|
||||
|
||||
new_info_ptr += bytes_read;
|
||||
@ -406,7 +409,8 @@ cooked_indexer::index_imported_unit (cutu_reader *reader,
|
||||
const gdb_byte *info_ptr,
|
||||
const abbrev_info *abbrev)
|
||||
{
|
||||
std::optional<section_and_offset> target;
|
||||
sect_offset sect_off {};
|
||||
bool is_dwz = false;
|
||||
|
||||
for (int i = 0; i < abbrev->num_attrs; ++i)
|
||||
{
|
||||
@ -415,18 +419,20 @@ cooked_indexer::index_imported_unit (cutu_reader *reader,
|
||||
info_ptr = reader->read_attribute (&attr, &abbrev->attrs[i], info_ptr);
|
||||
|
||||
if (attr.name == DW_AT_import)
|
||||
target = { &get_section_for_ref (attr, reader->cu ()->per_cu),
|
||||
attr.get_ref_die_offset () };
|
||||
{
|
||||
sect_off = attr.get_ref_die_offset ();
|
||||
is_dwz = (attr.form == DW_FORM_GNU_ref_alt
|
||||
|| reader->cu ()->per_cu->is_dwz);
|
||||
}
|
||||
}
|
||||
|
||||
/* Did not find DW_AT_import. */
|
||||
if (!target.has_value ())
|
||||
if (sect_off == sect_offset (0))
|
||||
return info_ptr;
|
||||
|
||||
dwarf2_per_objfile *per_objfile = reader->cu ()->per_objfile;
|
||||
cutu_reader *new_reader
|
||||
= ensure_cu_exists (reader, per_objfile, *target->section, target->offset,
|
||||
true);
|
||||
= ensure_cu_exists (reader, per_objfile, sect_off, is_dwz, true);
|
||||
if (new_reader != nullptr)
|
||||
{
|
||||
index_dies (new_reader, new_reader->info_ptr (), nullptr, false);
|
||||
|
@ -56,8 +56,9 @@ private:
|
||||
up just a single DIE. */
|
||||
cutu_reader *ensure_cu_exists (cutu_reader *reader,
|
||||
dwarf2_per_objfile *per_objfile,
|
||||
const dwarf2_section_info §ion,
|
||||
sect_offset sect_off, bool for_scanning);
|
||||
sect_offset sect_off,
|
||||
bool is_dwz,
|
||||
bool for_scanning);
|
||||
|
||||
/* Index DIEs in the READER starting at INFO_PTR. PARENT is
|
||||
the entry for the enclosing scope (nullptr at top level). FULLY
|
||||
|
@ -1313,27 +1313,14 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table,
|
||||
/* Store out the .debug_type CUs, if any. */
|
||||
data_buf types_cu_list;
|
||||
|
||||
/* dwarf_per_bfd::all_units is not necessarily sorted as needed in .gdb_index,
|
||||
so sort it here. */
|
||||
std::vector<dwarf2_per_cu *> units;
|
||||
|
||||
for (const auto &per_cu : per_bfd->all_units)
|
||||
units.emplace_back (per_cu.get ());
|
||||
|
||||
std::sort (units.begin (), units.end (),
|
||||
[] (const dwarf2_per_cu *a, const dwarf2_per_cu *b)
|
||||
{
|
||||
/* Comp units go before type units. */
|
||||
if (a->is_debug_types != b->is_debug_types)
|
||||
return a->is_debug_types < b->is_debug_types;
|
||||
|
||||
/* Then, sort by section offset. */
|
||||
return a->sect_off < b->sect_off;
|
||||
});
|
||||
/* The CU list is already sorted, so we don't need to do additional
|
||||
work here. */
|
||||
|
||||
int counter = 0;
|
||||
for (const dwarf2_per_cu *per_cu : units)
|
||||
for (int i = 0; i < per_bfd->all_units.size (); ++i)
|
||||
{
|
||||
dwarf2_per_cu *per_cu = per_bfd->all_units[i].get ();
|
||||
|
||||
const auto insertpair = cu_index_htab.emplace (per_cu, counter);
|
||||
gdb_assert (insertpair.second);
|
||||
|
||||
@ -1350,7 +1337,7 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table,
|
||||
to_underlying (per_cu->sect_off));
|
||||
if (per_cu->is_debug_types)
|
||||
{
|
||||
const signatured_type *sig_type = (const signatured_type *) per_cu;
|
||||
signatured_type *sig_type = (signatured_type *) per_cu;
|
||||
cu_list.append_uint (8, BFD_ENDIAN_LITTLE,
|
||||
to_underlying (sig_type->type_offset_in_tu));
|
||||
cu_list.append_uint (8, BFD_ENDIAN_LITTLE,
|
||||
@ -1413,12 +1400,14 @@ write_debug_names (dwarf2_per_bfd *per_bfd, cooked_index *table,
|
||||
debug_names nametable (per_bfd, dwarf5_is_dwarf64, dwarf5_byte_order);
|
||||
int counter = 0;
|
||||
int types_counter = 0;
|
||||
for (const dwarf2_per_cu_up &per_cu : per_bfd->all_units)
|
||||
for (int i = 0; i < per_bfd->all_units.size (); ++i)
|
||||
{
|
||||
dwarf2_per_cu *per_cu = per_bfd->all_units[i].get ();
|
||||
|
||||
int &this_counter = per_cu->is_debug_types ? types_counter : counter;
|
||||
data_buf &this_list = per_cu->is_debug_types ? types_cu_list : cu_list;
|
||||
|
||||
nametable.add_cu (per_cu.get (), this_counter);
|
||||
nametable.add_cu (per_cu, this_counter);
|
||||
this_list.append_uint (nametable.dwarf5_offset_size (),
|
||||
dwarf5_byte_order,
|
||||
to_underlying (per_cu->sect_off));
|
||||
@ -1426,8 +1415,8 @@ write_debug_names (dwarf2_per_bfd *per_bfd, cooked_index *table,
|
||||
}
|
||||
|
||||
/* Verify that all units are represented. */
|
||||
gdb_assert (counter == per_bfd->num_comp_units);
|
||||
gdb_assert (types_counter == per_bfd->num_type_units);
|
||||
gdb_assert (counter == per_bfd->all_comp_units.size ());
|
||||
gdb_assert (types_counter == per_bfd->all_type_units.size ());
|
||||
|
||||
for (const cooked_index_entry *entry : table->all_entries ())
|
||||
nametable.insert (entry);
|
||||
|
@ -95,14 +95,6 @@ struct mapped_debug_names_reader
|
||||
const gdb_byte *name_table_entry_offs_reordered = nullptr;
|
||||
const gdb_byte *entry_pool = nullptr;
|
||||
|
||||
/* The compilation units table, as found in this index. The CU indices in
|
||||
index entries can index directly into this. */
|
||||
std::vector<dwarf2_per_cu *> comp_units_table;
|
||||
|
||||
/* The type units table, as found in this index. The TU indices in index
|
||||
entries can index directly into this. */
|
||||
std::vector<dwarf2_per_cu *> type_units_table;
|
||||
|
||||
struct index_val
|
||||
{
|
||||
ULONGEST dwarf_tag;
|
||||
@ -122,14 +114,6 @@ struct mapped_debug_names_reader
|
||||
|
||||
gdb::unordered_map<ULONGEST, index_val> abbrev_map;
|
||||
|
||||
/* List of CUs in the same order as found in the index header (DWARF 5 section
|
||||
6.1.1.4.2). */
|
||||
std::vector<dwarf2_per_cu *> comp_units;
|
||||
|
||||
/* List of local TUs in the same order as found in the index (DWARF 5 section
|
||||
6.1.1.4.3). */
|
||||
std::vector<dwarf2_per_cu *> type_units;
|
||||
|
||||
/* Even though the scanning of .debug_names and creation of the cooked index
|
||||
entries is done serially, we create multiple shards so that the
|
||||
finalization step can be parallelized. The shards are filled in a round
|
||||
@ -247,7 +231,7 @@ mapped_debug_names_reader::scan_one_entry (const char *name,
|
||||
case DW_IDX_compile_unit:
|
||||
{
|
||||
/* Don't crash on bad data. */
|
||||
if (ull >= this->comp_units.size ())
|
||||
if (ull >= per_objfile->per_bfd->all_comp_units.size ())
|
||||
{
|
||||
complaint (_(".debug_names entry has bad CU index %s"
|
||||
" [in module %s]"),
|
||||
@ -255,31 +239,30 @@ mapped_debug_names_reader::scan_one_entry (const char *name,
|
||||
bfd_get_filename (abfd));
|
||||
continue;
|
||||
}
|
||||
|
||||
per_cu = this->comp_units[ull];
|
||||
break;
|
||||
}
|
||||
per_cu = per_objfile->per_bfd->get_cu (ull);
|
||||
break;
|
||||
case DW_IDX_type_unit:
|
||||
/* Don't crash on bad data. */
|
||||
if (ull >= per_objfile->per_bfd->all_type_units.size ())
|
||||
{
|
||||
complaint (_(".debug_names entry has bad TU index %s"
|
||||
" [in module %s]"),
|
||||
pulongest (ull),
|
||||
bfd_get_filename (abfd));
|
||||
continue;
|
||||
}
|
||||
{
|
||||
/* Don't crash on bad data. */
|
||||
if (ull >= this->type_units.size ())
|
||||
{
|
||||
complaint (_(".debug_names entry has bad TU index %s"
|
||||
" [in module %s]"),
|
||||
pulongest (ull),
|
||||
bfd_get_filename (abfd));
|
||||
continue;
|
||||
}
|
||||
|
||||
per_cu = this->type_units[ull];
|
||||
break;
|
||||
int nr_cus = per_objfile->per_bfd->all_comp_units.size ();
|
||||
per_cu = per_objfile->per_bfd->get_cu (nr_cus + ull);
|
||||
}
|
||||
break;
|
||||
case DW_IDX_die_offset:
|
||||
die_offset = sect_offset (ull);
|
||||
/* In a per-CU index (as opposed to a per-module index), index
|
||||
entries without CU attribute implicitly refer to the single CU. */
|
||||
if (per_cu == nullptr)
|
||||
per_cu = this->comp_units[0];
|
||||
if (per_cu == NULL)
|
||||
per_cu = per_objfile->per_bfd->get_cu (0);
|
||||
break;
|
||||
case DW_IDX_parent:
|
||||
parent = ull;
|
||||
@ -459,49 +442,45 @@ cooked_index_worker_debug_names::do_reading ()
|
||||
bfd_thread_cleanup ();
|
||||
}
|
||||
|
||||
/* Build the list of TUs (mapped_debug_names_reader::type_units) from the index
|
||||
header and verify that it matches the list of TUs read from the DIEs in
|
||||
`.debug_info`.
|
||||
|
||||
Return true if they match, false otherwise. */
|
||||
/* Check the signatured type hash table from .debug_names. */
|
||||
|
||||
static bool
|
||||
build_and_check_tu_list_from_debug_names (dwarf2_per_objfile *per_objfile,
|
||||
mapped_debug_names_reader &map,
|
||||
dwarf2_section_info *section)
|
||||
check_signatured_type_table_from_debug_names
|
||||
(dwarf2_per_objfile *per_objfile,
|
||||
const mapped_debug_names_reader &map,
|
||||
struct dwarf2_section_info *section)
|
||||
{
|
||||
struct objfile *objfile = per_objfile->objfile;
|
||||
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
|
||||
int nr_cus = per_bfd->all_comp_units.size ();
|
||||
int nr_cus_tus = per_bfd->all_units.size ();
|
||||
|
||||
section->read (objfile);
|
||||
|
||||
uint32_t j = nr_cus;
|
||||
for (uint32_t i = 0; i < map.tu_count; ++i)
|
||||
{
|
||||
/* Read one entry from the TU list. */
|
||||
sect_offset sect_off
|
||||
= (sect_offset) (extract_unsigned_integer
|
||||
(map.tu_table_reordered + i * map.offset_size,
|
||||
map.offset_size,
|
||||
map.dwarf5_byte_order));
|
||||
|
||||
/* Find the matching dwarf2_per_cu. */
|
||||
auto found
|
||||
= std::find_if (per_bfd->all_units.begin (), per_bfd->all_units.end (),
|
||||
[sect_off] (const dwarf2_per_cu_up &unit) {
|
||||
return unit->sect_off == sect_off
|
||||
&& unit->is_debug_types;
|
||||
});
|
||||
|
||||
if (found == per_bfd->all_units.end ())
|
||||
bool found = false;
|
||||
for (; j < nr_cus_tus; j++)
|
||||
if (per_bfd->get_cu (j)->sect_off == sect_off)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
warning (_("Section .debug_names has incorrect entry in TU table,"
|
||||
" ignoring .debug_names."));
|
||||
return false;
|
||||
}
|
||||
|
||||
map.type_units.emplace_back (found);
|
||||
per_bfd->all_comp_units_index_tus.push_back (per_bfd->get_cu (j));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -723,12 +702,42 @@ read_debug_names_from_section (dwarf2_per_objfile *per_objfile,
|
||||
list. */
|
||||
|
||||
static bool
|
||||
build_and_check_cu_list_from_debug_names (dwarf2_per_bfd *per_bfd,
|
||||
mapped_debug_names_reader &map,
|
||||
dwarf2_section_info §ion,
|
||||
bool is_dwz)
|
||||
check_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
|
||||
const mapped_debug_names_reader &map,
|
||||
dwarf2_section_info §ion,
|
||||
bool is_dwz)
|
||||
{
|
||||
if (map.cu_count != per_bfd->num_comp_units)
|
||||
int nr_cus = per_bfd->all_comp_units.size ();
|
||||
|
||||
if (!map.augmentation_is_gdb)
|
||||
{
|
||||
uint32_t j = 0;
|
||||
for (uint32_t i = 0; i < map.cu_count; ++i)
|
||||
{
|
||||
sect_offset sect_off
|
||||
= (sect_offset) (extract_unsigned_integer
|
||||
(map.cu_table_reordered + i * map.offset_size,
|
||||
map.offset_size,
|
||||
map.dwarf5_byte_order));
|
||||
bool found = false;
|
||||
for (; j < nr_cus; j++)
|
||||
if (per_bfd->get_cu (j)->sect_off == sect_off)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
warning (_("Section .debug_names has incorrect entry in CU table,"
|
||||
" ignoring .debug_names."));
|
||||
return false;
|
||||
}
|
||||
per_bfd->all_comp_units_index_cus.push_back (per_bfd->get_cu (j));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (map.cu_count != nr_cus)
|
||||
{
|
||||
warning (_("Section .debug_names has incorrect number of CUs in CU table,"
|
||||
" ignoring .debug_names."));
|
||||
@ -737,57 +746,40 @@ build_and_check_cu_list_from_debug_names (dwarf2_per_bfd *per_bfd,
|
||||
|
||||
for (uint32_t i = 0; i < map.cu_count; ++i)
|
||||
{
|
||||
/* Read one entry from the CU list. */
|
||||
sect_offset sect_off
|
||||
= (sect_offset) (extract_unsigned_integer
|
||||
(map.cu_table_reordered + i * map.offset_size,
|
||||
map.offset_size,
|
||||
map.dwarf5_byte_order));
|
||||
|
||||
/* Find the matching dwarf2_per_cu. */
|
||||
auto found
|
||||
= std::find_if (per_bfd->all_units.begin (), per_bfd->all_units.end (),
|
||||
[is_dwz, sect_off] (const dwarf2_per_cu_up &unit) {
|
||||
return unit->sect_off == sect_off
|
||||
&& !unit->is_debug_types
|
||||
&& unit->is_dwz == is_dwz;
|
||||
});
|
||||
|
||||
if (found == per_bfd->all_units.end ())
|
||||
if (sect_off != per_bfd->get_cu (i)->sect_off)
|
||||
{
|
||||
warning (_("Section .debug_names has incorrect entry in CU table,"
|
||||
" ignoring .debug_names."));
|
||||
return false;
|
||||
}
|
||||
|
||||
map.comp_units.emplace_back (found);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Build the list of CUs (mapped_debug_names_reader::compile_units) from the
|
||||
index header and verify that it matches the list of CUs read from the DIEs in
|
||||
`.debug_info`.
|
||||
|
||||
Return true if they match, false otherwise. */
|
||||
/* Read the CU list from the mapped index, and use it to create all
|
||||
the CU objects for this dwarf2_per_objfile. */
|
||||
|
||||
static bool
|
||||
build_and_check_cu_lists_from_debug_names (dwarf2_per_bfd *per_bfd,
|
||||
mapped_debug_names_reader &map,
|
||||
mapped_debug_names_reader &dwz_map)
|
||||
check_cus_from_debug_names (dwarf2_per_bfd *per_bfd,
|
||||
const mapped_debug_names_reader &map,
|
||||
const mapped_debug_names_reader &dwz_map)
|
||||
{
|
||||
if (!build_and_check_cu_list_from_debug_names (per_bfd, map,
|
||||
per_bfd->infos[0],
|
||||
false /* is_dwz */))
|
||||
if (!check_cus_from_debug_names_list (per_bfd, map, per_bfd->infos[0],
|
||||
false /* is_dwz */))
|
||||
return false;
|
||||
|
||||
if (dwz_map.cu_count == 0)
|
||||
return true;
|
||||
|
||||
dwz_file *dwz = per_bfd->get_dwz_file ();
|
||||
return build_and_check_cu_list_from_debug_names (per_bfd, dwz_map, dwz->info,
|
||||
true /* is_dwz */);
|
||||
return check_cus_from_debug_names_list (per_bfd, dwz_map, dwz->info,
|
||||
true /* is_dwz */);
|
||||
}
|
||||
|
||||
/* This does all the work for dwarf2_read_debug_names, but putting it
|
||||
@ -825,7 +817,7 @@ do_dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
|
||||
}
|
||||
|
||||
create_all_units (per_objfile);
|
||||
if (!build_and_check_cu_lists_from_debug_names (per_bfd, map, dwz_map))
|
||||
if (!check_cus_from_debug_names (per_bfd, map, dwz_map))
|
||||
return false;
|
||||
|
||||
if (map.tu_count != 0)
|
||||
@ -841,8 +833,8 @@ do_dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
|
||||
? &per_bfd->types[0]
|
||||
: &per_bfd->infos[0]);
|
||||
|
||||
if (!build_and_check_tu_list_from_debug_names (per_objfile, map,
|
||||
section))
|
||||
if (!check_signatured_type_table_from_debug_names (per_objfile,
|
||||
map, section))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -117,10 +117,6 @@ struct mapped_gdb_index : public dwarf_scanner_base
|
||||
/* Index data format version. */
|
||||
int version = 0;
|
||||
|
||||
/* Compile units followed by type units, in the order as found in the
|
||||
index. Indices found in index entries can index directly in into this. */
|
||||
std::vector<dwarf2_per_cu *> units;
|
||||
|
||||
/* The address table data. */
|
||||
gdb::array_view<const gdb_byte> address_table;
|
||||
|
||||
@ -1110,16 +1106,17 @@ dw2_expand_marked_cus (dwarf2_per_objfile *per_objfile, offset_type idx,
|
||||
}
|
||||
|
||||
/* Don't crash on bad data. */
|
||||
if (cu_index >= index.units.size ())
|
||||
if (cu_index >= per_objfile->per_bfd->all_units.size ())
|
||||
{
|
||||
complaint (_(".gdb_index entry has bad CU index"
|
||||
" [in module %s]"), objfile_name (per_objfile->objfile));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dw2_expand_symtabs_matching_one (index.units[cu_index], per_objfile,
|
||||
file_matcher, expansion_notify,
|
||||
lang_matcher))
|
||||
dwarf2_per_cu *per_cu = per_objfile->per_bfd->get_cu (cu_index);
|
||||
|
||||
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
|
||||
expansion_notify, lang_matcher))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1316,7 +1313,7 @@ static void
|
||||
create_cus_from_gdb_index_list (dwarf2_per_bfd *per_bfd,
|
||||
const gdb_byte *cu_list, offset_type n_elements,
|
||||
struct dwarf2_section_info *section,
|
||||
int is_dwz, std::vector<dwarf2_per_cu *> &units)
|
||||
int is_dwz)
|
||||
{
|
||||
for (offset_type i = 0; i < n_elements; i += 2)
|
||||
{
|
||||
@ -1331,7 +1328,6 @@ create_cus_from_gdb_index_list (dwarf2_per_bfd *per_bfd,
|
||||
sect_off,
|
||||
length,
|
||||
is_dwz));
|
||||
units.emplace_back (per_bfd->all_units.back ().get ());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1341,21 +1337,20 @@ create_cus_from_gdb_index_list (dwarf2_per_bfd *per_bfd,
|
||||
static void
|
||||
create_cus_from_gdb_index (dwarf2_per_bfd *per_bfd,
|
||||
const gdb_byte *cu_list, offset_type cu_list_elements,
|
||||
std::vector<dwarf2_per_cu *> &units,
|
||||
const gdb_byte *dwz_list, offset_type dwz_elements)
|
||||
{
|
||||
gdb_assert (per_bfd->all_units.empty ());
|
||||
per_bfd->all_units.reserve ((cu_list_elements + dwz_elements) / 2);
|
||||
|
||||
create_cus_from_gdb_index_list (per_bfd, cu_list, cu_list_elements,
|
||||
&per_bfd->infos[0], 0, units);
|
||||
&per_bfd->infos[0], 0);
|
||||
|
||||
if (dwz_elements == 0)
|
||||
return;
|
||||
|
||||
dwz_file *dwz = per_bfd->get_dwz_file ();
|
||||
create_cus_from_gdb_index_list (per_bfd, dwz_list, dwz_elements,
|
||||
&dwz->info, 1, units);
|
||||
&dwz->info, 1);
|
||||
}
|
||||
|
||||
/* Create the signatured type hash table from the index. */
|
||||
@ -1363,8 +1358,7 @@ create_cus_from_gdb_index (dwarf2_per_bfd *per_bfd,
|
||||
static void
|
||||
create_signatured_type_table_from_gdb_index
|
||||
(dwarf2_per_bfd *per_bfd, struct dwarf2_section_info *section,
|
||||
const gdb_byte *bytes, offset_type elements,
|
||||
std::vector<dwarf2_per_cu *> &units)
|
||||
const gdb_byte *bytes, offset_type elements)
|
||||
{
|
||||
signatured_type_set sig_types_hash;
|
||||
|
||||
@ -1388,7 +1382,6 @@ create_signatured_type_table_from_gdb_index
|
||||
sig_type->type_offset_in_tu = type_offset_in_tu;
|
||||
|
||||
sig_types_hash.emplace (sig_type.get ());
|
||||
units.emplace_back (sig_type.get ());
|
||||
per_bfd->all_units.emplace_back (sig_type.release ());
|
||||
}
|
||||
|
||||
@ -1426,14 +1419,14 @@ create_addrmap_from_gdb_index (dwarf2_per_objfile *per_objfile,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cu_index >= index->units.size ())
|
||||
if (cu_index >= per_bfd->all_units.size ())
|
||||
{
|
||||
complaint (_(".gdb_index address table has invalid CU number %u"),
|
||||
(unsigned) cu_index);
|
||||
continue;
|
||||
}
|
||||
|
||||
mutable_map.set_empty (lo, hi - 1, index->units[cu_index]);
|
||||
mutable_map.set_empty (lo, hi - 1, per_bfd->get_cu (cu_index));
|
||||
}
|
||||
|
||||
index->index_addrmap
|
||||
@ -1535,8 +1528,8 @@ dwarf2_read_gdb_index
|
||||
}
|
||||
}
|
||||
|
||||
create_cus_from_gdb_index (per_bfd, cu_list, cu_list_elements, map->units,
|
||||
dwz_list, dwz_list_elements);
|
||||
create_cus_from_gdb_index (per_bfd, cu_list, cu_list_elements, dwz_list,
|
||||
dwz_list_elements);
|
||||
|
||||
if (types_list_elements)
|
||||
{
|
||||
@ -1555,8 +1548,7 @@ dwarf2_read_gdb_index
|
||||
: &per_bfd->infos[0]);
|
||||
|
||||
create_signatured_type_table_from_gdb_index (per_bfd, section, types_list,
|
||||
types_list_elements,
|
||||
map->units);
|
||||
types_list_elements);
|
||||
}
|
||||
|
||||
finalize_all_units (per_bfd);
|
||||
|
@ -1733,7 +1733,6 @@ dwarf2_per_bfd::allocate_per_cu (dwarf2_section_info *section,
|
||||
dwarf2_per_cu_up result (new dwarf2_per_cu (this, section, sect_off,
|
||||
length, is_dwz));
|
||||
result->index = all_units.size ();
|
||||
this->num_comp_units++;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1750,7 +1749,7 @@ dwarf2_per_bfd::allocate_signatured_type (dwarf2_section_info *section,
|
||||
= std::make_unique<signatured_type> (this, section, sect_off, length,
|
||||
is_dwz, signature);
|
||||
result->index = all_units.size ();
|
||||
this->num_type_units++;
|
||||
tu_stats.nr_tus++;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1949,32 +1948,36 @@ dwarf2_base_index_functions::print_stats (struct objfile *objfile,
|
||||
return;
|
||||
|
||||
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
|
||||
unsigned int read_count = 0;
|
||||
unsigned int unread_count = 0;
|
||||
int total = per_objfile->per_bfd->all_units.size ();
|
||||
int count = 0;
|
||||
|
||||
for (auto &per_cu : per_objfile->per_bfd->all_units)
|
||||
if (per_objfile->symtab_set_p (&*per_cu))
|
||||
++read_count;
|
||||
else
|
||||
++unread_count;
|
||||
for (int i = 0; i < total; ++i)
|
||||
{
|
||||
dwarf2_per_cu *per_cu = per_objfile->per_bfd->get_cu (i);
|
||||
|
||||
gdb_printf (_(" Number of read units: %u\n"), read_count);
|
||||
gdb_printf (_(" Number of unread units: %u\n"), unread_count);
|
||||
if (!per_objfile->symtab_set_p (per_cu))
|
||||
++count;
|
||||
}
|
||||
gdb_printf (_(" Number of read CUs: %d\n"), total - count);
|
||||
gdb_printf (_(" Number of unread CUs: %d\n"), count);
|
||||
}
|
||||
|
||||
void
|
||||
dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
|
||||
{
|
||||
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
|
||||
int total_units = per_objfile->per_bfd->all_units.size ();
|
||||
|
||||
for (const dwarf2_per_cu_up &per_cu : per_objfile->per_bfd->all_units)
|
||||
for (int i = 0; i < total_units; ++i)
|
||||
{
|
||||
dwarf2_per_cu *per_cu = per_objfile->per_bfd->get_cu (i);
|
||||
|
||||
/* We don't want to directly expand a partial CU, because if we
|
||||
read it with the wrong language, then assertion failures can
|
||||
be triggered later on. See PR symtab/23010. So, tell
|
||||
dw2_instantiate_symtab to skip partial CUs -- any important
|
||||
partial CU will be read via DW_TAG_imported_unit anyway. */
|
||||
dw2_instantiate_symtab (per_cu.get (), per_objfile, true);
|
||||
dw2_instantiate_symtab (per_cu, per_objfile, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3559,6 +3562,9 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile,
|
||||
/* It's up to the caller to not call us multiple times. */
|
||||
gdb_assert (per_objfile->per_bfd->type_unit_groups == NULL);
|
||||
|
||||
if (per_objfile->per_bfd->all_type_units.size () == 0)
|
||||
return;
|
||||
|
||||
/* TUs typically share abbrev tables, and there can be way more TUs than
|
||||
abbrev tables. Sort by abbrev table to reduce the number of times we
|
||||
read each abbrev table in.
|
||||
@ -3583,17 +3589,18 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile,
|
||||
/* Sort in a separate table to maintain the order of all_units
|
||||
for .gdb_index: TU indices directly index all_type_units. */
|
||||
std::vector<tu_abbrev_offset> sorted_by_abbrev;
|
||||
sorted_by_abbrev.reserve (per_objfile->per_bfd->num_type_units);
|
||||
sorted_by_abbrev.reserve (per_objfile->per_bfd->all_type_units.size ());
|
||||
|
||||
for (const auto &cu : per_objfile->per_bfd->all_units)
|
||||
if (cu->is_debug_types)
|
||||
{
|
||||
auto sig_type = static_cast<signatured_type *> (cu.get ());
|
||||
sorted_by_abbrev.emplace_back (sig_type,
|
||||
read_abbrev_offset (per_objfile,
|
||||
sig_type->section,
|
||||
sig_type->sect_off));
|
||||
}
|
||||
{
|
||||
if (cu->is_debug_types)
|
||||
{
|
||||
auto sig_type = static_cast<signatured_type *> (cu.get ());
|
||||
sorted_by_abbrev.emplace_back
|
||||
(sig_type, read_abbrev_offset (per_objfile, sig_type->section,
|
||||
sig_type->sect_off));
|
||||
}
|
||||
}
|
||||
|
||||
std::sort (sorted_by_abbrev.begin (), sorted_by_abbrev.end ());
|
||||
|
||||
@ -3625,11 +3632,10 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile,
|
||||
static void
|
||||
print_tu_stats (dwarf2_per_objfile *per_objfile)
|
||||
{
|
||||
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
|
||||
struct tu_stats *tu_stats = &per_bfd->tu_stats;
|
||||
struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
|
||||
|
||||
dwarf_read_debug_printf ("Type unit statistics:");
|
||||
dwarf_read_debug_printf (" %d TUs", per_bfd->num_type_units);
|
||||
dwarf_read_debug_printf (" %d TUs", tu_stats->nr_tus);
|
||||
dwarf_read_debug_printf (" %d uniq abbrev tables",
|
||||
tu_stats->nr_uniq_abbrev_tables);
|
||||
dwarf_read_debug_printf (" %d symtabs from stmt_list entries",
|
||||
@ -3932,51 +3938,17 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
|
||||
per_objfile->per_bfd->all_units.push_back (std::move (this_cu));
|
||||
}
|
||||
}
|
||||
/* "less than" function used to both sort and bisect units in the
|
||||
`dwarf2_per_bfd::all_units` vector. Return true if the LHS CU comes before
|
||||
(is "less" than) the section and offset in RHS.
|
||||
|
||||
For simplicity, sort sections by their pointer. This is not ideal, because
|
||||
it can cause the behavior to change across runs, making some bugs harder to
|
||||
investigate. Instead, sections could be sorted by their properties, but it
|
||||
is important that two different sections never compare equal.
|
||||
|
||||
LENGTH_REQUIRED indicates whether the length of the units is required
|
||||
to be set already. When this functions gets called to sort units,
|
||||
the length of the units may not be known yet (for example, when readin
|
||||
.gdb_index). But this doesn't affect the outcome when sorting. On the
|
||||
other hand, when called in the context of looking up a unit by section
|
||||
offset, the length is required in order to know if the offset falls within
|
||||
the section or not. */
|
||||
|
||||
template<bool length_required>
|
||||
static bool
|
||||
all_units_less_than (const dwarf2_per_cu &lhs,
|
||||
const section_and_offset &rhs)
|
||||
{
|
||||
if (lhs.section != rhs.section)
|
||||
return lhs.section < rhs.section;
|
||||
|
||||
|
||||
/* Compare the end of the unit'srange, so that std::lower_bound finds the
|
||||
unit we are looking for, not the one after. */
|
||||
return lhs.sect_off + lhs.length (length_required) - 1 < rhs.offset;
|
||||
}
|
||||
/* Initialize the views on all_units. */
|
||||
|
||||
void
|
||||
finalize_all_units (dwarf2_per_bfd *per_bfd)
|
||||
{
|
||||
/* Ensure that the all_units vector is in the expected order for
|
||||
dwarf2_find_containing_unit to be able to perform a binary search.
|
||||
|
||||
Sort first by section (using the pointer of the section as the key) and
|
||||
then by the offset within the section. */
|
||||
std::
|
||||
sort (per_bfd->all_units.begin (), per_bfd->all_units.end (),
|
||||
[] (const dwarf2_per_cu_up &a, const dwarf2_per_cu_up &b)
|
||||
{
|
||||
return all_units_less_than<false> (*a, { b->section, b->sect_off });
|
||||
});
|
||||
size_t nr_tus = per_bfd->tu_stats.nr_tus;
|
||||
size_t nr_cus = per_bfd->all_units.size () - nr_tus;
|
||||
gdb::array_view<dwarf2_per_cu_up> tmp = per_bfd->all_units;
|
||||
per_bfd->all_comp_units = tmp.slice (0, nr_cus);
|
||||
per_bfd->all_type_units = tmp.slice (nr_cus, nr_tus);
|
||||
}
|
||||
|
||||
/* See read.h. */
|
||||
@ -5245,19 +5217,6 @@ process_full_type_unit (dwarf2_cu *cu,
|
||||
cu->reset_builder ();
|
||||
}
|
||||
|
||||
/* See read.h. */
|
||||
|
||||
dwarf2_section_info &
|
||||
get_section_for_ref (const attribute &attr, dwarf2_per_cu *per_cu)
|
||||
{
|
||||
gdb_assert (attr.form_is_ref ());
|
||||
|
||||
if (attr.form == DW_FORM_GNU_ref_alt)
|
||||
return per_cu->per_bfd->get_dwz_file (true)->info;
|
||||
|
||||
return *per_cu->section;
|
||||
}
|
||||
|
||||
/* Process an imported unit DIE. */
|
||||
|
||||
static void
|
||||
@ -5277,12 +5236,12 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
|
||||
attr = dwarf2_attr (die, DW_AT_import, cu);
|
||||
if (attr != NULL)
|
||||
{
|
||||
const dwarf2_section_info §ion
|
||||
= get_section_for_ref (*attr, cu->per_cu);
|
||||
sect_offset sect_off = attr->get_ref_die_offset ();
|
||||
bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
|
||||
dwarf2_per_objfile *per_objfile = cu->per_objfile;
|
||||
dwarf2_per_cu *per_cu
|
||||
= dwarf2_find_containing_unit (section, sect_off, per_objfile->per_bfd);
|
||||
= dwarf2_find_containing_comp_unit (sect_off, is_dwz,
|
||||
per_objfile->per_bfd);
|
||||
|
||||
/* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
|
||||
into another compilation unit, at root level. Regard this as a hint,
|
||||
@ -14776,60 +14735,6 @@ cutu_reader::read_toplevel_die (die_info **diep, const gdb_byte *info_ptr,
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
cooked_index_functions::dump (struct objfile *objfile)
|
||||
{
|
||||
/* Building the index fills some information in dwarf2_per_cu (e.g. the
|
||||
unit type), which we print in the CU/TU list. We also need to wait for the
|
||||
index to be built before calling `cooked_index::dump` below. */
|
||||
cooked_index *index = this->wait (objfile, true);
|
||||
|
||||
const auto per_bfd = get_dwarf2_per_objfile (objfile)->per_bfd;
|
||||
|
||||
gdb_printf (" Number of compilation units: %u\n", per_bfd->num_comp_units);
|
||||
gdb_printf (" Number of type units: %u\n", per_bfd->num_type_units);
|
||||
gdb_printf ("\n");
|
||||
|
||||
gdb_printf (" Compilation/type units:\n");
|
||||
gdb_printf ("\n");
|
||||
|
||||
for (std::size_t i = 0; i < per_bfd->all_units.size (); ++i)
|
||||
{
|
||||
const auto &unit = *per_bfd->all_units[i];
|
||||
const char *gdb_type_name
|
||||
= unit.is_debug_types ? "signatured_type" : "dwarf2_per_cu";
|
||||
const auto bool_str
|
||||
= [] (const bool val) { return val ? "true" : "false"; };
|
||||
|
||||
gdb_printf (" [%zu] ((%s *) %p)\n", i, gdb_type_name, &unit);
|
||||
gdb_printf (" type: %s\n",
|
||||
dwarf_unit_type_name (unit.unit_type (false)));
|
||||
gdb_printf (" offset: 0x%" PRIx64 "\n",
|
||||
to_underlying (unit.sect_off));
|
||||
gdb_printf (" size: 0x%x\n", unit.length ());
|
||||
|
||||
if (unit.is_debug_types)
|
||||
{
|
||||
const auto &tu = static_cast<const signatured_type &> (unit);
|
||||
|
||||
gdb_printf (" signature: 0x%s\n", phex (tu.signature, 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
gdb_printf (" artificial: %s\n", bool_str (unit.lto_artificial));
|
||||
gdb_printf (" GDB lang: %s\n", language_str (unit.lang (false)));
|
||||
gdb_printf (" DWARF lang: %s\n",
|
||||
dwarf_source_language_name (unit.dw_lang ()));
|
||||
}
|
||||
|
||||
gdb_printf ("\n");
|
||||
}
|
||||
|
||||
gdb_printf ("Cooked index in use:\n");
|
||||
gdb_printf ("\n");
|
||||
index->dump (objfile->arch ());
|
||||
}
|
||||
|
||||
struct compunit_symtab *
|
||||
cooked_index_functions::find_compunit_symtab_by_address
|
||||
(struct objfile *objfile, CORE_ADDR address)
|
||||
@ -15558,7 +15463,6 @@ cutu_reader::read_attribute_value (attribute *attr, unsigned form,
|
||||
}
|
||||
|
||||
/* Super hack. */
|
||||
// RLY NEEDED?,get_section_for_ref should return the dwz section if the ref source if in the dwz
|
||||
if (m_cu->per_cu->is_dwz && attr->form_is_ref ())
|
||||
attr->form = DW_FORM_GNU_ref_alt;
|
||||
|
||||
@ -17900,11 +17804,9 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
|
||||
|
||||
if (attr->form == DW_FORM_GNU_ref_alt)
|
||||
{
|
||||
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
|
||||
const dwarf2_section_info §ion = per_bfd->get_dwz_file ()->info;
|
||||
sect_offset sect_off = attr->get_ref_die_offset ();
|
||||
dwarf2_per_cu *per_cu
|
||||
= dwarf2_find_containing_unit (section, sect_off, per_bfd);
|
||||
= dwarf2_find_containing_comp_unit (sect_off, 1, per_objfile->per_bfd);
|
||||
|
||||
this_type = get_die_type_at_offset (sect_off, per_cu, per_objfile);
|
||||
}
|
||||
@ -18607,41 +18509,42 @@ follow_die_ref_or_sig (struct die_info *src_die, const struct attribute *attr,
|
||||
return die;
|
||||
}
|
||||
|
||||
/* Follow reference TARGET.
|
||||
On entry *REF_CU is the CU of the source die referencing TARGET.
|
||||
/* Follow reference OFFSET.
|
||||
On entry *REF_CU is the CU of the source die referencing OFFSET.
|
||||
On exit *REF_CU is the CU of the result.
|
||||
Returns NULL if TARGET is invalid. */
|
||||
Returns NULL if OFFSET is invalid. */
|
||||
|
||||
static die_info *
|
||||
follow_die_offset (const section_and_offset &target, dwarf2_cu **ref_cu)
|
||||
static struct die_info *
|
||||
follow_die_offset (sect_offset sect_off, int offset_in_dwz,
|
||||
struct dwarf2_cu **ref_cu)
|
||||
{
|
||||
struct dwarf2_cu *source_cu = *ref_cu;
|
||||
dwarf2_per_objfile *per_objfile = source_cu->per_objfile;
|
||||
struct dwarf2_cu *target_cu, *cu = *ref_cu;
|
||||
dwarf2_per_objfile *per_objfile = cu->per_objfile;
|
||||
|
||||
gdb_assert (source_cu->per_cu != NULL);
|
||||
gdb_assert (cu->per_cu != NULL);
|
||||
|
||||
dwarf2_cu *target_cu = source_cu;
|
||||
target_cu = cu;
|
||||
|
||||
dwarf_read_debug_printf_v ("source CU offset: %s, target offset: %s, "
|
||||
"source CU contains target offset: %d",
|
||||
sect_offset_str (source_cu->per_cu->sect_off),
|
||||
sect_offset_str (cu->per_cu->sect_off),
|
||||
sect_offset_str (sect_off),
|
||||
source_cu->header.offset_in_cu_p (sect_off));
|
||||
cu->header.offset_in_cu_p (sect_off));
|
||||
|
||||
if (source_cu->per_cu->is_debug_types)
|
||||
if (cu->per_cu->is_debug_types)
|
||||
{
|
||||
/* .debug_types CUs cannot reference anything outside their CU.
|
||||
If they need to, they have to reference a signatured type via
|
||||
DW_FORM_ref_sig8. */
|
||||
if (!source_cu->header.offset_in_cu_p (sect_off))
|
||||
if (!cu->header.offset_in_cu_p (sect_off))
|
||||
return NULL;
|
||||
}
|
||||
else if (§ion != source_cu->per_cu->section
|
||||
|| !source_cu->header.offset_in_cu_p (sect_off))
|
||||
else if (offset_in_dwz != cu->per_cu->is_dwz
|
||||
|| !cu->header.offset_in_cu_p (sect_off))
|
||||
{
|
||||
dwarf2_per_cu *per_cu
|
||||
= dwarf2_find_containing_unit (section, sect_off,
|
||||
per_objfile->per_bfd);
|
||||
= dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
|
||||
per_objfile->per_bfd);
|
||||
|
||||
dwarf_read_debug_printf_v ("target CU offset: %s, "
|
||||
"target CU DIEs loaded: %d",
|
||||
@ -18653,11 +18556,10 @@ follow_die_offset (const section_and_offset &target, dwarf2_cu **ref_cu)
|
||||
Even if maybe_queue_comp_unit doesn't require us to load the CU's DIEs,
|
||||
it doesn't mean they are currently loaded. Since we require them
|
||||
to be loaded, we must check for ourselves. */
|
||||
if (maybe_queue_comp_unit (source_cu, per_cu, per_objfile,
|
||||
source_cu->lang ())
|
||||
if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->lang ())
|
||||
|| per_objfile->get_cu (per_cu) == nullptr)
|
||||
load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
|
||||
false, source_cu->lang ());
|
||||
false, cu->lang ());
|
||||
|
||||
target_cu = per_objfile->get_cu (per_cu);
|
||||
if (target_cu == nullptr)
|
||||
@ -18667,10 +18569,10 @@ follow_die_offset (const section_and_offset &target, dwarf2_cu **ref_cu)
|
||||
sect_offset_str (sect_off),
|
||||
objfile_name (per_objfile->objfile));
|
||||
}
|
||||
else if (source_cu->dies == NULL)
|
||||
else if (cu->dies == NULL)
|
||||
{
|
||||
/* We're loading full DIEs during partial symbol reading. */
|
||||
load_full_comp_unit (source_cu->per_cu, per_objfile, source_cu, false,
|
||||
load_full_comp_unit (cu->per_cu, per_objfile, cu, false,
|
||||
language_minimal);
|
||||
}
|
||||
|
||||
@ -18689,24 +18591,24 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
|
||||
struct dwarf2_cu **ref_cu)
|
||||
{
|
||||
sect_offset sect_off = attr->get_ref_die_offset ();
|
||||
struct dwarf2_cu *source_cu = *ref_cu;
|
||||
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 != DW_FORM_GNU_ref_alt && src_die->sect_off == sect_off)
|
||||
{
|
||||
/* Self-reference, we're done. */
|
||||
return src_die;
|
||||
}
|
||||
|
||||
const dwarf2_section_info §ion
|
||||
= get_section_for_ref (*attr, source_cu->per_cu);
|
||||
|
||||
die_info *die = follow_die_offset (section, sect_off,
|
||||
ref_cu);
|
||||
if (die == nullptr)
|
||||
die = follow_die_offset (sect_off,
|
||||
(attr->form == DW_FORM_GNU_ref_alt
|
||||
|| cu->per_cu->is_dwz),
|
||||
ref_cu);
|
||||
if (!die)
|
||||
error (_(DWARF_ERROR_PREFIX
|
||||
"Cannot find DIE at %s referenced from DIE at %s [in module %s]"),
|
||||
sect_offset_str (sect_off), sect_offset_str (src_die->sect_off),
|
||||
objfile_name (source_cu->per_objfile->objfile));
|
||||
objfile_name (cu->per_objfile->objfile));
|
||||
|
||||
return die;
|
||||
}
|
||||
@ -18719,6 +18621,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
|
||||
gdb::function_view<CORE_ADDR ()> get_frame_pc,
|
||||
bool resolve_abstract_p)
|
||||
{
|
||||
struct die_info *die;
|
||||
struct attribute *attr;
|
||||
struct dwarf2_locexpr_baton retval;
|
||||
struct objfile *objfile = per_objfile->objfile;
|
||||
@ -18736,8 +18639,8 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
|
||||
sect_offset_str (sect_off), objfile_name (objfile));
|
||||
}
|
||||
|
||||
die_info *die = follow_die_offset (*per_cu->section, sect_off, &cu);
|
||||
if (die == nullptr)
|
||||
die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
|
||||
if (!die)
|
||||
error (_(DWARF_ERROR_PREFIX
|
||||
"Cannot find DIE at %s referenced [in module %s]"),
|
||||
sect_offset_str (sect_off), objfile_name (objfile));
|
||||
@ -18754,7 +18657,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
|
||||
{
|
||||
struct dwarf2_cu *cand_cu = cu;
|
||||
struct die_info *cand
|
||||
= follow_die_offset (*per_cu->section, cand_off, &cand_cu);
|
||||
= follow_die_offset (cand_off, per_cu->is_dwz, &cand_cu);
|
||||
if (!cand
|
||||
|| !cand->parent
|
||||
|| cand->parent->tag != DW_TAG_subprogram)
|
||||
@ -18877,7 +18780,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
|
||||
sect_offset_str (sect_off), objfile_name (objfile));
|
||||
}
|
||||
|
||||
die = follow_die_offset (*per_cu->section, sect_off, &cu);
|
||||
die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
|
||||
if (!die)
|
||||
error (_(DWARF_ERROR_PREFIX
|
||||
"Cannot find DIE at %s referenced [in module %s]"),
|
||||
@ -19003,7 +18906,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
|
||||
if (cu == nullptr)
|
||||
return nullptr;
|
||||
|
||||
die = follow_die_offset (*per_cu->section, sect_off, &cu);
|
||||
die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
|
||||
if (!die)
|
||||
return NULL;
|
||||
|
||||
@ -19759,45 +19662,63 @@ dwarf2_per_cu::ensure_lang (dwarf2_per_objfile *per_objfile)
|
||||
occur in any CU. This is separate so that it can be unit
|
||||
tested. */
|
||||
|
||||
static dwarf2_per_cu *
|
||||
dwarf2_find_containing_unit (section_and_offset const dwarf2_section_info §ion,
|
||||
sect_offset sect_off,
|
||||
const std::vector<dwarf2_per_cu_up> &all_units)
|
||||
static int
|
||||
dwarf2_find_containing_comp_unit
|
||||
(sect_offset sect_off,
|
||||
unsigned int offset_in_dwz,
|
||||
const std::vector<dwarf2_per_cu_up> &all_units)
|
||||
{
|
||||
auto it = std::lower_bound (all_units.begin (), all_units.end (),
|
||||
section_and_offset { §ion, sect_off },
|
||||
[] (const dwarf2_per_cu_up &per_cu,
|
||||
const section_and_offset &key)
|
||||
{
|
||||
return all_units_less_than<true>
|
||||
(*per_cu, key);
|
||||
});
|
||||
int low, high;
|
||||
|
||||
if (it == all_units.begin ())
|
||||
return sect_off >= (*it)->sect_off ? it->get () : nullptr;
|
||||
low = 0;
|
||||
high = all_units.size () - 1;
|
||||
while (high > low)
|
||||
{
|
||||
int mid = low + (high - low) / 2;
|
||||
dwarf2_per_cu *mid_cu = all_units[mid].get ();
|
||||
|
||||
if (it == all_units.end ())
|
||||
return nullptr;
|
||||
|
||||
return it->get ();
|
||||
if (mid_cu->is_dwz > offset_in_dwz
|
||||
|| (mid_cu->is_dwz == offset_in_dwz
|
||||
&& mid_cu->sect_off + mid_cu->length () > sect_off))
|
||||
high = mid;
|
||||
else
|
||||
low = mid + 1;
|
||||
}
|
||||
gdb_assert (low == high);
|
||||
return low;
|
||||
}
|
||||
|
||||
/* See read.h. */
|
||||
|
||||
dwarf2_per_cu *
|
||||
dwarf2_find_containing_unit (section_and_offset const dwarf2_section_info §ion,
|
||||
sect_offset sect_off, dwarf2_per_bfd *per_bfd)
|
||||
dwarf2_find_containing_comp_unit (sect_offset sect_off,
|
||||
unsigned int offset_in_dwz,
|
||||
dwarf2_per_bfd *per_bfd)
|
||||
{
|
||||
dwarf2_per_cu *per_cu
|
||||
= dwarf2_find_containing_unit (section, sect_off, per_bfd->all_units);
|
||||
int low = dwarf2_find_containing_comp_unit
|
||||
(sect_off, offset_in_dwz, per_bfd->all_units);
|
||||
dwarf2_per_cu *this_cu = per_bfd->all_units[low].get ();
|
||||
|
||||
if (per_cu == nullptr)
|
||||
error (_(DWARF_ERROR_PREFIX
|
||||
"could not find compile or type unit containing offset %s "
|
||||
"[in module %s]"),
|
||||
sect_offset_str (sect_off), per_bfd->filename ());
|
||||
if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
|
||||
{
|
||||
if (low == 0 || this_cu->is_dwz != offset_in_dwz)
|
||||
error (_(DWARF_ERROR_PREFIX
|
||||
"could not find CU containing offset %s [in module %s]"),
|
||||
sect_offset_str (sect_off),
|
||||
per_bfd->filename ());
|
||||
|
||||
return per_cu;
|
||||
gdb_assert (per_bfd->all_units[low-1]->sect_off
|
||||
<= sect_off);
|
||||
return per_bfd->all_units[low - 1].get ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (low == per_bfd->all_units.size () - 1
|
||||
&& sect_off >= this_cu->sect_off + this_cu->length ())
|
||||
error (_("invalid dwarf2 offset %s"), sect_offset_str (sect_off));
|
||||
gdb_assert (sect_off < this_cu->sect_off + this_cu->length ());
|
||||
return this_cu;
|
||||
}
|
||||
}
|
||||
|
||||
#if GDB_SELF_TEST
|
||||
@ -19809,36 +19730,31 @@ static void
|
||||
run_test ()
|
||||
{
|
||||
char dummy_per_bfd;
|
||||
auto &main_section = *reinterpret_cast<dwarf2_section_info *> (0x4000);
|
||||
auto &dwz_section = *reinterpret_cast<dwarf2_section_info *>(0x5000);
|
||||
char dummy_section;
|
||||
|
||||
const auto create_dummy_per_cu = [&] (dwarf2_section_info §ion,
|
||||
sect_offset sect_off,
|
||||
const auto create_dummy_per_cu = [&] (sect_offset sect_off,
|
||||
unsigned int length,
|
||||
bool is_dwz)
|
||||
{
|
||||
auto per_bfd = reinterpret_cast<dwarf2_per_bfd *> (&dummy_per_bfd);
|
||||
auto section = reinterpret_cast<dwarf2_section_info *> (&dummy_section);
|
||||
|
||||
return dwarf2_per_cu_up (new dwarf2_per_cu (per_bfd, §ion, sect_off,
|
||||
return dwarf2_per_cu_up (new dwarf2_per_cu (per_bfd, section, sect_off,
|
||||
length, is_dwz));
|
||||
};
|
||||
|
||||
/* Units in the main file. */
|
||||
dwarf2_per_cu_up one
|
||||
= create_dummy_per_cu (main_section, sect_offset (0), 5, false);
|
||||
dwarf2_per_cu_up one = create_dummy_per_cu (sect_offset (0), 5, false);
|
||||
dwarf2_per_cu *one_ptr = one.get ();
|
||||
dwarf2_per_cu_up two
|
||||
= create_dummy_per_cu (main_section, sect_offset (one->length ()), 7,
|
||||
false);
|
||||
= create_dummy_per_cu (sect_offset (one->length ()), 7, false);
|
||||
dwarf2_per_cu *two_ptr = two.get ();
|
||||
|
||||
/* Units in the supplementary (dwz) file. */
|
||||
dwarf2_per_cu_up three
|
||||
= create_dummy_per_cu (dwz_section, sect_offset (0), 5, true);
|
||||
dwarf2_per_cu_up three = create_dummy_per_cu (sect_offset (0), 5, true);
|
||||
dwarf2_per_cu *three_ptr = three.get ();
|
||||
dwarf2_per_cu_up four
|
||||
= create_dummy_per_cu (dwz_section, sect_offset (three->length ()), 7,
|
||||
true);
|
||||
= create_dummy_per_cu (sect_offset (three->length ()), 7, true);
|
||||
dwarf2_per_cu *four_ptr = four.get ();
|
||||
|
||||
std::vector<dwarf2_per_cu_up> units;
|
||||
@ -19847,21 +19763,21 @@ run_test ()
|
||||
units.push_back (std::move (three));
|
||||
units.push_back (std::move (four));
|
||||
|
||||
dwarf2_per_cu *result;
|
||||
int result;
|
||||
|
||||
result = dwarf2_find_containing_unit (main_section, sect_offset (0), units);
|
||||
SELF_CHECK (result == one_ptr);
|
||||
result = dwarf2_find_containing_unit (main_section, sect_offset (3), units);
|
||||
SELF_CHECK (result == one_ptr);
|
||||
result = dwarf2_find_containing_unit (main_section, sect_offset (5), units);
|
||||
SELF_CHECK (result == two_ptr);
|
||||
result = dwarf2_find_containing_comp_unit (sect_offset (0), 0, units);
|
||||
SELF_CHECK (units[result].get () == one_ptr);
|
||||
result = dwarf2_find_containing_comp_unit (sect_offset (3), 0, units);
|
||||
SELF_CHECK (units[result].get () == one_ptr);
|
||||
result = dwarf2_find_containing_comp_unit (sect_offset (5), 0, units);
|
||||
SELF_CHECK (units[result].get () == two_ptr);
|
||||
|
||||
result = dwarf2_find_containing_unit (dwz_section, sect_offset (0), units);
|
||||
SELF_CHECK (result == three_ptr);
|
||||
result = dwarf2_find_containing_unit (dwz_section, sect_offset (3), units);
|
||||
SELF_CHECK (result == three_ptr);
|
||||
result = dwarf2_find_containing_unit (dwz_section, sect_offset (5), units);
|
||||
SELF_CHECK (result == four_ptr);
|
||||
result = dwarf2_find_containing_comp_unit (sect_offset (0), 1, units);
|
||||
SELF_CHECK (units[result].get () == three_ptr);
|
||||
result = dwarf2_find_containing_comp_unit (sect_offset (3), 1, units);
|
||||
SELF_CHECK (units[result].get () == three_ptr);
|
||||
result = dwarf2_find_containing_comp_unit (sect_offset (5), 1, units);
|
||||
SELF_CHECK (units[result].get () == four_ptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ struct tu_stats
|
||||
int nr_symtab_sharers = 0;
|
||||
int nr_stmt_less_type_units = 0;
|
||||
int nr_all_type_units_reallocs = 0;
|
||||
int nr_tus = 0;
|
||||
};
|
||||
|
||||
struct abbrev_table_cache;
|
||||
@ -269,10 +270,10 @@ public:
|
||||
int ref_addr_size () const;
|
||||
|
||||
/* Return length of this CU. */
|
||||
unsigned int length (bool require = true) const
|
||||
unsigned int length () const
|
||||
{
|
||||
/* Make sure it's set already. */
|
||||
gdb_assert (!require || m_length != 0);
|
||||
gdb_assert (m_length != 0);
|
||||
return m_length;
|
||||
}
|
||||
|
||||
@ -494,12 +495,26 @@ struct dwarf2_per_bfd
|
||||
const char *filename () const
|
||||
{ return bfd_get_filename (this->obfd); }
|
||||
|
||||
/* Return the unit given its index. */
|
||||
dwarf2_per_cu *get_unit (int index) const
|
||||
/* Return the CU given its index. */
|
||||
dwarf2_per_cu *get_cu (int index) const
|
||||
{
|
||||
return this->all_units[index].get ();
|
||||
}
|
||||
|
||||
/* Return the CU given its index in the CU table in the index. */
|
||||
dwarf2_per_cu *get_index_cu (int index) const
|
||||
{
|
||||
if (this->all_comp_units_index_cus.empty ())
|
||||
return get_cu (index);
|
||||
|
||||
return this->all_comp_units_index_cus[index];
|
||||
}
|
||||
|
||||
dwarf2_per_cu *get_index_tu (int index) const
|
||||
{
|
||||
return this->all_comp_units_index_tus[index];
|
||||
}
|
||||
|
||||
/* 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,
|
||||
@ -580,12 +595,17 @@ public:
|
||||
|
||||
std::vector<dwarf2_section_info> types;
|
||||
|
||||
/* Table of all the compilation and type units. This is used to locate
|
||||
/* Table of all the compilation units. This is used to locate
|
||||
the target compilation unit of a particular reference. */
|
||||
std::vector<dwarf2_per_cu_up> all_units;
|
||||
|
||||
unsigned int num_comp_units = 0;
|
||||
unsigned int num_type_units = 0;
|
||||
/* The all_units vector contains both CUs and TUs. Provide views on the
|
||||
vector that are limited to either the CU part or the TU part. */
|
||||
gdb::array_view<dwarf2_per_cu_up> all_comp_units;
|
||||
gdb::array_view<dwarf2_per_cu_up> all_type_units;
|
||||
|
||||
std::vector<dwarf2_per_cu *> all_comp_units_index_cus;
|
||||
std::vector<dwarf2_per_cu *> all_comp_units_index_tus;
|
||||
|
||||
/* Table of struct type_unit_group objects.
|
||||
The hash key is the DW_AT_stmt_list value. */
|
||||
@ -671,7 +691,7 @@ public:
|
||||
|
||||
dwarf2_per_cu *operator* () const
|
||||
{
|
||||
return m_per_bfd->get_unit (m_index);
|
||||
return m_per_bfd->get_cu (m_index);
|
||||
}
|
||||
|
||||
bool operator== (const all_units_iterator &other) const
|
||||
@ -1174,7 +1194,7 @@ extern void dw_expand_symtabs_matching_file_matcher
|
||||
extern const char *read_indirect_string_at_offset
|
||||
(dwarf2_per_objfile *per_objfile, LONGEST str_offset);
|
||||
|
||||
/* Finalize the all_units vector. */
|
||||
/* Initialize the views on all_units. */
|
||||
|
||||
extern void finalize_all_units (dwarf2_per_bfd *per_bfd);
|
||||
|
||||
@ -1223,12 +1243,14 @@ extern pc_bounds_kind dwarf2_get_pc_bounds (die_info *die,
|
||||
dwarf2_cu *cu, addrmap_mutable *map,
|
||||
void *datum);
|
||||
|
||||
/* Locate the unit in PER_BFD which contains the DIE at OFFSET. Raises an
|
||||
error on failure. */
|
||||
/* Locate the .debug_info compilation unit from CU's objfile which contains
|
||||
the DIE at OFFSET. Raises an error on failure. */
|
||||
|
||||
extern dwarf2_per_cu *dwarf2_find_containing_unit
|
||||
(const dwarf2_section_info §ion, sect_offset sect_off,
|
||||
dwarf2_per_bfd *per_bfd);
|
||||
extern dwarf2_per_cu *dwarf2_find_containing_comp_unit (sect_offset sect_off,
|
||||
unsigned int
|
||||
offset_in_dwz,
|
||||
dwarf2_per_bfd
|
||||
*per_bfd);
|
||||
|
||||
/* Decode simple location descriptions.
|
||||
|
||||
@ -1271,9 +1293,4 @@ extern int dwarf2_ranges_read (unsigned offset, unrelocated_addr *low_return,
|
||||
extern file_and_directory &find_file_and_directory (die_info *die,
|
||||
dwarf2_cu *cu);
|
||||
|
||||
/* Return the section that ATTR, an attribute with ref form, references. */
|
||||
|
||||
extern dwarf2_section_info &get_section_for_ref (const attribute &attr,
|
||||
dwarf2_per_cu *per_cu);
|
||||
|
||||
#endif /* GDB_DWARF2_READ_H */
|
||||
|
@ -43,8 +43,6 @@
|
||||
the real section this "virtual" section is contained in, and BUFFER,SIZE
|
||||
describe the virtual section. */
|
||||
|
||||
#include "dwarf2/types.h"
|
||||
|
||||
struct dwarf2_section_info
|
||||
{
|
||||
/* Return the name of this section. */
|
||||
@ -127,12 +125,4 @@ struct dwarf2_section_info
|
||||
bool is_virtual;
|
||||
};
|
||||
|
||||
/* A pair-like structure to represent an offset into a section. */
|
||||
|
||||
struct section_and_offset
|
||||
{
|
||||
const dwarf2_section_info *section;
|
||||
sect_offset offset;
|
||||
};
|
||||
|
||||
#endif /* GDB_DWARF2_SECTION_H */
|
||||
|
@ -124,16 +124,3 @@ dwarf_unit_type_name (int unit_type)
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/* See stringify.h. */
|
||||
|
||||
const char *
|
||||
dwarf_source_language_name (unsigned int lang)
|
||||
{
|
||||
const char *name = get_DW_LANG_name (lang);
|
||||
|
||||
if (name == nullptr)
|
||||
return dwarf_unknown ("LANG", lang);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
@ -38,7 +38,4 @@ extern const char *dwarf_type_encoding_name (unsigned enc);
|
||||
/* Convert a DWARF unit type into its string name. */
|
||||
extern const char *dwarf_unit_type_name (int unit_type);
|
||||
|
||||
/* Convert a DWARF language into its string name. */
|
||||
extern const char *dwarf_source_language_name (unsigned int lang);
|
||||
|
||||
#endif /* GDB_DWARF2_STRINGIFY_H */
|
||||
|
@ -205,8 +205,8 @@ set re \
|
||||
"( Number of \"partial\" symbols read: $decimal" \
|
||||
")?( Number of psym tables \\(not yet expanded\\): $decimal" \
|
||||
")?( Total memory used for psymbol cache: $decimal" \
|
||||
")?( Number of read units: $decimal" \
|
||||
" Number of unread units: $decimal" \
|
||||
")?( Number of read CUs: $decimal" \
|
||||
" Number of unread CUs: $decimal" \
|
||||
")? Total memory used for objfile obstack: $decimal" \
|
||||
" Total memory used for BFD obstack: $decimal" \
|
||||
" Total memory used for string cache: $decimal" \
|
||||
|
@ -1,108 +0,0 @@
|
||||
# Copyright 2025 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This is a reproducer for PR 29518:
|
||||
#
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=29518
|
||||
#
|
||||
# The root cause for the problem was that function
|
||||
# dwarf2_find_containing_comp_unit was searching the whole "all_units" vector,
|
||||
# containing both compile units and type units, causing it to sometimes
|
||||
# erroneously return a type unit. It should have been restricted to searching
|
||||
# compile units.
|
||||
#
|
||||
# To get dwarf2_find_containing_comp_unit to be called and reproduce the
|
||||
# original bug, we need a value with form DW_FORM_ref_addr pointing to a
|
||||
# different compile unit. This is produced by `%$int_type` below.
|
||||
#
|
||||
# We need enough type units in the "all_units" vector trick the binary search
|
||||
# in dwarf2_find_containing_comp_unit in returning a type unit instead of a
|
||||
# compile unit.
|
||||
#
|
||||
# Finally, since the type units are sorted after the compile units in the
|
||||
# "all_units" vector, it helps to have the target compile unit have a section
|
||||
# offset larger than the type unit. This makes the binary search go towards
|
||||
# the end of the vector, where type units are located.
|
||||
|
||||
load_lib dwarf.exp
|
||||
require dwarf2_support
|
||||
standard_testfile main.c .S
|
||||
|
||||
set asm_file [standard_output_file $srcfile2]
|
||||
|
||||
Dwarf::assemble $asm_file {
|
||||
global srcfile
|
||||
declare_labels int_type
|
||||
|
||||
# The source CU.
|
||||
cu {version 5} {
|
||||
compile_unit {
|
||||
} {
|
||||
subprogram {
|
||||
{MACRO_AT_func {main}}
|
||||
{type %$int_type}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create many TUs.
|
||||
for {set i 1} {$i < 20} {incr i} {
|
||||
tu {version 5} $i the_type_i {
|
||||
type_unit {} {
|
||||
declare_labels dummy_int_type
|
||||
|
||||
the_type_i: structure_type {
|
||||
{name s}
|
||||
{byte_size 4 sdata}
|
||||
} {
|
||||
member {
|
||||
{name i}
|
||||
{type :$dummy_int_type}
|
||||
}
|
||||
}
|
||||
|
||||
dummy_int_type: base_type {
|
||||
{name int}
|
||||
{encoding @DW_ATE_signed}
|
||||
{byte_size 4 sdata}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# The target CU.
|
||||
cu {version 5} {
|
||||
compile_unit {
|
||||
} {
|
||||
int_type: DW_TAG_base_type {
|
||||
{DW_AT_byte_size 4 DW_FORM_sdata}
|
||||
{DW_AT_encoding @DW_ATE_signed}
|
||||
{DW_AT_name int}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if { [prepare_for_testing "failed to prepare" ${testfile} \
|
||||
[list $srcfile $asm_file] {nodebug}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Without the corresponding fix, we get:
|
||||
#
|
||||
# (gdb) p main
|
||||
# invalid dwarf2 offset 0x398
|
||||
#
|
||||
gdb_test "p main" " = {int \\(void\\)} $hex <main>"
|
@ -348,6 +348,6 @@ if ![runto_main] {
|
||||
}
|
||||
gdb_test "print badval" "value has been optimized out"
|
||||
gdb_test "print bad_die_val1" \
|
||||
{DWARF Error: could not find compile or type unit containing offset 0xabcdef11 \[in module .*/varval\]}
|
||||
"invalid dwarf2 offset 0xabcdef11"
|
||||
gdb_test "print bad_die_val2" \
|
||||
"Bad DW_OP_GNU_variable_value DIE\\."
|
||||
|
@ -827,92 +827,3 @@ DW_UT (DW_UT_split_type, 0x06)
|
||||
DW_UT (DW_UT_lo_user, 0x80)
|
||||
DW_UT (DW_UT_hi_user, 0xff)
|
||||
DW_END_UT
|
||||
|
||||
DW_FIRST_LANG (DW_LANG_C89, 0x0001)
|
||||
DW_LANG (DW_LANG_C, 0x0002)
|
||||
DW_LANG (DW_LANG_Ada83, 0x0003)
|
||||
DW_LANG (DW_LANG_C_plus_plus, 0x0004)
|
||||
DW_LANG (DW_LANG_Cobol74, 0x0005)
|
||||
DW_LANG (DW_LANG_Cobol85, 0x0006)
|
||||
DW_LANG (DW_LANG_Fortran77, 0x0007)
|
||||
DW_LANG (DW_LANG_Fortran90, 0x0008)
|
||||
DW_LANG (DW_LANG_Pascal83, 0x0009)
|
||||
DW_LANG (DW_LANG_Modula2, 0x000a)
|
||||
/* DWARF 3. */
|
||||
DW_LANG (DW_LANG_Java, 0x000b)
|
||||
DW_LANG (DW_LANG_C99, 0x000c)
|
||||
DW_LANG (DW_LANG_Ada95, 0x000d)
|
||||
DW_LANG (DW_LANG_Fortran95, 0x000e)
|
||||
DW_LANG (DW_LANG_PLI, 0x000f)
|
||||
DW_LANG (DW_LANG_ObjC, 0x0010)
|
||||
DW_LANG (DW_LANG_ObjC_plus_plus, 0x0011)
|
||||
DW_LANG (DW_LANG_UPC, 0x0012)
|
||||
DW_LANG (DW_LANG_D, 0x0013)
|
||||
/* DWARF 4. */
|
||||
DW_LANG (DW_LANG_Python, 0x0014)
|
||||
/* DWARF 5. */
|
||||
DW_LANG (DW_LANG_OpenCL, 0x0015)
|
||||
DW_LANG (DW_LANG_Go, 0x0016)
|
||||
DW_LANG (DW_LANG_Modula3, 0x0017)
|
||||
DW_LANG (DW_LANG_Haskell, 0x0018)
|
||||
DW_LANG (DW_LANG_C_plus_plus_03, 0x0019)
|
||||
DW_LANG (DW_LANG_C_plus_plus_11, 0x001a)
|
||||
DW_LANG (DW_LANG_OCaml, 0x001b)
|
||||
DW_LANG (DW_LANG_Rust, 0x001c)
|
||||
DW_LANG (DW_LANG_C11, 0x001d)
|
||||
DW_LANG (DW_LANG_Swift, 0x001e)
|
||||
DW_LANG (DW_LANG_Julia, 0x001f)
|
||||
DW_LANG (DW_LANG_Dylan, 0x0020)
|
||||
DW_LANG (DW_LANG_C_plus_plus_14, 0x0021)
|
||||
DW_LANG (DW_LANG_Fortran03, 0x0022)
|
||||
DW_LANG (DW_LANG_Fortran08, 0x0023)
|
||||
DW_LANG (DW_LANG_RenderScript, 0x0024)
|
||||
DW_LANG (DW_LANG_BLISS, 0x0025)
|
||||
/* Post DWARF 5 additions to the DWARF set.
|
||||
See https://dwarfstd.org/languages.html . */
|
||||
DW_LANG (DW_LANG_Kotlin, 0x0026)
|
||||
DW_LANG (DW_LANG_Zig, 0x0027)
|
||||
DW_LANG (DW_LANG_Crystal, 0x0028)
|
||||
DW_LANG (DW_LANG_C_plus_plus_17, 0x002a)
|
||||
DW_LANG (DW_LANG_C_plus_plus_20, 0x002b)
|
||||
DW_LANG (DW_LANG_C17, 0x002c)
|
||||
DW_LANG (DW_LANG_Fortran18, 0x002d)
|
||||
DW_LANG (DW_LANG_Ada2005, 0x002e)
|
||||
DW_LANG (DW_LANG_Ada2012, 0x002f)
|
||||
DW_LANG (DW_LANG_HIP, 0x0030)
|
||||
DW_LANG (DW_LANG_Assembly, 0x0031)
|
||||
DW_LANG (DW_LANG_C_sharp, 0x0032)
|
||||
DW_LANG (DW_LANG_Mojo, 0x0033)
|
||||
DW_LANG (DW_LANG_GLSL, 0x0034)
|
||||
DW_LANG (DW_LANG_GLSL_ES, 0x0035)
|
||||
DW_LANG (DW_LANG_HLSL, 0x0036)
|
||||
DW_LANG (DW_LANG_OpenCL_CPP, 0x0037)
|
||||
DW_LANG (DW_LANG_CPP_for_OpenCL, 0x0038)
|
||||
DW_LANG (DW_LANG_SYCL, 0x0039)
|
||||
DW_LANG (DW_LANG_C_plus_plus_23, 0x003a)
|
||||
DW_LANG (DW_LANG_Odin, 0x003b)
|
||||
DW_LANG (DW_LANG_P4, 0x003c)
|
||||
DW_LANG (DW_LANG_Metal, 0x003d)
|
||||
DW_LANG (DW_LANG_C23, 0x003e)
|
||||
DW_LANG (DW_LANG_Fortran23, 0x003f)
|
||||
DW_LANG (DW_LANG_Ruby, 0x0040)
|
||||
DW_LANG (DW_LANG_Move, 0x0041)
|
||||
DW_LANG (DW_LANG_Hylo, 0x0042)
|
||||
|
||||
DW_LANG (DW_LANG_lo_user, 0x8000) /* Implementation-defined range start. */
|
||||
DW_LANG (DW_LANG_hi_user, 0xffff) /* Implementation-defined range start. */
|
||||
|
||||
/* MIPS. */
|
||||
DW_LANG (DW_LANG_Mips_Assembler, 0x8001)
|
||||
/* UPC. */
|
||||
DW_LANG (DW_LANG_Upc, 0x8765)
|
||||
/* HP extensions. */
|
||||
DW_LANG (DW_LANG_HP_Bliss, 0x8003)
|
||||
DW_LANG (DW_LANG_HP_Basic91, 0x8004)
|
||||
DW_LANG (DW_LANG_HP_Pascal91, 0x8005)
|
||||
DW_LANG (DW_LANG_HP_IMacro, 0x8006)
|
||||
DW_LANG (DW_LANG_HP_Assembler, 0x8007)
|
||||
|
||||
/* Rust extension, but replaced in DWARF 5. */
|
||||
DW_LANG (DW_LANG_Rust_old, 0x9000)
|
||||
DW_END_LANG
|
||||
|
103
include/dwarf2.h
103
include/dwarf2.h
@ -56,7 +56,6 @@
|
||||
#define DW_IDX(name, value) , name = value
|
||||
#define DW_IDX_DUP(name, value) , name = value
|
||||
#define DW_UT(name, value) , name = value
|
||||
#define DW_LANG(name, value) , name = value
|
||||
|
||||
#define DW_FIRST_TAG(name, value) enum dwarf_tag { \
|
||||
name = value
|
||||
@ -87,9 +86,6 @@
|
||||
#define DW_FIRST_UT(name, value) enum dwarf_unit_type { \
|
||||
name = value
|
||||
#define DW_END_UT };
|
||||
#define DW_FIRST_LANG(name, value) enum dwarf_source_language { \
|
||||
name = value
|
||||
#define DW_END_LANG };
|
||||
|
||||
#include "dwarf2.def"
|
||||
|
||||
@ -109,8 +105,6 @@
|
||||
#undef DW_END_IDX
|
||||
#undef DW_FIRST_UT
|
||||
#undef DW_END_UT
|
||||
#undef DW_FIRST_LANG
|
||||
#undef DW_END_LANG
|
||||
|
||||
#undef DW_TAG
|
||||
#undef DW_TAG_DUP
|
||||
@ -126,7 +120,6 @@
|
||||
#undef DW_IDX
|
||||
#undef DW_IDX_DUP
|
||||
#undef DW_UT
|
||||
#undef DW_LANG
|
||||
|
||||
/* Flag that tells whether entry has a child or not. */
|
||||
#define DW_children_no 0
|
||||
@ -343,6 +336,98 @@ enum dwarf_location_list_entry_type
|
||||
|
||||
#define DW_ADDR_none 0
|
||||
|
||||
/* Source language names and codes. */
|
||||
enum dwarf_source_language
|
||||
{
|
||||
DW_LANG_C89 = 0x0001,
|
||||
DW_LANG_C = 0x0002,
|
||||
DW_LANG_Ada83 = 0x0003,
|
||||
DW_LANG_C_plus_plus = 0x0004,
|
||||
DW_LANG_Cobol74 = 0x0005,
|
||||
DW_LANG_Cobol85 = 0x0006,
|
||||
DW_LANG_Fortran77 = 0x0007,
|
||||
DW_LANG_Fortran90 = 0x0008,
|
||||
DW_LANG_Pascal83 = 0x0009,
|
||||
DW_LANG_Modula2 = 0x000a,
|
||||
/* DWARF 3. */
|
||||
DW_LANG_Java = 0x000b,
|
||||
DW_LANG_C99 = 0x000c,
|
||||
DW_LANG_Ada95 = 0x000d,
|
||||
DW_LANG_Fortran95 = 0x000e,
|
||||
DW_LANG_PLI = 0x000f,
|
||||
DW_LANG_ObjC = 0x0010,
|
||||
DW_LANG_ObjC_plus_plus = 0x0011,
|
||||
DW_LANG_UPC = 0x0012,
|
||||
DW_LANG_D = 0x0013,
|
||||
/* DWARF 4. */
|
||||
DW_LANG_Python = 0x0014,
|
||||
/* DWARF 5. */
|
||||
DW_LANG_OpenCL = 0x0015,
|
||||
DW_LANG_Go = 0x0016,
|
||||
DW_LANG_Modula3 = 0x0017,
|
||||
DW_LANG_Haskell = 0x0018,
|
||||
DW_LANG_C_plus_plus_03 = 0x0019,
|
||||
DW_LANG_C_plus_plus_11 = 0x001a,
|
||||
DW_LANG_OCaml = 0x001b,
|
||||
DW_LANG_Rust = 0x001c,
|
||||
DW_LANG_C11 = 0x001d,
|
||||
DW_LANG_Swift = 0x001e,
|
||||
DW_LANG_Julia = 0x001f,
|
||||
DW_LANG_Dylan = 0x0020,
|
||||
DW_LANG_C_plus_plus_14 = 0x0021,
|
||||
DW_LANG_Fortran03 = 0x0022,
|
||||
DW_LANG_Fortran08 = 0x0023,
|
||||
DW_LANG_RenderScript = 0x0024,
|
||||
DW_LANG_BLISS = 0x0025,
|
||||
/* Post DWARF 5 additions to the DWARF set.
|
||||
See https://dwarfstd.org/languages.html . */
|
||||
DW_LANG_Kotlin = 0x0026,
|
||||
DW_LANG_Zig = 0x0027,
|
||||
DW_LANG_Crystal = 0x0028,
|
||||
DW_LANG_C_plus_plus_17 = 0x002a,
|
||||
DW_LANG_C_plus_plus_20 = 0x002b,
|
||||
DW_LANG_C17 = 0x002c,
|
||||
DW_LANG_Fortran18 = 0x002d,
|
||||
DW_LANG_Ada2005 = 0x002e,
|
||||
DW_LANG_Ada2012 = 0x002f,
|
||||
DW_LANG_HIP = 0x0030,
|
||||
DW_LANG_Assembly = 0x0031,
|
||||
DW_LANG_C_sharp = 0x0032,
|
||||
DW_LANG_Mojo = 0x0033,
|
||||
DW_LANG_GLSL = 0x0034,
|
||||
DW_LANG_GLSL_ES = 0x0035,
|
||||
DW_LANG_HLSL = 0x0036,
|
||||
DW_LANG_OpenCL_CPP = 0x0037,
|
||||
DW_LANG_CPP_for_OpenCL = 0x0038,
|
||||
DW_LANG_SYCL = 0x0039,
|
||||
DW_LANG_C_plus_plus_23 = 0x003a,
|
||||
DW_LANG_Odin = 0x003b,
|
||||
DW_LANG_P4 = 0x003c,
|
||||
DW_LANG_Metal = 0x003d,
|
||||
DW_LANG_C23 = 0x003e,
|
||||
DW_LANG_Fortran23 = 0x003f,
|
||||
DW_LANG_Ruby = 0x0040,
|
||||
DW_LANG_Move = 0x0041,
|
||||
DW_LANG_Hylo = 0x0042,
|
||||
|
||||
DW_LANG_lo_user = 0x8000, /* Implementation-defined range start. */
|
||||
DW_LANG_hi_user = 0xffff, /* Implementation-defined range start. */
|
||||
|
||||
/* MIPS. */
|
||||
DW_LANG_Mips_Assembler = 0x8001,
|
||||
/* UPC. */
|
||||
DW_LANG_Upc = 0x8765,
|
||||
/* HP extensions. */
|
||||
DW_LANG_HP_Bliss = 0x8003,
|
||||
DW_LANG_HP_Basic91 = 0x8004,
|
||||
DW_LANG_HP_Pascal91 = 0x8005,
|
||||
DW_LANG_HP_IMacro = 0x8006,
|
||||
DW_LANG_HP_Assembler = 0x8007,
|
||||
|
||||
/* Rust extension, but replaced in DWARF 5. */
|
||||
DW_LANG_Rust_old = 0x9000
|
||||
};
|
||||
|
||||
/* Names and codes for macro information. */
|
||||
enum dwarf_macinfo_record_type
|
||||
{
|
||||
@ -500,10 +585,6 @@ extern const char *get_DW_IDX_name (unsigned int idx);
|
||||
recognized. */
|
||||
extern const char *get_DW_UT_name (unsigned int ut);
|
||||
|
||||
/* Return the name of a DW_LANG_ constant, or NULL if the value is not
|
||||
recognized. */
|
||||
extern const char *get_DW_LANG_name (unsigned int lang);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
@ -69,11 +69,6 @@ Boston, MA 02110-1301, USA. */
|
||||
switch (ut) { \
|
||||
DW_UT (name, value)
|
||||
#define DW_END_UT } return 0; }
|
||||
#define DW_FIRST_LANG(name, value) \
|
||||
const char *get_DW_LANG_name (unsigned int lang) { \
|
||||
switch (lang) { \
|
||||
DW_LANG (name, value)
|
||||
#define DW_END_LANG } return 0; }
|
||||
|
||||
#define DW_TAG(name, value) case name: return # name ;
|
||||
#define DW_TAG_DUP(name, value)
|
||||
@ -89,7 +84,6 @@ Boston, MA 02110-1301, USA. */
|
||||
#define DW_IDX(name, value) case name: return # name ;
|
||||
#define DW_IDX_DUP(name, value)
|
||||
#define DW_UT(name, value) case name: return # name ;
|
||||
#define DW_LANG(name, value) case name: return # name ;
|
||||
|
||||
#include "dwarf2.def"
|
||||
|
||||
@ -108,8 +102,6 @@ Boston, MA 02110-1301, USA. */
|
||||
#undef DW_FIRST_IDX
|
||||
#undef DW_END_IDX
|
||||
#undef DW_END_UT
|
||||
#undef DW_FIRST_LANG
|
||||
#undef DW_END_LANG
|
||||
|
||||
#undef DW_TAG
|
||||
#undef DW_TAG_DUP
|
||||
@ -124,4 +116,3 @@ Boston, MA 02110-1301, USA. */
|
||||
#undef DW_CFA_DUP
|
||||
#undef DW_IDX
|
||||
#undef DW_IDX_DUP
|
||||
#undef DW_LANG
|
||||
|
Loading…
x
Reference in New Issue
Block a user