+ for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ {
+ int j;
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+ struct quick_file_names *file_data;
+ void **slot;
+
+ QUIT;
+
+ per_cu->v.quick->mark = 0;
+
+ /* We only need to look at symtabs not already expanded. */
+ if (per_cu->v.quick->compunit_symtab)
+ continue;
+
+ file_data = dw2_get_file_names (per_cu);
+ if (file_data == NULL)
+ continue;
+
+ if (htab_find (visited_not_found.get (), file_data) != NULL)
+ continue;
+ else if (htab_find (visited_found.get (), file_data) != NULL)
+ {
+ per_cu->v.quick->mark = 1;
+ continue;
+ }
+
+ for (j = 0; j < file_data->num_file_names; ++j)
+ {
+ const char *this_real_name;
+
+ if (file_matcher (file_data->file_names[j], false))
+ {
+ per_cu->v.quick->mark = 1;
+ break;
+ }
+
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (!basenames_may_differ
+ && !file_matcher (lbasename (file_data->file_names[j]),
+ true))
+ continue;
+
+ this_real_name = dw2_get_real_path (objfile, file_data, j);
+ if (file_matcher (this_real_name, false))
+ {
+ per_cu->v.quick->mark = 1;
+ break;
+ }
+ }
+
+ slot = htab_find_slot (per_cu->v.quick->mark
+ ? visited_found.get ()
+ : visited_not_found.get (),
+ file_data, INSERT);
+ *slot = file_data;
+ }
+}
+
+static void
+dw2_expand_symtabs_matching
+ (struct objfile *objfile,
+ gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+ const lookup_name_info &lookup_name,
+ gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+ gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ enum search_domain kind)
+{
+ int i;
+
+ dw2_setup (objfile);
+
+ /* index_table is NULL if OBJF_READNOW. */
+ if (!dwarf2_per_objfile->index_table)
+ return;
+
+ dw_expand_symtabs_matching_file_matcher (file_matcher);
+
+ mapped_index &index = *dwarf2_per_objfile->index_table;
+
+ dw2_expand_symtabs_matching_symbol (index, lookup_name,
+ symbol_matcher,
+ kind, [&] (offset_type idx)
+ {
+ dw2_expand_marked_cus (index, idx, objfile, file_matcher,
+ expansion_notify, kind);
+ });
+}
+
+/* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
+ symtab. */
+
+static struct compunit_symtab *
+recursively_find_pc_sect_compunit_symtab (struct compunit_symtab *cust,
+ CORE_ADDR pc)
+{
+ int i;
+
+ if (COMPUNIT_BLOCKVECTOR (cust) != NULL
+ && blockvector_contains_pc (COMPUNIT_BLOCKVECTOR (cust), pc))
+ return cust;
+
+ if (cust->includes == NULL)
+ return NULL;
+
+ for (i = 0; cust->includes[i]; ++i)
+ {
+ struct compunit_symtab *s = cust->includes[i];
+
+ s = recursively_find_pc_sect_compunit_symtab (s, pc);
+ if (s != NULL)
+ return s;
+ }
+
+ return NULL;
+}
+
+static struct compunit_symtab *
+dw2_find_pc_sect_compunit_symtab (struct objfile *objfile,
+ struct bound_minimal_symbol msymbol,
+ CORE_ADDR pc,
+ struct obj_section *section,
+ int warn_if_readin)
+{
+ struct dwarf2_per_cu_data *data;
+ struct compunit_symtab *result;
+
+ dw2_setup (objfile);
+
+ if (!objfile->psymtabs_addrmap)
+ return NULL;
+
+ data = (struct dwarf2_per_cu_data *) addrmap_find (objfile->psymtabs_addrmap,
+ pc);
+ if (!data)
+ return NULL;
+
+ if (warn_if_readin && data->v.quick->compunit_symtab)
+ warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
+ paddress (get_objfile_arch (objfile), pc));
+
+ result
+ = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data),
+ pc);
+ gdb_assert (result != NULL);
+ return result;
+}
+
+static void
+dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
+ void *data, int need_fullname)
+{
+ dw2_setup (objfile);
+
+ if (!dwarf2_per_objfile->filenames_cache)
+ {
+ dwarf2_per_objfile->filenames_cache.emplace ();
+
+ htab_up visited (htab_create_alloc (10,
+ htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree));
+
+ /* The rule is CUs specify all the files, including those used
+ by any TU, so there's no need to scan TUs here. We can
+ ignore file names coming from already-expanded CUs. */
+
+ for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ {
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+
+ if (per_cu->v.quick->compunit_symtab)
+ {
+ void **slot = htab_find_slot (visited.get (),
+ per_cu->v.quick->file_names,
+ INSERT);
+
+ *slot = per_cu->v.quick->file_names;
+ }
+ }
+
+ for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ {
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+ struct quick_file_names *file_data;
+ void **slot;
+
+ /* We only need to look at symtabs not already expanded. */
+ if (per_cu->v.quick->compunit_symtab)
+ continue;
+
+ file_data = dw2_get_file_names (per_cu);
+ if (file_data == NULL)
+ continue;
+
+ slot = htab_find_slot (visited.get (), file_data, INSERT);
+ if (*slot)
+ {
+ /* Already visited. */
+ continue;
+ }
+ *slot = file_data;
+
+ for (int j = 0; j < file_data->num_file_names; ++j)
+ {
+ const char *filename = file_data->file_names[j];
+ dwarf2_per_objfile->filenames_cache->seen (filename);
+ }
+ }
+ }
+
+ dwarf2_per_objfile->filenames_cache->traverse ([&] (const char *filename)
+ {
+ gdb::unique_xmalloc_ptr<char> this_real_name;
+
+ if (need_fullname)
+ this_real_name = gdb_realpath (filename);
+ (*fun) (filename, this_real_name.get (), data);
+ });
+}
+
+static int
+dw2_has_symbols (struct objfile *objfile)
+{
+ return 1;
+}
+
+const struct quick_symbol_functions dwarf2_gdb_index_functions =
+{
+ dw2_has_symbols,
+ dw2_find_last_source_symtab,
+ dw2_forget_cached_source_info,
+ dw2_map_symtabs_matching_filename,
+ dw2_lookup_symbol,
+ dw2_print_stats,
+ dw2_dump,
+ dw2_relocate,
+ dw2_expand_symtabs_for_function,
+ dw2_expand_all_symtabs,
+ dw2_expand_symtabs_with_fullname,
+ dw2_map_matching_symbols,
+ dw2_expand_symtabs_matching,
+ dw2_find_pc_sect_compunit_symtab,
+ NULL,
+ dw2_map_symbol_filenames
+};
+
+/* DWARF-5 debug_names reader. */
+
+/* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension. */
+static const gdb_byte dwarf5_augmentation[] = { 'G', 'D', 'B', 0 };
+
+/* A helper function that reads the .debug_names section in SECTION
+ and fills in MAP. FILENAME is the name of the file containing the
+ section; it is used for error reporting.
+
+ Returns true if all went well, false otherwise. */
+
+static bool
+read_debug_names_from_section (struct objfile *objfile,
+ const char *filename,
+ struct dwarf2_section_info *section,
+ mapped_debug_names &map)
+{
+ if (dwarf2_section_empty_p (section))
+ return false;
+
+ /* Older elfutils strip versions could keep the section in the main
+ executable while splitting it for the separate debug info file. */
+ if ((get_section_flags (section) & SEC_HAS_CONTENTS) == 0)
+ return false;
+
+ dwarf2_read_section (objfile, section);
+
+ map.dwarf5_byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+
+ const gdb_byte *addr = section->buffer;
+
+ bfd *const abfd = get_section_bfd_owner (section);
+
+ unsigned int bytes_read;
+ LONGEST length = read_initial_length (abfd, addr, &bytes_read);
+ addr += bytes_read;
+
+ map.dwarf5_is_dwarf64 = bytes_read != 4;
+ map.offset_size = map.dwarf5_is_dwarf64 ? 8 : 4;
+ if (bytes_read + length != section->size)
+ {
+ /* There may be multiple per-CU indices. */
+ warning (_("Section .debug_names in %s length %s does not match "
+ "section length %s, ignoring .debug_names."),
+ filename, plongest (bytes_read + length),
+ pulongest (section->size));
+ return false;
+ }
+
+ /* The version number. */
+ uint16_t version = read_2_bytes (abfd, addr);
+ addr += 2;
+ if (version != 5)
+ {
+ warning (_("Section .debug_names in %s has unsupported version %d, "
+ "ignoring .debug_names."),
+ filename, version);
+ return false;
+ }
+
+ /* Padding. */
+ uint16_t padding = read_2_bytes (abfd, addr);
+ addr += 2;
+ if (padding != 0)
+ {
+ warning (_("Section .debug_names in %s has unsupported padding %d, "
+ "ignoring .debug_names."),
+ filename, padding);
+ return false;
+ }
+
+ /* comp_unit_count - The number of CUs in the CU list. */
+ map.cu_count = read_4_bytes (abfd, addr);
+ addr += 4;
+
+ /* local_type_unit_count - The number of TUs in the local TU
+ list. */
+ map.tu_count = read_4_bytes (abfd, addr);
+ addr += 4;
+
+ /* foreign_type_unit_count - The number of TUs in the foreign TU
+ list. */
+ uint32_t foreign_tu_count = read_4_bytes (abfd, addr);
+ addr += 4;
+ if (foreign_tu_count != 0)
+ {
+ warning (_("Section .debug_names in %s has unsupported %lu foreign TUs, "
+ "ignoring .debug_names."),
+ filename, static_cast<unsigned long> (foreign_tu_count));
+ return false;
+ }
+
+ /* bucket_count - The number of hash buckets in the hash lookup
+ table. */
+ map.bucket_count = read_4_bytes (abfd, addr);
+ addr += 4;
+
+ /* name_count - The number of unique names in the index. */
+ map.name_count = read_4_bytes (abfd, addr);
+ addr += 4;
+
+ /* abbrev_table_size - The size in bytes of the abbreviations
+ table. */
+ uint32_t abbrev_table_size = read_4_bytes (abfd, addr);
+ addr += 4;
+
+ /* augmentation_string_size - The size in bytes of the augmentation
+ string. This value is rounded up to a multiple of 4. */
+ uint32_t augmentation_string_size = read_4_bytes (abfd, addr);
+ addr += 4;
+ map.augmentation_is_gdb = ((augmentation_string_size
+ == sizeof (dwarf5_augmentation))
+ && memcmp (addr, dwarf5_augmentation,
+ sizeof (dwarf5_augmentation)) == 0);
+ augmentation_string_size += (-augmentation_string_size) & 3;
+ addr += augmentation_string_size;
+
+ /* List of CUs */
+ map.cu_table_reordered = addr;
+ addr += map.cu_count * map.offset_size;
+
+ /* List of Local TUs */
+ map.tu_table_reordered = addr;
+ addr += map.tu_count * map.offset_size;
+
+ /* Hash Lookup Table */
+ map.bucket_table_reordered = reinterpret_cast<const uint32_t *> (addr);
+ addr += map.bucket_count * 4;
+ map.hash_table_reordered = reinterpret_cast<const uint32_t *> (addr);
+ addr += map.name_count * 4;
+
+ /* Name Table */
+ map.name_table_string_offs_reordered = addr;
+ addr += map.name_count * map.offset_size;
+ map.name_table_entry_offs_reordered = addr;
+ addr += map.name_count * map.offset_size;
+
+ const gdb_byte *abbrev_table_start = addr;
+ for (;;)
+ {
+ unsigned int bytes_read;
+ const ULONGEST index_num = read_unsigned_leb128 (abfd, addr, &bytes_read);
+ addr += bytes_read;
+ if (index_num == 0)
+ break;
+
+ const auto insertpair
+ = map.abbrev_map.emplace (index_num, mapped_debug_names::index_val ());
+ if (!insertpair.second)
+ {
+ warning (_("Section .debug_names in %s has duplicate index %s, "
+ "ignoring .debug_names."),
+ filename, pulongest (index_num));
+ return false;
+ }
+ mapped_debug_names::index_val &indexval = insertpair.first->second;
+ indexval.dwarf_tag = read_unsigned_leb128 (abfd, addr, &bytes_read);
+ addr += bytes_read;
+
+ for (;;)
+ {
+ mapped_debug_names::index_val::attr attr;
+ attr.dw_idx = read_unsigned_leb128 (abfd, addr, &bytes_read);
+ addr += bytes_read;
+ attr.form = read_unsigned_leb128 (abfd, addr, &bytes_read);
+ addr += bytes_read;
+ if (attr.form == DW_FORM_implicit_const)
+ {
+ attr.implicit_const = read_signed_leb128 (abfd, addr,
+ &bytes_read);
+ addr += bytes_read;
+ }
+ if (attr.dw_idx == 0 && attr.form == 0)
+ break;
+ indexval.attr_vec.push_back (std::move (attr));
+ }
+ }
+ if (addr != abbrev_table_start + abbrev_table_size)
+ {
+ warning (_("Section .debug_names in %s has abbreviation_table "
+ "of size %zu vs. written as %u, ignoring .debug_names."),
+ filename, addr - abbrev_table_start, abbrev_table_size);
+ return false;
+ }
+ map.entry_pool = addr;
+
+ return true;
+}
+
+/* A helper for create_cus_from_debug_names that handles the MAP's CU
+ list. */
+
+static void
+create_cus_from_debug_names_list (struct objfile *objfile,
+ const mapped_debug_names &map,
+ dwarf2_section_info §ion,
+ bool is_dwz, int base_offset)
+{
+ sect_offset sect_off_prev;
+ for (uint32_t i = 0; i <= map.cu_count; ++i)
+ {
+ sect_offset sect_off_next;
+ if (i < map.cu_count)
+ {
+ sect_off_next
+ = (sect_offset) (extract_unsigned_integer
+ (map.cu_table_reordered + i * map.offset_size,
+ map.offset_size,
+ map.dwarf5_byte_order));
+ }
+ else
+ sect_off_next = (sect_offset) section.size;
+ if (i >= 1)
+ {
+ const ULONGEST length = sect_off_next - sect_off_prev;
+ dwarf2_per_objfile->all_comp_units[base_offset + (i - 1)]
+ = create_cu_from_index_list (objfile, §ion, is_dwz,
+ sect_off_prev, length);
+ }
+ sect_off_prev = sect_off_next;
+ }
+}
+
+/* Read the CU list from the mapped index, and use it to create all
+ the CU objects for this objfile. */
+
+static void
+create_cus_from_debug_names (struct objfile *objfile,
+ const mapped_debug_names &map,
+ const mapped_debug_names &dwz_map)
+{
+
+ dwarf2_per_objfile->n_comp_units = map.cu_count + dwz_map.cu_count;
+ dwarf2_per_objfile->all_comp_units
+ = XOBNEWVEC (&objfile->objfile_obstack, struct dwarf2_per_cu_data *,
+ dwarf2_per_objfile->n_comp_units);
+
+ create_cus_from_debug_names_list (objfile, map, dwarf2_per_objfile->info,
+ false /* is_dwz */,
+ 0 /* base_offset */);
+
+ if (dwz_map.cu_count == 0)
+ return;
+
+ dwz_file *dwz = dwarf2_get_dwz_file ();
+ create_cus_from_debug_names_list (objfile, dwz_map, dwz->info,
+ true /* is_dwz */,
+ map.cu_count /* base_offset */);
+}
+
+/* Read .debug_names. If everything went ok, initialize the "quick"
+ elements of all the CUs and return true. Otherwise, return false. */
+
+static bool
+dwarf2_read_debug_names (struct objfile *objfile)
+{
+ mapped_debug_names local_map, dwz_map;
+
+ if (!read_debug_names_from_section (objfile, objfile_name (objfile),
+ &dwarf2_per_objfile->debug_names,
+ local_map))
+ return false;
+
+ /* Don't use the index if it's empty. */
+ if (local_map.name_count == 0)
+ return false;
+
+ /* If there is a .dwz file, read it so we can get its CU list as
+ well. */
+ dwz_file *dwz = dwarf2_get_dwz_file ();
+ if (dwz != NULL)
+ {
+ if (!read_debug_names_from_section (objfile,
+ bfd_get_filename (dwz->dwz_bfd),
+ &dwz->debug_names, dwz_map))
+ {
+ warning (_("could not read '.debug_names' section from %s; skipping"),
+ bfd_get_filename (dwz->dwz_bfd));
+ return false;
+ }
+ }
+
+ create_cus_from_debug_names (objfile, local_map, dwz_map);
+
+ if (local_map.tu_count != 0)
+ {
+ /* We can only handle a single .debug_types when we have an
+ index. */
+ if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) != 1)
+ return false;
+
+ dwarf2_section_info *section = VEC_index (dwarf2_section_info_def,
+ dwarf2_per_objfile->types, 0);
+
+ create_signatured_type_table_from_debug_names
+ (objfile, local_map, section, &dwarf2_per_objfile->abbrev);
+ }
+
+ create_addrmap_from_aranges (objfile, &dwarf2_per_objfile->debug_aranges);
+
+ dwarf2_per_objfile->debug_names_table.reset (new mapped_debug_names);
+ *dwarf2_per_objfile->debug_names_table = std::move (local_map);
+ dwarf2_per_objfile->using_index = 1;
+ dwarf2_per_objfile->quick_file_names_table =
+ create_quick_file_names_table (dwarf2_per_objfile->n_comp_units);
+
+ return true;
+}
+
+/* Symbol name hashing function as specified by DWARF-5. */
+
+static uint32_t
+dwarf5_djb_hash (const char *str_)
+{
+ const unsigned char *str = (const unsigned char *) str_;
+
+ /* Note: tolower here ignores UTF-8, which isn't fully compliant.
+ See http://dwarfstd.org/ShowIssue.php?issue=161027.1. */
+
+ uint32_t hash = 5381;
+ while (int c = *str++)
+ hash = hash * 33 + tolower (c);
+ return hash;
+}
+
+/* Type used to manage iterating over all CUs looking for a symbol for
+ .debug_names. */
+
+class dw2_debug_names_iterator
+{
+public:
+ /* If WANT_SPECIFIC_BLOCK is true, only look for symbols in block
+ BLOCK_INDEX. Otherwise BLOCK_INDEX is ignored. */
+ dw2_debug_names_iterator (const mapped_debug_names &map,
+ bool want_specific_block,
+ block_enum block_index, domain_enum domain,
+ const char *name)
+ : m_map (map), m_want_specific_block (want_specific_block),
+ m_block_index (block_index), m_domain (domain),
+ m_addr (find_vec_in_debug_names (map, name))
+ {}
+
+ dw2_debug_names_iterator (const mapped_debug_names &map,
+ search_domain search, uint32_t namei)
+ : m_map (map),
+ m_search (search),
+ m_addr (find_vec_in_debug_names (map, namei))
+ {}
+
+ /* Return the next matching CU or NULL if there are no more. */
+ dwarf2_per_cu_data *next ();
+
+private:
+ static const gdb_byte *find_vec_in_debug_names (const mapped_debug_names &map,
+ const char *name);
+ static const gdb_byte *find_vec_in_debug_names (const mapped_debug_names &map,
+ uint32_t namei);
+
+ /* The internalized form of .debug_names. */
+ const mapped_debug_names &m_map;
+
+ /* If true, only look for symbols that match BLOCK_INDEX. */
+ const bool m_want_specific_block = false;
+
+ /* One of GLOBAL_BLOCK or STATIC_BLOCK.
+ Unused if !WANT_SPECIFIC_BLOCK - FIRST_LOCAL_BLOCK is an invalid
+ value. */
+ const block_enum m_block_index = FIRST_LOCAL_BLOCK;
+
+ /* The kind of symbol we're looking for. */
+ const domain_enum m_domain = UNDEF_DOMAIN;
+ const search_domain m_search = ALL_DOMAIN;
+
+ /* The list of CUs from the index entry of the symbol, or NULL if
+ not found. */
+ const gdb_byte *m_addr;
+};
+
+const char *
+mapped_debug_names::namei_to_name (uint32_t namei) const
+{
+ const ULONGEST namei_string_offs
+ = extract_unsigned_integer ((name_table_string_offs_reordered
+ + namei * offset_size),
+ offset_size,
+ dwarf5_byte_order);
+ return read_indirect_string_at_offset
+ (dwarf2_per_objfile->objfile->obfd, namei_string_offs);
+}
+
+/* Find a slot in .debug_names for the object named NAME. If NAME is
+ found, return pointer to its pool data. If NAME cannot be found,
+ return NULL. */
+
+const gdb_byte *
+dw2_debug_names_iterator::find_vec_in_debug_names
+ (const mapped_debug_names &map, const char *name)
+{
+ int (*cmp) (const char *, const char *);
+
+ if (current_language->la_language == language_cplus
+ || current_language->la_language == language_fortran
+ || current_language->la_language == language_d)
+ {
+ /* NAME is already canonical. Drop any qualifiers as
+ .debug_names does not contain any. */
+
+ if (strchr (name, '(') != NULL)
+ {
+ gdb::unique_xmalloc_ptr<char> without_params
+ = cp_remove_params (name);
+
+ if (without_params != NULL)
+ {
+ name = without_params.get();
+ }
+ }
+ }
+
+ cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
+
+ const uint32_t full_hash = dwarf5_djb_hash (name);
+ uint32_t namei
+ = extract_unsigned_integer (reinterpret_cast<const gdb_byte *>
+ (map.bucket_table_reordered
+ + (full_hash % map.bucket_count)), 4,
+ map.dwarf5_byte_order);
+ if (namei == 0)
+ return NULL;
+ --namei;
+ if (namei >= map.name_count)
+ {
+ complaint (&symfile_complaints,
+ _("Wrong .debug_names with name index %u but name_count=%u "
+ "[in module %s]"),
+ namei, map.name_count,
+ objfile_name (dwarf2_per_objfile->objfile));
+ return NULL;
+ }
+
+ for (;;)
+ {
+ const uint32_t namei_full_hash
+ = extract_unsigned_integer (reinterpret_cast<const gdb_byte *>
+ (map.hash_table_reordered + namei), 4,
+ map.dwarf5_byte_order);
+ if (full_hash % map.bucket_count != namei_full_hash % map.bucket_count)
+ return NULL;
+
+ if (full_hash == namei_full_hash)
+ {
+ const char *const namei_string = map.namei_to_name (namei);
+
+#if 0 /* An expensive sanity check. */
+ if (namei_full_hash != dwarf5_djb_hash (namei_string))
+ {
+ complaint (&symfile_complaints,
+ _("Wrong .debug_names hash for string at index %u "
+ "[in module %s]"),
+ namei, objfile_name (dwarf2_per_objfile->objfile));
+ return NULL;
+ }
+#endif
+
+ if (cmp (namei_string, name) == 0)
+ {
+ const ULONGEST namei_entry_offs
+ = extract_unsigned_integer ((map.name_table_entry_offs_reordered
+ + namei * map.offset_size),
+ map.offset_size, map.dwarf5_byte_order);
+ return map.entry_pool + namei_entry_offs;
+ }
+ }
+
+ ++namei;
+ if (namei >= map.name_count)
+ return NULL;
+ }
+}
+
+const gdb_byte *
+dw2_debug_names_iterator::find_vec_in_debug_names
+ (const mapped_debug_names &map, uint32_t namei)
+{
+ if (namei >= map.name_count)
+ {
+ complaint (&symfile_complaints,
+ _("Wrong .debug_names with name index %u but name_count=%u "
+ "[in module %s]"),
+ namei, map.name_count,
+ objfile_name (dwarf2_per_objfile->objfile));
+ return NULL;
+ }
+
+ const ULONGEST namei_entry_offs
+ = extract_unsigned_integer ((map.name_table_entry_offs_reordered
+ + namei * map.offset_size),
+ map.offset_size, map.dwarf5_byte_order);
+ return map.entry_pool + namei_entry_offs;
+}
+
+/* See dw2_debug_names_iterator. */
+
+dwarf2_per_cu_data *
+dw2_debug_names_iterator::next ()
+{
+ if (m_addr == NULL)
+ return NULL;
+
+ bfd *const abfd = dwarf2_per_objfile->objfile->obfd;
+
+ again:
+
+ unsigned int bytes_read;
+ const ULONGEST abbrev = read_unsigned_leb128 (abfd, m_addr, &bytes_read);
+ m_addr += bytes_read;
+ if (abbrev == 0)
+ return NULL;
+
+ const auto indexval_it = m_map.abbrev_map.find (abbrev);
+ if (indexval_it == m_map.abbrev_map.cend ())
+ {
+ complaint (&symfile_complaints,
+ _("Wrong .debug_names undefined abbrev code %s "
+ "[in module %s]"),
+ pulongest (abbrev), objfile_name (dwarf2_per_objfile->objfile));
+ return NULL;
+ }
+ const mapped_debug_names::index_val &indexval = indexval_it->second;
+ bool have_is_static = false;
+ bool is_static;
+ dwarf2_per_cu_data *per_cu = NULL;
+ for (const mapped_debug_names::index_val::attr &attr : indexval.attr_vec)
+ {
+ ULONGEST ull;
+ switch (attr.form)
+ {
+ case DW_FORM_implicit_const:
+ ull = attr.implicit_const;
+ break;
+ case DW_FORM_flag_present:
+ ull = 1;
+ break;
+ case DW_FORM_udata:
+ ull = read_unsigned_leb128 (abfd, m_addr, &bytes_read);
+ m_addr += bytes_read;
+ break;
+ default:
+ complaint (&symfile_complaints,
+ _("Unsupported .debug_names form %s [in module %s]"),
+ dwarf_form_name (attr.form),
+ objfile_name (dwarf2_per_objfile->objfile));
+ return NULL;
+ }
+ switch (attr.dw_idx)
+ {
+ case DW_IDX_compile_unit:
+ /* Don't crash on bad data. */
+ if (ull >= (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units))
+ {
+ complaint (&symfile_complaints,
+ _(".debug_names entry has bad CU index %s"
+ " [in module %s]"),
+ pulongest (ull),
+ objfile_name (dwarf2_per_objfile->objfile));
+ continue;
+ }
+ per_cu = dw2_get_cutu (ull);
+ break;
+ case DW_IDX_GNU_internal:
+ if (!m_map.augmentation_is_gdb)
+ break;
+ have_is_static = true;
+ is_static = true;
+ break;
+ case DW_IDX_GNU_external:
+ if (!m_map.augmentation_is_gdb)
+ break;
+ have_is_static = true;
+ is_static = false;
+ break;
+ }
+ }
+
+ /* Skip if already read in. */
+ if (per_cu->v.quick->compunit_symtab)
+ goto again;
+
+ /* Check static vs global. */
+ if (have_is_static)
+ {
+ const bool want_static = m_block_index != GLOBAL_BLOCK;
+ if (m_want_specific_block && want_static != is_static)
+ goto again;
+ }
+
+ /* Match dw2_symtab_iter_next, symbol_kind
+ and debug_names::psymbol_tag. */
+ switch (m_domain)
+ {
+ case VAR_DOMAIN:
+ switch (indexval.dwarf_tag)
+ {
+ case DW_TAG_variable:
+ case DW_TAG_subprogram:
+ /* Some types are also in VAR_DOMAIN. */
+ case DW_TAG_typedef:
+ case DW_TAG_structure_type:
+ break;
+ default:
+ goto again;
+ }
+ break;
+ case STRUCT_DOMAIN:
+ switch (indexval.dwarf_tag)
+ {
+ case DW_TAG_typedef:
+ case DW_TAG_structure_type:
+ break;
+ default:
+ goto again;
+ }
+ break;
+ case LABEL_DOMAIN:
+ switch (indexval.dwarf_tag)
+ {
+ case 0:
+ case DW_TAG_variable:
+ break;
+ default:
+ goto again;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Match dw2_expand_symtabs_matching, symbol_kind and
+ debug_names::psymbol_tag. */
+ switch (m_search)