diff options
Diffstat (limited to 'gdb/dwarf2/read-debug-names.c')
-rw-r--r-- | gdb/dwarf2/read-debug-names.c | 221 |
1 files changed, 105 insertions, 116 deletions
diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c index edac713..97677c0 100644 --- a/gdb/dwarf2/read-debug-names.c +++ b/gdb/dwarf2/read-debug-names.c @@ -1,6 +1,6 @@ /* Reading code for .debug_names - Copyright (C) 2023-2024 Free Software Foundation, Inc. + Copyright (C) 2023-2025 Free Software Foundation, Inc. This file is part of GDB. @@ -114,11 +114,20 @@ struct mapped_debug_names_reader gdb::unordered_map<ULONGEST, index_val> abbrev_map; - /* 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 - robin fashion. */ - std::vector<cooked_index_shard_up> shards; + /* 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 robin fashion. It's convenient to use a + result object rather than an actual shard. */ + std::vector<cooked_index_worker_result> indices; /* Next shard to insert an entry in. */ int next_shard = 0; @@ -231,7 +240,7 @@ mapped_debug_names_reader::scan_one_entry (const char *name, case DW_IDX_compile_unit: { /* Don't crash on bad data. */ - if (ull >= per_objfile->per_bfd->all_comp_units.size ()) + if (ull >= this->comp_units.size ()) { complaint (_(".debug_names entry has bad CU index %s" " [in module %s]"), @@ -239,30 +248,31 @@ 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; - } { - int nr_cus = per_objfile->per_bfd->all_comp_units.size (); - per_cu = per_objfile->per_bfd->get_cu (nr_cus + ull); + /* 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; } - 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 == NULL) - per_cu = per_objfile->per_bfd->get_cu (0); + if (per_cu == nullptr) + per_cu = this->comp_units[0]; break; case DW_IDX_parent: parent = ull; @@ -290,11 +300,11 @@ mapped_debug_names_reader::scan_one_entry (const char *name, if (per_cu != nullptr) { *result - = shards[next_shard]->add (die_offset, (dwarf_tag) indexval.dwarf_tag, + = indices[next_shard].add (die_offset, (dwarf_tag) indexval.dwarf_tag, flags, lang, name, nullptr, per_cu); ++next_shard; - if (next_shard == shards.size ()) + if (next_shard == indices.size ()) next_shard = 0; entry_pool_offsets_to_entries.emplace (offset_in_entry_pool, *result); @@ -414,72 +424,70 @@ void cooked_index_worker_debug_names::do_reading () { complaint_interceptor complaint_handler; - std::vector<gdb_exception> exceptions; - try + + /* Arbitrarily put all exceptions into the first result. */ + m_map.indices[0].catch_error ([&] () { m_map.scan_all_names (); - } - catch (const gdb_exception &exc) + }); + + bool first = true; + for (auto &iter : m_map.indices) { - exceptions.push_back (std::move (exc)); + if (first) + { + iter.done_reading (complaint_handler.release ()); + first = false; + } + else + iter.done_reading ({}); } - m_results.emplace_back (nullptr, - complaint_handler.release (), - std::move (exceptions), - parent_map ()); - - dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd; - cooked_index *table - = (gdb::checked_static_cast<cooked_index *> - (per_bfd->index_table.get ())); - - /* Note that this code never uses IS_PARENT_DEFERRED, so it is safe - to pass nullptr here. */ - table->set_contents (std::move (m_map.shards), &m_warnings, nullptr); + m_results = std::move (m_map.indices); + done_reading (); bfd_thread_cleanup (); } -/* Check the signatured type hash table from .debug_names. */ +/* 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. */ static bool -check_signatured_type_table_from_debug_names - (dwarf2_per_objfile *per_objfile, - const mapped_debug_names_reader &map, - struct dwarf2_section_info *section) +build_and_check_tu_list_from_debug_names (dwarf2_per_objfile *per_objfile, + mapped_debug_names_reader &map, + 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)); - bool found = false; - for (; j < nr_cus_tus; j++) - if (per_bfd->get_cu (j)->sect_off == sect_off) - { - found = true; - break; - } - if (!found) + /* Find the matching dwarf2_per_cu. */ + dwarf2_per_cu *per_cu = dwarf2_find_unit ({ section, sect_off }, + per_bfd); + + if (per_cu == nullptr || !per_cu->is_debug_types) { warning (_("Section .debug_names has incorrect entry in TU table," " ignoring .debug_names.")); return false; } - per_bfd->all_comp_units_index_tus.push_back (per_bfd->get_cu (j)); + + map.type_units.emplace_back (per_cu); } + return true; } @@ -701,40 +709,11 @@ read_debug_names_from_section (dwarf2_per_objfile *per_objfile, list. */ static bool -check_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd, - const mapped_debug_names_reader &map, - dwarf2_section_info §ion, - bool is_dwz) +build_and_check_cu_list_from_debug_names (dwarf2_per_bfd *per_bfd, + mapped_debug_names_reader &map, + dwarf2_section_info §ion) { - 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; - } + int nr_cus = per_bfd->num_comp_units; if (map.cu_count != nr_cus) { @@ -750,35 +729,43 @@ check_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd, (map.cu_table_reordered + i * map.offset_size, map.offset_size, map.dwarf5_byte_order)); - if (sect_off != per_bfd->get_cu (i)->sect_off) + + /* Find the matching dwarf2_per_cu. */ + dwarf2_per_cu *per_cu = dwarf2_find_unit ({ §ion, sect_off }, per_bfd); + + if (per_cu == nullptr || per_cu->is_debug_types) { warning (_("Section .debug_names has incorrect entry in CU table," " ignoring .debug_names.")); return false; } + + map.comp_units.emplace_back (per_cu); } return true; } -/* Read the CU list from the mapped index, and use it to create all - the CU objects for this dwarf2_per_objfile. */ +/* 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. */ static bool -check_cus_from_debug_names (dwarf2_per_bfd *per_bfd, - const mapped_debug_names_reader &map, - const mapped_debug_names_reader &dwz_map) +build_and_check_cu_lists_from_debug_names (dwarf2_per_bfd *per_bfd, + mapped_debug_names_reader &map, + mapped_debug_names_reader &dwz_map) { - if (!check_cus_from_debug_names_list (per_bfd, map, per_bfd->infos[0], - false /* is_dwz */)) + if (!build_and_check_cu_list_from_debug_names (per_bfd, map, + per_bfd->infos[0])) return false; if (dwz_map.cu_count == 0) return true; dwz_file *dwz = per_bfd->get_dwz_file (); - return check_cus_from_debug_names_list (per_bfd, dwz_map, dwz->info, - true /* is_dwz */); + return build_and_check_cu_list_from_debug_names (per_bfd, dwz_map, dwz->info); } /* This does all the work for dwarf2_read_debug_names, but putting it @@ -816,7 +803,7 @@ do_dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile) } create_all_units (per_objfile); - if (!check_cus_from_debug_names (per_bfd, map, dwz_map)) + if (!build_and_check_cu_lists_from_debug_names (per_bfd, map, dwz_map)) return false; if (map.tu_count != 0) @@ -832,30 +819,32 @@ do_dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile) ? &per_bfd->types[0] : &per_bfd->infos[0]); - if (!check_signatured_type_table_from_debug_names (per_objfile, - map, section)) + if (!build_and_check_tu_list_from_debug_names (per_objfile, map, + section)) return false; } per_bfd->debug_aranges.read (per_objfile->objfile); - addrmap_mutable addrmap; + + /* There is a single address map for the whole index (coming from + .debug_aranges). We only need to install it into a single shard + for it to get searched by cooked_index. So, we make the first + result object here, so we can store the addrmap, then move it + into place later. */ + cooked_index_worker_result first; deferred_warnings warnings; read_addrmap_from_aranges (per_objfile, &per_bfd->debug_aranges, - &addrmap, &warnings); + first.get_addrmap (), &warnings); warnings.emit (); const auto n_workers = std::max<std::size_t> (gdb::thread_pool::g_thread_pool->thread_count (), 1); - /* Create as many index shard as there are worker threads. */ - for (int i = 0; i < n_workers; ++i) - map.shards.emplace_back (std::make_unique<cooked_index_shard> ()); - - /* There is a single address map for the whole index (coming from - .debug_aranges). We only need to install it into a single shard for it to - get searched by cooked_index. */ - map.shards[0]->install_addrmap (&addrmap); + /* Create as many index shard as there are worker threads, + preserving the first one. */ + map.indices.push_back (std::move (first)); + map.indices.resize (n_workers); auto cidn = (std::make_unique<cooked_index_worker_debug_names> (per_objfile, std::move (map))); |