Handle unaligned mapping of .gdb_index
[deliverable/binutils-gdb.git] / gdb / dwarf2 / read.c
index befaea5aea78fa5d82d0beff4d1e82428ea297a7..40aeb298c14d70279413c90d33539ab7dac45310 100644 (file)
@@ -223,17 +223,50 @@ protected:
   ~mapped_index_base() = default;
 };
 
+/* This is a view into the index that converts from bytes to an
+   offset_type, and allows indexing.  Unaligned bytes are specifically
+   allowed here, and handled via unpacking.  */
+
+class offset_view
+{
+public:
+  offset_view () = default;
+
+  explicit offset_view (gdb::array_view<const gdb_byte> bytes)
+    : m_bytes (bytes)
+  {
+  }
+
+  /* Extract the INDEXth offset_type from the array.  */
+  offset_type operator[] (size_t index) const
+  {
+    const gdb_byte *bytes = &m_bytes[index * sizeof (offset_type)];
+    return (offset_type) extract_unsigned_integer (bytes,
+                                                  sizeof (offset_type),
+                                                  BFD_ENDIAN_LITTLE);
+  }
+
+  /* Return the number of offset_types in this array.  */
+  size_t size () const
+  {
+    return m_bytes.size () / sizeof (offset_type);
+  }
+
+  /* Return true if this view is empty.  */
+  bool empty () const
+  {
+    return m_bytes.empty ();
+  }
+
+private:
+  /* The underlying bytes.  */
+  gdb::array_view<const gdb_byte> m_bytes;
+};
+
 /* A description of the mapped index.  The file format is described in
    a comment by the code that writes the index.  */
 struct mapped_index final : public mapped_index_base
 {
-  /* A slot/bucket in the symbol table hash.  */
-  struct symbol_table_slot
-  {
-    const offset_type name;
-    const offset_type vec;
-  };
-
   /* Index data format version.  */
   int version = 0;
 
@@ -241,25 +274,42 @@ struct mapped_index final : public mapped_index_base
   gdb::array_view<const gdb_byte> address_table;
 
   /* The symbol table, implemented as a hash table.  */
-  gdb::array_view<symbol_table_slot> symbol_table;
+  offset_view symbol_table;
 
   /* A pointer to the constant pool.  */
-  const char *constant_pool = nullptr;
+  gdb::array_view<const gdb_byte> constant_pool;
+
+  /* Return the index into the constant pool of the name of the IDXth
+     symbol in the symbol table.  */
+  offset_type symbol_name_index (offset_type idx) const
+  {
+    return symbol_table[2 * idx];
+  }
+
+  /* Return the index into the constant pool of the CU vector of the
+     IDXth symbol in the symbol table.  */
+  offset_type symbol_vec_index (offset_type idx) const
+  {
+    return symbol_table[2 * idx + 1];
+  }
 
   bool symbol_name_slot_invalid (offset_type idx) const override
   {
-    const auto &bucket = this->symbol_table[idx];
-    return bucket.name == 0 && bucket.vec == 0;
+    return (symbol_name_index (idx) == 0
+           && symbol_vec_index (idx) == 0);
   }
 
   /* Convenience method to get at the name of the symbol at IDX in the
      symbol table.  */
   const char *symbol_name_at
     (offset_type idx, dwarf2_per_objfile *per_objfile) const override
-  { return this->constant_pool + MAYBE_SWAP (this->symbol_table[idx].name); }
+  {
+    return (const char *) (this->constant_pool.data ()
+                          + symbol_name_index (idx));
+  }
 
   size_t symbol_name_count () const override
-  { return this->symbol_table.size (); }
+  { return this->symbol_table.size () / 2; }
 };
 
 /* A description of the mapped .debug_names.
@@ -1951,11 +2001,14 @@ dwarf2_has_info (struct objfile *objfile,
     {
       dwarf2_per_bfd *per_bfd;
 
-      /* We can share a "dwarf2_per_bfd" with other objfiles if the BFD
-        doesn't require relocations and if there aren't partial symbols
-        from some other reader.  */
-      if (!objfile->has_partial_symbols ()
-         && !gdb_bfd_requires_relocations (objfile->obfd))
+      /* We can share a "dwarf2_per_bfd" with other objfiles if the
+        BFD doesn't require relocations.
+
+        We don't share with objfiles for which -readnow was requested,
+        because it would complicate things when loading the same BFD with
+        -readnow and then without -readnow.  */
+      if (!gdb_bfd_requires_relocations (objfile->obfd)
+         && (objfile->flags & OBJF_READNOW) == 0)
        {
          /* See if one has been created for this BFD yet.  */
          per_bfd = dwarf2_per_bfd_bfd_data_key.get (objfile->obfd);
@@ -2193,6 +2246,30 @@ struct dwarf2_per_cu_quick_data
   unsigned int no_file_data : 1;
 };
 
+/* A subclass of psymbol_functions that arranges to read the DWARF
+   partial symbols when needed.  */
+struct lazy_dwarf_reader : public psymbol_functions
+{
+  using psymbol_functions::psymbol_functions;
+
+  bool can_lazily_read_symbols () override
+  {
+    return true;
+  }
+
+  void read_partial_symbols (struct objfile *objfile) override
+  {
+    if (dwarf2_has_info (objfile, nullptr))
+      dwarf2_build_psymtabs (objfile, this);
+  }
+};
+
+static quick_symbol_functions_up
+make_lazy_dwarf_reader ()
+{
+  return quick_symbol_functions_up (new lazy_dwarf_reader);
+}
+
 struct dwarf2_base_index_functions : public quick_symbol_functions
 {
   bool has_symbols (struct objfile *objfile) override;
@@ -2201,10 +2278,6 @@ struct dwarf2_base_index_functions : public quick_symbol_functions
 
   void forget_cached_source_info (struct objfile *objfile) override;
 
-  bool map_symtabs_matching_filename
-    (struct objfile *objfile, const char *name, const char *real_path,
-     gdb::function_view<bool (symtab *)> callback) override;
-
   enum language lookup_global_symbol_language (struct objfile *objfile,
                                               const char *name,
                                               domain_enum domain,
@@ -2218,9 +2291,6 @@ struct dwarf2_base_index_functions : public quick_symbol_functions
 
   void expand_all_symtabs (struct objfile *objfile) override;
 
-  void expand_symtabs_with_fullname (struct objfile *objfile,
-                                    const char *fullname) override;
-
   struct compunit_symtab *find_pc_sect_compunit_symtab
     (struct objfile *objfile, struct bound_minimal_symbol msymbol,
      CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override;
@@ -2232,75 +2302,61 @@ struct dwarf2_base_index_functions : public quick_symbol_functions
   }
 
   void map_symbol_filenames (struct objfile *objfile,
-                            symbol_filename_ftype *fun, void *data,
-                            int need_fullname) override;
+                            gdb::function_view<symbol_filename_ftype> fun,
+                            bool need_fullname) override;
 };
 
 struct dwarf2_gdb_index : public dwarf2_base_index_functions
 {
-  struct compunit_symtab *lookup_symbol (struct objfile *objfile,
-                                        block_enum block_index,
-                                        const char *name,
-                                        domain_enum domain) override;
-
   void dump (struct objfile *objfile) override;
 
-  void expand_symtabs_for_function (struct objfile *objfile,
-                                   const char *func_name) override;
-
-  void map_matching_symbols
+  void expand_matching_symbols
     (struct objfile *,
      const lookup_name_info &lookup_name,
      domain_enum domain,
      int global,
-     gdb::function_view<symbol_found_callback_ftype> callback,
      symbol_compare_ftype *ordered_compare) override;
 
-  void expand_symtabs_matching
+  bool 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,
+     block_search_flags search_flags,
+     domain_enum domain,
      enum search_domain kind) override;
 };
 
 struct dwarf2_debug_names_index : public dwarf2_base_index_functions
 {
-  struct compunit_symtab *lookup_symbol (struct objfile *objfile,
-                                        block_enum block_index,
-                                        const char *name,
-                                        domain_enum domain) override;
-
   void dump (struct objfile *objfile) override;
 
-  void expand_symtabs_for_function (struct objfile *objfile,
-                                   const char *func_name) override;
-
-  void map_matching_symbols
+  void expand_matching_symbols
     (struct objfile *,
      const lookup_name_info &lookup_name,
      domain_enum domain,
      int global,
-     gdb::function_view<symbol_found_callback_ftype> callback,
      symbol_compare_ftype *ordered_compare) override;
 
-  void expand_symtabs_matching
+  bool 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,
+     block_search_flags search_flags,
+     domain_enum domain,
      enum search_domain kind) override;
 };
 
-quick_symbol_functions_up
+static quick_symbol_functions_up
 make_dwarf_gdb_index ()
 {
   return quick_symbol_functions_up (new dwarf2_gdb_index);
 }
 
-quick_symbol_functions_up
+static quick_symbol_functions_up
 make_dwarf_debug_names ()
 {
   return quick_symbol_functions_up (new dwarf2_debug_names_index);
@@ -2776,7 +2832,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                     dwarf2_per_cu_data *,
                     gdb::hash_enum<sect_offset>>
     debug_info_offset_to_per_cu;
-  for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : per_bfd->all_comp_units)
     {
       const auto insertpair
        = debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu);
@@ -2922,68 +2978,6 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                                                 &per_bfd->obstack);
 }
 
-/* Find a slot in the mapped index INDEX for the object named NAME.
-   If NAME is found, set *VEC_OUT to point to the CU vector in the
-   constant pool and return true.  If NAME cannot be found, return
-   false.  */
-
-static bool
-find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
-                         offset_type **vec_out)
-{
-  offset_type hash;
-  offset_type slot, step;
-  int (*cmp) (const char *, const char *);
-
-  gdb::unique_xmalloc_ptr<char> without_params;
-  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 .gdb_index does
-        not contain any.  */
-
-      if (strchr (name, '(') != NULL)
-       {
-         without_params = cp_remove_params (name);
-
-         if (without_params != NULL)
-           name = without_params.get ();
-       }
-    }
-
-  /* Index version 4 did not support case insensitive searches.  But the
-     indices for case insensitive languages are built in lowercase, therefore
-     simulate our NAME being searched is also lowercased.  */
-  hash = mapped_index_string_hash ((index->version == 4
-                                   && case_sensitivity == case_sensitive_off
-                                   ? 5 : index->version),
-                                  name);
-
-  slot = hash & (index->symbol_table.size () - 1);
-  step = ((hash * 17) & (index->symbol_table.size () - 1)) | 1;
-  cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
-
-  for (;;)
-    {
-      const char *str;
-
-      const auto &bucket = index->symbol_table[slot];
-      if (bucket.name == 0 && bucket.vec == 0)
-       return false;
-
-      str = index->constant_pool + MAYBE_SWAP (bucket.name);
-      if (!cmp (name, str))
-       {
-         *vec_out = (offset_type *) (index->constant_pool
-                                     + MAYBE_SWAP (bucket.vec));
-         return true;
-       }
-
-      slot = (slot + step) & (index->symbol_table.size () - 1);
-    }
-}
-
 /* A helper function that reads the .gdb_index from BUFFER and fills
    in MAP.  FILENAME is the name of the file containing the data;
    it is used for error reporting.  DEPRECATED_OK is true if it is
@@ -3006,9 +3000,10 @@ read_gdb_index_from_buffer (const char *filename,
                            offset_type *types_list_elements)
 {
   const gdb_byte *addr = &buffer[0];
+  offset_view metadata (buffer);
 
   /* Version check.  */
-  offset_type version = MAYBE_SWAP (*(offset_type *) addr);
+  offset_type version = metadata[0];
   /* Versions earlier than 3 emitted every copy of a psymbol.  This
      causes the index to behave very poorly for certain requests.  Version 3
      contained incomplete addrmap.  So, it seems better to just ignore such
@@ -3061,35 +3056,29 @@ to use the section anyway."),
 
   map->version = version;
 
-  offset_type *metadata = (offset_type *) (addr + sizeof (offset_type));
-
-  int i = 0;
-  *cu_list = addr + MAYBE_SWAP (metadata[i]);
-  *cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
-                      / 8);
+  int i = 1;
+  *cu_list = addr + metadata[i];
+  *cu_list_elements = (metadata[i + 1] - metadata[i]) / 8;
   ++i;
 
-  *types_list = addr + MAYBE_SWAP (metadata[i]);
-  *types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
-                          - MAYBE_SWAP (metadata[i]))
-                         / 8);
+  *types_list = addr + metadata[i];
+  *types_list_elements = (metadata[i + 1] - metadata[i]) / 8;
   ++i;
 
-  const gdb_byte *address_table = addr + MAYBE_SWAP (metadata[i]);
-  const gdb_byte *address_table_end = addr + MAYBE_SWAP (metadata[i + 1]);
+  const gdb_byte *address_table = addr + metadata[i];
+  const gdb_byte *address_table_end = addr + metadata[i + 1];
   map->address_table
     = gdb::array_view<const gdb_byte> (address_table, address_table_end);
   ++i;
 
-  const gdb_byte *symbol_table = addr + MAYBE_SWAP (metadata[i]);
-  const gdb_byte *symbol_table_end = addr + MAYBE_SWAP (metadata[i + 1]);
+  const gdb_byte *symbol_table = addr + metadata[i];
+  const gdb_byte *symbol_table_end = addr + metadata[i + 1];
   map->symbol_table
-    = gdb::array_view<mapped_index::symbol_table_slot>
-       ((mapped_index::symbol_table_slot *) symbol_table,
-       (mapped_index::symbol_table_slot *) symbol_table_end);
+    = offset_view (gdb::array_view<const gdb_byte> (symbol_table,
+                                                   symbol_table_end));
 
   ++i;
-  map->constant_pool = (char *) (addr + MAYBE_SWAP (metadata[i]));
+  map->constant_pool = buffer.slice (metadata[i]);
 
   return 1;
 }
@@ -3360,100 +3349,6 @@ dwarf2_base_index_functions::forget_cached_source_info
                          dw2_free_cached_file_names, NULL);
 }
 
-/* Helper function for dw2_map_symtabs_matching_filename that expands
-   the symtabs and calls the iterator.  */
-
-static int
-dw2_map_expand_apply (struct objfile *objfile,
-                     struct dwarf2_per_cu_data *per_cu,
-                     const char *name, const char *real_path,
-                     gdb::function_view<bool (symtab *)> callback)
-{
-  struct compunit_symtab *last_made = objfile->compunit_symtabs;
-
-  /* Don't visit already-expanded CUs.  */
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-  if (per_objfile->symtab_set_p (per_cu))
-    return 0;
-
-  /* This may expand more than one symtab, and we want to iterate over
-     all of them.  */
-  dw2_instantiate_symtab (per_cu, per_objfile, false);
-
-  return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
-                                   last_made, callback);
-}
-
-/* Implementation of the map_symtabs_matching_filename method.  */
-
-bool
-dwarf2_base_index_functions::map_symtabs_matching_filename
-  (struct objfile *objfile, const char *name, const char *real_path,
-   gdb::function_view<bool (symtab *)> callback)
-{
-  const char *name_basename = lbasename (name);
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
-  /* The rule is CUs specify all the files, including those used by
-     any TU, so there's no need to scan TUs here.  */
-
-  for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
-    {
-      /* We only need to look at symtabs not already expanded.  */
-      if (per_objfile->symtab_set_p (per_cu))
-       continue;
-
-      quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
-      if (file_data == NULL)
-       continue;
-
-      for (int j = 0; j < file_data->num_file_names; ++j)
-       {
-         const char *this_name = file_data->file_names[j];
-         const char *this_real_name;
-
-         if (compare_filenames_for_search (this_name, name))
-           {
-             if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-                                       callback))
-               return true;
-             continue;
-           }
-
-         /* Before we invoke realpath, which can get expensive when many
-            files are involved, do a quick comparison of the basenames.  */
-         if (! basenames_may_differ
-             && FILENAME_CMP (lbasename (this_name), name_basename) != 0)
-           continue;
-
-         this_real_name = dw2_get_real_path (per_objfile, file_data, j);
-         if (compare_filenames_for_search (this_real_name, name))
-           {
-             if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-                                       callback))
-               return true;
-             continue;
-           }
-
-         if (real_path != NULL)
-           {
-             gdb_assert (IS_ABSOLUTE_PATH (real_path));
-             gdb_assert (IS_ABSOLUTE_PATH (name));
-             if (this_real_name != NULL
-                 && FILENAME_CMP (real_path, this_real_name) == 0)
-               {
-                 if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-                                           callback))
-                   return true;
-                 continue;
-               }
-           }
-       }
-    }
-
-  return false;
-}
-
 /* Struct used to manage iterating over all CUs looking for a symbol.  */
 
 struct dw2_symtab_iterator
@@ -3467,7 +3362,7 @@ struct dw2_symtab_iterator
   domain_enum domain;
   /* The list of CUs from the index entry of the symbol,
      or NULL if not found.  */
-  offset_type *vec;
+  offset_view vec;
   /* The next element in VEC to look at.  */
   int next;
   /* The number of elements in VEC, or zero if there is no match.  */
@@ -3479,52 +3374,21 @@ struct dw2_symtab_iterator
   int global_seen;
 };
 
-/* Initialize the index symtab iterator ITER, common part.  */
+/* Initialize the index symtab iterator ITER, offset_type NAMEI variant.  */
 
 static void
-dw2_symtab_iter_init_common (struct dw2_symtab_iterator *iter,
-                            dwarf2_per_objfile *per_objfile,
-                            gdb::optional<block_enum> block_index,
-                            domain_enum domain)
+dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
+                     dwarf2_per_objfile *per_objfile,
+                     gdb::optional<block_enum> block_index,
+                     domain_enum domain, offset_type namei)
 {
   iter->per_objfile = per_objfile;
   iter->block_index = block_index;
   iter->domain = domain;
   iter->next = 0;
   iter->global_seen = 0;
-  iter->vec = NULL;
+  iter->vec = {};
   iter->length = 0;
-}
-
-/* Initialize the index symtab iterator ITER, const char *NAME variant.  */
-
-static void
-dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
-                     dwarf2_per_objfile *per_objfile,
-                     gdb::optional<block_enum> block_index,
-                     domain_enum domain,
-                     const char *name)
-{
-  dw2_symtab_iter_init_common (iter, per_objfile, block_index, domain);
-
-  mapped_index *index = per_objfile->per_bfd->index_table.get ();
-  /* index is NULL if OBJF_READNOW.  */
-  if (index == NULL)
-    return;
-
-  if (find_slot_in_mapped_hash (index, name, &iter->vec))
-    iter->length = MAYBE_SWAP (*iter->vec);
-}
-
-/* Initialize the index symtab iterator ITER, offset_type NAMEI variant.  */
-
-static void
-dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
-                     dwarf2_per_objfile *per_objfile,
-                     gdb::optional<block_enum> block_index,
-                     domain_enum domain, offset_type namei)
-{
-  dw2_symtab_iter_init_common (iter, per_objfile, block_index, domain);
 
   mapped_index *index = per_objfile->per_bfd->index_table.get ();
   /* index is NULL if OBJF_READNOW.  */
@@ -3532,11 +3396,10 @@ dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
     return;
 
   gdb_assert (!index->symbol_name_slot_invalid (namei));
-  const auto &bucket = index->symbol_table[namei];
+  offset_type vec_idx = index->symbol_vec_index (namei);
 
-  iter->vec = (offset_type *) (index->constant_pool
-                              + MAYBE_SWAP (bucket.vec));
-  iter->length = MAYBE_SWAP (*iter->vec);
+  iter->vec = offset_view (index->constant_pool.slice (vec_idx));
+  iter->length = iter->vec[0];
 }
 
 /* Return the next matching CU or NULL if there are no more.  */
@@ -3548,8 +3411,7 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
 
   for ( ; iter->next < iter->length; ++iter->next)
     {
-      offset_type cu_index_and_attrs =
-       MAYBE_SWAP (iter->vec[iter->next + 1]);
+      offset_type cu_index_and_attrs = iter->vec[iter->next + 1];
       offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
       gdb_index_symbol_kind symbol_kind =
        GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
@@ -3636,50 +3498,6 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
   return NULL;
 }
 
-struct compunit_symtab *
-dwarf2_gdb_index::lookup_symbol (struct objfile *objfile,
-                                block_enum block_index,
-                                const char *name, domain_enum domain)
-{
-  struct compunit_symtab *stab_best = NULL;
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
-  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
-
-  struct dw2_symtab_iterator iter;
-  struct dwarf2_per_cu_data *per_cu;
-
-  dw2_symtab_iter_init (&iter, per_objfile, block_index, domain, name);
-
-  while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
-    {
-      struct symbol *sym, *with_opaque = NULL;
-      struct compunit_symtab *stab
-       = dw2_instantiate_symtab (per_cu, per_objfile, false);
-      const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
-      const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
-
-      sym = block_find_symbol (block, name, domain,
-                              block_find_non_opaque_type_preferred,
-                              &with_opaque);
-
-      /* Some caution must be observed with overloaded functions
-        and methods, since the index will not contain any overload
-        information (but NAME might contain it).  */
-
-      if (sym != NULL
-         && SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name))
-       return stab;
-      if (with_opaque != NULL
-         && SYMBOL_MATCHES_SEARCH_NAME (with_opaque, lookup_name))
-       stab_best = stab;
-
-      /* Keep looking through other CUs.  */
-    }
-
-  return stab_best;
-}
-
 void
 dwarf2_base_index_functions::print_stats (struct objfile *objfile,
                                          bool print_bcache)
@@ -3725,22 +3543,6 @@ dwarf2_gdb_index::dump (struct objfile *objfile)
   printf_filtered ("\n");
 }
 
-void
-dwarf2_gdb_index::expand_symtabs_for_function (struct objfile *objfile,
-                                              const char *func_name)
-{
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
-  struct dw2_symtab_iterator iter;
-  struct dwarf2_per_cu_data *per_cu;
-
-  dw2_symtab_iter_init (&iter, per_objfile, {}, VAR_DOMAIN, func_name);
-
-  while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
-    dw2_instantiate_symtab (per_cu, per_objfile, false);
-
-}
-
 void
 dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
 {
@@ -3761,62 +3563,26 @@ dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
     }
 }
 
-void
-dwarf2_base_index_functions::expand_symtabs_with_fullname
-     (struct objfile *objfile, const char *fullname)
-{
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
-  /* We don't need to consider type units here.
-     This is only called for examining code, e.g. expand_line_sal.
-     There can be an order of magnitude (or more) more type units
-     than comp units, and we avoid them if we can.  */
-
-  for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
-    {
-      /* We only need to look at symtabs not already expanded.  */
-      if (per_objfile->symtab_set_p (per_cu))
-       continue;
-
-      quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
-      if (file_data == NULL)
-       continue;
-
-      for (int j = 0; j < file_data->num_file_names; ++j)
-       {
-         const char *this_fullname = file_data->file_names[j];
-
-         if (filename_cmp (this_fullname, fullname) == 0)
-           {
-             dw2_instantiate_symtab (per_cu, per_objfile, false);
-             break;
-           }
-       }
-    }
-}
-
-static void
+static bool
 dw2_expand_symtabs_matching_symbol
   (mapped_index_base &index,
    const lookup_name_info &lookup_name_in,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
-   enum search_domain kind,
    gdb::function_view<bool (offset_type)> match_callback,
    dwarf2_per_objfile *per_objfile);
 
-static void
+static bool
 dw2_expand_symtabs_matching_one
   (dwarf2_per_cu_data *per_cu,
    dwarf2_per_objfile *per_objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify);
 
-static void
-dw2_map_matching_symbols
+void
+dwarf2_gdb_index::expand_matching_symbols
   (struct objfile *objfile,
    const lookup_name_info &name, domain_enum domain,
    int global,
-   gdb::function_view<symbol_found_callback_ftype> callback,
    symbol_compare_ftype *ordered_compare)
 {
   /* Used for Ada.  */
@@ -3836,7 +3602,7 @@ dw2_map_matching_symbols
          return ordered_compare (symname, match_name) == 0;
        };
 
-      dw2_expand_symtabs_matching_symbol (index, name, matcher, ALL_DOMAIN,
+      dw2_expand_symtabs_matching_symbol (index, name, matcher,
                                          [&] (offset_type namei)
       {
        struct dw2_symtab_iterator iter;
@@ -3855,30 +3621,6 @@ dw2_map_matching_symbols
       /* We have -readnow: no .gdb_index, but no partial symtabs either.  So,
         proceed assuming all symtabs have been read in.  */
     }
-
-  for (compunit_symtab *cust : objfile->compunits ())
-    {
-      const struct block *block;
-
-      if (cust == NULL)
-       continue;
-      block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), block_kind);
-      if (!iterate_over_symbols_terminated (block, name,
-                                           domain, callback))
-       return;
-    }
-}
-
-void
-dwarf2_gdb_index::map_matching_symbols
-  (struct objfile *objfile,
-   const lookup_name_info &name, domain_enum domain,
-   int global,
-   gdb::function_view<symbol_found_callback_ftype> callback,
-   symbol_compare_ftype *ordered_compare)
-{
-  dw2_map_matching_symbols (objfile, name, domain, global, callback,
-                           ordered_compare);
 }
 
 /* Starting from a search name, return the string that finds the upper
@@ -4111,12 +3853,11 @@ mapped_index_base::build_name_components (dwarf2_per_objfile *per_objfile)
    symbol name that matches, calls MATCH_CALLBACK, passing it the
    symbol's index in the mapped_index_base symbol table.  */
 
-static void
+static bool
 dw2_expand_symtabs_matching_symbol
   (mapped_index_base &index,
    const lookup_name_info &lookup_name_in,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
-   enum search_domain kind,
    gdb::function_view<bool (offset_type)> match_callback,
    dwarf2_per_objfile *per_objfile)
 {
@@ -4197,12 +3938,16 @@ dw2_expand_symtabs_matching_symbol
 
   /* Finally call the callback, once per match.  */
   ULONGEST prev = -1;
+  bool result = true;
   for (offset_type idx : matches)
     {
       if (prev != idx)
        {
          if (!match_callback (idx))
-           break;
+           {
+             result = false;
+             break;
+           }
          prev = idx;
        }
     }
@@ -4210,6 +3955,8 @@ dw2_expand_symtabs_matching_symbol
   /* Above we use a type wider than idx's for 'prev', since 0 and
      (offset_type)-1 are both possible values.  */
   static_assert (sizeof (prev) > sizeof (offset_type), "");
+
+  return result;
 }
 
 #if GDB_SELF_TEST
@@ -4290,7 +4037,7 @@ check_match (const char *file, int line,
   auto expected_end = expected_list.end ();
 
   dw2_expand_symtabs_matching_symbol (mock_index, lookup_name,
-                                     NULL, ALL_DOMAIN,
+                                     nullptr,
                                      [&] (offset_type idx)
   {
     const char *matched_name = mock_index.symbol_name_at (idx, per_objfile);
@@ -4650,7 +4397,7 @@ run_test ()
    dw_expand_symtabs_matching_file_matcher), expand the CU and call
    EXPANSION_NOTIFY on it.  */
 
-static void
+static bool
 dw2_expand_symtabs_matching_one
   (dwarf2_per_cu_data *per_cu,
    dwarf2_per_objfile *per_objfile,
@@ -4666,31 +4413,32 @@ dw2_expand_symtabs_matching_one
       gdb_assert (symtab != nullptr);
 
       if (expansion_notify != NULL && symtab_was_null)
-       expansion_notify (symtab);
+       return expansion_notify (symtab);
     }
+  return true;
 }
 
 /* Helper for dw2_expand_matching symtabs.  Called on each symbol
    matched, to expand corresponding CUs that were marked.  IDX is the
    index of the symbol name that matched.  */
 
-static void
+static bool
 dw2_expand_marked_cus
   (dwarf2_per_objfile *per_objfile, offset_type idx,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+   block_search_flags search_flags,
    search_domain kind)
 {
-  offset_type *vec, vec_len, vec_idx;
+  offset_type vec_len, vec_idx;
   bool global_seen = false;
   mapped_index &index = *per_objfile->per_bfd->index_table;
 
-  vec = (offset_type *) (index.constant_pool
-                        + MAYBE_SWAP (index.symbol_table[idx].vec));
-  vec_len = MAYBE_SWAP (vec[0]);
+  offset_view vec (index.constant_pool.slice (index.symbol_vec_index (idx)));
+  vec_len = vec[0];
   for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
     {
-      offset_type cu_index_and_attrs = MAYBE_SWAP (vec[vec_idx + 1]);
+      offset_type cu_index_and_attrs = vec[vec_idx + 1];
       /* This value is only valid for index versions >= 7.  */
       int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
       gdb_index_symbol_kind symbol_kind =
@@ -4718,6 +4466,17 @@ dw2_expand_marked_cus
       /* Only check the symbol's kind if it has one.  */
       if (attrs_valid)
        {
+         if (is_static)
+           {
+             if ((search_flags & SEARCH_STATIC_BLOCK) == 0)
+               continue;
+           }
+         else
+           {
+             if ((search_flags & SEARCH_GLOBAL_BLOCK) == 0)
+               continue;
+           }
+
          switch (kind)
            {
            case VARIABLES_DOMAIN:
@@ -4751,9 +4510,12 @@ dw2_expand_marked_cus
        }
 
       dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cutu (cu_index);
-      dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
-                                      expansion_notify);
+      if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
+                                           expansion_notify))
+       return false;
     }
+
+  return true;
 }
 
 /* If FILE_MATCHER is non-NULL, set all the
@@ -4833,20 +4595,22 @@ dw_expand_symtabs_matching_file_matcher
     }
 }
 
-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)
+bool
+dwarf2_gdb_index::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,
+     block_search_flags search_flags,
+     domain_enum domain,
+     enum search_domain kind)
 {
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
 
   /* index_table is NULL if OBJF_READNOW.  */
   if (!per_objfile->per_bfd->index_table)
-    return;
+    return true;
 
   dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
 
@@ -4856,35 +4620,28 @@ dw2_expand_symtabs_matching
        {
          QUIT;
 
-         dw2_expand_symtabs_matching_one (per_cu, per_objfile,
-                                          file_matcher, expansion_notify);
+         if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
+                                               file_matcher,
+                                               expansion_notify))
+           return false;
        }
-      return;
+      return true;
     }
 
   mapped_index &index = *per_objfile->per_bfd->index_table;
 
-  dw2_expand_symtabs_matching_symbol (index, *lookup_name,
-                                     symbol_matcher,
-                                     kind, [&] (offset_type idx)
+  bool result
+    = dw2_expand_symtabs_matching_symbol (index, *lookup_name,
+                                         symbol_matcher,
+                                         [&] (offset_type idx)
     {
-      dw2_expand_marked_cus (per_objfile, idx, file_matcher, expansion_notify,
-                            kind);
+      if (!dw2_expand_marked_cus (per_objfile, idx, file_matcher,
+                                 expansion_notify, search_flags, kind))
+       return false;
       return true;
     }, per_objfile);
-}
 
-void
-dwarf2_gdb_index::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)
-{
-  dw2_expand_symtabs_matching (objfile, file_matcher, lookup_name,
-                              symbol_matcher, expansion_notify, kind);
+  return result;
 }
 
 /* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
@@ -4949,10 +4706,10 @@ dwarf2_base_index_functions::find_pc_sect_compunit_symtab
 }
 
 void
-dwarf2_base_index_functions::map_symbol_filenames (struct objfile *objfile,
-                                                  symbol_filename_ftype *fun,
-                                                  void *data,
-                                                  int need_fullname)
+dwarf2_base_index_functions::map_symbol_filenames
+     (struct objfile *objfile,
+      gdb::function_view<symbol_filename_ftype> fun,
+      bool need_fullname)
 {
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
 
@@ -5013,7 +4770,7 @@ dwarf2_base_index_functions::map_symbol_filenames (struct objfile *objfile,
 
       if (need_fullname)
        this_real_name = gdb_realpath (filename);
-      (*fun) (filename, this_real_name.get (), data);
+      fun (filename, this_real_name.get ());
     });
 }
 
@@ -5303,7 +5060,7 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
 
   if (!read_debug_names_from_section (objfile, objfile_name (objfile),
-                                     &per_objfile->per_bfd->debug_names, *map))
+                                     &per_bfd->debug_names, *map))
     return false;
 
   /* Don't use the index if it's empty.  */
@@ -5345,7 +5102,7 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
   per_bfd->debug_names_table = std::move (map);
   per_bfd->using_index = 1;
   per_bfd->quick_file_names_table =
-    create_quick_file_names_table (per_objfile->per_bfd->all_comp_units.size ());
+    create_quick_file_names_table (per_bfd->all_comp_units.size ());
 
   return true;
 }
@@ -5357,7 +5114,7 @@ class dw2_debug_names_iterator
 {
 public:
   dw2_debug_names_iterator (const mapped_debug_names &map,
-                           gdb::optional<block_enum> block_index,
+                           block_search_flags block_index,
                            domain_enum domain,
                            const char *name, dwarf2_per_objfile *per_objfile)
     : m_map (map), m_block_index (block_index), m_domain (domain),
@@ -5366,15 +5123,18 @@ public:
   {}
 
   dw2_debug_names_iterator (const mapped_debug_names &map,
-                           search_domain search, uint32_t namei, dwarf2_per_objfile *per_objfile)
+                           search_domain search, uint32_t namei,
+                           dwarf2_per_objfile *per_objfile,
+                           domain_enum domain = UNDEF_DOMAIN)
     : m_map (map),
+      m_domain (domain),
       m_search (search),
       m_addr (find_vec_in_debug_names (map, namei, per_objfile)),
       m_per_objfile (per_objfile)
   {}
 
   dw2_debug_names_iterator (const mapped_debug_names &map,
-                           block_enum block_index, domain_enum domain,
+                           block_search_flags block_index, domain_enum domain,
                            uint32_t namei, dwarf2_per_objfile *per_objfile)
     : m_map (map), m_block_index (block_index), m_domain (domain),
       m_addr (find_vec_in_debug_names (map, namei, per_objfile)),
@@ -5395,9 +5155,9 @@ private:
   /* The internalized form of .debug_names.  */
   const mapped_debug_names &m_map;
 
-  /* If set, only look for symbols that match that block.  Valid values are
-     GLOBAL_BLOCK and STATIC_BLOCK.  */
-  const gdb::optional<block_enum> m_block_index;
+  /* Restrict the search to these blocks.  */
+  block_search_flags m_block_index = (SEARCH_GLOBAL_BLOCK
+                                     | SEARCH_STATIC_BLOCK);
 
   /* The kind of symbol we're looking for.  */
   const domain_enum m_domain = UNDEF_DOMAIN;
@@ -5600,7 +5360,7 @@ dw2_debug_names_iterator::next ()
        {
        case DW_IDX_compile_unit:
          /* Don't crash on bad data.  */
-         if (ull >= m_per_objfile->per_bfd->all_comp_units.size ())
+         if (ull >= per_bfd->all_comp_units.size ())
            {
              complaint (_(".debug_names entry has bad CU index %s"
                           " [in module %s]"),
@@ -5646,13 +5406,18 @@ dw2_debug_names_iterator::next ()
     goto again;
 
   /* Check static vs global.  */
-  if (symbol_linkage_ != symbol_linkage::unknown && m_block_index.has_value ())
+  if (symbol_linkage_ != symbol_linkage::unknown)
     {
-       const bool want_static = *m_block_index == STATIC_BLOCK;
-       const bool symbol_is_static =
-         symbol_linkage_ == symbol_linkage::static_;
-       if (want_static != symbol_is_static)
-         goto again;
+      if (symbol_linkage_ == symbol_linkage::static_)
+       {
+         if ((m_block_index & SEARCH_STATIC_BLOCK) == 0)
+           goto again;
+       }
+      else
+       {
+         if ((m_block_index & SEARCH_GLOBAL_BLOCK) == 0)
+           goto again;
+       }
     }
 
   /* Match dw2_symtab_iter_next, symbol_kind
@@ -5752,54 +5517,6 @@ dw2_debug_names_iterator::next ()
   return per_cu;
 }
 
-struct compunit_symtab *
-dwarf2_debug_names_index::lookup_symbol
-     (struct objfile *objfile, block_enum block_index,
-      const char *name, domain_enum domain)
-{
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
-  const auto &mapp = per_objfile->per_bfd->debug_names_table;
-  if (!mapp)
-    {
-      /* index is NULL if OBJF_READNOW.  */
-      return NULL;
-    }
-  const auto &map = *mapp;
-
-  dw2_debug_names_iterator iter (map, block_index, domain, name, per_objfile);
-
-  struct compunit_symtab *stab_best = NULL;
-  struct dwarf2_per_cu_data *per_cu;
-  while ((per_cu = iter.next ()) != NULL)
-    {
-      struct symbol *sym, *with_opaque = NULL;
-      compunit_symtab *stab
-       = dw2_instantiate_symtab (per_cu, per_objfile, false);
-      const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
-      const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
-
-      sym = block_find_symbol (block, name, domain,
-                              block_find_non_opaque_type_preferred,
-                              &with_opaque);
-
-      /* Some caution must be observed with overloaded functions and
-        methods, since the index will not contain any overload
-        information (but NAME might contain it).  */
-
-      if (sym != NULL
-         && strcmp_iw (sym->search_name (), name) == 0)
-       return stab;
-      if (with_opaque != NULL
-         && strcmp_iw (with_opaque->search_name (), name) == 0)
-       stab_best = stab;
-
-      /* Keep looking through other CUs.  */
-    }
-
-  return stab_best;
-}
-
 /* This dumps minimal information about .debug_names.  It is called
    via "mt print objfiles".  The gdb.dwarf2/gdb-index.exp testcase
    uses this to verify that .debug_names has been loaded.  */
@@ -5819,31 +5536,10 @@ dwarf2_debug_names_index::dump (struct objfile *objfile)
 }
 
 void
-dwarf2_debug_names_index::expand_symtabs_for_function
-     (struct objfile *objfile, const char *func_name)
-{
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
-  /* per_objfile->per_bfd->debug_names_table is NULL if OBJF_READNOW.  */
-  if (per_objfile->per_bfd->debug_names_table)
-    {
-      const mapped_debug_names &map = *per_objfile->per_bfd->debug_names_table;
-
-      dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name,
-                                    per_objfile);
-
-      struct dwarf2_per_cu_data *per_cu;
-      while ((per_cu = iter.next ()) != NULL)
-       dw2_instantiate_symtab (per_cu, per_objfile, false);
-    }
-}
-
-void
-dwarf2_debug_names_index::map_matching_symbols
+dwarf2_debug_names_index::expand_matching_symbols
   (struct objfile *objfile,
    const lookup_name_info &name, domain_enum domain,
    int global,
-   gdb::function_view<symbol_found_callback_ftype> callback,
    symbol_compare_ftype *ordered_compare)
 {
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
@@ -5853,7 +5549,8 @@ dwarf2_debug_names_index::map_matching_symbols
     return;
 
   mapped_debug_names &map = *per_objfile->per_bfd->debug_names_table;
-  const block_enum block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
+  const block_search_flags block_flags
+    = global ? SEARCH_GLOBAL_BLOCK : SEARCH_STATIC_BLOCK;
 
   const char *match_name = name.ada ().lookup_name ().c_str ();
   auto matcher = [&] (const char *symname)
@@ -5863,12 +5560,12 @@ dwarf2_debug_names_index::map_matching_symbols
       return ordered_compare (symname, match_name) == 0;
     };
 
-  dw2_expand_symtabs_matching_symbol (map, name, matcher, ALL_DOMAIN,
+  dw2_expand_symtabs_matching_symbol (map, name, matcher,
                                      [&] (offset_type namei)
     {
       /* The name was matched, now expand corresponding CUs that were
         marked.  */
-      dw2_debug_names_iterator iter (map, block_kind, domain, namei,
+      dw2_debug_names_iterator iter (map, block_flags, domain, namei,
                                     per_objfile);
 
       struct dwarf2_per_cu_data *per_cu;
@@ -5877,39 +5574,24 @@ dwarf2_debug_names_index::map_matching_symbols
                                         nullptr);
       return true;
     }, per_objfile);
-
-  /* It's a shame we couldn't do this inside the
-     dw2_expand_symtabs_matching_symbol callback, but that skips CUs
-     that have already been expanded.  Instead, this loop matches what
-     the psymtab code does.  */
-  for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
-    {
-      compunit_symtab *symtab = per_objfile->get_symtab (per_cu);
-      if (symtab != nullptr)
-       {
-         const struct block *block
-           = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (symtab), block_kind);
-         if (!iterate_over_symbols_terminated (block, name,
-                                               domain, callback))
-           break;
-       }
-    }
 }
 
-void
+bool
 dwarf2_debug_names_index::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,
+   block_search_flags search_flags,
+   domain_enum domain,
    enum search_domain kind)
 {
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
 
   /* debug_names_table is NULL if OBJF_READNOW.  */
   if (!per_objfile->per_bfd->debug_names_table)
-    return;
+    return true;
 
   dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
 
@@ -5919,28 +5601,35 @@ dwarf2_debug_names_index::expand_symtabs_matching
        {
          QUIT;
 
-         dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
-                                          expansion_notify);
+         if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
+                                               file_matcher,
+                                               expansion_notify))
+           return false;
        }
-      return;
+      return true;
     }
 
   mapped_debug_names &map = *per_objfile->per_bfd->debug_names_table;
 
-  dw2_expand_symtabs_matching_symbol (map, *lookup_name,
-                                     symbol_matcher,
-                                     kind, [&] (offset_type namei)
+  bool result
+    = dw2_expand_symtabs_matching_symbol (map, *lookup_name,
+                                         symbol_matcher,
+                                         [&] (offset_type namei)
     {
       /* The name was matched, now expand corresponding CUs that were
         marked.  */
-      dw2_debug_names_iterator iter (map, kind, namei, per_objfile);
+      dw2_debug_names_iterator iter (map, kind, namei, per_objfile, domain);
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
-       dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
-                                        expansion_notify);
+       if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
+                                             file_matcher,
+                                             expansion_notify))
+         return false;
       return true;
     }, per_objfile);
+
+  return result;
 }
 
 /* Get the content of the .gdb_index section of OBJ.  SECTION_OWNER should point
@@ -5997,10 +5686,10 @@ get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz)
   return global_index_cache.lookup_gdb_index (build_id, &dwz->index_cache_res);
 }
 
-/* See symfile.h.  */
+/* See dwarf2/public.h.  */
 
-bool
-dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
+void
+dwarf2_initialize_objfile (struct objfile *objfile)
 {
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
@@ -6020,9 +5709,9 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
       if (per_bfd->using_index)
        {
          dwarf_read_debug_printf ("using_index already set");
-         *index_kind = dw_index_kind::GDB_INDEX;
          per_objfile->resize_symtabs ();
-         return true;
+         objfile->qf.push_front (make_dwarf_gdb_index ());
+         return;
        }
 
       per_bfd->using_index = 1;
@@ -6041,11 +5730,11 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
                                            struct dwarf2_per_cu_quick_data);
        }
 
-      /* Return 1 so that gdb sees the "quick" functions.  However,
-        these functions will be no-ops because we will have expanded
-        all symtabs.  */
-      *index_kind = dw_index_kind::GDB_INDEX;
-      return true;
+      /* Arrange for gdb to see the "quick" functions.  However, these
+        functions will be no-ops because we will have expanded all
+        symtabs.  */
+      objfile->qf.push_front (make_dwarf_gdb_index ());
+      return;
     }
 
   /* Was a debug names index already read when we processed an objfile sharing
@@ -6053,9 +5742,9 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
   if (per_bfd->debug_names_table != nullptr)
     {
       dwarf_read_debug_printf ("re-using shared debug names table");
-      *index_kind = dw_index_kind::DEBUG_NAMES;
       per_objfile->resize_symtabs ();
-      return true;
+      objfile->qf.push_front (make_dwarf_debug_names ());
+      return;
     }
 
   /* Was a GDB index already read when we processed an objfile sharing
@@ -6063,9 +5752,9 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
   if (per_bfd->index_table != nullptr)
     {
       dwarf_read_debug_printf ("re-using shared index table");
-      *index_kind = dw_index_kind::GDB_INDEX;
       per_objfile->resize_symtabs ();
-      return true;
+      objfile->qf.push_front (make_dwarf_gdb_index ());
+      return;
     }
 
   /* There might already be partial symtabs built for this BFD.  This happens
@@ -6076,15 +5765,16 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
   if (per_bfd->partial_symtabs != nullptr)
     {
       dwarf_read_debug_printf ("re-using shared partial symtabs");
-      return false;
+      objfile->qf.push_front (make_lazy_dwarf_reader ());
+      return;
     }
 
   if (dwarf2_read_debug_names (per_objfile))
     {
       dwarf_read_debug_printf ("found debug names");
-      *index_kind = dw_index_kind::DEBUG_NAMES;
       per_objfile->resize_symtabs ();
-      return true;
+      objfile->qf.push_front (make_dwarf_debug_names ());
+      return;
     }
 
   if (dwarf2_read_gdb_index (per_objfile,
@@ -6092,9 +5782,9 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
                             get_gdb_index_contents_from_section<dwz_file>))
     {
       dwarf_read_debug_printf ("found gdb index from file");
-      *index_kind = dw_index_kind::GDB_INDEX;
       per_objfile->resize_symtabs ();
-      return true;
+      objfile->qf.push_front (make_dwarf_gdb_index ());
+      return;
     }
 
   /* ... otherwise, try to find the index in the index cache.  */
@@ -6104,13 +5794,13 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
     {
       dwarf_read_debug_printf ("found gdb index from cache");
       global_index_cache.hit ();
-      *index_kind = dw_index_kind::GDB_INDEX;
       per_objfile->resize_symtabs ();
-      return true;
+      objfile->qf.push_front (make_dwarf_gdb_index ());
+      return;
     }
 
   global_index_cache.miss ();
-  return false;
+  objfile->qf.push_front (make_lazy_dwarf_reader ());
 }
 
 \f
@@ -6118,7 +5808,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
 /* Build a partial symbol table.  */
 
 void
-dwarf2_build_psymtabs (struct objfile *objfile)
+dwarf2_build_psymtabs (struct objfile *objfile, psymbol_functions *psf)
 {
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
@@ -6127,23 +5817,37 @@ dwarf2_build_psymtabs (struct objfile *objfile)
     {
       /* Partial symbols were already read, so now we can simply
         attach them.  */
-      objfile->partial_symtabs = per_bfd->partial_symtabs;
+      if (psf == nullptr)
+       {
+         psf = new psymbol_functions (per_bfd->partial_symtabs);
+         objfile->qf.emplace_front (psf);
+       }
+      else
+       psf->set_partial_symtabs (per_bfd->partial_symtabs);
       per_objfile->resize_symtabs ();
       return;
     }
 
+  if (psf == nullptr)
+    {
+      psf = new psymbol_functions;
+      objfile->qf.emplace_front (psf);
+    }
+  const std::shared_ptr<psymtab_storage> &partial_symtabs
+    = psf->get_partial_symtabs ();
+
   /* Set the local reference to partial symtabs, so that we don't try
      to read them again if reading another objfile with the same BFD.
      If we can't in fact share, this won't make a difference anyway as
      the dwarf2_per_bfd object won't be shared.  */
-  per_bfd->partial_symtabs = objfile->partial_symtabs;
+  per_bfd->partial_symtabs = partial_symtabs;
 
   try
     {
       /* This isn't really ideal: all the data we allocate on the
         objfile's obstack is still uselessly kept around.  However,
         freeing it seems unsafe.  */
-      psymtab_discarder psymtabs (objfile->partial_symtabs.get ());
+      psymtab_discarder psymtabs (partial_symtabs.get ());
       dwarf2_build_psymtabs_hard (per_objfile);
       psymtabs.keep ();
 
@@ -6231,8 +5935,10 @@ read_abbrev_offset (dwarf2_per_objfile *per_objfile,
 /* A partial symtab that is used only for include files.  */
 struct dwarf2_include_psymtab : public partial_symtab
 {
-  dwarf2_include_psymtab (const char *filename, struct objfile *objfile)
-    : partial_symtab (filename, objfile)
+  dwarf2_include_psymtab (const char *filename,
+                         psymtab_storage *partial_symtabs,
+                         objfile_per_bfd_storage *objfile_per_bfd)
+    : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
   {
   }
 
@@ -6285,10 +5991,13 @@ private:
 
 static void
 dwarf2_create_include_psymtab (dwarf2_per_bfd *per_bfd,
-                              const char *name, dwarf2_psymtab *pst,
-                              struct objfile *objfile)
+                              const char *name,
+                              dwarf2_psymtab *pst,
+                              psymtab_storage *partial_symtabs,
+                              objfile_per_bfd_storage *objfile_per_bfd)
 {
-  dwarf2_include_psymtab *subpst = new dwarf2_include_psymtab (name, objfile);
+  dwarf2_include_psymtab *subpst
+    = new dwarf2_include_psymtab (name, partial_symtabs, objfile_per_bfd);
 
   if (!IS_ABSOLUTE_PATH (subpst->filename))
     subpst->dirname = pst->dirname;
@@ -7440,7 +7149,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
   struct dwarf2_per_cu_data *per_cu;
   struct type_unit_group *tu_group;
 
-  tu_group = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, type_unit_group);
+  tu_group = OBSTACK_ZALLOC (&per_bfd->obstack, type_unit_group);
   per_cu = &tu_group->per_cu;
   per_cu->per_bfd = per_bfd;
 
@@ -7540,10 +7249,9 @@ create_partial_symtab (dwarf2_per_cu_data *per_cu,
                       dwarf2_per_objfile *per_objfile,
                       const char *name)
 {
-  struct objfile *objfile = per_objfile->objfile;
-  dwarf2_psymtab *pst;
-
-  pst = new dwarf2_psymtab (name, objfile, per_cu);
+  dwarf2_psymtab *pst
+    = new dwarf2_psymtab (name, per_objfile->per_bfd->partial_symtabs.get (),
+                         per_objfile->objfile->per_bfd, per_cu);
 
   pst->psymtabs_addrmap_supported = true;
 
@@ -7719,7 +7427,10 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
       this_cu->unit_type = DW_UT_type;
       break;
     default:
-      abort ();
+      error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"),
+            dwarf_tag_name (reader.comp_unit_die->tag),
+            sect_offset_str (reader.cu->per_cu->sect_off),
+            objfile_name (per_objfile->objfile));
     }
 
   if (reader.dummy_p)
@@ -8062,8 +7773,7 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
                           objfile_name (objfile));
 
   scoped_restore restore_reading_psyms
-    = make_scoped_restore (&per_objfile->per_bfd->reading_partial_symbols,
-                          true);
+    = make_scoped_restore (&per_bfd->reading_partial_symbols, true);
 
   per_bfd->info.read (objfile);
 
@@ -8657,7 +8367,9 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
                                            &objfile->objfile_obstack);
          psymbol.ginfo.set_linkage_name (pdi->linkage_name);
        }
-      cu->per_cu->v.psymtab->add_psymbol (psymbol, *where, objfile);
+      cu->per_cu->v.psymtab->add_psymbol
+       (psymbol, *where, per_objfile->per_bfd->partial_symtabs.get (),
+        objfile);
     }
 }
 
@@ -9974,6 +9686,21 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
 
   dwarf2_find_base_address (cu->dies, cu);
 
+  /* Before we start reading the top-level DIE, ensure it has a valid tag
+     type.  */
+  switch (cu->dies->tag)
+    {
+    case DW_TAG_compile_unit:
+    case DW_TAG_partial_unit:
+    case DW_TAG_type_unit:
+      break;
+    default:
+      error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"),
+            dwarf_tag_name (cu->dies->tag),
+            sect_offset_str (cu->per_cu->sect_off),
+            objfile_name (per_objfile->objfile));
+    }
+
   /* Do line number decoding in read_file_scope () */
   process_die (cu->dies, cu);
 
@@ -12685,6 +12412,13 @@ try_open_dwop_file (dwarf2_per_objfile *per_objfile,
   else
     search_path = debug_file_directory;
 
+  /* Add the path for the executable binary to the list of search paths.  */
+  std::string objfile_dir = ldirname (objfile_name (per_objfile->objfile));
+  search_path_holder.reset (concat (objfile_dir.c_str (),
+                                   dirname_separator_string,
+                                   search_path, nullptr));
+  search_path = search_path_holder.get ();
+
   openp_flags flags = OPF_RETURN_REALPATH;
   if (is_dwp)
     flags |= OPF_SEARCH_IN_PATH;
@@ -13447,6 +13181,37 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
               sect_offset_str (die->sect_off),
               sect_offset_str (origin_die->sect_off));
 
+  /* Find if the concrete and abstract trees are structurally the
+     same.  This is a shallow traversal and it is not bullet-proof;
+     the compiler can trick the debugger into believing that the trees
+     are isomorphic, whereas they actually are not.  However, the
+     likelyhood of this happening is pretty low, and a full-fledged
+     check would be an overkill.  */
+  bool are_isomorphic = true;
+  die_info *concrete_child = die->child;
+  die_info *abstract_child = origin_die->child;
+  while (concrete_child != nullptr || abstract_child != nullptr)
+    {
+      if (concrete_child == nullptr
+         || abstract_child == nullptr
+         || concrete_child->tag != abstract_child->tag)
+       {
+         are_isomorphic = false;
+         break;
+       }
+
+      concrete_child = concrete_child->sibling;
+      abstract_child = abstract_child->sibling;
+    }
+
+  /* Walk the origin's children in parallel to the concrete children.
+     This helps match an origin child in case the debug info misses
+     DW_AT_abstract_origin attributes.  Keep in mind that the abstract
+     origin tree may not have the same tree structure as the concrete
+     DIE, though.  */
+  die_info *corresponding_abstract_child
+    = are_isomorphic ? origin_die->child : nullptr;
+
   std::vector<sect_offset> offsets;
 
   for (child_die = die->child;
@@ -13463,7 +13228,12 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
         one.  */
       if (child_die->tag == DW_TAG_call_site
          || child_die->tag == DW_TAG_GNU_call_site)
-       continue;
+       {
+         if (are_isomorphic)
+           corresponding_abstract_child
+             = corresponding_abstract_child->sibling;
+         continue;
+       }
 
       /* For each CHILD_DIE, find the corresponding child of
         ORIGIN_DIE.  If there is more than one layer of
@@ -13482,6 +13252,14 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
                                             &child_origin_cu);
        }
 
+      /* If missing DW_AT_abstract_origin, try the corresponding child
+        of the origin.  Clang emits such lexical scopes.  */
+      if (child_origin_die == child_die
+         && dwarf2_attr (child_die, DW_AT_abstract_origin, cu) == nullptr
+         && are_isomorphic
+         && child_die->tag == DW_TAG_lexical_block)
+       child_origin_die = corresponding_abstract_child;
+
       /* According to DWARF3 3.3.8.2 #3 new entries without their abstract
         counterpart may exist.  */
       if (child_origin_die != child_die)
@@ -13501,6 +13279,9 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
          else
            offsets.push_back (child_origin_die->sect_off);
        }
+
+      if (are_isomorphic)
+       corresponding_abstract_child = corresponding_abstract_child->sibling;
     }
   std::sort (offsets.begin (), offsets.end ());
   sect_offset *offsets_end = offsets.data () + offsets.size ();
@@ -13608,6 +13389,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
        }
     }
 
+  gdb_assert (cu->get_builder () != nullptr);
   newobj = cu->get_builder ()->push_context (0, lowpc);
   newobj->name = new_symbol (die, read_type_die (die, cu), cu,
                             (struct symbol *) templ_func);
@@ -16106,7 +15888,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
-    TYPE_DECLARED_CLASS (type) = 1;
+    type->set_is_declared_class (true);
 
   /* Store the calling convention in the type if it's available in
      the die.  Otherwise the calling convention remains set to
@@ -16636,7 +16418,7 @@ update_enumeration_type_from_children (struct die_info *die,
     type->set_is_unsigned (true);
 
   if (flag_enum)
-    TYPE_FLAG_ENUM (type) = 1;
+    type->set_is_flag_enum (true);
 }
 
 /* Given a DW_AT_enumeration_type die, set its type.  We do not
@@ -16720,7 +16502,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
        set_type_align (type, TYPE_RAW_ALIGN (underlying_type));
     }
 
-  TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
+  type->set_is_declared_class (dwarf2_flag_true_p (die, DW_AT_enum_class, cu));
 
   set_die_type (die, type, cu);
 
@@ -21966,8 +21748,10 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
              psymtab_include_file_name (lh, file_entry, pst,
                                         comp_dir, &name_holder);
            if (include_name != NULL)
-             dwarf2_create_include_psymtab (cu->per_objfile->per_bfd,
-                                            include_name, pst, objfile);
+             dwarf2_create_include_psymtab
+               (cu->per_objfile->per_bfd, include_name, pst,
+                cu->per_objfile->per_bfd->partial_symtabs.get (),
+                objfile->per_bfd);
          }
     }
   else
@@ -23264,7 +23048,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
        return determine_prefix (parent, cu);
       case DW_TAG_enumeration_type:
        parent_type = read_type_die (parent, cu);
-       if (TYPE_DECLARED_CLASS (parent_type))
+       if (parent_type->is_declared_class ())
          {
            if (parent_type->name () != NULL)
              return parent_type->name ();
This page took 0.049904 seconds and 4 git commands to generate.