Move some declarations to source.h
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index d97ef922662ef6abdf0a4ce9b5f628cfe2a31c7f..93453431c155273e66c653a55f40dedc6de68aba 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF 2 debugging format support for GDB.
 
-   Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
    Inc.  with support from Florida State University (under contract
 #include "common/gdb_optional.h"
 #include "common/underlying.h"
 #include "common/byte-vector.h"
+#include "common/hash_enum.h"
 #include "filename-seen-cache.h"
+#include "producer.h"
 #include <fcntl.h>
 #include <sys/types.h>
 #include <algorithm>
 #include <unordered_set>
 #include <unordered_map>
-
-typedef struct symbol *symbolp;
-DEF_VEC_P (symbolp);
+#include "selftest.h"
+#include <cmath>
+#include <set>
+#include <forward_list>
 
 /* When == 1, print basic high level tracing messages.
    When > 1, be more verbose.
@@ -181,30 +184,185 @@ DEF_VEC_I (offset_type);
     GDB_INDEX_CU_SET_VALUE((cu_index), (value)); \
   } while (0)
 
+#if WORDS_BIGENDIAN
+
+/* Convert VALUE between big- and little-endian.  */
+
+static offset_type
+byte_swap (offset_type value)
+{
+  offset_type result;
+
+  result = (value & 0xff) << 24;
+  result |= (value & 0xff00) << 8;
+  result |= (value & 0xff0000) >> 8;
+  result |= (value & 0xff000000) >> 24;
+  return result;
+}
+
+#define MAYBE_SWAP(V)  byte_swap (V)
+
+#else
+#define MAYBE_SWAP(V) static_cast<offset_type> (V)
+#endif /* WORDS_BIGENDIAN */
+
+/* An index into a (C++) symbol name component in a symbol name as
+   recorded in the mapped_index's symbol table.  For each C++ symbol
+   in the symbol table, we record one entry for the start of each
+   component in the symbol in a table of name components, and then
+   sort the table, in order to be able to binary search symbol names,
+   ignoring leading namespaces, both completion and regular look up.
+   For example, for symbol "A::B::C", we'll have an entry that points
+   to "A::B::C", another that points to "B::C", and another for "C".
+   Note that function symbols in GDB index have no parameter
+   information, just the function/method names.  You can convert a
+   name_component to a "const char *" using the
+   'mapped_index::symbol_name_at(offset_type)' method.  */
+
+struct name_component
+{
+  /* Offset in the symbol name where the component starts.  Stored as
+     a (32-bit) offset instead of a pointer to save memory and improve
+     locality on 64-bit architectures.  */
+  offset_type name_offset;
+
+  /* The symbol's index in the symbol and constant pool tables of a
+     mapped_index.  */
+  offset_type idx;
+};
+
+/* Base class containing bits shared by both .gdb_index and
+   .debug_name indexes.  */
+
+struct mapped_index_base
+{
+  /* The name_component table (a sorted vector).  See name_component's
+     description above.  */
+  std::vector<name_component> name_components;
+
+  /* How NAME_COMPONENTS is sorted.  */
+  enum case_sensitivity name_components_casing;
+
+  /* Return the number of names in the symbol table.  */
+  virtual size_t symbol_name_count () const = 0;
+
+  /* Get the name of the symbol at IDX in the symbol table.  */
+  virtual const char *symbol_name_at (offset_type idx) const = 0;
+
+  /* Return whether the name at IDX in the symbol table should be
+     ignored.  */
+  virtual bool symbol_name_slot_invalid (offset_type idx) const
+  {
+    return false;
+  }
+
+  /* Build the symbol name component sorted vector, if we haven't
+     yet.  */
+  void build_name_components ();
+
+  /* Returns the lower (inclusive) and upper (exclusive) bounds of the
+     possible matches for LN_NO_PARAMS in the name component
+     vector.  */
+  std::pair<std::vector<name_component>::const_iterator,
+           std::vector<name_component>::const_iterator>
+    find_name_components_bounds (const lookup_name_info &ln_no_params) const;
+
+  /* Prevent deleting/destroying via a base class pointer.  */
+protected:
+  ~mapped_index_base() = default;
+};
+
 /* A description of the mapped index.  The file format is described in
    a comment by the code that writes the index.  */
-struct mapped_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;
 
   /* The total length of the buffer.  */
   off_t total_size;
 
-  /* A pointer to the address table data.  */
-  const gdb_byte *address_table;
-
-  /* Size of the address table data in bytes.  */
-  offset_type address_table_size;
+  /* The address table data.  */
+  gdb::array_view<const gdb_byte> address_table;
 
   /* The symbol table, implemented as a hash table.  */
-  const offset_type *symbol_table;
-
-  /* Size in slots, each slot is 2 offset_types.  */
-  offset_type symbol_table_slots;
+  gdb::array_view<symbol_table_slot> symbol_table;
 
   /* A pointer to the constant pool.  */
   const char *constant_pool;
+
+  bool symbol_name_slot_invalid (offset_type idx) const override
+  {
+    const auto &bucket = this->symbol_table[idx];
+    return bucket.name == 0 && bucket.vec;
+  }
+
+  /* Convenience method to get at the name of the symbol at IDX in the
+     symbol table.  */
+  const char *symbol_name_at (offset_type idx) const override
+  { return this->constant_pool + MAYBE_SWAP (this->symbol_table[idx].name); }
+
+  size_t symbol_name_count () const override
+  { return this->symbol_table.size (); }
+};
+
+/* A description of the mapped .debug_names.
+   Uninitialized map has CU_COUNT 0.  */
+struct mapped_debug_names final : public mapped_index_base
+{
+  mapped_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile_)
+  : dwarf2_per_objfile (dwarf2_per_objfile_)
+  {}
+
+  struct dwarf2_per_objfile *dwarf2_per_objfile;
+  bfd_endian dwarf5_byte_order;
+  bool dwarf5_is_dwarf64;
+  bool augmentation_is_gdb;
+  uint8_t offset_size;
+  uint32_t cu_count = 0;
+  uint32_t tu_count, bucket_count, name_count;
+  const gdb_byte *cu_table_reordered, *tu_table_reordered;
+  const uint32_t *bucket_table_reordered, *hash_table_reordered;
+  const gdb_byte *name_table_string_offs_reordered;
+  const gdb_byte *name_table_entry_offs_reordered;
+  const gdb_byte *entry_pool;
+
+  struct index_val
+  {
+    ULONGEST dwarf_tag;
+    struct attr
+    {
+      /* Attribute name DW_IDX_*.  */
+      ULONGEST dw_idx;
+
+      /* Attribute form DW_FORM_*.  */
+      ULONGEST form;
+
+      /* Value if FORM is DW_FORM_implicit_const.  */
+      LONGEST implicit_const;
+    };
+    std::vector<attr> attr_vec;
+  };
+
+  std::unordered_map<ULONGEST, index_val> abbrev_map;
+
+  const char *namei_to_name (uint32_t namei) const;
+
+  /* Implementation of the mapped_index_base virtual interface, for
+     the name_components cache.  */
+
+  const char *symbol_name_at (offset_type idx) const override
+  { return namei_to_name (idx); }
+
+  size_t symbol_name_count () const override
+  { return this->name_count; }
 };
 
 typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr;
@@ -232,9 +390,7 @@ struct dwarf2_per_objfile
 
   ~dwarf2_per_objfile ();
 
-  /* Disable copy.  */
-  dwarf2_per_objfile (const dwarf2_per_objfile &) = delete;
-  void operator= (const dwarf2_per_objfile &) = delete;
+  DISABLE_COPY_AND_ASSIGN (dwarf2_per_objfile);
 
   /* Free all cached compilation units.  */
   void free_cached_comp_units ();
@@ -261,6 +417,8 @@ public:
   dwarf2_section_info frame {};
   dwarf2_section_info eh_frame {};
   dwarf2_section_info gdb_index {};
+  dwarf2_section_info debug_names {};
+  dwarf2_section_info debug_aranges {};
 
   VEC (dwarf2_section_info_def) *types = NULL;
 
@@ -326,6 +484,9 @@ public:
   /* The mapped index, or NULL if .gdb_index is missing or not being used.  */
   mapped_index *index_table = NULL;
 
+  /* The mapped index, or NULL if .debug_names is missing or not being used.  */
+  std::unique_ptr<mapped_debug_names> debug_names_table;
+
   /* When using index_table, this keeps track of all quick_file_names entries.
      TUs typically share line table entries with a CU, so we maintain a
      separate table of all line table entries to support the sharing.
@@ -355,7 +516,24 @@ public:
   gdb::optional<filename_seen_cache> filenames_cache;
 };
 
-static struct dwarf2_per_objfile *dwarf2_per_objfile;
+/* Get the dwarf2_per_objfile associated to OBJFILE.  */
+
+struct dwarf2_per_objfile *
+get_dwarf2_per_objfile (struct objfile *objfile)
+{
+  return ((struct dwarf2_per_objfile *)
+         objfile_data (objfile, dwarf2_objfile_data_key));
+}
+
+/* Set the dwarf2_per_objfile associated to OBJFILE.  */
+
+void
+set_dwarf2_per_objfile (struct objfile *objfile,
+                       struct dwarf2_per_objfile *dwarf2_per_objfile)
+{
+  gdb_assert (get_dwarf2_per_objfile (objfile) == NULL);
+  set_objfile_data (objfile, dwarf2_objfile_data_key, dwarf2_per_objfile);
+}
 
 /* Default names of the debugging sections.  */
 
@@ -380,6 +558,8 @@ static const struct dwarf2_debug_sections dwarf2_elf_names =
   { ".debug_frame", ".zdebug_frame" },
   { ".eh_frame", NULL },
   { ".gdb_index", ".zgdb_index" },
+  { ".debug_names", ".zdebug_names" },
+  { ".debug_aranges", ".zdebug_aranges" },
   23
 };
 
@@ -472,29 +652,28 @@ struct delayed_method_info
   struct die_info *die;
 };
 
-typedef struct delayed_method_info delayed_method_info;
-DEF_VEC_O (delayed_method_info);
-
 /* Internal state when decoding a particular compilation unit.  */
 struct dwarf2_cu
 {
-  /* The objfile containing this compilation unit.  */
-  struct objfile *objfile;
+  explicit dwarf2_cu (struct dwarf2_per_cu_data *per_cu);
+  ~dwarf2_cu ();
+
+  DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
 
   /* The header of the compilation unit.  */
-  struct comp_unit_head header;
+  struct comp_unit_head header {};
 
   /* Base address of this compilation unit.  */
-  CORE_ADDR base_address;
+  CORE_ADDR base_address = 0;
 
   /* Non-zero if base_address has been set.  */
-  int base_known;
+  int base_known = 0;
 
   /* The language we are debugging.  */
-  enum language language;
-  const struct language_defn *language_defn;
+  enum language language = language_unknown;
+  const struct language_defn *language_defn = nullptr;
 
-  const char *producer;
+  const char *producer = nullptr;
 
   /* The generic symbol table building routines have separate lists for
      file scope symbols and all all other scopes (local scopes).  So
@@ -505,60 +684,55 @@ struct dwarf2_cu
      first local scope, and all other local scopes as nested local
      scopes, and worked fine.  Check to see if we really need to
      distinguish these in buildsym.c.  */
-  struct pending **list_in_scope;
-
-  /* The abbrev table for this CU.
-     Normally this points to the abbrev table in the objfile.
-     But if DWO_UNIT is non-NULL this is the abbrev table in the DWO file.  */
-  struct abbrev_table *abbrev_table;
+  struct pending **list_in_scope = nullptr;
 
   /* Hash table holding all the loaded partial DIEs
      with partial_die->offset.SECT_OFF as hash.  */
-  htab_t partial_dies;
+  htab_t partial_dies = nullptr;
 
   /* Storage for things with the same lifetime as this read-in compilation
      unit, including partial DIEs.  */
-  struct obstack comp_unit_obstack;
+  auto_obstack comp_unit_obstack;
 
   /* When multiple dwarf2_cu structures are living in memory, this field
      chains them all together, so that they can be released efficiently.
      We will probably also want a generation counter so that most-recently-used
      compilation units are cached...  */
-  struct dwarf2_per_cu_data *read_in_chain;
+  struct dwarf2_per_cu_data *read_in_chain = nullptr;
 
   /* Backlink to our per_cu entry.  */
   struct dwarf2_per_cu_data *per_cu;
 
   /* How many compilation units ago was this CU last referenced?  */
-  int last_used;
+  int last_used = 0;
 
   /* A hash table of DIE cu_offset for following references with
      die_info->offset.sect_off as hash.  */
-  htab_t die_hash;
+  htab_t die_hash = nullptr;
 
   /* Full DIEs if read in.  */
-  struct die_info *dies;
+  struct die_info *dies = nullptr;
 
   /* A set of pointers to dwarf2_per_cu_data objects for compilation
      units referenced by this one.  Only set during full symbol processing;
      partial symbol tables do not have dependencies.  */
-  htab_t dependencies;
+  htab_t dependencies = nullptr;
 
   /* Header data from the line table, during full symbol processing.  */
-  struct line_header *line_header;
+  struct line_header *line_header = nullptr;
   /* Non-NULL if LINE_HEADER is owned by this DWARF_CU.  Otherwise,
      it's owned by dwarf2_per_objfile::line_header_hash.  If non-NULL,
      this is the DW_TAG_compile_unit die for this CU.  We'll hold on
      to the line header as long as this DIE is being processed.  See
      process_die_scope.  */
-  die_info *line_header_die_owner;
+  die_info *line_header_die_owner = nullptr;
 
   /* A list of methods which need to have physnames computed
      after all type information has been read.  */
-  VEC (delayed_method_info) *method_list;
+  std::vector<delayed_method_info> method_list;
 
   /* To be copied to symtab->call_site_htab.  */
-  htab_t call_site_htab;
+  htab_t call_site_htab = nullptr;
 
   /* Non-NULL if this CU came from a DWO file.
      There is an invariant here that is important to remember:
@@ -569,12 +743,12 @@ struct dwarf2_cu
      is moot), or there is and either we're not going to read it (in which
      case this is NULL) or there is and we are reading it (in which case this
      is non-NULL).  */
-  struct dwo_unit *dwo_unit;
+  struct dwo_unit *dwo_unit = nullptr;
 
   /* The DW_AT_addr_base attribute if present, zero otherwise
      (zero is a valid value though).
      Note this value comes from the Fission stub CU/TU's DIE.  */
-  ULONGEST addr_base;
+  ULONGEST addr_base = 0;
 
   /* The DW_AT_ranges_base attribute if present, zero otherwise
      (zero is a valid value though).
@@ -586,7 +760,7 @@ struct dwarf2_cu
      DW_AT_ranges appeared in the DW_TAG_compile_unit of DWO DIEs: then
      DW_AT_ranges_base *would* have to be applied, and we'd have to care
      whether the DW_AT_ranges attribute came from the skeleton or DWO.  */
-  ULONGEST ranges_base;
+  ULONGEST ranges_base = 0;
 
   /* Mark used when releasing cached dies.  */
   unsigned int mark : 1;
@@ -604,7 +778,7 @@ struct dwarf2_cu
   unsigned int checked_producer : 1;
   unsigned int producer_is_gxx_lt_4_6 : 1;
   unsigned int producer_is_gcc_lt_4_3 : 1;
-  unsigned int producer_is_icc : 1;
+  unsigned int producer_is_icc_lt_14 : 1;
 
   /* When set, the file that we're processing is known to have
      debugging info for C++ namespaces.  GCC 3.3.x did not produce
@@ -674,10 +848,8 @@ struct dwarf2_per_cu_data
      dummy CUs (a CU header, but nothing else).  */
   struct dwarf2_cu *cu;
 
-  /* The corresponding objfile.
-     Normally we can get the objfile from dwarf2_per_objfile.
-     However we can enter this file with just a "per_cu" handle.  */
-  struct objfile *objfile;
+  /* The corresponding dwarf2_per_objfile.  */
+  struct dwarf2_per_objfile *dwarf2_per_objfile;
 
   /* When dwarf2_per_objfile->using_index is true, the 'quick' field
      is active.  Otherwise, the 'psymtab' field is active.  */
@@ -1046,6 +1218,7 @@ struct dwz_file
   struct dwarf2_section_info line;
   struct dwarf2_section_info macro;
   struct dwarf2_section_info gdb_index;
+  struct dwarf2_section_info debug_names;
 
   /* The dwz's BFD.  */
   bfd *dwz_bfd;
@@ -1079,6 +1252,9 @@ struct die_reader_specs
 
   /* The value of the DW_AT_comp_dir attribute.  */
   const char *comp_dir;
+
+  /* The abbreviation table to use when reading the DIEs.  */
+  struct abbrev_table *abbrev_table;
 };
 
 /* Type of function passed to init_cutu_and_read_dies, et.al.  */
@@ -1335,20 +1511,47 @@ struct attr_abbrev
 
 struct abbrev_table
 {
+  explicit abbrev_table (sect_offset off)
+    : sect_off (off)
+  {
+    m_abbrevs =
+      XOBNEWVEC (&abbrev_obstack, struct abbrev_info *, ABBREV_HASH_SIZE);
+    memset (m_abbrevs, 0, ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
+  }
+
+  DISABLE_COPY_AND_ASSIGN (abbrev_table);
+
+  /* Allocate space for a struct abbrev_info object in
+     ABBREV_TABLE.  */
+  struct abbrev_info *alloc_abbrev ();
+
+  /* Add an abbreviation to the table.  */
+  void add_abbrev (unsigned int abbrev_number, struct abbrev_info *abbrev);
+
+  /* Look up an abbrev in the table.
+     Returns NULL if the abbrev is not found.  */
+
+  struct abbrev_info *lookup_abbrev (unsigned int abbrev_number);
+
+
   /* Where the abbrev table came from.
      This is used as a sanity check when the table is used.  */
-  sect_offset sect_off;
+  const sect_offset sect_off;
 
   /* Storage for the abbrev table.  */
-  struct obstack abbrev_obstack;
+  auto_obstack abbrev_obstack;
+
+private:
 
   /* Hash table of abbrevs.
      This is an array of size ABBREV_HASH_SIZE allocated in abbrev_obstack.
      It could be statically allocated, but the previous code didn't so we
      don't either.  */
-  struct abbrev_info **abbrevs;
+  struct abbrev_info **m_abbrevs;
 };
 
+typedef std::unique_ptr<struct abbrev_table> abbrev_table_up;
+
 /* Attributes have a name and a value.  */
 struct attribute
   {
@@ -1462,10 +1665,10 @@ struct fnfieldlist
   struct nextfnfield *head;
 };
 
-struct typedef_field_list
+struct decl_field_list
 {
-  struct typedef_field field;
-  struct typedef_field_list *next;
+  struct decl_field field;
+  struct decl_field_list *next;
 };
 
 /* The routines that read and process dies for a C struct or C++ class
@@ -1495,8 +1698,13 @@ struct field_info
 
     /* typedefs defined inside this class.  TYPEDEF_FIELD_LIST contains head of
        a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements.  */
-    struct typedef_field_list *typedef_field_list;
+    struct decl_field_list *typedef_field_list;
     unsigned typedef_field_list_count;
+
+    /* Nested types defined by this class and the number of elements in this
+       list.  */
+    struct decl_field_list *nested_types_list;
+    unsigned nested_types_list_count;
   };
 
 /* One item on the queue of compilation units to read in full symbols
@@ -1543,7 +1751,8 @@ static void build_type_psymtabs_reader (const struct die_reader_specs *reader,
                                        struct die_info *type_unit_die,
                                        int has_children, void *data);
 
-static void dwarf2_build_psymtabs_hard (struct objfile *);
+static void dwarf2_build_psymtabs_hard
+  (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
 static void scan_partial_symbols (struct partial_die_info *,
                                  CORE_ADDR *, CORE_ADDR *,
@@ -1572,20 +1781,9 @@ static void dwarf2_read_symtab (struct partial_symtab *,
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
-static struct abbrev_info *abbrev_table_lookup_abbrev
-  (const struct abbrev_table *, unsigned int);
-
-static struct abbrev_table *abbrev_table_read_table
-  (struct dwarf2_section_info *, sect_offset);
-
-static void abbrev_table_free (struct abbrev_table *);
-
-static void abbrev_table_free_cleanup (void *);
-
-static void dwarf2_read_abbrevs (struct dwarf2_cu *,
-                                struct dwarf2_section_info *);
-
-static void dwarf2_free_abbrev_table (void *);
+static abbrev_table_up abbrev_table_read_table
+  (struct dwarf2_per_objfile *dwarf2_per_objfile, struct dwarf2_section_info *,
+   sect_offset);
 
 static unsigned int peek_abbrev_code (bfd *, const gdb_byte *);
 
@@ -1633,22 +1831,28 @@ static LONGEST read_offset (bfd *, const gdb_byte *,
 
 static LONGEST read_offset_1 (bfd *, const gdb_byte *, unsigned int);
 
-static sect_offset read_abbrev_offset (struct dwarf2_section_info *,
-                                      sect_offset);
+static sect_offset read_abbrev_offset
+  (struct dwarf2_per_objfile *dwarf2_per_objfile,
+   struct dwarf2_section_info *, sect_offset);
 
 static const gdb_byte *read_n_bytes (bfd *, const gdb_byte *, unsigned int);
 
 static const char *read_direct_string (bfd *, const gdb_byte *, unsigned int *);
 
-static const char *read_indirect_string (bfd *, const gdb_byte *,
-                                        const struct comp_unit_head *,
-                                        unsigned int *);
+static const char *read_indirect_string
+  (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *, const gdb_byte *,
+   const struct comp_unit_head *, unsigned int *);
 
-static const char *read_indirect_line_string (bfd *, const gdb_byte *,
-                                             const struct comp_unit_head *,
-                                             unsigned int *);
+static const char *read_indirect_line_string
+  (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *, const gdb_byte *,
+   const struct comp_unit_head *, unsigned int *);
+
+static const char *read_indirect_string_at_offset
+  (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
+   LONGEST str_offset);
 
-static const char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST);
+static const char *read_indirect_string_from_dwz
+  (struct objfile *objfile, struct dwz_file *, LONGEST);
 
 static LONGEST read_signed_leb128 (bfd *, const gdb_byte *, unsigned int *);
 
@@ -1692,10 +1896,7 @@ static struct compunit_symtab *dwarf2_start_symtab (struct dwarf2_cu *,
                                                    CORE_ADDR);
 
 static struct symbol *new_symbol (struct die_info *, struct type *,
-                                 struct dwarf2_cu *);
-
-static struct symbol *new_symbol_full (struct die_info *, struct type *,
-                                      struct dwarf2_cu *, struct symbol *);
+                                 struct dwarf2_cu *, struct symbol * = NULL);
 
 static void dwarf2_const_value (const struct attribute *, struct symbol *,
                                struct dwarf2_cu *);
@@ -1744,6 +1945,8 @@ static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
 
 static void read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu);
 
+static void read_variable (struct die_info *die, struct dwarf2_cu *cu);
+
 static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
                               struct dwarf2_cu *, struct partial_symtab *);
 
@@ -1936,36 +2139,30 @@ static const gdb_byte *skip_one_die (const struct die_reader_specs *reader,
                                     const gdb_byte *info_ptr,
                                     struct abbrev_info *abbrev);
 
-static void free_stack_comp_unit (void *);
-
 static hashval_t partial_die_hash (const void *item);
 
 static int partial_die_eq (const void *item_lhs, const void *item_rhs);
 
 static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
-  (sect_offset sect_off, unsigned int offset_in_dwz, struct objfile *objfile);
-
-static void init_one_comp_unit (struct dwarf2_cu *cu,
-                               struct dwarf2_per_cu_data *per_cu);
+  (sect_offset sect_off, unsigned int offset_in_dwz,
+   struct dwarf2_per_objfile *dwarf2_per_objfile);
 
 static void prepare_one_comp_unit (struct dwarf2_cu *cu,
                                   struct die_info *comp_unit_die,
                                   enum language pretend_language);
 
-static void free_heap_comp_unit (void *);
-
 static void free_cached_comp_units (void *);
 
-static void age_cached_comp_units (void);
+static void age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
 static void free_one_cached_comp_unit (struct dwarf2_per_cu_data *);
 
 static struct type *set_die_type (struct die_info *, struct type *,
                                  struct dwarf2_cu *);
 
-static void create_all_comp_units (struct objfile *);
+static void create_all_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
-static int create_all_type_units (struct objfile *);
+static int create_all_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
 static void load_full_comp_unit (struct dwarf2_per_cu_data *,
                                 enum language);
@@ -1988,12 +2185,47 @@ static struct type *get_die_type_at_offset (sect_offset,
 
 static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
 
-static void dwarf2_release_queue (void *dummy);
-
 static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
                             enum language pretend_language);
 
-static void process_queue (void);
+static void process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile);
+
+/* Class, the destructor of which frees all allocated queue entries.  This
+   will only have work to do if an error was thrown while processing the
+   dwarf.  If no error was thrown then the queue entries should have all
+   been processed, and freed, as we went along.  */
+
+class dwarf2_queue_guard
+{
+public:
+  dwarf2_queue_guard () = default;
+
+  /* Free any entries remaining on the queue.  There should only be
+     entries left if we hit an error while processing the dwarf.  */
+  ~dwarf2_queue_guard ()
+  {
+    struct dwarf2_queue_item *item, *last;
+
+    item = dwarf2_queue;
+    while (item)
+      {
+       /* Anything still marked queued is likely to be in an
+          inconsistent state, so discard it.  */
+       if (item->per_cu->queued)
+         {
+           if (item->per_cu->cu != NULL)
+             free_one_cached_comp_unit (item->per_cu);
+           item->per_cu->queued = 0;
+         }
+
+       last = item;
+       item = item->next;
+       xfree (last);
+      }
+
+    dwarf2_queue = dwarf2_queue_tail = NULL;
+  }
+};
 
 /* The return type of find_file_and_directory.  Note, the enclosed
    string pointers are only valid while this object is valid.  */
@@ -2024,7 +2256,8 @@ static char *file_full_name (int file, struct line_header *lh,
 enum class rcuh_kind { COMPILE, TYPE };
 
 static const gdb_byte *read_and_check_comp_unit_head
-  (struct comp_unit_head *header,
+  (struct dwarf2_per_objfile* dwarf2_per_objfile,
+   struct comp_unit_head *header,
    struct dwarf2_section_info *section,
    struct dwarf2_section_info *abbrev_section, const gdb_byte *info_ptr,
    rcuh_kind section_kind);
@@ -2043,10 +2276,12 @@ static htab_t allocate_signatured_type_table (struct objfile *objfile);
 static htab_t allocate_dwo_unit_table (struct objfile *objfile);
 
 static struct dwo_unit *lookup_dwo_unit_in_dwp
-  (struct dwp_file *dwp_file, const char *comp_dir,
+  (struct dwarf2_per_objfile *dwarf2_per_objfile,
+   struct dwp_file *dwp_file, const char *comp_dir,
    ULONGEST signature, int is_debug_types);
 
-static struct dwp_file *get_dwp_file (void);
+static struct dwp_file *get_dwp_file
+  (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
 static struct dwo_unit *lookup_dwo_comp_unit
   (struct dwarf2_per_cu_data *, const char *, const char *, ULONGEST);
@@ -2058,7 +2293,13 @@ static void queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *);
 
 static void free_dwo_file_cleanup (void *);
 
-static void process_cu_includes (void);
+struct free_dwo_file_cleanup_data
+{
+  struct dwo_file *dwo_file;
+  struct dwarf2_per_objfile *dwarf2_per_objfile;
+};
+
+static void process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
 static void check_producer (struct dwarf2_cu *cu);
 
@@ -2161,26 +2402,6 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
 }
 
 \f
-#if WORDS_BIGENDIAN
-
-/* Convert VALUE between big- and little-endian.  */
-static offset_type
-byte_swap (offset_type value)
-{
-  offset_type result;
-
-  result = (value & 0xff) << 24;
-  result |= (value & 0xff00) << 8;
-  result |= (value & 0xff0000) >> 8;
-  result |= (value & 0xff000000) >> 24;
-  return result;
-}
-
-#define MAYBE_SWAP(V)  byte_swap (V)
-
-#else
-#define MAYBE_SWAP(V) static_cast<offset_type> (V)
-#endif /* WORDS_BIGENDIAN */
 
 /* Read the given attribute value as an address, taking the attribute's
    form into account.  */
@@ -2213,7 +2434,9 @@ attr_value_as_address (struct attribute *attr)
 }
 
 /* The suffix for an index file.  */
-#define INDEX_SUFFIX ".gdb-index"
+#define INDEX4_SUFFIX ".gdb-index"
+#define INDEX5_SUFFIX ".debug_names"
+#define DEBUG_STR_SUFFIX ".debug_str"
 
 /* See declaration.  */
 
@@ -2230,6 +2453,8 @@ dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_,
     locate_sections (obfd, sec, *names);
 }
 
+static void free_dwo_files (htab_t dwo_files, struct objfile *objfile);
+
 dwarf2_per_objfile::~dwarf2_per_objfile ()
 {
   /* Cached DIE trees use xmalloc and the comp_unit_obstack.  */
@@ -2241,6 +2466,27 @@ dwarf2_per_objfile::~dwarf2_per_objfile ()
   if (line_header_hash)
     htab_delete (line_header_hash);
 
+  for (int ix = 0; ix < n_comp_units; ++ix)
+   VEC_free (dwarf2_per_cu_ptr, all_comp_units[ix]->imported_symtabs);
+
+  for (int ix = 0; ix < n_type_units; ++ix)
+    VEC_free (dwarf2_per_cu_ptr,
+             all_type_units[ix]->per_cu.imported_symtabs);
+  xfree (all_type_units);
+
+  VEC_free (dwarf2_section_info_def, types);
+
+  if (dwo_files != NULL)
+    free_dwo_files (dwo_files, objfile);
+  if (dwp_file != NULL)
+    gdb_bfd_unref (dwp_file->dbfd);
+
+  if (dwz_file != NULL && dwz_file->dwz_bfd)
+    gdb_bfd_unref (dwz_file->dwz_bfd);
+
+  if (index_table != NULL)
+    index_table->~mapped_index ();
+
   /* Everything else should be on the objfile obstack.  */
 }
 
@@ -2255,7 +2501,7 @@ dwarf2_per_objfile::free_cached_comp_units ()
     {
       dwarf2_per_cu_data *next_cu = per_cu->cu->read_in_chain;
 
-      free_heap_comp_unit (per_cu->cu);
+      delete per_cu->cu;
       *last_chain = next_cu;
       per_cu = next_cu;
     }
@@ -2270,16 +2516,20 @@ int
 dwarf2_has_info (struct objfile *objfile,
                  const struct dwarf2_debug_sections *names)
 {
-  dwarf2_per_objfile = ((struct dwarf2_per_objfile *)
-                       objfile_data (objfile, dwarf2_objfile_data_key));
-  if (!dwarf2_per_objfile)
+  if (objfile->flags & OBJF_READNEVER)
+    return 0;
+
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
+  if (dwarf2_per_objfile == NULL)
     {
       /* Initialize per-objfile state.  */
       struct dwarf2_per_objfile *data
        = XOBNEW (&objfile->objfile_obstack, struct dwarf2_per_objfile);
 
       dwarf2_per_objfile = new (data) struct dwarf2_per_objfile (objfile, names);
-      set_objfile_data (objfile, dwarf2_objfile_data_key, dwarf2_per_objfile);
+      set_dwarf2_per_objfile (objfile, dwarf2_per_objfile);
     }
   return (!dwarf2_per_objfile->info.is_virtual
          && dwarf2_per_objfile->info.s.section != NULL
@@ -2482,6 +2732,16 @@ dwarf2_per_objfile::locate_sections (bfd *abfd, asection *sectp,
       this->gdb_index.s.section = sectp;
       this->gdb_index.size = bfd_get_section_size (sectp);
     }
+  else if (section_is_p (sectp->name, &names.debug_names))
+    {
+      this->debug_names.s.section = sectp;
+      this->debug_names.size = bfd_get_section_size (sectp);
+    }
+  else if (section_is_p (sectp->name, &names.debug_aranges))
+    {
+      this->debug_aranges.s.section = sectp;
+      this->debug_aranges.size = bfd_get_section_size (sectp);
+    }
 
   if ((bfd_get_section_flags (abfd, sectp) & (SEC_LOAD | SEC_ALLOC))
       && bfd_section_vma (abfd, sectp) == 0)
@@ -2678,6 +2938,11 @@ locate_dwz_sections (bfd *abfd, asection *sectp, void *arg)
       dwz_file->gdb_index.s.section = sectp;
       dwz_file->gdb_index.size = bfd_get_section_size (sectp);
     }
+  else if (section_is_p (sectp->name, &dwarf2_elf_names.debug_names))
+    {
+      dwz_file->debug_names.s.section = sectp;
+      dwz_file->debug_names.size = bfd_get_section_size (sectp);
+    }
 }
 
 /* Open the separate '.dwz' debug file, if needed.  Return NULL if
@@ -2685,10 +2950,8 @@ locate_dwz_sections (bfd *abfd, asection *sectp, void *arg)
    is such a section but the file cannot be found.  */
 
 static struct dwz_file *
-dwarf2_get_dwz_file (void)
+dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  char *data;
-  struct cleanup *cleanup;
   const char *filename;
   struct dwz_file *result;
   bfd_size_type buildid_len_arg;
@@ -2699,8 +2962,9 @@ dwarf2_get_dwz_file (void)
     return dwarf2_per_objfile->dwz_file;
 
   bfd_set_error (bfd_error_no_error);
-  data = bfd_get_alt_debug_link_info (dwarf2_per_objfile->objfile->obfd,
-                                     &buildid_len_arg, &buildid);
+  gdb::unique_xmalloc_ptr<char> data
+    (bfd_get_alt_debug_link_info (dwarf2_per_objfile->objfile->obfd,
+                                 &buildid_len_arg, &buildid));
   if (data == NULL)
     {
       if (bfd_get_error () == bfd_error_no_error)
@@ -2708,12 +2972,12 @@ dwarf2_get_dwz_file (void)
       error (_("could not read '.gnu_debugaltlink' section: %s"),
             bfd_errmsg (bfd_get_error ()));
     }
-  cleanup = make_cleanup (xfree, data);
-  make_cleanup (xfree, buildid);
+
+  gdb::unique_xmalloc_ptr<bfd_byte> buildid_holder (buildid);
 
   buildid_len = (size_t) buildid_len_arg;
 
-  filename = (const char *) data;
+  filename = data.get ();
 
   std::string abs_storage;
   if (!IS_ABSOLUTE_PATH (filename))
@@ -2747,8 +3011,6 @@ dwarf2_get_dwz_file (void)
 
   bfd_map_over_sections (result->dwz_bfd, locate_dwz_sections, result);
 
-  do_cleanups (cleanup);
-
   gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, result->dwz_bfd);
   dwarf2_per_objfile->dwz_file = result;
   return result;
@@ -2903,14 +3165,17 @@ load_cu (struct dwarf2_per_cu_data *per_cu)
 static void
 dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
 {
-  struct cleanup *back_to;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
 
   /* Skip type_unit_groups, reading the type units they contain
      is handled elsewhere.  */
   if (IS_TYPE_UNIT_GROUP (per_cu))
     return;
 
-  back_to = make_cleanup (dwarf2_release_queue, NULL);
+  /* The destructor of dwarf2_queue_guard frees any entries left on
+     the queue.  After this point we're guaranteed to leave this function
+     with the dwarf queue empty.  */
+  dwarf2_queue_guard q_guard;
 
   if (dwarf2_per_objfile->using_index
       ? per_cu->v.quick->compunit_symtab == NULL
@@ -2928,17 +3193,15 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
          && dwarf2_per_objfile->index_table != NULL
          && dwarf2_per_objfile->index_table->version <= 7
          /* DWP files aren't supported yet.  */
-         && get_dwp_file () == NULL)
+         && get_dwp_file (dwarf2_per_objfile) == NULL)
        queue_and_load_all_dwo_tus (per_cu);
     }
 
-  process_queue ();
+  process_queue (dwarf2_per_objfile);
 
   /* Age the cache, releasing compilation units that have not
      been used recently.  */
-  age_cached_comp_units ();
-
-  do_cleanups (back_to);
+  age_cached_comp_units (dwarf2_per_objfile);
 }
 
 /* Ensure that the symbols for PER_CU have been read in.  OBJFILE is
@@ -2948,13 +3211,16 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
 static struct compunit_symtab *
 dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+
   gdb_assert (dwarf2_per_objfile->using_index);
   if (!per_cu->v.quick->compunit_symtab)
     {
-      struct cleanup *back_to = make_cleanup (free_cached_comp_units, NULL);
+      struct cleanup *back_to = make_cleanup (free_cached_comp_units,
+                                             dwarf2_per_objfile);
       scoped_restore decrementer = increment_reading_symtab ();
       dw2_do_instantiate_symtab (per_cu);
-      process_cu_includes ();
+      process_cu_includes (dwarf2_per_objfile);
       do_cleanups (back_to);
     }
 
@@ -2975,7 +3241,8 @@ dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
 */
 
 static struct dwarf2_per_cu_data *
-dw2_get_cutu (int index)
+dw2_get_cutu (struct dwarf2_per_objfile *dwarf2_per_objfile,
+             int index)
 {
   if (index >= dwarf2_per_objfile->n_comp_units)
     {
@@ -2992,13 +3259,37 @@ dw2_get_cutu (int index)
    refers to a CU.  */
 
 static struct dwarf2_per_cu_data *
-dw2_get_cu (int index)
+dw2_get_cu (struct dwarf2_per_objfile *dwarf2_per_objfile, int index)
 {
   gdb_assert (index >= 0 && index < dwarf2_per_objfile->n_comp_units);
 
   return dwarf2_per_objfile->all_comp_units[index];
 }
 
+/* Return a new dwarf2_per_cu_data allocated on OBJFILE's
+   objfile_obstack, and constructed with the specified field
+   values.  */
+
+static dwarf2_per_cu_data *
+create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                          struct dwarf2_section_info *section,
+                          int is_dwz,
+                          sect_offset sect_off, ULONGEST length)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  dwarf2_per_cu_data *the_cu
+    = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                     struct dwarf2_per_cu_data);
+  the_cu->sect_off = sect_off;
+  the_cu->length = length;
+  the_cu->dwarf2_per_objfile = dwarf2_per_objfile;
+  the_cu->section = section;
+  the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                                   struct dwarf2_per_cu_quick_data);
+  the_cu->is_dwz = is_dwz;
+  return the_cu;
+}
+
 /* A helper for create_cus_from_index that handles a given list of
    CUs.  */
 
@@ -3010,6 +3301,8 @@ create_cus_from_index_list (struct objfile *objfile,
                            int base_offset)
 {
   offset_type i;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
   for (i = 0; i < n_elements; i += 2)
     {
@@ -3020,17 +3313,9 @@ create_cus_from_index_list (struct objfile *objfile,
       ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
       cu_list += 2 * 8;
 
-      dwarf2_per_cu_data *the_cu
-       = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                         struct dwarf2_per_cu_data);
-      the_cu->sect_off = sect_off;
-      the_cu->length = length;
-      the_cu->objfile = objfile;
-      the_cu->section = section;
-      the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                                       struct dwarf2_per_cu_quick_data);
-      the_cu->is_dwz = is_dwz;
-      dwarf2_per_objfile->all_comp_units[base_offset + i / 2] = the_cu;
+      dwarf2_per_objfile->all_comp_units[base_offset + i / 2]
+       = create_cu_from_index_list (dwarf2_per_objfile, section, is_dwz,
+                                    sect_off, length);
     }
 }
 
@@ -3043,6 +3328,8 @@ create_cus_from_index (struct objfile *objfile,
                       const gdb_byte *dwz_list, offset_type dwz_elements)
 {
   struct dwz_file *dwz;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
   dwarf2_per_objfile->n_comp_units = (cu_list_elements + dwz_elements) / 2;
   dwarf2_per_objfile->all_comp_units =
@@ -3055,7 +3342,7 @@ create_cus_from_index (struct objfile *objfile,
   if (dwz_elements == 0)
     return;
 
-  dwz = dwarf2_get_dwz_file ();
+  dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
   create_cus_from_index_list (objfile, dwz_list, dwz_elements, &dwz->info, 1,
                              cu_list_elements / 2);
 }
@@ -3070,6 +3357,8 @@ create_signatured_type_table_from_index (struct objfile *objfile,
 {
   offset_type i;
   htab_t sig_types_hash;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
   dwarf2_per_objfile->n_type_units
     = dwarf2_per_objfile->n_allocated_type_units
@@ -3102,7 +3391,7 @@ create_signatured_type_table_from_index (struct objfile *objfile,
       sig_type->per_cu.is_debug_types = 1;
       sig_type->per_cu.section = section;
       sig_type->per_cu.sect_off = sect_off;
-      sig_type->per_cu.objfile = objfile;
+      sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
        = OBSTACK_ZALLOC (&objfile->objfile_obstack,
                          struct dwarf2_per_cu_quick_data);
@@ -3116,12 +3405,76 @@ create_signatured_type_table_from_index (struct objfile *objfile,
   dwarf2_per_objfile->signatured_types = sig_types_hash;
 }
 
+/* Create the signatured type hash table from .debug_names.  */
+
+static void
+create_signatured_type_table_from_debug_names
+  (struct dwarf2_per_objfile *dwarf2_per_objfile,
+   const mapped_debug_names &map,
+   struct dwarf2_section_info *section,
+   struct dwarf2_section_info *abbrev_section)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+
+  dwarf2_read_section (objfile, section);
+  dwarf2_read_section (objfile, abbrev_section);
+
+  dwarf2_per_objfile->n_type_units
+    = dwarf2_per_objfile->n_allocated_type_units
+    = map.tu_count;
+  dwarf2_per_objfile->all_type_units
+    = XNEWVEC (struct signatured_type *, dwarf2_per_objfile->n_type_units);
+
+  htab_t sig_types_hash = allocate_signatured_type_table (objfile);
+
+  for (uint32_t i = 0; i < map.tu_count; ++i)
+    {
+      struct signatured_type *sig_type;
+      ULONGEST signature;
+      void **slot;
+      cu_offset type_offset_in_tu;
+
+      sect_offset sect_off
+       = (sect_offset) (extract_unsigned_integer
+                        (map.tu_table_reordered + i * map.offset_size,
+                         map.offset_size,
+                         map.dwarf5_byte_order));
+
+      comp_unit_head cu_header;
+      read_and_check_comp_unit_head (dwarf2_per_objfile, &cu_header, section,
+                                    abbrev_section,
+                                    section->buffer + to_underlying (sect_off),
+                                    rcuh_kind::TYPE);
+
+      sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                                struct signatured_type);
+      sig_type->signature = cu_header.signature;
+      sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
+      sig_type->per_cu.is_debug_types = 1;
+      sig_type->per_cu.section = section;
+      sig_type->per_cu.sect_off = sect_off;
+      sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
+      sig_type->per_cu.v.quick
+       = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                         struct dwarf2_per_cu_quick_data);
+
+      slot = htab_find_slot (sig_types_hash, sig_type, INSERT);
+      *slot = sig_type;
+
+      dwarf2_per_objfile->all_type_units[i] = sig_type;
+    }
+
+  dwarf2_per_objfile->signatured_types = sig_types_hash;
+}
+
 /* Read the address map data from the mapped index, and use it to
    populate the objfile's psymtabs_addrmap.  */
 
 static void
-create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index)
+create_addrmap_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                          struct mapped_index *index)
 {
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   const gdb_byte *iter, *end;
   struct addrmap *mutable_map;
@@ -3131,8 +3484,8 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index)
 
   mutable_map = addrmap_create_mutable (&temp_obstack);
 
-  iter = index->address_table;
-  end = iter + index->address_table_size;
+  iter = index->address_table.data ();
+  end = iter + index->address_table.size ();
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -3164,51 +3517,213 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index)
 
       lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr);
       hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr);
-      addrmap_set_empty (mutable_map, lo, hi - 1, dw2_get_cutu (cu_index));
+      addrmap_set_empty (mutable_map, lo, hi - 1,
+                        dw2_get_cutu (dwarf2_per_objfile, cu_index));
     }
 
   objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map,
                                                    &objfile->objfile_obstack);
 }
 
-/* The hash function for strings in the mapped index.  This is the same as
-   SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the
-   implementation.  This is necessary because the hash function is tied to the
-   format of the mapped index file.  The hash values do not have to match with
-   SYMBOL_HASH_NEXT.
-   
-   Use INT_MAX for INDEX_VERSION if you generate the current index format.  */
+/* Read the address map data from DWARF-5 .debug_aranges, and use it to
+   populate the objfile's psymtabs_addrmap.  */
 
-static hashval_t
-mapped_index_string_hash (int index_version, const void *p)
+static void
+create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                            struct dwarf2_section_info *section)
 {
-  const unsigned char *str = (const unsigned char *) p;
-  hashval_t r = 0;
-  unsigned char c;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  bfd *abfd = objfile->obfd;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  const CORE_ADDR baseaddr = ANOFFSET (objfile->section_offsets,
+                                      SECT_OFF_TEXT (objfile));
 
-  while ((c = *str++) != 0)
-    {
-      if (index_version >= 5)
-       c = tolower (c);
-      r = r * 67 + c - 113;
+  auto_obstack temp_obstack;
+  addrmap *mutable_map = addrmap_create_mutable (&temp_obstack);
+
+  std::unordered_map<sect_offset,
+                    dwarf2_per_cu_data *,
+                    gdb::hash_enum<sect_offset>>
+    debug_info_offset_to_per_cu;
+  for (int cui = 0; cui < dwarf2_per_objfile->n_comp_units; ++cui)
+    {
+      dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, cui);
+      const auto insertpair
+       = debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu);
+      if (!insertpair.second)
+       {
+         warning (_("Section .debug_aranges in %s has duplicate "
+                    "debug_info_offset %u, ignoring .debug_aranges."),
+                  objfile_name (objfile), to_underlying (per_cu->sect_off));
+         return;
+       }
     }
 
-  return r;
-}
+  dwarf2_read_section (objfile, section);
 
-/* 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 1.  If NAME cannot be found, return 0.  */
+  const bfd_endian dwarf5_byte_order = gdbarch_byte_order (gdbarch);
 
-static int
+  const gdb_byte *addr = section->buffer;
+
+  while (addr < section->buffer + section->size)
+    {
+      const gdb_byte *const entry_addr = addr;
+      unsigned int bytes_read;
+
+      const LONGEST entry_length = read_initial_length (abfd, addr,
+                                                       &bytes_read);
+      addr += bytes_read;
+
+      const gdb_byte *const entry_end = addr + entry_length;
+      const bool dwarf5_is_dwarf64 = bytes_read != 4;
+      const uint8_t offset_size = dwarf5_is_dwarf64 ? 8 : 4;
+      if (addr + entry_length > section->buffer + section->size)
+       {
+         warning (_("Section .debug_aranges in %s entry at offset %zu "
+                    "length %s exceeds section length %s, "
+                    "ignoring .debug_aranges."),
+                  objfile_name (objfile), entry_addr - section->buffer,
+                  plongest (bytes_read + entry_length),
+                  pulongest (section->size));
+         return;
+       }
+
+      /* The version number.  */
+      const uint16_t version = read_2_bytes (abfd, addr);
+      addr += 2;
+      if (version != 2)
+       {
+         warning (_("Section .debug_aranges in %s entry at offset %zu "
+                    "has unsupported version %d, ignoring .debug_aranges."),
+                  objfile_name (objfile), entry_addr - section->buffer,
+                  version);
+         return;
+       }
+
+      const uint64_t debug_info_offset
+       = extract_unsigned_integer (addr, offset_size, dwarf5_byte_order);
+      addr += offset_size;
+      const auto per_cu_it
+       = debug_info_offset_to_per_cu.find (sect_offset (debug_info_offset));
+      if (per_cu_it == debug_info_offset_to_per_cu.cend ())
+       {
+         warning (_("Section .debug_aranges in %s entry at offset %zu "
+                    "debug_info_offset %s does not exists, "
+                    "ignoring .debug_aranges."),
+                  objfile_name (objfile), entry_addr - section->buffer,
+                  pulongest (debug_info_offset));
+         return;
+       }
+      dwarf2_per_cu_data *const per_cu = per_cu_it->second;
+
+      const uint8_t address_size = *addr++;
+      if (address_size < 1 || address_size > 8)
+       {
+         warning (_("Section .debug_aranges in %s entry at offset %zu "
+                    "address_size %u is invalid, ignoring .debug_aranges."),
+                  objfile_name (objfile), entry_addr - section->buffer,
+                  address_size);
+         return;
+       }
+
+      const uint8_t segment_selector_size = *addr++;
+      if (segment_selector_size != 0)
+       {
+         warning (_("Section .debug_aranges in %s entry at offset %zu "
+                    "segment_selector_size %u is not supported, "
+                    "ignoring .debug_aranges."),
+                  objfile_name (objfile), entry_addr - section->buffer,
+                  segment_selector_size);
+         return;
+       }
+
+      /* Must pad to an alignment boundary that is twice the address
+         size.  It is undocumented by the DWARF standard but GCC does
+         use it.  */
+      for (size_t padding = ((-(addr - section->buffer))
+                            & (2 * address_size - 1));
+           padding > 0; padding--)
+       if (*addr++ != 0)
+         {
+           warning (_("Section .debug_aranges in %s entry at offset %zu "
+                      "padding is not zero, ignoring .debug_aranges."),
+                    objfile_name (objfile), entry_addr - section->buffer);
+           return;
+         }
+
+      for (;;)
+       {
+         if (addr + 2 * address_size > entry_end)
+           {
+             warning (_("Section .debug_aranges in %s entry at offset %zu "
+                        "address list is not properly terminated, "
+                        "ignoring .debug_aranges."),
+                      objfile_name (objfile), entry_addr - section->buffer);
+             return;
+           }
+         ULONGEST start = extract_unsigned_integer (addr, address_size,
+                                                    dwarf5_byte_order);
+         addr += address_size;
+         ULONGEST length = extract_unsigned_integer (addr, address_size,
+                                                     dwarf5_byte_order);
+         addr += address_size;
+         if (start == 0 && length == 0)
+           break;
+         if (start == 0 && !dwarf2_per_objfile->has_section_at_zero)
+           {
+             /* Symbol was eliminated due to a COMDAT group.  */
+             continue;
+           }
+         ULONGEST end = start + length;
+         start = gdbarch_adjust_dwarf2_addr (gdbarch, start + baseaddr);
+         end = gdbarch_adjust_dwarf2_addr (gdbarch, end + baseaddr);
+         addrmap_set_empty (mutable_map, start, end - 1, per_cu);
+       }
+    }
+
+  objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map,
+                                                   &objfile->objfile_obstack);
+}
+
+/* The hash function for strings in the mapped index.  This is the same as
+   SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the
+   implementation.  This is necessary because the hash function is tied to the
+   format of the mapped index file.  The hash values do not have to match with
+   SYMBOL_HASH_NEXT.
+   
+   Use INT_MAX for INDEX_VERSION if you generate the current index format.  */
+
+static hashval_t
+mapped_index_string_hash (int index_version, const void *p)
+{
+  const unsigned char *str = (const unsigned char *) p;
+  hashval_t r = 0;
+  unsigned char c;
+
+  while ((c = *str++) != 0)
+    {
+      if (index_version >= 5)
+       c = tolower (c);
+      r = r * 67 + c - 113;
+    }
+
+  return r;
+}
+
+/* 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)
 {
-  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   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)
@@ -3218,13 +3733,10 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
 
       if (strchr (name, '(') != NULL)
        {
-         char *without_params = cp_remove_params (name);
+         without_params = cp_remove_params (name);
 
          if (without_params != NULL)
-           {
-             make_cleanup (xfree, without_params);
-             name = without_params;
-           }
+           name = without_params.get ();
        }
     }
 
@@ -3236,31 +3748,27 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
                                    ? 5 : index->version),
                                   name);
 
-  slot = hash & (index->symbol_table_slots - 1);
-  step = ((hash * 17) & (index->symbol_table_slots - 1)) | 1;
+  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 (;;)
     {
-      /* Convert a slot number to an offset into the table.  */
-      offset_type i = 2 * slot;
       const char *str;
-      if (index->symbol_table[i] == 0 && index->symbol_table[i + 1] == 0)
-       {
-         do_cleanups (back_to);
-         return 0;
-       }
 
-      str = index->constant_pool + MAYBE_SWAP (index->symbol_table[i]);
+      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 (index->symbol_table[i + 1]));
-         do_cleanups (back_to);
-         return 1;
+                                     + MAYBE_SWAP (bucket.vec));
+         return true;
        }
 
-      slot = (slot + step) & (index->symbol_table_slots - 1);
+      slot = (slot + step) & (index->symbol_table.size () - 1);
     }
 }
 
@@ -3371,24 +3879,26 @@ to use the section anyway."),
                          / 8);
   ++i;
 
-  map->address_table = addr + MAYBE_SWAP (metadata[i]);
-  map->address_table_size = (MAYBE_SWAP (metadata[i + 1])
-                            - MAYBE_SWAP (metadata[i]));
+  const gdb_byte *address_table = addr + MAYBE_SWAP (metadata[i]);
+  const gdb_byte *address_table_end = addr + MAYBE_SWAP (metadata[i + 1]);
+  map->address_table
+    = gdb::array_view<const gdb_byte> (address_table, address_table_end);
   ++i;
 
-  map->symbol_table = (offset_type *) (addr + MAYBE_SWAP (metadata[i]));
-  map->symbol_table_slots = ((MAYBE_SWAP (metadata[i + 1])
-                             - MAYBE_SWAP (metadata[i]))
-                            / (2 * sizeof (offset_type)));
-  ++i;
+  const gdb_byte *symbol_table = addr + MAYBE_SWAP (metadata[i]);
+  const gdb_byte *symbol_table_end = addr + MAYBE_SWAP (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);
 
+  ++i;
   map->constant_pool = (char *) (addr + MAYBE_SWAP (metadata[i]));
 
   return 1;
 }
 
-
-/* Read the index file.  If everything went ok, initialize the "quick"
+/* Read .gdb_index.  If everything went ok, initialize the "quick"
    elements of all the CUs and return 1.  Otherwise, return 0.  */
 
 static int
@@ -3398,6 +3908,8 @@ dwarf2_read_index (struct objfile *objfile)
   const gdb_byte *cu_list, *types_list, *dwz_list = NULL;
   offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0;
   struct dwz_file *dwz;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
   if (!read_index_from_section (objfile, objfile_name (objfile),
                                use_deprecated_index_sections,
@@ -3407,12 +3919,12 @@ dwarf2_read_index (struct objfile *objfile)
     return 0;
 
   /* Don't use the index if it's empty.  */
-  if (local_map.symbol_table_slots == 0)
+  if (local_map.symbol_table.empty ())
     return 0;
 
   /* If there is a .dwz file, read it so we can get its CU list as
      well.  */
-  dwz = dwarf2_get_dwz_file ();
+  dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
   if (dwz != NULL)
     {
       struct mapped_index dwz_map;
@@ -3451,9 +3963,10 @@ dwarf2_read_index (struct objfile *objfile)
                                               types_list_elements);
     }
 
-  create_addrmap_from_index (objfile, &local_map);
+  create_addrmap_from_index (dwarf2_per_objfile, &local_map);
 
   map = XOBNEW (&objfile->objfile_obstack, struct mapped_index);
+  map = new (map) mapped_index ();
   *map = local_map;
 
   dwarf2_per_objfile->index_table = map;
@@ -3464,17 +3977,6 @@ dwarf2_read_index (struct objfile *objfile)
   return 1;
 }
 
-/* A helper for the "quick" functions which sets the global
-   dwarf2_per_objfile according to OBJFILE.  */
-
-static void
-dw2_setup (struct objfile *objfile)
-{
-  dwarf2_per_objfile = ((struct dwarf2_per_objfile *)
-                       objfile_data (objfile, dwarf2_objfile_data_key));
-  gdb_assert (dwarf2_per_objfile);
-}
-
 /* die_reader_func for dw2_get_file_names.  */
 
 static void
@@ -3485,7 +3987,9 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
                           void *data)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct dwarf2_per_cu_data *this_cu = cu->per_cu;  
+  struct dwarf2_per_cu_data *this_cu = cu->per_cu;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *lh_cu;
   struct attribute *attr;
@@ -3598,14 +4102,15 @@ dw2_get_real_path (struct objfile *objfile,
 static struct symtab *
 dw2_find_last_source_symtab (struct objfile *objfile)
 {
-  struct compunit_symtab *cust;
-  int index;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+  int index = dwarf2_per_objfile->n_comp_units - 1;
+  dwarf2_per_cu_data *dwarf_cu = dw2_get_cutu (dwarf2_per_objfile, index);
+  compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu);
 
-  dw2_setup (objfile);
-  index = dwarf2_per_objfile->n_comp_units - 1;
-  cust = dw2_instantiate_symtab (dw2_get_cutu (index));
   if (cust == NULL)
     return NULL;
+
   return compunit_primary_filetab (cust);
 }
 
@@ -3633,7 +4138,8 @@ dw2_free_cached_file_names (void **slot, void *info)
 static void
 dw2_forget_cached_source_info (struct objfile *objfile)
 {
-  dw2_setup (objfile);
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
   htab_traverse_noresize (dwarf2_per_objfile->quick_file_names_table,
                          dw2_free_cached_file_names, NULL);
@@ -3671,16 +4177,16 @@ dw2_map_symtabs_matching_filename
 {
   int i;
   const char *name_basename = lbasename (name);
-
-  dw2_setup (objfile);
+  struct dwarf2_per_objfile *dwarf2_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 (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  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 dwarf2_per_cu_data *per_cu = dw2_get_cu (dwarf2_per_objfile, i);
       struct quick_file_names *file_data;
 
       /* We only need to look at symtabs not already expanded.  */
@@ -3742,8 +4248,8 @@ dw2_map_symtabs_matching_filename
 
 struct dw2_symtab_iterator
 {
-  /* The internalized form of .gdb_index.  */
-  struct mapped_index *index;
+  /* The dwarf2_per_objfile owning the CUs we are iterating on.  */
+  struct dwarf2_per_objfile *dwarf2_per_objfile;
   /* If non-zero, only look for symbols that match BLOCK_INDEX.  */
   int want_specific_block;
   /* One of GLOBAL_BLOCK or STATIC_BLOCK.
@@ -3771,20 +4277,23 @@ struct dw2_symtab_iterator
 
 static void
 dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
-                     struct mapped_index *index,
+                     struct dwarf2_per_objfile *dwarf2_per_objfile,
                      int want_specific_block,
                      int block_index,
                      domain_enum domain,
                      const char *name)
 {
-  iter->index = index;
+  iter->dwarf2_per_objfile = dwarf2_per_objfile;
   iter->want_specific_block = want_specific_block;
   iter->block_index = block_index;
   iter->domain = domain;
   iter->next = 0;
   iter->global_seen = 0;
 
-  if (find_slot_in_mapped_hash (index, name, &iter->vec))
+  mapped_index *index = dwarf2_per_objfile->index_table;
+
+  /* index is NULL if OBJF_READNOW.  */
+  if (index != NULL && find_slot_in_mapped_hash (index, name, &iter->vec))
     iter->length = MAYBE_SWAP (*iter->vec);
   else
     {
@@ -3798,6 +4307,8 @@ dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
 static struct dwarf2_per_cu_data *
 dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile = iter->dwarf2_per_objfile;
+
   for ( ; iter->next < iter->length; ++iter->next)
     {
       offset_type cu_index_and_attrs =
@@ -3814,7 +4325,7 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
         and indices >= 7 may elide them for certain symbols
         (gold does this).  */
       int attrs_valid =
-       (iter->index->version >= 7
+       (dwarf2_per_objfile->index_table->version >= 7
         && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
 
       /* Don't crash on bad data.  */
@@ -3828,7 +4339,7 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
          continue;
        }
 
-      per_cu = dw2_get_cutu (cu_index);
+      per_cu = dw2_get_cutu (dwarf2_per_objfile, cu_index);
 
       /* Skip if already read in.  */
       if (per_cu->v.quick->compunit_symtab)
@@ -3884,44 +4395,39 @@ dw2_lookup_symbol (struct objfile *objfile, int block_index,
                   const char *name, domain_enum domain)
 {
   struct compunit_symtab *stab_best = NULL;
-  struct mapped_index *index;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
-  dw2_setup (objfile);
+  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
 
-  index = dwarf2_per_objfile->index_table;
-
-  /* index is NULL if OBJF_READNOW.  */
-  if (index)
-    {
-      struct dw2_symtab_iterator iter;
-      struct dwarf2_per_cu_data *per_cu;
+  struct dw2_symtab_iterator iter;
+  struct dwarf2_per_cu_data *per_cu;
 
-      dw2_symtab_iter_init (&iter, index, 1, block_index, domain, name);
+  dw2_symtab_iter_init (&iter, dwarf2_per_objfile, 1, 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);
-         const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
-         struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+  while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+    {
+      struct symbol *sym, *with_opaque = NULL;
+      struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu);
+      const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
+      struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
 
-         sym = block_find_symbol (block, name, domain,
-                                  block_find_non_opaque_type_preferred,
-                                  &with_opaque);
+      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).  */
+      /* 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, name))
-           return stab;
-         if (with_opaque != NULL
-             && SYMBOL_MATCHES_SEARCH_NAME (with_opaque, name))
-           stab_best = stab;
+      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.  */
-       }
+      /* Keep looking through other CUs.  */
     }
 
   return stab_best;
@@ -3930,14 +4436,14 @@ dw2_lookup_symbol (struct objfile *objfile, int block_index,
 static void
 dw2_print_stats (struct objfile *objfile)
 {
-  int i, total, count;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+  int total = dwarf2_per_objfile->n_comp_units + dwarf2_per_objfile->n_type_units;
+  int count = 0;
 
-  dw2_setup (objfile);
-  total = dwarf2_per_objfile->n_comp_units + dwarf2_per_objfile->n_type_units;
-  count = 0;
-  for (i = 0; i < total; ++i)
+  for (int i = 0; i < total; ++i)
     {
-      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
 
       if (!per_cu->v.quick->compunit_symtab)
        ++count;
@@ -3954,7 +4460,9 @@ dw2_print_stats (struct objfile *objfile)
 static void
 dw2_dump (struct objfile *objfile)
 {
-  dw2_setup (objfile);
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
   gdb_assert (dwarf2_per_objfile->using_index);
   printf_filtered (".gdb_index:");
   if (dwarf2_per_objfile->index_table != NULL)
@@ -3979,38 +4487,33 @@ static void
 dw2_expand_symtabs_for_function (struct objfile *objfile,
                                 const char *func_name)
 {
-  struct mapped_index *index;
-
-  dw2_setup (objfile);
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
-  index = dwarf2_per_objfile->index_table;
+  struct dw2_symtab_iterator iter;
+  struct dwarf2_per_cu_data *per_cu;
 
-  /* index is NULL if OBJF_READNOW.  */
-  if (index)
-    {
-      struct dw2_symtab_iterator iter;
-      struct dwarf2_per_cu_data *per_cu;
+  /* Note: It doesn't matter what we pass for block_index here.  */
+  dw2_symtab_iter_init (&iter, dwarf2_per_objfile, 0, GLOBAL_BLOCK, VAR_DOMAIN,
+                       func_name);
 
-      /* Note: It doesn't matter what we pass for block_index here.  */
-      dw2_symtab_iter_init (&iter, index, 0, GLOBAL_BLOCK, VAR_DOMAIN,
-                           func_name);
+  while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+    dw2_instantiate_symtab (per_cu);
 
-      while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
-       dw2_instantiate_symtab (per_cu);
-    }
 }
 
 static void
 dw2_expand_all_symtabs (struct objfile *objfile)
 {
-  int i;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+  int total_units = (dwarf2_per_objfile->n_comp_units
+                    + dwarf2_per_objfile->n_type_units);
 
-  dw2_setup (objfile);
-
-  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
-                  + dwarf2_per_objfile->n_type_units); ++i)
+  for (int i = 0; i < total_units; ++i)
     {
-      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+      struct dwarf2_per_cu_data *per_cu
+       = dw2_get_cutu (dwarf2_per_objfile, i);
 
       dw2_instantiate_symtab (per_cu);
     }
@@ -4020,19 +4523,18 @@ static void
 dw2_expand_symtabs_with_fullname (struct objfile *objfile,
                                  const char *fullname)
 {
-  int i;
-
-  dw2_setup (objfile);
+  struct dwarf2_per_objfile *dwarf2_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 (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
     {
       int j;
-      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
       struct quick_file_names *file_data;
 
       /* We only need to look at symtabs not already expanded.  */
@@ -4062,7 +4564,7 @@ dw2_map_matching_symbols (struct objfile *objfile,
                          int global,
                          int (*callback) (struct block *,
                                           struct symbol *, void *),
-                         void *data, symbol_compare_ftype *match,
+                         void *data, symbol_name_match_type match,
                          symbol_compare_ftype *ordered_compare)
 {
   /* Currently unimplemented; used for Ada.  The function can be called if the
@@ -4070,359 +4572,2021 @@ dw2_map_matching_symbols (struct objfile *objfile,
      does not look for non-Ada symbols this function should just return.  */
 }
 
-static void
-dw2_expand_symtabs_matching
-  (struct objfile *objfile,
-   gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   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;
-  offset_type iter;
-  struct mapped_index *index;
+/* Symbol name matcher for .gdb_index names.
 
-  dw2_setup (objfile);
+   Symbol names in .gdb_index have a few particularities:
 
-  /* index_table is NULL if OBJF_READNOW.  */
-  if (!dwarf2_per_objfile->index_table)
-    return;
-  index = dwarf2_per_objfile->index_table;
+   - There's no indication of which is the language of each symbol.
 
-  if (file_matcher != NULL)
-    {
-      htab_up visited_found (htab_create_alloc (10, htab_hash_pointer,
-                                               htab_eq_pointer,
-                                               NULL, xcalloc, xfree));
-      htab_up visited_not_found (htab_create_alloc (10, htab_hash_pointer,
-                                                   htab_eq_pointer,
-                                                   NULL, xcalloc, xfree));
+     Since each language has its own symbol name matching algorithm,
+     and we don't know which language is the right one, we must match
+     each symbol against all languages.  This would be a potential
+     performance problem if it were not mitigated by the
+     mapped_index::name_components lookup table, which significantly
+     reduces the number of times we need to call into this matcher,
+     making it a non-issue.
 
-      /* The rule is CUs specify all the files, including those used by
-        any TU, so there's no need to scan TUs here.  */
+   - Symbol names in the index have no overload (parameter)
+     information.  I.e., in C++, "foo(int)" and "foo(long)" both
+     appear as "foo" in the index, for example.
 
-      for (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;
+     This means that the lookup names passed to the symbol name
+     matcher functions must have no parameter information either
+     because (e.g.) symbol search name "foo" does not match
+     lookup-name "foo(int)" [while swapping search name for lookup
+     name would match].
+*/
+class gdb_index_symbol_name_matcher
+{
+public:
+  /* Prepares the vector of comparison functions for LOOKUP_NAME.  */
+  gdb_index_symbol_name_matcher (const lookup_name_info &lookup_name);
 
-         QUIT;
+  /* Walk all the matcher routines and match SYMBOL_NAME against them.
+     Returns true if any matcher matches.  */
+  bool matches (const char *symbol_name);
 
-         per_cu->v.quick->mark = 0;
+private:
+  /* A reference to the lookup name we're matching against.  */
+  const lookup_name_info &m_lookup_name;
 
-         /* We only need to look at symtabs not already expanded.  */
-         if (per_cu->v.quick->compunit_symtab)
-           continue;
+  /* A vector holding all the different symbol name matchers, for all
+     languages.  */
+  std::vector<symbol_name_matcher_ftype *> m_symbol_name_matcher_funcs;
+};
 
-         file_data = dw2_get_file_names (per_cu);
-         if (file_data == NULL)
-           continue;
+gdb_index_symbol_name_matcher::gdb_index_symbol_name_matcher
+  (const lookup_name_info &lookup_name)
+    : m_lookup_name (lookup_name)
+{
+  /* Prepare the vector of comparison functions upfront, to avoid
+     doing the same work for each symbol.  Care is taken to avoid
+     matching with the same matcher more than once if/when multiple
+     languages use the same matcher function.  */
+  auto &matchers = m_symbol_name_matcher_funcs;
+  matchers.reserve (nr_languages);
 
-         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;
-           }
+  matchers.push_back (default_symbol_name_matcher);
 
-         for (j = 0; j < file_data->num_file_names; ++j)
-           {
-             const char *this_real_name;
+  for (int i = 0; i < nr_languages; i++)
+    {
+      const language_defn *lang = language_def ((enum language) i);
+      symbol_name_matcher_ftype *name_matcher
+       = get_symbol_name_matcher (lang, m_lookup_name);
 
-             if (file_matcher (file_data->file_names[j], false))
-               {
-                 per_cu->v.quick->mark = 1;
-                 break;
-               }
+      /* Don't insert the same comparison routine more than once.
+        Note that we do this linear walk instead of a seemingly
+        cheaper sorted insert, or use a std::set or something like
+        that, because relative order of function addresses is not
+        stable.  This is not a problem in practice because the number
+        of supported languages is low, and the cost here is tiny
+        compared to the number of searches we'll do afterwards using
+        this object.  */
+      if (name_matcher != default_symbol_name_matcher
+         && (std::find (matchers.begin (), matchers.end (), name_matcher)
+             == matchers.end ()))
+       matchers.push_back (name_matcher);
+    }
+}
 
-             /* 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;
+bool
+gdb_index_symbol_name_matcher::matches (const char *symbol_name)
+{
+  for (auto matches_name : m_symbol_name_matcher_funcs)
+    if (matches_name (symbol_name, m_lookup_name, NULL))
+      return true;
 
-             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;
-               }
-           }
+  return false;
+}
 
-         slot = htab_find_slot (per_cu->v.quick->mark
-                                ? visited_found.get ()
-                                : visited_not_found.get (),
-                                file_data, INSERT);
-         *slot = file_data;
-       }
-    }
+/* Starting from a search name, return the string that finds the upper
+   bound of all strings that start with SEARCH_NAME in a sorted name
+   list.  Returns the empty string to indicate that the upper bound is
+   the end of the list.  */
 
-  for (iter = 0; iter < index->symbol_table_slots; ++iter)
-    {
-      offset_type idx = 2 * iter;
-      const char *name;
-      offset_type *vec, vec_len, vec_idx;
-      int global_seen = 0;
+static std::string
+make_sort_after_prefix_name (const char *search_name)
+{
+  /* When looking to complete "func", we find the upper bound of all
+     symbols that start with "func" by looking for where we'd insert
+     the closest string that would follow "func" in lexicographical
+     order.  Usually, that's "func"-with-last-character-incremented,
+     i.e. "fund".  Mind non-ASCII characters, though.  Usually those
+     will be UTF-8 multi-byte sequences, but we can't be certain.
+     Especially mind the 0xff character, which is a valid character in
+     non-UTF-8 source character sets (e.g. Latin1 'ÿ'), and we can't
+     rule out compilers allowing it in identifiers.  Note that
+     conveniently, strcmp/strcasecmp are specified to compare
+     characters interpreted as unsigned char.  So what we do is treat
+     the whole string as a base 256 number composed of a sequence of
+     base 256 "digits" and add 1 to it.  I.e., adding 1 to 0xff wraps
+     to 0, and carries 1 to the following more-significant position.
+     If the very first character in SEARCH_NAME ends up incremented
+     and carries/overflows, then the upper bound is the end of the
+     list.  The string after the empty string is also the empty
+     string.
 
-      QUIT;
+     Some examples of this operation:
 
-      if (index->symbol_table[idx] == 0 && index->symbol_table[idx + 1] == 0)
-       continue;
+       SEARCH_NAME  => "+1" RESULT
 
-      name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
+       "abc"              => "abd"
+       "ab\xff"           => "ac"
+       "\xff" "a" "\xff"  => "\xff" "b"
+       "\xff"             => ""
+       "\xff\xff"         => ""
+       ""                 => ""
 
-      if (!symbol_matcher (name))
-       continue;
+     Then, with these symbols for example:
 
-      /* The name was matched, now expand corresponding CUs that were
-        marked.  */
-      vec = (offset_type *) (index->constant_pool
-                            + MAYBE_SWAP (index->symbol_table[idx + 1]));
-      vec_len = MAYBE_SWAP (vec[0]);
-      for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
-       {
-         struct dwarf2_per_cu_data *per_cu;
-         offset_type cu_index_and_attrs = MAYBE_SWAP (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 =
-           GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
-         int cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
-         /* Only check the symbol attributes if they're present.
-            Indices prior to version 7 don't record them,
-            and indices >= 7 may elide them for certain symbols
-            (gold does this).  */
-         int attrs_valid =
-           (index->version >= 7
-            && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
+      func
+      func1
+      fund
 
-         /* Work around gold/15646.  */
-         if (attrs_valid)
-           {
-             if (!is_static && global_seen)
-               continue;
-             if (!is_static)
-               global_seen = 1;
-           }
+     completing "func" looks for symbols between "func" and
+     "func"-with-last-character-incremented, i.e. "fund" (exclusive),
+     which finds "func" and "func1", but not "fund".
 
-         /* Only check the symbol's kind if it has one.  */
-         if (attrs_valid)
-           {
-             switch (kind)
-               {
-               case VARIABLES_DOMAIN:
-                 if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE)
-                   continue;
-                 break;
-               case FUNCTIONS_DOMAIN:
-                 if (symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION)
-                   continue;
-                 break;
-               case TYPES_DOMAIN:
-                 if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
-                   continue;
-                 break;
-               default:
-                 break;
-               }
-           }
+     And with:
 
-         /* Don't crash on bad data.  */
-         if (cu_index >= (dwarf2_per_objfile->n_comp_units
-                          + dwarf2_per_objfile->n_type_units))
-           {
-             complaint (&symfile_complaints,
-                        _(".gdb_index entry has bad CU index"
-                          " [in module %s]"), objfile_name (objfile));
-             continue;
-           }
+      funcÿ     (Latin1 'ÿ' [0xff])
+      funcÿ1
+      fund
 
-         per_cu = dw2_get_cutu (cu_index);
-         if (file_matcher == NULL || per_cu->v.quick->mark)
-           {
-             int symtab_was_null =
-               (per_cu->v.quick->compunit_symtab == NULL);
+     completing "funcÿ" looks for symbols between "funcÿ" and "fund"
+     (exclusive), which finds "funcÿ" and "funcÿ1", but not "fund".
 
-             dw2_instantiate_symtab (per_cu);
+     And with:
 
-             if (expansion_notify != NULL
-                 && symtab_was_null
-                 && per_cu->v.quick->compunit_symtab != NULL)
-               {
-                 expansion_notify (per_cu->v.quick->compunit_symtab);
-               }
-           }
-       }
-    }
+      Ã¿Ã¿        (Latin1 'ÿ' [0xff])
+      Ã¿Ã¿1
+
+     completing "ÿ" or "ÿÿ" looks for symbols between between "ÿÿ" and
+     the end of the list.
+  */
+  std::string after = search_name;
+  while (!after.empty () && (unsigned char) after.back () == 0xff)
+    after.pop_back ();
+  if (!after.empty ())
+    after.back () = (unsigned char) after.back () + 1;
+  return after;
 }
 
-/* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
-   symtab.  */
+/* See declaration.  */
 
-static struct compunit_symtab *
-recursively_find_pc_sect_compunit_symtab (struct compunit_symtab *cust,
-                                         CORE_ADDR pc)
+std::pair<std::vector<name_component>::const_iterator,
+         std::vector<name_component>::const_iterator>
+mapped_index_base::find_name_components_bounds
+  (const lookup_name_info &lookup_name_without_params) const
 {
-  int i;
+  auto *name_cmp
+    = this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
 
-  if (COMPUNIT_BLOCKVECTOR (cust) != NULL
-      && blockvector_contains_pc (COMPUNIT_BLOCKVECTOR (cust), pc))
-    return cust;
+  const char *cplus
+    = lookup_name_without_params.cplus ().lookup_name ().c_str ();
 
-  if (cust->includes == NULL)
-    return NULL;
+  /* Comparison function object for lower_bound that matches against a
+     given symbol name.  */
+  auto lookup_compare_lower = [&] (const name_component &elem,
+                                  const char *name)
+    {
+      const char *elem_qualified = this->symbol_name_at (elem.idx);
+      const char *elem_name = elem_qualified + elem.name_offset;
+      return name_cmp (elem_name, name) < 0;
+    };
 
-  for (i = 0; cust->includes[i]; ++i)
+  /* Comparison function object for upper_bound that matches against a
+     given symbol name.  */
+  auto lookup_compare_upper = [&] (const char *name,
+                                  const name_component &elem)
     {
-      struct compunit_symtab *s = cust->includes[i];
+      const char *elem_qualified = this->symbol_name_at (elem.idx);
+      const char *elem_name = elem_qualified + elem.name_offset;
+      return name_cmp (name, elem_name) < 0;
+    };
 
-      s = recursively_find_pc_sect_compunit_symtab (s, pc);
-      if (s != NULL)
-       return s;
-    }
+  auto begin = this->name_components.begin ();
+  auto end = this->name_components.end ();
 
-  return NULL;
+  /* Find the lower bound.  */
+  auto lower = [&] ()
+    {
+      if (lookup_name_without_params.completion_mode () && cplus[0] == '\0')
+       return begin;
+      else
+       return std::lower_bound (begin, end, cplus, lookup_compare_lower);
+    } ();
+
+  /* Find the upper bound.  */
+  auto upper = [&] ()
+    {
+      if (lookup_name_without_params.completion_mode ())
+       {
+         /* In completion mode, we want UPPER to point past all
+            symbols names that have the same prefix.  I.e., with
+            these symbols, and completing "func":
+
+             function        << lower bound
+             function1
+             other_function  << upper bound
+
+            We find the upper bound by looking for the insertion
+            point of "func"-with-last-character-incremented,
+            i.e. "fund".  */
+         std::string after = make_sort_after_prefix_name (cplus);
+         if (after.empty ())
+           return end;
+         return std::lower_bound (lower, end, after.c_str (),
+                                  lookup_compare_lower);
+       }
+      else
+       return std::upper_bound (lower, end, cplus, lookup_compare_upper);
+    } ();
+
+  return {lower, upper};
 }
 
-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)
+/* See declaration.  */
+
+void
+mapped_index_base::build_name_components ()
 {
-  struct dwarf2_per_cu_data *data;
-  struct compunit_symtab *result;
+  if (!this->name_components.empty ())
+    return;
 
-  dw2_setup (objfile);
+  this->name_components_casing = case_sensitivity;
+  auto *name_cmp
+    = this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
+
+  /* The code below only knows how to break apart components of C++
+     symbol names (and other languages that use '::' as
+     namespace/module separator).  If we add support for wild matching
+     to some language that uses some other operator (E.g., Ada, Go and
+     D use '.'), then we'll need to try splitting the symbol name
+     according to that language too.  Note that Ada does support wild
+     matching, but doesn't currently support .gdb_index.  */
+  auto count = this->symbol_name_count ();
+  for (offset_type idx = 0; idx < count; idx++)
+    {
+      if (this->symbol_name_slot_invalid (idx))
+       continue;
+
+      const char *name = this->symbol_name_at (idx);
+
+      /* Add each name component to the name component table.  */
+      unsigned int previous_len = 0;
+      for (unsigned int current_len = cp_find_first_component (name);
+          name[current_len] != '\0';
+          current_len += cp_find_first_component (name + current_len))
+       {
+         gdb_assert (name[current_len] == ':');
+         this->name_components.push_back ({previous_len, idx});
+         /* Skip the '::'.  */
+         current_len += 2;
+         previous_len = current_len;
+       }
+      this->name_components.push_back ({previous_len, idx});
+    }
+
+  /* Sort name_components elements by name.  */
+  auto name_comp_compare = [&] (const name_component &left,
+                               const name_component &right)
+    {
+      const char *left_qualified = this->symbol_name_at (left.idx);
+      const char *right_qualified = this->symbol_name_at (right.idx);
+
+      const char *left_name = left_qualified + left.name_offset;
+      const char *right_name = right_qualified + right.name_offset;
+
+      return name_cmp (left_name, right_name) < 0;
+    };
+
+  std::sort (this->name_components.begin (),
+            this->name_components.end (),
+            name_comp_compare);
+}
+
+/* Helper for dw2_expand_symtabs_matching that works with a
+   mapped_index_base instead of the containing objfile.  This is split
+   to a separate function in order to be able to unit test the
+   name_components matching using a mock mapped_index_base.  For each
+   symbol name that matches, calls MATCH_CALLBACK, passing it the
+   symbol's index in the mapped_index_base symbol table.  */
+
+static void
+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<void (offset_type)> match_callback)
+{
+  lookup_name_info lookup_name_without_params
+    = lookup_name_in.make_ignore_params ();
+  gdb_index_symbol_name_matcher lookup_name_matcher
+    (lookup_name_without_params);
+
+  /* Build the symbol name component sorted vector, if we haven't
+     yet.  */
+  index.build_name_components ();
+
+  auto bounds = index.find_name_components_bounds (lookup_name_without_params);
+
+  /* Now for each symbol name in range, check to see if we have a name
+     match, and if so, call the MATCH_CALLBACK callback.  */
+
+  /* The same symbol may appear more than once in the range though.
+     E.g., if we're looking for symbols that complete "w", and we have
+     a symbol named "w1::w2", we'll find the two name components for
+     that same symbol in the range.  To be sure we only call the
+     callback once per symbol, we first collect the symbol name
+     indexes that matched in a temporary vector and ignore
+     duplicates.  */
+  std::vector<offset_type> matches;
+  matches.reserve (std::distance (bounds.first, bounds.second));
+
+  for (; bounds.first != bounds.second; ++bounds.first)
+    {
+      const char *qualified = index.symbol_name_at (bounds.first->idx);
+
+      if (!lookup_name_matcher.matches (qualified)
+         || (symbol_matcher != NULL && !symbol_matcher (qualified)))
+       continue;
+
+      matches.push_back (bounds.first->idx);
+    }
+
+  std::sort (matches.begin (), matches.end ());
+
+  /* Finally call the callback, once per match.  */
+  ULONGEST prev = -1;
+  for (offset_type idx : matches)
+    {
+      if (prev != idx)
+       {
+         match_callback (idx);
+         prev = idx;
+       }
+    }
+
+  /* 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), "");
+}
+
+#if GDB_SELF_TEST
+
+namespace selftests { namespace dw2_expand_symtabs_matching {
+
+/* A mock .gdb_index/.debug_names-like name index table, enough to
+   exercise dw2_expand_symtabs_matching_symbol, which works with the
+   mapped_index_base interface.  Builds an index from the symbol list
+   passed as parameter to the constructor.  */
+class mock_mapped_index : public mapped_index_base
+{
+public:
+  mock_mapped_index (gdb::array_view<const char *> symbols)
+    : m_symbol_table (symbols)
+  {}
+
+  DISABLE_COPY_AND_ASSIGN (mock_mapped_index);
+
+  /* Return the number of names in the symbol table.  */
+  virtual size_t symbol_name_count () const
+  {
+    return m_symbol_table.size ();
+  }
+
+  /* Get the name of the symbol at IDX in the symbol table.  */
+  virtual const char *symbol_name_at (offset_type idx) const
+  {
+    return m_symbol_table[idx];
+  }
+
+private:
+  gdb::array_view<const char *> m_symbol_table;
+};
+
+/* Convenience function that converts a NULL pointer to a "<null>"
+   string, to pass to print routines.  */
+
+static const char *
+string_or_null (const char *str)
+{
+  return str != NULL ? str : "<null>";
+}
+
+/* Check if a lookup_name_info built from
+   NAME/MATCH_TYPE/COMPLETION_MODE matches the symbols in the mock
+   index.  EXPECTED_LIST is the list of expected matches, in expected
+   matching order.  If no match expected, then an empty list is
+   specified.  Returns true on success.  On failure prints a warning
+   indicating the file:line that failed, and returns false.  */
+
+static bool
+check_match (const char *file, int line,
+            mock_mapped_index &mock_index,
+            const char *name, symbol_name_match_type match_type,
+            bool completion_mode,
+            std::initializer_list<const char *> expected_list)
+{
+  lookup_name_info lookup_name (name, match_type, completion_mode);
+
+  bool matched = true;
+
+  auto mismatch = [&] (const char *expected_str,
+                      const char *got)
+  {
+    warning (_("%s:%d: match_type=%s, looking-for=\"%s\", "
+              "expected=\"%s\", got=\"%s\"\n"),
+            file, line,
+            (match_type == symbol_name_match_type::FULL
+             ? "FULL" : "WILD"),
+            name, string_or_null (expected_str), string_or_null (got));
+    matched = false;
+  };
+
+  auto expected_it = expected_list.begin ();
+  auto expected_end = expected_list.end ();
+
+  dw2_expand_symtabs_matching_symbol (mock_index, lookup_name,
+                                     NULL, ALL_DOMAIN,
+                                     [&] (offset_type idx)
+  {
+    const char *matched_name = mock_index.symbol_name_at (idx);
+    const char *expected_str
+      = expected_it == expected_end ? NULL : *expected_it++;
+
+    if (expected_str == NULL || strcmp (expected_str, matched_name) != 0)
+      mismatch (expected_str, matched_name);
+  });
+
+  const char *expected_str
+  = expected_it == expected_end ? NULL : *expected_it++;
+  if (expected_str != NULL)
+    mismatch (expected_str, NULL);
+
+  return matched;
+}
+
+/* The symbols added to the mock mapped_index for testing (in
+   canonical form).  */
+static const char *test_symbols[] = {
+  "function",
+  "std::bar",
+  "std::zfunction",
+  "std::zfunction2",
+  "w1::w2",
+  "ns::foo<char*>",
+  "ns::foo<int>",
+  "ns::foo<long>",
+  "ns2::tmpl<int>::foo2",
+  "(anonymous namespace)::A::B::C",
+
+  /* These are used to check that the increment-last-char in the
+     matching algorithm for completion doesn't match "t1_fund" when
+     completing "t1_func".  */
+  "t1_func",
+  "t1_func1",
+  "t1_fund",
+  "t1_fund1",
+
+  /* A UTF-8 name with multi-byte sequences to make sure that
+     cp-name-parser understands this as a single identifier ("função"
+     is "function" in PT).  */
+  u8"u8função",
+
+  /* \377 (0xff) is Latin1 'ÿ'.  */
+  "yfunc\377",
+
+  /* \377 (0xff) is Latin1 'ÿ'.  */
+  "\377",
+  "\377\377123",
+
+  /* A name with all sorts of complications.  Starts with "z" to make
+     it easier for the completion tests below.  */
+#define Z_SYM_NAME \
+  "z::std::tuple<(anonymous namespace)::ui*, std::bar<(anonymous namespace)::ui> >" \
+    "::tuple<(anonymous namespace)::ui*, " \
+    "std::default_delete<(anonymous namespace)::ui>, void>"
+
+  Z_SYM_NAME
+};
+
+/* Returns true if the mapped_index_base::find_name_component_bounds
+   method finds EXPECTED_SYMS in INDEX when looking for SEARCH_NAME,
+   in completion mode.  */
+
+static bool
+check_find_bounds_finds (mapped_index_base &index,
+                        const char *search_name,
+                        gdb::array_view<const char *> expected_syms)
+{
+  lookup_name_info lookup_name (search_name,
+                               symbol_name_match_type::FULL, true);
+
+  auto bounds = index.find_name_components_bounds (lookup_name);
+
+  size_t distance = std::distance (bounds.first, bounds.second);
+  if (distance != expected_syms.size ())
+    return false;
+
+  for (size_t exp_elem = 0; exp_elem < distance; exp_elem++)
+    {
+      auto nc_elem = bounds.first + exp_elem;
+      const char *qualified = index.symbol_name_at (nc_elem->idx);
+      if (strcmp (qualified, expected_syms[exp_elem]) != 0)
+       return false;
+    }
+
+  return true;
+}
+
+/* Test the lower-level mapped_index::find_name_component_bounds
+   method.  */
+
+static void
+test_mapped_index_find_name_component_bounds ()
+{
+  mock_mapped_index mock_index (test_symbols);
+
+  mock_index.build_name_components ();
+
+  /* Test the lower-level mapped_index::find_name_component_bounds
+     method in completion mode.  */
+  {
+    static const char *expected_syms[] = {
+      "t1_func",
+      "t1_func1",
+    };
+
+    SELF_CHECK (check_find_bounds_finds (mock_index,
+                                        "t1_func", expected_syms));
+  }
+
+  /* Check that the increment-last-char in the name matching algorithm
+     for completion doesn't get confused with Ansi1 'ÿ' / 0xff.  */
+  {
+    static const char *expected_syms1[] = {
+      "\377",
+      "\377\377123",
+    };
+    SELF_CHECK (check_find_bounds_finds (mock_index,
+                                        "\377", expected_syms1));
+
+    static const char *expected_syms2[] = {
+      "\377\377123",
+    };
+    SELF_CHECK (check_find_bounds_finds (mock_index,
+                                        "\377\377", expected_syms2));
+  }
+}
+
+/* Test dw2_expand_symtabs_matching_symbol.  */
+
+static void
+test_dw2_expand_symtabs_matching_symbol ()
+{
+  mock_mapped_index mock_index (test_symbols);
+
+  /* We let all tests run until the end even if some fails, for debug
+     convenience.  */
+  bool any_mismatch = false;
+
+  /* Create the expected symbols list (an initializer_list).  Needed
+     because lists have commas, and we need to pass them to CHECK,
+     which is a macro.  */
+#define EXPECT(...) { __VA_ARGS__ }
+
+  /* Wrapper for check_match that passes down the current
+     __FILE__/__LINE__.  */
+#define CHECK_MATCH(NAME, MATCH_TYPE, COMPLETION_MODE, EXPECTED_LIST)  \
+  any_mismatch |= !check_match (__FILE__, __LINE__,                    \
+                               mock_index,                             \
+                               NAME, MATCH_TYPE, COMPLETION_MODE,      \
+                               EXPECTED_LIST)
+
+  /* Identity checks.  */
+  for (const char *sym : test_symbols)
+    {
+      /* Should be able to match all existing symbols.  */
+      CHECK_MATCH (sym, symbol_name_match_type::FULL, false,
+                  EXPECT (sym));
+
+      /* Should be able to match all existing symbols with
+        parameters.  */
+      std::string with_params = std::string (sym) + "(int)";
+      CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
+                  EXPECT (sym));
+
+      /* Should be able to match all existing symbols with
+        parameters and qualifiers.  */
+      with_params = std::string (sym) + " ( int ) const";
+      CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
+                  EXPECT (sym));
+
+      /* This should really find sym, but cp-name-parser.y doesn't
+        know about lvalue/rvalue qualifiers yet.  */
+      with_params = std::string (sym) + " ( int ) &&";
+      CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
+                  {});
+    }
+
+  /* Check that the name matching algorithm for completion doesn't get
+     confused with Latin1 'ÿ' / 0xff.  */
+  {
+    static const char str[] = "\377";
+    CHECK_MATCH (str, symbol_name_match_type::FULL, true,
+                EXPECT ("\377", "\377\377123"));
+  }
+
+  /* Check that the increment-last-char in the matching algorithm for
+     completion doesn't match "t1_fund" when completing "t1_func".  */
+  {
+    static const char str[] = "t1_func";
+    CHECK_MATCH (str, symbol_name_match_type::FULL, true,
+                EXPECT ("t1_func", "t1_func1"));
+  }
+
+  /* Check that completion mode works at each prefix of the expected
+     symbol name.  */
+  {
+    static const char str[] = "function(int)";
+    size_t len = strlen (str);
+    std::string lookup;
+
+    for (size_t i = 1; i < len; i++)
+      {
+       lookup.assign (str, i);
+       CHECK_MATCH (lookup.c_str (), symbol_name_match_type::FULL, true,
+                    EXPECT ("function"));
+      }
+  }
+
+  /* While "w" is a prefix of both components, the match function
+     should still only be called once.  */
+  {
+    CHECK_MATCH ("w", symbol_name_match_type::FULL, true,
+                EXPECT ("w1::w2"));
+    CHECK_MATCH ("w", symbol_name_match_type::WILD, true,
+                EXPECT ("w1::w2"));
+  }
+
+  /* Same, with a "complicated" symbol.  */
+  {
+    static const char str[] = Z_SYM_NAME;
+    size_t len = strlen (str);
+    std::string lookup;
+
+    for (size_t i = 1; i < len; i++)
+      {
+       lookup.assign (str, i);
+       CHECK_MATCH (lookup.c_str (), symbol_name_match_type::FULL, true,
+                    EXPECT (Z_SYM_NAME));
+      }
+  }
+
+  /* In FULL mode, an incomplete symbol doesn't match.  */
+  {
+    CHECK_MATCH ("std::zfunction(int", symbol_name_match_type::FULL, false,
+                {});
+  }
+
+  /* A complete symbol with parameters matches any overload, since the
+     index has no overload info.  */
+  {
+    CHECK_MATCH ("std::zfunction(int)", symbol_name_match_type::FULL, true,
+                EXPECT ("std::zfunction", "std::zfunction2"));
+    CHECK_MATCH ("zfunction(int)", symbol_name_match_type::WILD, true,
+                EXPECT ("std::zfunction", "std::zfunction2"));
+    CHECK_MATCH ("zfunc", symbol_name_match_type::WILD, true,
+                EXPECT ("std::zfunction", "std::zfunction2"));
+  }
+
+  /* Check that whitespace is ignored appropriately.  A symbol with a
+     template argument list. */
+  {
+    static const char expected[] = "ns::foo<int>";
+    CHECK_MATCH ("ns :: foo < int > ", symbol_name_match_type::FULL, false,
+                EXPECT (expected));
+    CHECK_MATCH ("foo < int > ", symbol_name_match_type::WILD, false,
+                EXPECT (expected));
+  }
+
+  /* Check that whitespace is ignored appropriately.  A symbol with a
+     template argument list that includes a pointer.  */
+  {
+    static const char expected[] = "ns::foo<char*>";
+    /* Try both completion and non-completion modes.  */
+    static const bool completion_mode[2] = {false, true};
+    for (size_t i = 0; i < 2; i++)
+      {
+       CHECK_MATCH ("ns :: foo < char * >", symbol_name_match_type::FULL,
+                    completion_mode[i], EXPECT (expected));
+       CHECK_MATCH ("foo < char * >", symbol_name_match_type::WILD,
+                    completion_mode[i], EXPECT (expected));
+
+       CHECK_MATCH ("ns :: foo < char * > (int)", symbol_name_match_type::FULL,
+                    completion_mode[i], EXPECT (expected));
+       CHECK_MATCH ("foo < char * > (int)", symbol_name_match_type::WILD,
+                    completion_mode[i], EXPECT (expected));
+      }
+  }
+
+  {
+    /* Check method qualifiers are ignored.  */
+    static const char expected[] = "ns::foo<char*>";
+    CHECK_MATCH ("ns :: foo < char * >  ( int ) const",
+                symbol_name_match_type::FULL, true, EXPECT (expected));
+    CHECK_MATCH ("ns :: foo < char * >  ( int ) &&",
+                symbol_name_match_type::FULL, true, EXPECT (expected));
+    CHECK_MATCH ("foo < char * >  ( int ) const",
+                symbol_name_match_type::WILD, true, EXPECT (expected));
+    CHECK_MATCH ("foo < char * >  ( int ) &&",
+                symbol_name_match_type::WILD, true, EXPECT (expected));
+  }
+
+  /* Test lookup names that don't match anything.  */
+  {
+    CHECK_MATCH ("bar2", symbol_name_match_type::WILD, false,
+                {});
+
+    CHECK_MATCH ("doesntexist", symbol_name_match_type::FULL, false,
+                {});
+  }
+
+  /* Some wild matching tests, exercising "(anonymous namespace)",
+     which should not be confused with a parameter list.  */
+  {
+    static const char *syms[] = {
+      "A::B::C",
+      "B::C",
+      "C",
+      "A :: B :: C ( int )",
+      "B :: C ( int )",
+      "C ( int )",
+    };
+
+    for (const char *s : syms)
+      {
+       CHECK_MATCH (s, symbol_name_match_type::WILD, false,
+                    EXPECT ("(anonymous namespace)::A::B::C"));
+      }
+  }
+
+  {
+    static const char expected[] = "ns2::tmpl<int>::foo2";
+    CHECK_MATCH ("tmp", symbol_name_match_type::WILD, true,
+                EXPECT (expected));
+    CHECK_MATCH ("tmpl<", symbol_name_match_type::WILD, true,
+                EXPECT (expected));
+  }
+
+  SELF_CHECK (!any_mismatch);
+
+#undef EXPECT
+#undef CHECK_MATCH
+}
+
+static void
+run_test ()
+{
+  test_mapped_index_find_name_component_bounds ();
+  test_dw2_expand_symtabs_matching_symbol ();
+}
+
+}} // namespace selftests::dw2_expand_symtabs_matching
+
+#endif /* GDB_SELF_TEST */
+
+/* If FILE_MATCHER is NULL or if PER_CU has
+   dwarf2_per_cu_quick_data::MARK set (see
+   dw_expand_symtabs_matching_file_matcher), expand the CU and call
+   EXPANSION_NOTIFY on it.  */
+
+static void
+dw2_expand_symtabs_matching_one
+  (struct dwarf2_per_cu_data *per_cu,
+   gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify)
+{
+  if (file_matcher == NULL || per_cu->v.quick->mark)
+    {
+      bool symtab_was_null
+       = (per_cu->v.quick->compunit_symtab == NULL);
+
+      dw2_instantiate_symtab (per_cu);
+
+      if (expansion_notify != NULL
+         && symtab_was_null
+         && per_cu->v.quick->compunit_symtab != NULL)
+       expansion_notify (per_cu->v.quick->compunit_symtab);
+    }
+}
+
+/* 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
+dw2_expand_marked_cus
+  (struct dwarf2_per_objfile *dwarf2_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,
+   search_domain kind)
+{
+  offset_type *vec, vec_len, vec_idx;
+  bool global_seen = false;
+  mapped_index &index = *dwarf2_per_objfile->index_table;
+
+  vec = (offset_type *) (index.constant_pool
+                        + MAYBE_SWAP (index.symbol_table[idx].vec));
+  vec_len = MAYBE_SWAP (vec[0]);
+  for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
+    {
+      struct dwarf2_per_cu_data *per_cu;
+      offset_type cu_index_and_attrs = MAYBE_SWAP (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 =
+       GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
+      int cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
+      /* Only check the symbol attributes if they're present.
+        Indices prior to version 7 don't record them,
+        and indices >= 7 may elide them for certain symbols
+        (gold does this).  */
+      int attrs_valid =
+       (index.version >= 7
+        && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
+
+      /* Work around gold/15646.  */
+      if (attrs_valid)
+       {
+         if (!is_static && global_seen)
+           continue;
+         if (!is_static)
+           global_seen = true;
+       }
+
+      /* Only check the symbol's kind if it has one.  */
+      if (attrs_valid)
+       {
+         switch (kind)
+           {
+           case VARIABLES_DOMAIN:
+             if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE)
+               continue;
+             break;
+           case FUNCTIONS_DOMAIN:
+             if (symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION)
+               continue;
+             break;
+           case TYPES_DOMAIN:
+             if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+               continue;
+             break;
+           default:
+             break;
+           }
+       }
+
+      /* Don't crash on bad data.  */
+      if (cu_index >= (dwarf2_per_objfile->n_comp_units
+                      + dwarf2_per_objfile->n_type_units))
+       {
+         complaint (&symfile_complaints,
+                    _(".gdb_index entry has bad CU index"
+                      " [in module %s]"),
+                      objfile_name (dwarf2_per_objfile->objfile));
+         continue;
+       }
+
+      per_cu = dw2_get_cutu (dwarf2_per_objfile, cu_index);
+      dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+                                      expansion_notify);
+    }
+}
+
+/* If FILE_MATCHER is non-NULL, set all the
+   dwarf2_per_cu_quick_data::MARK of the current DWARF2_PER_OBJFILE
+   that match FILE_MATCHER.  */
+
+static void
+dw_expand_symtabs_matching_file_matcher
+  (struct dwarf2_per_objfile *dwarf2_per_objfile,
+   gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher)
+{
+  if (file_matcher == NULL)
+    return;
+
+  objfile *const objfile = dwarf2_per_objfile->objfile;
+
+  htab_up visited_found (htab_create_alloc (10, htab_hash_pointer,
+                                           htab_eq_pointer,
+                                           NULL, xcalloc, xfree));
+  htab_up visited_not_found (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.  */
+
+  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+    {
+      int j;
+      struct dwarf2_per_cu_data *per_cu = dw2_get_cu (dwarf2_per_objfile, 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)
+{
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
+  /* index_table is NULL if OBJF_READNOW.  */
+  if (!dwarf2_per_objfile->index_table)
+    return;
+
+  dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, 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 (dwarf2_per_objfile, idx, 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;
 
   if (!objfile->psymtabs_addrmap)
     return NULL;
 
-  data = (struct dwarf2_per_cu_data *) addrmap_find (objfile->psymtabs_addrmap,
-                                                    pc);
-  if (!data)
+  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)
+{
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (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)
+       {
+         dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, 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)
+       {
+         dwarf2_per_cu_data *per_cu = dw2_get_cu (dwarf2_per_objfile, 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 dwarf2_per_objfile *dwarf2_per_objfile,
+                                 const mapped_debug_names &map,
+                                 dwarf2_section_info &section,
+                                 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 (dwarf2_per_objfile, &section, 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 dwarf2_per_objfile.  */
+
+static void
+create_cus_from_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                            const mapped_debug_names &map,
+                            const mapped_debug_names &dwz_map)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+
+  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 (dwarf2_per_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 (dwarf2_per_objfile);
+  create_cus_from_debug_names_list (dwarf2_per_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 dwarf2_per_objfile *dwarf2_per_objfile)
+{
+  mapped_debug_names local_map (dwarf2_per_objfile);
+  mapped_debug_names dwz_map (dwarf2_per_objfile);
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+
+  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 (dwarf2_per_objfile);
+  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 (dwarf2_per_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
+       (dwarf2_per_objfile, local_map, section, &dwarf2_per_objfile->abbrev);
+    }
+
+  create_addrmap_from_aranges (dwarf2_per_objfile,
+                              &dwarf2_per_objfile->debug_aranges);
+
+  dwarf2_per_objfile->debug_names_table.reset
+    (new mapped_debug_names (dwarf2_per_objfile));
+  *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, 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 (map.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 (map.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;
 
-  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));
+  struct dwarf2_per_objfile *dwarf2_per_objfile = m_map.dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  bfd *const abfd = 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 (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 (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)
+           {
+             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 (dwarf2_per_objfile, ull);
+         break;
+       case DW_IDX_type_unit:
+         /* Don't crash on bad data.  */
+         if (ull >= dwarf2_per_objfile->n_type_units)
+           {
+             complaint (&symfile_complaints,
+                        _(".debug_names entry has bad TU index %s"
+                          " [in module %s]"),
+                        pulongest (ull),
+                        objfile_name (dwarf2_per_objfile->objfile));
+             continue;
+           }
+         per_cu = dw2_get_cutu (dwarf2_per_objfile,
+                                dwarf2_per_objfile->n_comp_units + 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)
+    {
+    case VARIABLES_DOMAIN:
+      switch (indexval.dwarf_tag)
+       {
+       case DW_TAG_variable:
+         break;
+       default:
+         goto again;
+       }
+      break;
+    case FUNCTIONS_DOMAIN:
+      switch (indexval.dwarf_tag)
+       {
+       case DW_TAG_subprogram:
+         break;
+       default:
+         goto again;
+       }
+      break;
+    case TYPES_DOMAIN:
+      switch (indexval.dwarf_tag)
+       {
+       case DW_TAG_typedef:
+       case DW_TAG_structure_type:
+         break;
+       default:
+         goto again;
+       }
+      break;
+    default:
+      break;
+    }
 
-  result
-    = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data),
-                                               pc);
-  gdb_assert (result != NULL);
-  return result;
+  return per_cu;
 }
 
-static void
-dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
-                         void *data, int need_fullname)
+static struct compunit_symtab *
+dw2_debug_names_lookup_symbol (struct objfile *objfile, int block_index_int,
+                              const char *name, domain_enum domain)
 {
-  dw2_setup (objfile);
+  const block_enum block_index = static_cast<block_enum> (block_index_int);
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
-  if (!dwarf2_per_objfile->filenames_cache)
+  const auto &mapp = dwarf2_per_objfile->debug_names_table;
+  if (!mapp)
     {
-      dwarf2_per_objfile->filenames_cache.emplace ();
+      /* index is NULL if OBJF_READNOW.  */
+      return NULL;
+    }
+  const auto &map = *mapp;
 
-      htab_up visited (htab_create_alloc (10,
-                                         htab_hash_pointer, htab_eq_pointer,
-                                         NULL, xcalloc, xfree));
+  dw2_debug_names_iterator iter (map, true /* want_specific_block */,
+                                block_index, domain, name);
 
-      /* 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.  */
+  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;
+      struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu);
+      const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
+      struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
 
-      for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
-       {
-         struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+      sym = block_find_symbol (block, name, domain,
+                              block_find_non_opaque_type_preferred,
+                              &with_opaque);
 
-         if (per_cu->v.quick->compunit_symtab)
-           {
-             void **slot = htab_find_slot (visited.get (),
-                                           per_cu->v.quick->file_names,
-                                           INSERT);
+      /* Some caution must be observed with overloaded functions and
+        methods, since the index will not contain any overload
+        information (but NAME might contain it).  */
 
-             *slot = per_cu->v.quick->file_names;
-           }
-       }
+      if (sym != NULL
+         && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+       return stab;
+      if (with_opaque != NULL
+         && strcmp_iw (SYMBOL_SEARCH_NAME (with_opaque), name) == 0)
+       stab_best = stab;
 
-      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;
+      /* Keep looking through other CUs.  */
+    }
 
-         /* We only need to look at symtabs not already expanded.  */
-         if (per_cu->v.quick->compunit_symtab)
-           continue;
+  return stab_best;
+}
 
-         file_data = dw2_get_file_names (per_cu);
-         if (file_data == NULL)
-           continue;
+/* 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.  */
 
-         slot = htab_find_slot (visited.get (), file_data, INSERT);
-         if (*slot)
-           {
-             /* Already visited.  */
-             continue;
-           }
-         *slot = file_data;
+static void
+dw2_debug_names_dump (struct objfile *objfile)
+{
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
-         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);
-           }
-       }
-    }
+  gdb_assert (dwarf2_per_objfile->using_index);
+  printf_filtered (".debug_names:");
+  if (dwarf2_per_objfile->debug_names_table)
+    printf_filtered (" exists\n");
+  else
+    printf_filtered (" faked for \"readnow\"\n");
+  printf_filtered ("\n");
+}
 
-  dwarf2_per_objfile->filenames_cache->traverse ([&] (const char *filename)
+static void
+dw2_debug_names_expand_symtabs_for_function (struct objfile *objfile,
+                                            const char *func_name)
+{
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
+  /* dwarf2_per_objfile->debug_names_table is NULL if OBJF_READNOW.  */
+  if (dwarf2_per_objfile->debug_names_table)
     {
-      gdb::unique_xmalloc_ptr<char> this_real_name;
+      const mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
 
-      if (need_fullname)
-       this_real_name = gdb_realpath (filename);
-      (*fun) (filename, this_real_name.get (), data);
-    });
+      /* Note: It doesn't matter what we pass for block_index here.  */
+      dw2_debug_names_iterator iter (map, false /* want_specific_block */,
+                                    GLOBAL_BLOCK, VAR_DOMAIN, func_name);
+
+      struct dwarf2_per_cu_data *per_cu;
+      while ((per_cu = iter.next ()) != NULL)
+       dw2_instantiate_symtab (per_cu);
+    }
 }
 
-static int
-dw2_has_symbols (struct objfile *objfile)
+static void
+dw2_debug_names_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)
 {
-  return 1;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
+  /* debug_names_table is NULL if OBJF_READNOW.  */
+  if (!dwarf2_per_objfile->debug_names_table)
+    return;
+
+  dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
+
+  mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+
+  dw2_expand_symtabs_matching_symbol (map, lookup_name,
+                                     symbol_matcher,
+                                     kind, [&] (offset_type namei)
+    {
+      /* The name was matched, now expand corresponding CUs that were
+        marked.  */
+      dw2_debug_names_iterator iter (map, kind, namei);
+
+      struct dwarf2_per_cu_data *per_cu;
+      while ((per_cu = iter.next ()) != NULL)
+       dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+                                        expansion_notify);
+    });
 }
 
-const struct quick_symbol_functions dwarf2_gdb_index_functions =
+const struct quick_symbol_functions dwarf2_debug_names_functions =
 {
   dw2_has_symbols,
   dw2_find_last_source_symtab,
   dw2_forget_cached_source_info,
   dw2_map_symtabs_matching_filename,
-  dw2_lookup_symbol,
+  dw2_debug_names_lookup_symbol,
   dw2_print_stats,
-  dw2_dump,
+  dw2_debug_names_dump,
   dw2_relocate,
-  dw2_expand_symtabs_for_function,
+  dw2_debug_names_expand_symtabs_for_function,
   dw2_expand_all_symtabs,
   dw2_expand_symtabs_with_fullname,
   dw2_map_matching_symbols,
-  dw2_expand_symtabs_matching,
+  dw2_debug_names_expand_symtabs_matching,
   dw2_find_pc_sect_compunit_symtab,
+  NULL,
   dw2_map_symbol_filenames
 };
 
-/* Initialize for reading DWARF for this objfile.  Return 0 if this
-   file will use psymtabs, or 1 if using the GNU index.  */
+/* See symfile.h.  */
 
-int
-dwarf2_initialize_objfile (struct objfile *objfile)
+bool
+dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
   /* If we're about to read full symbols, don't bother with the
      indices.  In this case we also don't care if some other debug
      format is making psymtabs, because they are all about to be
@@ -4432,15 +6596,15 @@ dwarf2_initialize_objfile (struct objfile *objfile)
       int i;
 
       dwarf2_per_objfile->using_index = 1;
-      create_all_comp_units (objfile);
-      create_all_type_units (objfile);
+      create_all_comp_units (dwarf2_per_objfile);
+      create_all_type_units (dwarf2_per_objfile);
       dwarf2_per_objfile->quick_file_names_table =
        create_quick_file_names_table (dwarf2_per_objfile->n_comp_units);
 
       for (i = 0; i < (dwarf2_per_objfile->n_comp_units
                       + dwarf2_per_objfile->n_type_units); ++i)
        {
-         struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+         dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
 
          per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
                                            struct dwarf2_per_cu_quick_data);
@@ -4449,13 +6613,23 @@ dwarf2_initialize_objfile (struct objfile *objfile)
       /* Return 1 so that gdb sees the "quick" functions.  However,
         these functions will be no-ops because we will have expanded
         all symtabs.  */
-      return 1;
+      *index_kind = dw_index_kind::GDB_INDEX;
+      return true;
+    }
+
+  if (dwarf2_read_debug_names (dwarf2_per_objfile))
+    {
+      *index_kind = dw_index_kind::DEBUG_NAMES;
+      return true;
     }
 
   if (dwarf2_read_index (objfile))
-    return 1;
+    {
+      *index_kind = dw_index_kind::GDB_INDEX;
+      return true;
+    }
 
-  return 0;
+  return false;
 }
 
 \f
@@ -4465,11 +6639,12 @@ dwarf2_initialize_objfile (struct objfile *objfile)
 void
 dwarf2_build_psymtabs (struct objfile *objfile)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
-  if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
-    {
-      init_psymbol_list (objfile, 1024);
-    }
+  if (objfile->global_psymbols.capacity () == 0
+      && objfile->static_psymbols.capacity () == 0)
+    init_psymbol_list (objfile, 1024);
 
   TRY
     {
@@ -4477,7 +6652,7 @@ dwarf2_build_psymtabs (struct objfile *objfile)
         objfile's obstack is still uselessly kept around.  However,
         freeing it seems unsafe.  */
       psymtab_discarder psymtabs (objfile);
-      dwarf2_build_psymtabs_hard (objfile);
+      dwarf2_build_psymtabs_hard (dwarf2_per_objfile);
       psymtabs.keep ();
     }
   CATCH (except, RETURN_MASK_ERROR)
@@ -4638,9 +6813,10 @@ static struct dwarf2_section_info *
 get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
 {
   struct dwarf2_section_info *abbrev;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
 
   if (this_cu->is_dwz)
-    abbrev = &dwarf2_get_dwz_file ()->abbrev;
+    abbrev = &dwarf2_get_dwz_file (dwarf2_per_objfile)->abbrev;
   else
     abbrev = &dwarf2_per_objfile->abbrev;
 
@@ -4652,7 +6828,8 @@ get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
    Perform various error checking on the header.  */
 
 static void
-error_check_comp_unit_head (struct comp_unit_head *header,
+error_check_comp_unit_head (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                           struct comp_unit_head *header,
                            struct dwarf2_section_info *section,
                            struct dwarf2_section_info *abbrev_section)
 {
@@ -4686,14 +6863,14 @@ error_check_comp_unit_head (struct comp_unit_head *header,
    The result is a pointer to the start of the first DIE.  */
 
 static const gdb_byte *
-read_and_check_comp_unit_head (struct comp_unit_head *header,
+read_and_check_comp_unit_head (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                              struct comp_unit_head *header,
                               struct dwarf2_section_info *section,
                               struct dwarf2_section_info *abbrev_section,
                               const gdb_byte *info_ptr,
                               rcuh_kind section_kind)
 {
   const gdb_byte *beg_of_comp_unit = info_ptr;
-  bfd *abfd = get_section_bfd_owner (section);
 
   header->sect_off = (sect_offset) (beg_of_comp_unit - section->buffer);
 
@@ -4701,7 +6878,8 @@ read_and_check_comp_unit_head (struct comp_unit_head *header,
 
   header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit);
 
-  error_check_comp_unit_head (header, section, abbrev_section);
+  error_check_comp_unit_head (dwarf2_per_objfile, header, section,
+                             abbrev_section);
 
   return info_ptr;
 }
@@ -4709,7 +6887,8 @@ read_and_check_comp_unit_head (struct comp_unit_head *header,
 /* Fetch the abbreviation table offset from a comp or type unit header.  */
 
 static sect_offset
-read_abbrev_offset (struct dwarf2_section_info *section,
+read_abbrev_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                   struct dwarf2_section_info *section,
                    sect_offset sect_off)
 {
   bfd *abfd = get_section_bfd_owner (section);
@@ -4845,7 +7024,8 @@ add_signatured_type_cu_to_table (void **slot, void *datum)
    therefore DW_UT_type.  */
 
 static void
-create_debug_type_hash_table (struct dwo_file *dwo_file,
+create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                             struct dwo_file *dwo_file,
                              dwarf2_section_info *section, htab_t &types_htab,
                              rcuh_kind section_kind)
 {
@@ -4896,7 +7076,7 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
       /* We need to read the type's signature in order to build the hash
         table, but we don't need anything else just yet.  */
 
-      ptr = read_and_check_comp_unit_head (&header, section,
+      ptr = read_and_check_comp_unit_head (dwarf2_per_objfile, &header, section,
                                           abbrev_section, ptr, section_kind);
 
       length = get_cu_length (&header);
@@ -4939,7 +7119,7 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
                                     struct signatured_type);
          sig_type->signature = header.signature;
          sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
-         sig_type->per_cu.objfile = objfile;
+         sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
          sig_type->per_cu.is_debug_types = 1;
          sig_type->per_cu.section = section;
          sig_type->per_cu.sect_off = sect_off;
@@ -4996,7 +7176,8 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
    Note: This function processes DWO files only, not DWP files.  */
 
 static void
-create_debug_types_hash_table (struct dwo_file *dwo_file,
+create_debug_types_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                              struct dwo_file *dwo_file,
                               VEC (dwarf2_section_info_def) *types,
                               htab_t &types_htab)
 {
@@ -5009,8 +7190,8 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
   for (ix = 0;
        VEC_iterate (dwarf2_section_info_def, types, ix, section);
        ++ix)
-    create_debug_type_hash_table (dwo_file, section, types_htab,
-                                 rcuh_kind::TYPE);
+    create_debug_type_hash_table (dwarf2_per_objfile, dwo_file, section,
+                                 types_htab, rcuh_kind::TYPE);
 }
 
 /* Create the hash table of all entries in the .debug_types section,
@@ -5019,14 +7200,16 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
    otherwise non-zero. */
 
 static int
-create_all_type_units (struct objfile *objfile)
+create_all_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   htab_t types_htab = NULL;
   struct signatured_type **iter;
 
-  create_debug_type_hash_table (NULL, &dwarf2_per_objfile->info, types_htab,
+  create_debug_type_hash_table (dwarf2_per_objfile, NULL,
+                               &dwarf2_per_objfile->info, types_htab,
                                rcuh_kind::COMPILE);
-  create_debug_types_hash_table (NULL, dwarf2_per_objfile->types, types_htab);
+  create_debug_types_hash_table (dwarf2_per_objfile, NULL,
+                                dwarf2_per_objfile->types, types_htab);
   if (types_htab == NULL)
     {
       dwarf2_per_objfile->signatured_types = NULL;
@@ -5053,7 +7236,8 @@ create_all_type_units (struct objfile *objfile)
    Otherwise we find one.  */
 
 static struct signatured_type *
-add_type_unit (ULONGEST sig, void **slot)
+add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
+              void **slot)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   int n_type_units = dwarf2_per_objfile->n_type_units;
@@ -5101,7 +7285,7 @@ add_type_unit (ULONGEST sig, void **slot)
    Fill in SIG_ENTRY with DWO_ENTRY.  */
 
 static void
-fill_in_sig_entry_from_dwo_entry (struct objfile *objfile,
+fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
                                  struct signatured_type *sig_entry,
                                  struct dwo_unit *dwo_entry)
 {
@@ -5124,7 +7308,7 @@ fill_in_sig_entry_from_dwo_entry (struct objfile *objfile,
   sig_entry->per_cu.sect_off = dwo_entry->sect_off;
   sig_entry->per_cu.length = dwo_entry->length;
   sig_entry->per_cu.reading_dwo_directly = 1;
-  sig_entry->per_cu.objfile = objfile;
+  sig_entry->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
   sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu;
   sig_entry->dwo_unit = dwo_entry;
 }
@@ -5144,6 +7328,8 @@ fill_in_sig_entry_from_dwo_entry (struct objfile *objfile,
 static struct signatured_type *
 lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwo_file *dwo_file;
   struct dwo_unit find_dwo_entry, *dwo_entry;
@@ -5197,9 +7383,9 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 
   /* If the global table doesn't have an entry for this TU, add one.  */
   if (sig_entry == NULL)
-    sig_entry = add_type_unit (sig, slot);
+    sig_entry = add_type_unit (dwarf2_per_objfile, sig, slot);
 
-  fill_in_sig_entry_from_dwo_entry (objfile, sig_entry, dwo_entry);
+  fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile, sig_entry, dwo_entry);
   sig_entry->per_cu.tu_read = 1;
   return sig_entry;
 }
@@ -5212,8 +7398,10 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 static struct signatured_type *
 lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct dwp_file *dwp_file = get_dwp_file ();
+  struct dwp_file *dwp_file = get_dwp_file (dwarf2_per_objfile);
   struct dwo_unit *dwo_entry;
   struct signatured_type find_sig_entry, *sig_entry;
   void **slot;
@@ -5242,13 +7430,13 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 
   if (dwp_file->tus == NULL)
     return NULL;
-  dwo_entry = lookup_dwo_unit_in_dwp (dwp_file, NULL,
+  dwo_entry = lookup_dwo_unit_in_dwp (dwarf2_per_objfile, dwp_file, NULL,
                                      sig, 1 /* is_debug_types */);
   if (dwo_entry == NULL)
     return NULL;
 
-  sig_entry = add_type_unit (sig, slot);
-  fill_in_sig_entry_from_dwo_entry (objfile, sig_entry, dwo_entry);
+  sig_entry = add_type_unit (dwarf2_per_objfile, sig, slot);
+  fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile, sig_entry, dwo_entry);
 
   return sig_entry;
 }
@@ -5260,12 +7448,15 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 static struct signatured_type *
 lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+
   if (cu->dwo_unit
       && dwarf2_per_objfile->using_index)
     {
       /* We're in a DWO/DWP file, and we're using .gdb_index.
         These cases require special processing.  */
-      if (get_dwp_file () == NULL)
+      if (get_dwp_file (dwarf2_per_objfile) == NULL)
        return lookup_dwo_signatured_type (cu, sig);
       else
        return lookup_dwp_signatured_type (cu, sig);
@@ -5291,7 +7482,8 @@ static void
 init_cu_die_reader (struct die_reader_specs *reader,
                    struct dwarf2_cu *cu,
                    struct dwarf2_section_info *section,
-                   struct dwo_file *dwo_file)
+                   struct dwo_file *dwo_file,
+                   struct abbrev_table *abbrev_table)
 {
   gdb_assert (section->readin && section->buffer != NULL);
   reader->abfd = get_section_bfd_owner (section);
@@ -5301,6 +7493,7 @@ init_cu_die_reader (struct die_reader_specs *reader,
   reader->buffer = section->buffer;
   reader->buffer_end = section->buffer + section->size;
   reader->comp_dir = NULL;
+  reader->abbrev_table = abbrev_table;
 }
 
 /* Subroutine of init_cutu_and_read_dies to simplify it.
@@ -5316,27 +7509,28 @@ init_cu_die_reader (struct die_reader_specs *reader,
    STUB_COMP_DIR may be non-NULL.
    *RESULT_READER,*RESULT_INFO_PTR,*RESULT_COMP_UNIT_DIE,*RESULT_HAS_CHILDREN
    are filled in with the info of the DIE from the DWO file.
-   ABBREV_TABLE_PROVIDED is non-zero if the caller of init_cutu_and_read_dies
-   provided an abbrev table to use.
+   *RESULT_DWO_ABBREV_TABLE will be filled in with the abbrev table allocated
+   from the dwo.  Since *RESULT_READER references this abbrev table, it must be
+   kept around for at least as long as *RESULT_READER.
+
    The result is non-zero if a valid (non-dummy) DIE was found.  */
 
 static int
 read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
                        struct dwo_unit *dwo_unit,
-                       int abbrev_table_provided,
                        struct die_info *stub_comp_unit_die,
                        const char *stub_comp_dir,
                        struct die_reader_specs *result_reader,
                        const gdb_byte **result_info_ptr,
                        struct die_info **result_comp_unit_die,
-                       int *result_has_children)
+                       int *result_has_children,
+                       abbrev_table_up *result_dwo_abbrev_table)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_cu *cu = this_cu->cu;
-  struct dwarf2_section_info *section;
   bfd *abfd;
   const gdb_byte *begin_info_ptr, *info_ptr;
-  ULONGEST signature; /* Or dwo_id.  */
   struct attribute *comp_dir, *stmt_list, *low_pc, *high_pc, *ranges;
   int i,num_extra_attrs;
   struct dwarf2_section_info *dwo_abbrev_section;
@@ -5397,19 +7591,19 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
 
   /* Set up for reading the DWO CU/TU.  */
   cu->dwo_unit = dwo_unit;
-  section = dwo_unit->section;
+  dwarf2_section_info *section = dwo_unit->section;
   dwarf2_read_section (objfile, section);
   abfd = get_section_bfd_owner (section);
   begin_info_ptr = info_ptr = (section->buffer
                               + to_underlying (dwo_unit->sect_off));
   dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
-  init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file);
 
   if (this_cu->is_debug_types)
     {
       struct signatured_type *sig_type = (struct signatured_type *) this_cu;
 
-      info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+      info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
+                                               &cu->header, section,
                                                dwo_abbrev_section,
                                                info_ptr, rcuh_kind::TYPE);
       /* This is not an assert because it can be caused by bad debug info.  */
@@ -5435,7 +7629,8 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
     }
   else
     {
-      info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+      info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
+                                               &cu->header, section,
                                                dwo_abbrev_section,
                                                info_ptr, rcuh_kind::COMPILE);
       gdb_assert (dwo_unit->sect_off == cu->header.sect_off);
@@ -5444,22 +7639,11 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
       dwo_unit->length = get_cu_length (&cu->header);
     }
 
-  /* Replace the CU's original abbrev table with the DWO's.
-     Reminder: We can't read the abbrev table until we've read the header.  */
-  if (abbrev_table_provided)
-    {
-      /* Don't free the provided abbrev table, the caller of
-        init_cutu_and_read_dies owns it.  */
-      dwarf2_read_abbrevs (cu, dwo_abbrev_section);
-      /* Ensure the DWO abbrev table gets freed.  */
-      make_cleanup (dwarf2_free_abbrev_table, cu);
-    }
-  else
-    {
-      dwarf2_free_abbrev_table (cu);
-      dwarf2_read_abbrevs (cu, dwo_abbrev_section);
-      /* Leave any existing abbrev table cleanup as is.  */
-    }
+  *result_dwo_abbrev_table
+    = abbrev_table_read_table (dwarf2_per_objfile, dwo_abbrev_section,
+                              cu->header.abbrev_sect_off);
+  init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file,
+                     result_dwo_abbrev_table->get ());
 
   /* Read in the die, but leave space to copy over the attributes
      from the stub.  This has the benefit of simplifying the rest of
@@ -5523,7 +7707,6 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
                 struct die_info *comp_unit_die)
 {
   struct dwarf2_cu *cu = this_cu->cu;
-  struct attribute *attr;
   ULONGEST signature;
   struct dwo_unit *dwo_unit;
   const char *comp_dir, *dwo_name;
@@ -5552,7 +7735,7 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
       if (! attr)
        error (_("Dwarf Error: missing dwo_id for dwo_name %s"
                 " [in module %s]"),
-              dwo_name, objfile_name (this_cu->objfile));
+              dwo_name, objfile_name (this_cu->dwarf2_per_objfile->objfile));
       signature = DW_UNSND (attr);
       dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir,
                                       signature);
@@ -5563,12 +7746,7 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
 
 /* Subroutine of init_cutu_and_read_dies to simplify it.
    See it for a description of the parameters.
-   Read a TU directly from a DWO file, bypassing the stub.
-
-   Note: This function could be a little bit simpler if we shared cleanups
-   with our caller, init_cutu_and_read_dies.  That's generally a fragile thing
-   to do, so we keep this function self-contained.  Or we could move this
-   into our caller, but it's complex enough already.  */
+   Read a TU directly from a DWO file, bypassing the stub.  */
 
 static void
 init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
@@ -5576,13 +7754,13 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
                           die_reader_func_ftype *die_reader_func,
                           void *data)
 {
-  struct dwarf2_cu *cu;
+  std::unique_ptr<dwarf2_cu> new_cu;
   struct signatured_type *sig_type;
-  struct cleanup *cleanups, *free_cu_cleanup = NULL;
   struct die_reader_specs reader;
   const gdb_byte *info_ptr;
   struct die_info *comp_unit_die;
   int has_children;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
 
   /* Verify we can do the following downcast, and that we have the
      data we need.  */
@@ -5590,12 +7768,9 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
   sig_type = (struct signatured_type *) this_cu;
   gdb_assert (sig_type->dwo_unit != NULL);
 
-  cleanups = make_cleanup (null_cleanup, NULL);
-
   if (use_existing_cu && this_cu->cu != NULL)
     {
       gdb_assert (this_cu->cu->dwo_unit == sig_type->dwo_unit);
-      cu = this_cu->cu;
       /* There's no need to do the rereading_dwo_cu handling that
         init_cutu_and_read_dies does since we don't read the stub.  */
     }
@@ -5603,25 +7778,25 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
     {
       /* If !use_existing_cu, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
-      cu = XNEW (struct dwarf2_cu);
-      init_one_comp_unit (cu, this_cu);
-      /* If an error occurs while loading, release our storage.  */
-      free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
+      new_cu.reset (new dwarf2_cu (this_cu));
     }
 
   /* A future optimization, if needed, would be to use an existing
      abbrev table.  When reading DWOs with skeletonless TUs, all the TUs
      could share abbrev tables.  */
 
+  /* The abbreviation table used by READER, this must live at least as long as
+     READER.  */
+  abbrev_table_up dwo_abbrev_table;
+
   if (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit,
-                             0 /* abbrev_table_provided */,
                              NULL /* stub_comp_unit_die */,
                              sig_type->dwo_unit->dwo_file->comp_dir,
                              &reader, &info_ptr,
-                             &comp_unit_die, &has_children) == 0)
+                             &comp_unit_die, &has_children,
+                             &dwo_abbrev_table) == 0)
     {
       /* Dummy die.  */
-      do_cleanups (cleanups);
       return;
     }
 
@@ -5632,27 +7807,14 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
      but the alternative is making the latter more complex.
      This function is only for the special case of using DWO files directly:
      no point in overly complicating the general case just to handle this.  */
-  if (free_cu_cleanup != NULL)
+  if (new_cu != NULL && keep)
     {
-      if (keep)
-       {
-         /* We've successfully allocated this compilation unit.  Let our
-            caller clean it up when finished with it.  */
-         discard_cleanups (free_cu_cleanup);
-
-         /* We can only discard free_cu_cleanup and all subsequent cleanups.
-            So we have to manually free the abbrev table.  */
-         dwarf2_free_abbrev_table (cu);
-
-         /* Link this CU into read_in_chain.  */
-         this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
-         dwarf2_per_objfile->read_in_chain = this_cu;
-       }
-      else
-       do_cleanups (free_cu_cleanup);
+      /* Link this CU into read_in_chain.  */
+      this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+      dwarf2_per_objfile->read_in_chain = this_cu;
+      /* The chain owns it now.  */
+      new_cu.release ();
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Initialize a CU (or TU) and read its DIEs.
@@ -5678,6 +7840,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
                         die_reader_func_ftype *die_reader_func,
                         void *data)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = this_cu->section;
   bfd *abfd = get_section_bfd_owner (section);
@@ -5687,7 +7850,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   struct die_info *comp_unit_die;
   int has_children;
   struct attribute *attr;
-  struct cleanup *cleanups, *free_cu_cleanup = NULL;
   struct signatured_type *sig_type = NULL;
   struct dwarf2_section_info *abbrev_section;
   /* Non-zero if CU currently points to a DWO file and we need to
@@ -5715,8 +7877,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
       return;
     }
 
-  cleanups = make_cleanup (null_cleanup, NULL);
-
   /* This is cheap if the section is already read in.  */
   dwarf2_read_section (objfile, section);
 
@@ -5724,6 +7884,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
 
   abbrev_section = get_abbrev_section_for_cu (this_cu);
 
+  std::unique_ptr<dwarf2_cu> new_cu;
   if (use_existing_cu && this_cu->cu != NULL)
     {
       cu = this_cu->cu;
@@ -5740,10 +7901,8 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
     {
       /* If !use_existing_cu, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
-      cu = XNEW (struct dwarf2_cu);
-      init_one_comp_unit (cu, this_cu);
-      /* If an error occurs while loading, release our storage.  */
-      free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
+      new_cu.reset (new dwarf2_cu (this_cu));
+      cu = new_cu.get ();
     }
 
   /* Get the header.  */
@@ -5756,7 +7915,8 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
     {
       if (this_cu->is_debug_types)
        {
-         info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+         info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
+                                                   &cu->header, section,
                                                    abbrev_section, info_ptr,
                                                    rcuh_kind::TYPE);
 
@@ -5780,7 +7940,8 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
        }
       else
        {
-         info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+         info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
+                                                   &cu->header, section,
                                                    abbrev_section,
                                                    info_ptr,
                                                    rcuh_kind::COMPILE);
@@ -5794,42 +7955,36 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   /* Skip dummy compilation units.  */
   if (info_ptr >= begin_info_ptr + this_cu->length
       || peek_abbrev_code (abfd, info_ptr) == 0)
-    {
-      do_cleanups (cleanups);
-      return;
-    }
+    return;
 
   /* If we don't have them yet, read the abbrevs for this compilation unit.
      And if we need to read them now, make sure they're freed when we're
-     done.  Note that it's important that if the CU had an abbrev table
-     on entry we don't free it when we're done: Somewhere up the call stack
-     it may be in use.  */
+     done (own the table through ABBREV_TABLE_HOLDER).  */
+  abbrev_table_up abbrev_table_holder;
   if (abbrev_table != NULL)
+    gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
+  else
     {
-      gdb_assert (cu->abbrev_table == NULL);
-      gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
-      cu->abbrev_table = abbrev_table;
-    }
-  else if (cu->abbrev_table == NULL)
-    {
-      dwarf2_read_abbrevs (cu, abbrev_section);
-      make_cleanup (dwarf2_free_abbrev_table, cu);
-    }
-  else if (rereading_dwo_cu)
-    {
-      dwarf2_free_abbrev_table (cu);
-      dwarf2_read_abbrevs (cu, abbrev_section);
+      abbrev_table_holder
+       = abbrev_table_read_table (dwarf2_per_objfile, abbrev_section,
+                                  cu->header.abbrev_sect_off);
+      abbrev_table = abbrev_table_holder.get ();
     }
 
   /* Read the top level CU/TU die.  */
-  init_cu_die_reader (&reader, cu, section, NULL);
+  init_cu_die_reader (&reader, cu, section, NULL, abbrev_table);
   info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
 
   /* If we are in a DWO stub, process it and then read in the "real" CU/TU
-     from the DWO file.
+     from the DWO file.  read_cutu_die_from_dwo will allocate the abbreviation
+     table from the DWO file and pass the ownership over to us.  It will be
+     referenced from READER, so we must make sure to free it after we're done
+     with READER.
+
      Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains a
      DWO CU, that this test will fail (the attribute will not be present).  */
   attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu);
+  abbrev_table_up dwo_abbrev_table;
   if (attr)
     {
       struct dwo_unit *dwo_unit;
@@ -5846,13 +8001,12 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
       if (dwo_unit != NULL)
        {
          if (read_cutu_die_from_dwo (this_cu, dwo_unit,
-                                     abbrev_table != NULL,
                                      comp_unit_die, NULL,
                                      &reader, &info_ptr,
-                                     &dwo_comp_unit_die, &has_children) == 0)
+                                     &dwo_comp_unit_die, &has_children,
+                                     &dwo_abbrev_table) == 0)
            {
              /* Dummy die.  */
-             do_cleanups (cleanups);
              return;
            }
          comp_unit_die = dwo_comp_unit_die;
@@ -5871,27 +8025,14 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
 
   /* Done, clean up.  */
-  if (free_cu_cleanup != NULL)
+  if (new_cu != NULL && keep)
     {
-      if (keep)
-       {
-         /* We've successfully allocated this compilation unit.  Let our
-            caller clean it up when finished with it.  */
-         discard_cleanups (free_cu_cleanup);
-
-         /* We can only discard free_cu_cleanup and all subsequent cleanups.
-            So we have to manually free the abbrev table.  */
-         dwarf2_free_abbrev_table (cu);
-
-         /* Link this CU into read_in_chain.  */
-         this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
-         dwarf2_per_objfile->read_in_chain = this_cu;
-       }
-      else
-       do_cleanups (free_cu_cleanup);
+      /* Link this CU into read_in_chain.  */
+      this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+      dwarf2_per_objfile->read_in_chain = this_cu;
+      /* The chain owns it now.  */
+      new_cu.release ();
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Read CU/TU THIS_CU but do not follow DW_AT_GNU_dwo_name if present.
@@ -5916,14 +8057,13 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
                                   die_reader_func_ftype *die_reader_func,
                                   void *data)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = this_cu->section;
   bfd *abfd = get_section_bfd_owner (section);
   struct dwarf2_section_info *abbrev_section;
-  struct dwarf2_cu cu;
   const gdb_byte *begin_info_ptr, *info_ptr;
   struct die_reader_specs reader;
-  struct cleanup *cleanups;
   struct die_info *comp_unit_die;
   int has_children;
 
@@ -5941,12 +8081,11 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
   /* This is cheap if the section is already read in.  */
   dwarf2_read_section (objfile, section);
 
-  init_one_comp_unit (&cu, this_cu);
-
-  cleanups = make_cleanup (free_stack_comp_unit, &cu);
+  struct dwarf2_cu cu (this_cu);
 
   begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
-  info_ptr = read_and_check_comp_unit_head (&cu.header, section,
+  info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
+                                           &cu.header, section,
                                            abbrev_section, info_ptr,
                                            (this_cu->is_debug_types
                                             ? rcuh_kind::TYPE
@@ -5957,20 +8096,16 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
   /* Skip dummy compilation units.  */
   if (info_ptr >= begin_info_ptr + this_cu->length
       || peek_abbrev_code (abfd, info_ptr) == 0)
-    {
-      do_cleanups (cleanups);
-      return;
-    }
+    return;
 
-  dwarf2_read_abbrevs (&cu, abbrev_section);
-  make_cleanup (dwarf2_free_abbrev_table, &cu);
+  abbrev_table_up abbrev_table
+    = abbrev_table_read_table (dwarf2_per_objfile, abbrev_section,
+                              cu.header.abbrev_sect_off);
 
-  init_cu_die_reader (&reader, &cu, section, dwo_file);
+  init_cu_die_reader (&reader, &cu, section, dwo_file, abbrev_table.get ());
   info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
 
   die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
-
-  do_cleanups (cleanups);
 }
 
 /* Read a CU/TU, except that this does not look for DW_AT_GNU_dwo_name and
@@ -6019,13 +8154,13 @@ eq_type_unit_group (const void *item_lhs, const void *item_rhs)
 /* Allocate a hash table for type unit groups.  */
 
 static htab_t
-allocate_type_unit_groups_table (void)
+allocate_type_unit_groups_table (struct objfile *objfile)
 {
   return htab_create_alloc_ex (3,
                               hash_type_unit_group,
                               eq_type_unit_group,
                               NULL,
-                              &dwarf2_per_objfile->objfile->objfile_obstack,
+                              &objfile->objfile_obstack,
                               hashtab_obstack_allocate,
                               dummy_obstack_deallocate);
 }
@@ -6042,6 +8177,8 @@ allocate_type_unit_groups_table (void)
 static struct type_unit_group *
 create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *per_cu;
   struct type_unit_group *tu_group;
@@ -6049,7 +8186,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
   tu_group = OBSTACK_ZALLOC (&objfile->objfile_obstack,
                             struct type_unit_group);
   per_cu = &tu_group->per_cu;
-  per_cu->objfile = objfile;
+  per_cu->dwarf2_per_objfile = dwarf2_per_objfile;
 
   if (dwarf2_per_objfile->using_index)
     {
@@ -6087,6 +8224,8 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
 static struct type_unit_group *
 get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
   struct type_unit_group *tu_group;
   void **slot;
@@ -6096,7 +8235,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
   if (dwarf2_per_objfile->type_unit_groups == NULL)
     {
       dwarf2_per_objfile->type_unit_groups =
-       allocate_type_unit_groups_table ();
+       allocate_type_unit_groups_table (dwarf2_per_objfile->objfile);
     }
 
   /* Do we need to create a new group, or can we use an existing one?  */
@@ -6149,12 +8288,12 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
 static struct partial_symtab *
 create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
 {
-  struct objfile *objfile = per_cu->objfile;
+  struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
   struct partial_symtab *pst;
 
   pst = start_psymtab_common (objfile, name, 0,
-                             objfile->global_psymbols.next,
-                             objfile->static_psymbols.next);
+                             objfile->global_psymbols,
+                             objfile->static_psymbols);
 
   pst->psymtabs_addrmap_supported = 1;
 
@@ -6191,7 +8330,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
                                  void *data)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
   CORE_ADDR baseaddr;
@@ -6341,7 +8480,7 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
     }
 
   /* Age out any secondary CUs.  */
-  age_cached_comp_units ();
+  age_cached_comp_units (this_cu->dwarf2_per_objfile);
 }
 
 /* Reader function for build_type_psymtabs.  */
@@ -6353,6 +8492,8 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader,
                            int has_children,
                            void *data)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = reader->cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_cu *cu = reader->cu;
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
@@ -6431,11 +8572,11 @@ sort_tu_by_abbrev_offset (const void *ap, const void *bp)
    dwarf2_per_objfile->type_unit_groups.  */
 
 static void
-build_type_psymtabs_1 (void)
+build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
   struct cleanup *cleanups;
-  struct abbrev_table *abbrev_table;
+  abbrev_table_up abbrev_table;
   sect_offset abbrev_offset;
   struct tu_abbrev_offset *sorted_by_abbrev;
   int i;
@@ -6478,7 +8619,8 @@ build_type_psymtabs_1 (void)
 
       sorted_by_abbrev[i].sig_type = sig_type;
       sorted_by_abbrev[i].abbrev_offset =
-       read_abbrev_offset (sig_type->per_cu.section,
+       read_abbrev_offset (dwarf2_per_objfile,
+                           sig_type->per_cu.section,
                            sig_type->per_cu.sect_off);
     }
   cleanups = make_cleanup (xfree, sorted_by_abbrev);
@@ -6486,8 +8628,6 @@ build_type_psymtabs_1 (void)
         sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset);
 
   abbrev_offset = (sect_offset) ~(unsigned) 0;
-  abbrev_table = NULL;
-  make_cleanup (abbrev_table_free_cleanup, &abbrev_table);
 
   for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i)
     {
@@ -6497,22 +8637,16 @@ build_type_psymtabs_1 (void)
       if (abbrev_table == NULL
          || tu->abbrev_offset != abbrev_offset)
        {
-         if (abbrev_table != NULL)
-           {
-             abbrev_table_free (abbrev_table);
-             /* Reset to NULL in case abbrev_table_read_table throws
-                an error: abbrev_table_free_cleanup will get called.  */
-             abbrev_table = NULL;
-           }
          abbrev_offset = tu->abbrev_offset;
          abbrev_table =
-           abbrev_table_read_table (&dwarf2_per_objfile->abbrev,
+           abbrev_table_read_table (dwarf2_per_objfile,
+                                    &dwarf2_per_objfile->abbrev,
                                     abbrev_offset);
          ++tu_stats->nr_uniq_abbrev_tables;
        }
 
-      init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table, 0, 0,
-                              build_type_psymtabs_reader, NULL);
+      init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table.get (),
+                              0, 0, build_type_psymtabs_reader, NULL);
     }
 
   do_cleanups (cleanups);
@@ -6521,7 +8655,7 @@ build_type_psymtabs_1 (void)
 /* Print collected type unit statistics.  */
 
 static void
-print_tu_stats (void)
+print_tu_stats (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
 
@@ -6545,6 +8679,8 @@ print_tu_stats (void)
 static int
 build_type_psymtab_dependencies (void **slot, void *info)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = (struct dwarf2_per_objfile *) info;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct type_unit_group *tu_group = (struct type_unit_group *) *slot;
   struct dwarf2_per_cu_data *per_cu = &tu_group->per_cu;
@@ -6577,12 +8713,12 @@ build_type_psymtab_dependencies (void **slot, void *info)
    Build partial symbol tables for the .debug_types comp-units.  */
 
 static void
-build_type_psymtabs (struct objfile *objfile)
+build_type_psymtabs (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  if (! create_all_type_units (objfile))
+  if (! create_all_type_units (dwarf2_per_objfile))
     return;
 
-  build_type_psymtabs_1 ();
+  build_type_psymtabs_1 (dwarf2_per_objfile);
 }
 
 /* Traversal function for process_skeletonless_type_unit.
@@ -6592,7 +8728,8 @@ static int
 process_skeletonless_type_unit (void **slot, void *info)
 {
   struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
-  struct objfile *objfile = (struct objfile *) info;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = (struct dwarf2_per_objfile *) info;
   struct signatured_type find_entry, *entry;
 
   /* If this TU doesn't exist in the global table, add it and read it in.  */
@@ -6600,7 +8737,7 @@ process_skeletonless_type_unit (void **slot, void *info)
   if (dwarf2_per_objfile->signatured_types == NULL)
     {
       dwarf2_per_objfile->signatured_types
-       = allocate_signatured_type_table (objfile);
+       = allocate_signatured_type_table (dwarf2_per_objfile->objfile);
     }
 
   find_entry.signature = dwo_unit->signature;
@@ -6613,8 +8750,8 @@ process_skeletonless_type_unit (void **slot, void *info)
 
   /* This does the job that create_all_type_units would have done for
      this TU.  */
-  entry = add_type_unit (dwo_unit->signature, slot);
-  fill_in_sig_entry_from_dwo_entry (objfile, entry, dwo_unit);
+  entry = add_type_unit (dwarf2_per_objfile, dwo_unit->signature, slot);
+  fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile, entry, dwo_unit);
   *slot = entry;
 
   /* This does the job that build_type_psymtabs_1 would have done.  */
@@ -6645,38 +8782,28 @@ process_dwo_file_for_skeletonless_type_units (void **slot, void *info)
    Note: This can't be done until we know what all the DWO files are.  */
 
 static void
-process_skeletonless_type_units (struct objfile *objfile)
+process_skeletonless_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   /* Skeletonless TUs in DWP files without .gdb_index is not supported yet.  */
-  if (get_dwp_file () == NULL
+  if (get_dwp_file (dwarf2_per_objfile) == NULL
       && dwarf2_per_objfile->dwo_files != NULL)
     {
       htab_traverse_noresize (dwarf2_per_objfile->dwo_files,
                              process_dwo_file_for_skeletonless_type_units,
-                             objfile);
+                             dwarf2_per_objfile);
     }
 }
 
-/* A cleanup function that clears objfile's psymtabs_addrmap field.  */
+/* Compute the 'user' field for each psymtab in DWARF2_PER_OBJFILE.  */
 
 static void
-psymtabs_addrmap_cleanup (void *o)
-{
-  struct objfile *objfile = (struct objfile *) o;
-
-  objfile->psymtabs_addrmap = NULL;
-}
-
-/* Compute the 'user' field for each psymtab in OBJFILE.  */
-
-static void
-set_partial_user (struct objfile *objfile)
+set_partial_user (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   int i;
 
   for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
     {
-      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
       struct partial_symtab *pst = per_cu->v.psymtab;
       int j;
 
@@ -6696,10 +8823,11 @@ set_partial_user (struct objfile *objfile)
    .debug_info and .debug_abbrev sections.  */
 
 static void
-dwarf2_build_psymtabs_hard (struct objfile *objfile)
+dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  struct cleanup *back_to, *addrmap_cleanup;
+  struct cleanup *back_to;
   int i;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   if (dwarf_read_debug)
     {
@@ -6713,43 +8841,46 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
 
   /* Any cached compilation units will be linked by the per-objfile
      read_in_chain.  Make sure to free them when we're done.  */
-  back_to = make_cleanup (free_cached_comp_units, NULL);
+  back_to = make_cleanup (free_cached_comp_units, dwarf2_per_objfile);
 
-  build_type_psymtabs (objfile);
+  build_type_psymtabs (dwarf2_per_objfile);
 
-  create_all_comp_units (objfile);
+  create_all_comp_units (dwarf2_per_objfile);
 
   /* Create a temporary address map on a temporary obstack.  We later
      copy this to the final obstack.  */
   auto_obstack temp_obstack;
-  objfile->psymtabs_addrmap = addrmap_create_mutable (&temp_obstack);
-  addrmap_cleanup = make_cleanup (psymtabs_addrmap_cleanup, objfile);
+
+  scoped_restore save_psymtabs_addrmap
+    = make_scoped_restore (&objfile->psymtabs_addrmap,
+                          addrmap_create_mutable (&temp_obstack));
 
   for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
     {
-      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+      struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
 
       process_psymtab_comp_unit (per_cu, 0, language_minimal);
     }
 
   /* This has to wait until we read the CUs, we need the list of DWOs.  */
-  process_skeletonless_type_units (objfile);
+  process_skeletonless_type_units (dwarf2_per_objfile);
 
   /* Now that all TUs have been processed we can fill in the dependencies.  */
   if (dwarf2_per_objfile->type_unit_groups != NULL)
     {
       htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups,
-                             build_type_psymtab_dependencies, NULL);
+                             build_type_psymtab_dependencies, dwarf2_per_objfile);
     }
 
   if (dwarf_read_debug)
-    print_tu_stats ();
+    print_tu_stats (dwarf2_per_objfile);
 
-  set_partial_user (objfile);
+  set_partial_user (dwarf2_per_objfile);
 
   objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
                                                    &objfile->objfile_obstack);
-  discard_cleanups (addrmap_cleanup);
+  /* At this point we want to keep the address map.  */
+  save_psymtabs_addrmap.release ();
 
   do_cleanups (back_to);
 
@@ -6789,7 +8920,7 @@ load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
 }
 
 static void
-read_comp_units_from_section (struct objfile *objfile,
+read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
                              struct dwarf2_section_info *section,
                              struct dwarf2_section_info *abbrev_section,
                              unsigned int is_dwz,
@@ -6798,7 +8929,7 @@ read_comp_units_from_section (struct objfile *objfile,
                              struct dwarf2_per_cu_data ***all_comp_units)
 {
   const gdb_byte *info_ptr;
-  bfd *abfd = get_section_bfd_owner (section);
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   if (dwarf_read_debug)
     fprintf_unfiltered (gdb_stdlog, "Reading %s for %s\n",
@@ -6816,8 +8947,9 @@ read_comp_units_from_section (struct objfile *objfile,
       sect_offset sect_off = (sect_offset) (info_ptr - section->buffer);
 
       comp_unit_head cu_header;
-      read_and_check_comp_unit_head (&cu_header, section, abbrev_section,
-                                    info_ptr, rcuh_kind::COMPILE);
+      read_and_check_comp_unit_head (dwarf2_per_objfile, &cu_header, section,
+                                    abbrev_section, info_ptr,
+                                    rcuh_kind::COMPILE);
 
       /* Save the compilation unit for later lookup.  */
       if (cu_header.unit_type != DW_UT_type)
@@ -6839,7 +8971,7 @@ read_comp_units_from_section (struct objfile *objfile,
       this_cu->sect_off = sect_off;
       this_cu->length = cu_header.length + cu_header.initial_length_size;
       this_cu->is_dwz = is_dwz;
-      this_cu->objfile = objfile;
+      this_cu->dwarf2_per_objfile = dwarf2_per_objfile;
       this_cu->section = section;
 
       if (*n_comp_units == *n_allocated)
@@ -6859,25 +8991,26 @@ read_comp_units_from_section (struct objfile *objfile,
    This is only done for -readnow and building partial symtabs.  */
 
 static void
-create_all_comp_units (struct objfile *objfile)
+create_all_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   int n_allocated;
   int n_comp_units;
   struct dwarf2_per_cu_data **all_comp_units;
   struct dwz_file *dwz;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   n_comp_units = 0;
   n_allocated = 10;
   all_comp_units = XNEWVEC (struct dwarf2_per_cu_data *, n_allocated);
 
-  read_comp_units_from_section (objfile, &dwarf2_per_objfile->info,
+  read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->info,
                                &dwarf2_per_objfile->abbrev, 0,
                                &n_allocated, &n_comp_units, &all_comp_units);
 
-  dwz = dwarf2_get_dwz_file ();
+  dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
   if (dwz != NULL)
-    read_comp_units_from_section (objfile, &dwz->info, &dwz->abbrev, 1,
-                                 &n_allocated, &n_comp_units,
+    read_comp_units_from_section (dwarf2_per_objfile, &dwz->info, &dwz->abbrev,
+                                 1, &n_allocated, &n_comp_units,
                                  &all_comp_units);
 
   dwarf2_per_objfile->all_comp_units = XOBNEWVEC (&objfile->objfile_obstack,
@@ -6918,11 +9051,13 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
 
       if (pdi->name != NULL || pdi->tag == DW_TAG_namespace
          || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type
-         || pdi->tag == DW_TAG_imported_unit)
+         || pdi->tag == DW_TAG_imported_unit
+         || pdi->tag == DW_TAG_inlined_subroutine)
        {
          switch (pdi->tag)
            {
            case DW_TAG_subprogram:
+           case DW_TAG_inlined_subroutine:
              add_partial_subprogram (pdi, lowpc, highpc, set_addrmap, cu);
              break;
            case DW_TAG_constant:
@@ -6970,12 +9105,12 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
                  {
                    error (_("Dwarf Error: DW_TAG_imported_unit is not"
                             " supported in type units [in module %s]"),
-                          objfile_name (cu->objfile));
+                          objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
                  }
 
-               per_cu = dwarf2_find_containing_comp_unit (pdi->d.sect_off,
-                                                          pdi->is_dwz,
-                                                          cu->objfile);
+               per_cu = dwarf2_find_containing_comp_unit
+                          (pdi->d.sect_off, pdi->is_dwz,
+                           cu->per_cu->dwarf2_per_objfile);
 
                /* Go read the partial unit, if needed.  */
                if (per_cu->v.psymtab == NULL)
@@ -7137,7 +9272,9 @@ partial_die_full_name (struct partial_die_info *pdi,
 static void
 add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   CORE_ADDR addr = 0;
   const char *actual_name = NULL;
@@ -7155,6 +9292,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
   switch (pdi->tag)
     {
+    case DW_TAG_inlined_subroutine:
     case DW_TAG_subprogram:
       addr = gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr);
       if (pdi->is_external || cu->language == language_ada)
@@ -7183,7 +9321,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
       break;
     case DW_TAG_constant:
       {
-        struct psymbol_allocation_list *list;
+       std::vector<partial_symbol *> *list;
 
        if (pdi->is_external)
          list = &objfile->global_psymbols;
@@ -7352,12 +9490,12 @@ add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
     scan_partial_symbols (pdi->die_child, lowpc, highpc, set_addrmap, cu);
 }
 
-/* Read a partial die corresponding to a subprogram and create a partial
-   symbol for that subprogram.  When the CU language allows it, this
-   routine also defines a partial symbol for each nested subprogram
-   that this subprogram contains.  If SET_ADDRMAP is true, record the
-   covered ranges in the addrmap.  Set *LOWPC and *HIGHPC to the lowest
-   and highest PC values found in PDI.
+/* Read a partial die corresponding to a subprogram or an inlined
+   subprogram and create a partial symbol for that subprogram.
+   When the CU language allows it, this routine also defines a partial
+   symbol for each nested subprogram that this subprogram contains.
+   If SET_ADDRMAP is true, record the covered ranges in the addrmap.
+   Set *LOWPC and *HIGHPC to the lowest and highest PC values found in PDI.
 
    PDI may also be a lexical block, in which case we simply search
    recursively for subprograms defined inside that lexical block.
@@ -7369,7 +9507,7 @@ add_partial_subprogram (struct partial_die_info *pdi,
                        CORE_ADDR *lowpc, CORE_ADDR *highpc,
                        int set_addrmap, struct dwarf2_cu *cu)
 {
-  if (pdi->tag == DW_TAG_subprogram)
+  if (pdi->tag == DW_TAG_subprogram || pdi->tag == DW_TAG_inlined_subroutine)
     {
       if (pdi->has_pc_info)
         {
@@ -7379,7 +9517,7 @@ add_partial_subprogram (struct partial_die_info *pdi,
             *highpc = pdi->highpc;
          if (set_addrmap)
            {
-             struct objfile *objfile = cu->objfile;
+             struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
              struct gdbarch *gdbarch = get_objfile_arch (objfile);
              CORE_ADDR baseaddr;
              CORE_ADDR highpc;
@@ -7417,6 +9555,7 @@ add_partial_subprogram (struct partial_die_info *pdi,
        {
          fixup_partial_die (pdi, cu);
          if (pdi->tag == DW_TAG_subprogram
+             || pdi->tag == DW_TAG_inlined_subroutine
              || pdi->tag == DW_TAG_lexical_block)
            add_partial_subprogram (pdi, lowpc, highpc, set_addrmap, cu);
          pdi = pdi->die_sibling;
@@ -7456,25 +9595,26 @@ peek_abbrev_code (bfd *abfd, const gdb_byte *info_ptr)
   return read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
 }
 
-/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
+/* Read the initial uleb128 in the die at INFO_PTR in compilation unit
+   READER::CU.  Use READER::ABBREV_TABLE to lookup any abbreviation.
+
    Return the corresponding abbrev, or NULL if the number is zero (indicating
    an empty DIE).  In either case *BYTES_READ will be set to the length of
    the initial number.  */
 
 static struct abbrev_info *
-peek_die_abbrev (const gdb_byte *info_ptr, unsigned int *bytes_read,
-                struct dwarf2_cu *cu)
+peek_die_abbrev (const die_reader_specs &reader,
+                const gdb_byte *info_ptr, unsigned int *bytes_read)
 {
-  bfd *abfd = cu->objfile->obfd;
-  unsigned int abbrev_number;
-  struct abbrev_info *abbrev;
-
-  abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+  dwarf2_cu *cu = reader.cu;
+  bfd *abfd = cu->per_cu->dwarf2_per_objfile->objfile->obfd;
+  unsigned int abbrev_number
+    = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
 
   if (abbrev_number == 0)
     return NULL;
 
-  abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number);
+  abbrev_info *abbrev = reader.abbrev_table->lookup_abbrev (abbrev_number);
   if (!abbrev)
     {
       error (_("Dwarf Error: Could not find abbrev number %d in %s"
@@ -7493,13 +9633,11 @@ peek_die_abbrev (const gdb_byte *info_ptr, unsigned int *bytes_read,
 static const gdb_byte *
 skip_children (const struct die_reader_specs *reader, const gdb_byte *info_ptr)
 {
-  struct dwarf2_cu *cu = reader->cu;
-  struct abbrev_info *abbrev;
-  unsigned int bytes_read;
-
   while (1)
     {
-      abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+      unsigned int bytes_read;
+      abbrev_info *abbrev = peek_die_abbrev (*reader, info_ptr, &bytes_read);
+
       if (abbrev == NULL)
        return info_ptr + bytes_read;
       else
@@ -7673,6 +9811,9 @@ static void
 dwarf2_read_symtab (struct partial_symtab *self,
                    struct objfile *objfile)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
   if (self->readin)
     {
       warning (_("bug: psymtab for %s is already read in."),
@@ -7687,11 +9828,6 @@ dwarf2_read_symtab (struct partial_symtab *self,
          gdb_flush (gdb_stdout);
        }
 
-      /* Restore our global data.  */
-      dwarf2_per_objfile
-       = (struct dwarf2_per_objfile *) objfile_data (objfile,
-                                                     dwarf2_objfile_data_key);
-
       /* If this psymtab is constructed from a debug-only objfile, the
         has_section_at_zero flag will not necessarily be correct.  We
         can get the correct value for this flag by looking at the data
@@ -7699,9 +9835,7 @@ dwarf2_read_symtab (struct partial_symtab *self,
       if (objfile->separate_debug_objfile_backlink)
        {
          struct dwarf2_per_objfile *dpo_backlink
-           = ((struct dwarf2_per_objfile *)
-              objfile_data (objfile->separate_debug_objfile_backlink,
-                            dwarf2_objfile_data_key));
+           = get_dwarf2_per_objfile (objfile->separate_debug_objfile_backlink);
 
          dwarf2_per_objfile->has_section_at_zero
            = dpo_backlink->has_section_at_zero;
@@ -7716,7 +9850,7 @@ dwarf2_read_symtab (struct partial_symtab *self,
        printf_filtered (_("done.\n"));
     }
 
-  process_cu_includes ();
+  process_cu_includes (dwarf2_per_objfile);
 }
 \f
 /* Reading in full CUs.  */
@@ -7760,7 +9894,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
   /* We may arrive here during partial symbol reading, if we need full
      DIEs to process an unusual case (e.g. template arguments).  Do
      not queue PER_CU, just tell our caller to load its DIEs.  */
-  if (dwarf2_per_objfile->reading_partial_symbols)
+  if (per_cu->dwarf2_per_objfile->reading_partial_symbols)
     {
       if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
        return 1;
@@ -7793,7 +9927,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
 /* Process the queue.  */
 
 static void
-process_queue (void)
+process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct dwarf2_queue_item *item, *next_item;
 
@@ -7863,35 +9997,6 @@ process_queue (void)
     }
 }
 
-/* Free all allocated queue entries.  This function only releases anything if
-   an error was thrown; if the queue was processed then it would have been
-   freed as we went along.  */
-
-static void
-dwarf2_release_queue (void *dummy)
-{
-  struct dwarf2_queue_item *item, *last;
-
-  item = dwarf2_queue;
-  while (item)
-    {
-      /* Anything still marked queued is likely to be in an
-        inconsistent state, so discard it.  */
-      if (item->per_cu->queued)
-       {
-         if (item->per_cu->cu != NULL)
-           free_one_cached_comp_unit (item->per_cu);
-         item->per_cu->queued = 0;
-       }
-
-      last = item;
-      item = item->next;
-      xfree (last);
-    }
-
-  dwarf2_queue = dwarf2_queue_tail = NULL;
-}
-
 /* Read in full symbols for PST, and anything it depends on.  */
 
 static void
@@ -8019,23 +10124,10 @@ add_to_method_list (struct type *type, int fnfield_index, int index,
   struct delayed_method_info mi;
   mi.type = type;
   mi.fnfield_index = fnfield_index;
-  mi.index = index;
-  mi.name = name;
-  mi.die = die;
-  VEC_safe_push (delayed_method_info, cu->method_list, &mi);
-}
-
-/* A cleanup for freeing the delayed method list.  */
-
-static void
-free_delayed_list (void *ptr)
-{
-  struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr;
-  if (cu->method_list != NULL)
-    {
-      VEC_free (delayed_method_info, cu->method_list);
-      cu->method_list = NULL;
-    }
+  mi.index = index;
+  mi.name = name;
+  mi.die = die;
+  cu->method_list.push_back (mi);
 }
 
 /* Check whether [PHYSNAME, PHYSNAME+LEN) ends with a modifier like
@@ -8064,21 +10156,18 @@ check_modifier (const char *physname, size_t &len, const char (&mod)[N])
 static void
 compute_delayed_physnames (struct dwarf2_cu *cu)
 {
-  int i;
-  struct delayed_method_info *mi;
-
   /* Only C++ delays computing physnames.  */
-  if (VEC_empty (delayed_method_info, cu->method_list))
+  if (cu->method_list.empty ())
     return;
   gdb_assert (cu->language == language_cplus);
 
-  for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i)
+  for (struct delayed_method_info &mi : cu->method_list)
     {
       const char *physname;
       struct fn_fieldlist *fn_flp
-       = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
-      physname = dwarf2_physname (mi->name, mi->die, cu);
-      TYPE_FN_FIELD_PHYSNAME (fn_flp->fn_fields, mi->index)
+       = &TYPE_FN_FIELDLIST (mi.type, mi.fnfield_index);
+      physname = dwarf2_physname (mi.name, mi.die, cu);
+      TYPE_FN_FIELD_PHYSNAME (fn_flp->fn_fields, mi.index)
        = physname ? physname : "";
 
       /* Since there's no tag to indicate whether a method is a
@@ -8093,14 +10182,17 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
              if (physname[len] == ')') /* shortcut */
                break;
              else if (check_modifier (physname, len, " const"))
-               TYPE_FN_FIELD_CONST (fn_flp->fn_fields, mi->index) = 1;
+               TYPE_FN_FIELD_CONST (fn_flp->fn_fields, mi.index) = 1;
              else if (check_modifier (physname, len, " volatile"))
-               TYPE_FN_FIELD_VOLATILE (fn_flp->fn_fields, mi->index) = 1;
+               TYPE_FN_FIELD_VOLATILE (fn_flp->fn_fields, mi.index) = 1;
              else
                break;
            }
        }
     }
+
+  /* The list is no longer needed.  */
+  cu->method_list.clear ();
 }
 
 /* Go objects should be embedded in a DW_TAG_module DIE,
@@ -8138,13 +10230,15 @@ fixup_go_packaging (struct dwarf2_cu *cu)
                package_name = this_package_name;
              else
                {
+                 struct objfile *objfile
+                   = cu->per_cu->dwarf2_per_objfile->objfile;
                  if (strcmp (package_name, this_package_name) != 0)
                    complaint (&symfile_complaints,
                               _("Symtab %s has objects from two different Go packages: %s and %s"),
                               (symbol_symtab (sym) != NULL
                                ? symtab_to_filename_for_display
                                    (symbol_symtab (sym))
-                               : objfile_name (cu->objfile)),
+                               : objfile_name (objfile)),
                               this_package_name, package_name);
                  xfree (this_package_name);
                }
@@ -8154,7 +10248,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
 
   if (package_name != NULL)
     {
-      struct objfile *objfile = cu->objfile;
+      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
       const char *saved_package_name
        = (const char *) obstack_copy0 (&objfile->per_bfd->storage_obstack,
                                        package_name,
@@ -8187,7 +10281,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
 static struct compunit_symtab *
 get_compunit_symtab (struct dwarf2_per_cu_data *per_cu)
 {
-  return (dwarf2_per_objfile->using_index
+  return (per_cu->dwarf2_per_objfile->using_index
          ? per_cu->v.quick->compunit_symtab
          : per_cu->v.psymtab->compunit_symtab);
 }
@@ -8287,7 +10381,7 @@ compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
       /* Now we have a transitive closure of all the included symtabs.  */
       len = VEC_length (compunit_symtab_ptr, result_symtabs);
       cust->includes
-       = XOBNEWVEC (&dwarf2_per_objfile->objfile->objfile_obstack,
+       = XOBNEWVEC (&per_cu->dwarf2_per_objfile->objfile->objfile_obstack,
                     struct compunit_symtab *, len + 1);
       for (ix = 0;
           VEC_iterate (compunit_symtab_ptr, result_symtabs, ix,
@@ -8306,7 +10400,7 @@ compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
    read.  */
 
 static void
-process_cu_includes (void)
+process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   int ix;
   struct dwarf2_per_cu_data *iter;
@@ -8331,11 +10425,11 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
                        enum language pretend_language)
 {
   struct dwarf2_cu *cu = per_cu->cu;
-  struct objfile *objfile = per_cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   CORE_ADDR lowpc, highpc;
   struct compunit_symtab *cust;
-  struct cleanup *back_to, *delayed_list_cleanup;
   CORE_ADDR baseaddr;
   struct block *static_block;
   CORE_ADDR addr;
@@ -8343,8 +10437,10 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   buildsym_init ();
-  back_to = make_cleanup (really_free_pendings, NULL);
-  delayed_list_cleanup = make_cleanup (free_delayed_list, cu);
+  scoped_free_pendings free_pending;
+
+  /* Clear the list here in case something was left over.  */
+  cu->method_list.clear ();
 
   cu->list_in_scope = &file_symbols;
 
@@ -8362,7 +10458,6 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
      should be complete, and it should now be safe to compute all of the
      physnames.  */
   compute_delayed_physnames (cu);
-  do_cleanups (delayed_list_cleanup);
 
   /* Some compilers don't define a DW_AT_high_pc attribute for the
      compilation unit.  If the DW_AT_high_pc is missing, synthesize
@@ -8425,8 +10520,6 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
 
   /* Push it for inclusion processing later.  */
   VEC_safe_push (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus, per_cu);
-
-  do_cleanups (back_to);
 }
 
 /* Generate full symbol information for type unit PER_CU, whose DIEs have
@@ -8437,17 +10530,19 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
                        enum language pretend_language)
 {
   struct dwarf2_cu *cu = per_cu->cu;
-  struct objfile *objfile = per_cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct compunit_symtab *cust;
-  struct cleanup *back_to, *delayed_list_cleanup;
   struct signatured_type *sig_type;
 
   gdb_assert (per_cu->is_debug_types);
   sig_type = (struct signatured_type *) per_cu;
 
   buildsym_init ();
-  back_to = make_cleanup (really_free_pendings, NULL);
-  delayed_list_cleanup = make_cleanup (free_delayed_list, cu);
+  scoped_free_pendings free_pending;
+
+  /* Clear the list here in case something was left over.  */
+  cu->method_list.clear ();
 
   cu->list_in_scope = &file_symbols;
 
@@ -8465,7 +10560,6 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
      should be complete, and it should now be safe to compute all of the
      physnames.  */
   compute_delayed_physnames (cu);
-  do_cleanups (delayed_list_cleanup);
 
   /* TUs share symbol tables.
      If this is the first TU to use this symtab, complete the construction
@@ -8501,8 +10595,6 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
       pst->compunit_symtab = cust;
       pst->readin = 1;
     }
-
-  do_cleanups (back_to);
 }
 
 /* Process an imported unit DIE.  */
@@ -8517,7 +10609,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
     {
       error (_("Dwarf Error: DW_TAG_imported_unit is not"
               " supported in type units [in module %s]"),
-            objfile_name (cu->objfile));
+            objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
     }
 
   attr = dwarf2_attr (die, DW_AT_import, cu);
@@ -8526,7 +10618,8 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
       sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
       bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
       dwarf2_per_cu_data *per_cu
-       = dwarf2_find_containing_comp_unit (sect_off, is_dwz, cu->objfile);
+       = dwarf2_find_containing_comp_unit (sect_off, is_dwz,
+                                           cu->per_cu->dwarf2_per_objfile);
 
       /* If necessary, add it to the queue and load its DIEs.  */
       if (maybe_queue_comp_unit (cu, per_cu, cu->language))
@@ -8661,6 +10754,10 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       process_imported_unit_die (die, cu);
       break;
 
+    case DW_TAG_variable:
+      read_variable (die, cu);
+      break;
+
     default:
       new_symbol (die, NULL, cu);
       break;
@@ -8779,7 +10876,7 @@ dwarf2_compute_name (const char *name,
                     struct die_info *die, struct dwarf2_cu *cu,
                     int physname)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
 
   if (name == NULL)
     name = dwarf2_name (die, cu);
@@ -8788,7 +10885,7 @@ dwarf2_compute_name (const char *name,
      but otherwise compute it by typename_concat inside GDB.
      FIXME: Actually this is not really true, or at least not always true.
      It's all very confusing.  SYMBOL_SET_NAMES doesn't try to demangle
-     Fortran names because there is no mangling standard.  So new_symbol_full
+     Fortran names because there is no mangling standard.  So new_symbol
      will set the demangled name to the result of dwarf2_full_name, and it is
      the demangled name that GDB uses if it exists.  */
   if (cu->language == language_ada
@@ -8813,7 +10910,6 @@ dwarf2_compute_name (const char *name,
     {
       if (die_needs_namespace (die, cu))
        {
-         long length;
          const char *prefix;
          const char *canonical_name = NULL;
 
@@ -9029,9 +11125,8 @@ dwarf2_full_name (const char *name, struct die_info *die, struct dwarf2_cu *cu)
 static const char *
 dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   const char *retval, *mangled = NULL, *canon = NULL;
-  struct cleanup *back_to;
   int need_copy = 1;
 
   /* In this case dwarf2_compute_name is just a shortcut not building anything
@@ -9039,8 +11134,6 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
   if (!die_needs_namespace (die, cu))
     return dwarf2_compute_name (name, die, cu, 1);
 
-  back_to = make_cleanup (null_cleanup, NULL);
-
   mangled = dw2_linkage_name (die, cu);
 
   /* rustc emits invalid values for DW_AT_linkage_name.  Ignore these.
@@ -9051,36 +11144,32 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
 
   /* DW_AT_linkage_name is missing in some cases - depend on what GDB
      has computed.  */
+  gdb::unique_xmalloc_ptr<char> demangled;
   if (mangled != NULL)
     {
-      char *demangled;
-
-      /* Use DMGL_RET_DROP for C++ template functions to suppress their return
-        type.  It is easier for GDB users to search for such functions as
-        `name(params)' than `long name(params)'.  In such case the minimal
-        symbol names do not match the full symbol names but for template
-        functions there is never a need to look up their definition from their
-        declaration so the only disadvantage remains the minimal symbol
-        variant `long name(params)' does not have the proper inferior type.
-        */
 
       if (cu->language == language_go)
        {
-         /* This is a lie, but we already lie to the caller new_symbol_full.
-            new_symbol_full assumes we return the mangled name.
+         /* This is a lie, but we already lie to the caller new_symbol.
+            new_symbol assumes we return the mangled name.
             This just undoes that lie until things are cleaned up.  */
-         demangled = NULL;
        }
       else
        {
-         demangled = gdb_demangle (mangled,
-                                   (DMGL_PARAMS | DMGL_ANSI | DMGL_RET_DROP));
+         /* Use DMGL_RET_DROP for C++ template functions to suppress
+            their return type.  It is easier for GDB users to search
+            for such functions as `name(params)' than `long name(params)'.
+            In such case the minimal symbol names do not match the full
+            symbol names but for template functions there is never a need
+            to look up their definition from their declaration so
+            the only disadvantage remains the minimal symbol variant
+            `long name(params)' does not have the proper inferior type.  */
+         demangled.reset (gdb_demangle (mangled,
+                                        (DMGL_PARAMS | DMGL_ANSI
+                                         | DMGL_RET_DROP)));
        }
       if (demangled)
-       {
-         make_cleanup (xfree, demangled);
-         canon = demangled;
-       }
+       canon = demangled.get ();
       else
        {
          canon = mangled;
@@ -9124,7 +11213,6 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
              obstack_copy0 (&objfile->per_bfd->storage_obstack,
                             retval, strlen (retval)));
 
-  do_cleanups (back_to);
   return retval;
 }
 
@@ -9211,7 +11299,7 @@ using_directives (enum language language)
 static void
 read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct attribute *import_attr;
   struct die_info *imported_die, *child_die;
   struct dwarf2_cu *imported_cu;
@@ -9349,6 +11437,19 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
                       &objfile->objfile_obstack);
 }
 
+/* ICC<14 does not output the required DW_AT_declaration on incomplete
+   types, but gives them a size of zero.  Starting with version 14,
+   ICC is compatible with GCC.  */
+
+static int
+producer_is_icc_lt_14 (struct dwarf2_cu *cu)
+{
+  if (!cu->checked_producer)
+    check_producer (cu);
+
+  return cu->producer_is_icc_lt_14;
+}
+
 /* Check for possibly missing DW_AT_comp_dir with relative .debug_line
    directory paths.  GCC SVN r127613 (new option -fdebug-prefix-map) fixed
    this, it was first present in GCC release 4.3.0.  */
@@ -9405,11 +11506,12 @@ static void
 handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
                        const char *comp_dir, CORE_ADDR lowpc) /* ARI: editCase function */
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct attribute *attr;
   struct line_header line_header_local;
   hashval_t line_header_local_hash;
-  unsigned u;
   void **slot;
   int decode_mapping;
 
@@ -9504,6 +11606,8 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
 static void
 read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
@@ -9755,10 +11859,8 @@ eq_dwo_file (const void *item_lhs, const void *item_rhs)
 /* Allocate a hash table for DWO files.  */
 
 static htab_t
-allocate_dwo_file_hash_table (void)
+allocate_dwo_file_hash_table (struct objfile *objfile)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-
   return htab_create_alloc_ex (41,
                               hash_dwo_file,
                               eq_dwo_file,
@@ -9771,13 +11873,16 @@ allocate_dwo_file_hash_table (void)
 /* Lookup DWO file DWO_NAME.  */
 
 static void **
-lookup_dwo_file_slot (const char *dwo_name, const char *comp_dir)
+lookup_dwo_file_slot (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                     const char *dwo_name,
+                     const char *comp_dir)
 {
   struct dwo_file find_entry;
   void **slot;
 
   if (dwarf2_per_objfile->dwo_files == NULL)
-    dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
+    dwarf2_per_objfile->dwo_files
+      = allocate_dwo_file_hash_table (dwarf2_per_objfile->objfile);
 
   memset (&find_entry, 0, sizeof (find_entry));
   find_entry.dwo_name = dwo_name;
@@ -9877,11 +11982,11 @@ create_dwo_cu_reader (const struct die_reader_specs *reader,
    Note: This function processes DWO files only, not DWP files.  */
 
 static void
-create_cus_hash_table (struct dwo_file &dwo_file, dwarf2_section_info &section,
+create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                      struct dwo_file &dwo_file, dwarf2_section_info &section,
                       htab_t &cus_htab)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  const struct dwarf2_section_info *abbrev_section = &dwo_file.sections.abbrev;
   const gdb_byte *info_ptr, *end_ptr;
 
   dwarf2_read_section (objfile, &section);
@@ -9909,7 +12014,7 @@ create_cus_hash_table (struct dwo_file &dwo_file, dwarf2_section_info &section,
       memset (&create_dwo_cu_data.dwo_unit, 0,
              sizeof (create_dwo_cu_data.dwo_unit));
       memset (&per_cu, 0, sizeof (per_cu));
-      per_cu.objfile = objfile;
+      per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       per_cu.is_debug_types = 0;
       per_cu.sect_off = sect_offset (info_ptr - section.buffer);
       per_cu.section = &section;
@@ -10083,7 +12188,8 @@ create_cus_hash_table (struct dwo_file &dwo_file, dwarf2_section_info &section,
    Note: This function processes DWP files only, not DWO files.  */
 
 static struct dwp_hash_table *
-create_dwp_hash_table (struct dwp_file *dwp_file, int is_debug_types)
+create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                      struct dwp_file *dwp_file, int is_debug_types)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *dbfd = dwp_file->dbfd;
@@ -10320,7 +12426,8 @@ locate_v1_virtual_dwo_sections (asection *sectp,
    This is for DWP version 1 files.  */
 
 static struct dwo_unit *
-create_dwo_unit_in_dwp_v1 (struct dwp_file *dwp_file,
+create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                          struct dwp_file *dwp_file,
                           uint32_t unit_index,
                           const char *comp_dir,
                           ULONGEST signature, int is_debug_types)
@@ -10334,8 +12441,6 @@ create_dwo_unit_in_dwp_v1 (struct dwp_file *dwp_file,
   struct dwo_unit *dwo_unit;
   struct virtual_v1_dwo_sections sections;
   void **dwo_file_slot;
-  char *virtual_dwo_name;
-  struct cleanup *cleanups;
   int i;
 
   gdb_assert (dwp_file->version == 1);
@@ -10362,7 +12467,6 @@ create_dwo_unit_in_dwp_v1 (struct dwp_file *dwp_file,
    + 1 /* trailing zero */)
 
   memset (&sections, 0, sizeof (sections));
-  cleanups = make_cleanup (null_cleanup, 0);
 
   for (i = 0; i < MAX_NR_V1_DWO_SECTIONS; ++i)
     {
@@ -10414,28 +12518,29 @@ create_dwo_unit_in_dwp_v1 (struct dwp_file *dwp_file,
      (fewer struct dwo_file objects to allocate).  Remember that for really
      large apps there can be on the order of 8K CUs and 200K TUs, or more.  */
 
-  virtual_dwo_name =
-    xstrprintf ("virtual-dwo/%d-%d-%d-%d",
-               get_section_id (&sections.abbrev),
-               get_section_id (&sections.line),
-               get_section_id (&sections.loc),
-               get_section_id (&sections.str_offsets));
-  make_cleanup (xfree, virtual_dwo_name);
+  std::string virtual_dwo_name =
+    string_printf ("virtual-dwo/%d-%d-%d-%d",
+                  get_section_id (&sections.abbrev),
+                  get_section_id (&sections.line),
+                  get_section_id (&sections.loc),
+                  get_section_id (&sections.str_offsets));
   /* Can we use an existing virtual DWO file?  */
-  dwo_file_slot = lookup_dwo_file_slot (virtual_dwo_name, comp_dir);
+  dwo_file_slot = lookup_dwo_file_slot (dwarf2_per_objfile,
+                                       virtual_dwo_name.c_str (),
+                                       comp_dir);
   /* Create one if necessary.  */
   if (*dwo_file_slot == NULL)
     {
       if (dwarf_read_debug)
        {
          fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
-                             virtual_dwo_name);
+                             virtual_dwo_name.c_str ());
        }
       dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
       dwo_file->dwo_name
        = (const char *) obstack_copy0 (&objfile->objfile_obstack,
-                                       virtual_dwo_name,
-                                       strlen (virtual_dwo_name));
+                                       virtual_dwo_name.c_str (),
+                                       virtual_dwo_name.size ());
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev = sections.abbrev;
       dwo_file->sections.line = sections.line;
@@ -10459,11 +12564,10 @@ create_dwo_unit_in_dwp_v1 (struct dwp_file *dwp_file,
       if (dwarf_read_debug)
        {
          fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
-                             virtual_dwo_name);
+                             virtual_dwo_name.c_str ());
        }
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
-  do_cleanups (cleanups);
 
   dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
@@ -10482,7 +12586,8 @@ create_dwo_unit_in_dwp_v1 (struct dwp_file *dwp_file,
    of just that piece.  */
 
 static struct dwarf2_section_info
-create_dwp_v2_section (struct dwarf2_section_info *section,
+create_dwp_v2_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                      struct dwarf2_section_info *section,
                       bfd_size_type offset, bfd_size_type size)
 {
   struct dwarf2_section_info result;
@@ -10506,8 +12611,6 @@ create_dwp_v2_section (struct dwarf2_section_info *section,
   if (sectp == NULL
       || offset + size > bfd_get_section_size (sectp))
     {
-      bfd *abfd = sectp->owner;
-
       error (_("Dwarf Error: Bad DWP V2 section info, doesn't fit"
               " in section %s [in module %s]"),
             sectp ? bfd_section_name (abfd, sectp) : "<unknown>",
@@ -10525,7 +12628,8 @@ create_dwp_v2_section (struct dwarf2_section_info *section,
    This is for DWP version 2 files.  */
 
 static struct dwo_unit *
-create_dwo_unit_in_dwp_v2 (struct dwp_file *dwp_file,
+create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                          struct dwp_file *dwp_file,
                           uint32_t unit_index,
                           const char *comp_dir,
                           ULONGEST signature, int is_debug_types)
@@ -10539,8 +12643,6 @@ create_dwo_unit_in_dwp_v2 (struct dwp_file *dwp_file,
   struct dwo_unit *dwo_unit;
   struct virtual_v2_dwo_sections sections;
   void **dwo_file_slot;
-  char *virtual_dwo_name;
-  struct cleanup *cleanups;
   int i;
 
   gdb_assert (dwp_file->version == 2);
@@ -10556,7 +12658,6 @@ create_dwo_unit_in_dwp_v2 (struct dwp_file *dwp_file,
   /* Fetch the section offsets of this DWO unit.  */
 
   memset (&sections, 0, sizeof (sections));
-  cleanups = make_cleanup (null_cleanup, 0);
 
   for (i = 0; i < dwp_htab->nr_columns; ++i)
     {
@@ -10614,47 +12715,49 @@ create_dwo_unit_in_dwp_v2 (struct dwp_file *dwp_file,
      (fewer struct dwo_file objects to allocate).  Remember that for really
      large apps there can be on the order of 8K CUs and 200K TUs, or more.  */
 
-  virtual_dwo_name =
-    xstrprintf ("virtual-dwo/%ld-%ld-%ld-%ld",
-               (long) (sections.abbrev_size ? sections.abbrev_offset : 0),
-               (long) (sections.line_size ? sections.line_offset : 0),
-               (long) (sections.loc_size ? sections.loc_offset : 0),
-               (long) (sections.str_offsets_size
-                       ? sections.str_offsets_offset : 0));
-  make_cleanup (xfree, virtual_dwo_name);
+  std::string virtual_dwo_name =
+    string_printf ("virtual-dwo/%ld-%ld-%ld-%ld",
+                  (long) (sections.abbrev_size ? sections.abbrev_offset : 0),
+                  (long) (sections.line_size ? sections.line_offset : 0),
+                  (long) (sections.loc_size ? sections.loc_offset : 0),
+                  (long) (sections.str_offsets_size
+                          ? sections.str_offsets_offset : 0));
   /* Can we use an existing virtual DWO file?  */
-  dwo_file_slot = lookup_dwo_file_slot (virtual_dwo_name, comp_dir);
+  dwo_file_slot = lookup_dwo_file_slot (dwarf2_per_objfile,
+                                       virtual_dwo_name.c_str (),
+                                       comp_dir);
   /* Create one if necessary.  */
   if (*dwo_file_slot == NULL)
     {
       if (dwarf_read_debug)
        {
          fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
-                             virtual_dwo_name);
+                             virtual_dwo_name.c_str ());
        }
       dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
       dwo_file->dwo_name
        = (const char *) obstack_copy0 (&objfile->objfile_obstack,
-                                       virtual_dwo_name,
-                                       strlen (virtual_dwo_name));
+                                       virtual_dwo_name.c_str (),
+                                       virtual_dwo_name.size ());
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev =
-       create_dwp_v2_section (&dwp_file->sections.abbrev,
+       create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.abbrev,
                               sections.abbrev_offset, sections.abbrev_size);
       dwo_file->sections.line =
-       create_dwp_v2_section (&dwp_file->sections.line,
+       create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.line,
                               sections.line_offset, sections.line_size);
       dwo_file->sections.loc =
-       create_dwp_v2_section (&dwp_file->sections.loc,
+       create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.loc,
                               sections.loc_offset, sections.loc_size);
       dwo_file->sections.macinfo =
-       create_dwp_v2_section (&dwp_file->sections.macinfo,
+       create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.macinfo,
                               sections.macinfo_offset, sections.macinfo_size);
       dwo_file->sections.macro =
-       create_dwp_v2_section (&dwp_file->sections.macro,
+       create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.macro,
                               sections.macro_offset, sections.macro_size);
       dwo_file->sections.str_offsets =
-       create_dwp_v2_section (&dwp_file->sections.str_offsets,
+       create_dwp_v2_section (dwarf2_per_objfile,
+                              &dwp_file->sections.str_offsets,
                               sections.str_offsets_offset,
                               sections.str_offsets_size);
       /* The "str" section is global to the entire DWP file.  */
@@ -10673,18 +12776,18 @@ create_dwo_unit_in_dwp_v2 (struct dwp_file *dwp_file,
       if (dwarf_read_debug)
        {
          fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
-                             virtual_dwo_name);
+                             virtual_dwo_name.c_str ());
        }
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
-  do_cleanups (cleanups);
 
   dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = signature;
   dwo_unit->section =
     XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
-  *dwo_unit->section = create_dwp_v2_section (is_debug_types
+  *dwo_unit->section = create_dwp_v2_section (dwarf2_per_objfile,
+                                             is_debug_types
                                              ? &dwp_file->sections.types
                                              : &dwp_file->sections.info,
                                              sections.info_or_types_offset,
@@ -10698,7 +12801,8 @@ create_dwo_unit_in_dwp_v2 (struct dwp_file *dwp_file,
    Returns NULL if the signature isn't found.  */
 
 static struct dwo_unit *
-lookup_dwo_unit_in_dwp (struct dwp_file *dwp_file, const char *comp_dir,
+lookup_dwo_unit_in_dwp (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                       struct dwp_file *dwp_file, const char *comp_dir,
                        ULONGEST signature, int is_debug_types)
 {
   const struct dwp_hash_table *dwp_htab =
@@ -10736,13 +12840,15 @@ lookup_dwo_unit_in_dwp (struct dwp_file *dwp_file, const char *comp_dir,
 
          if (dwp_file->version == 1)
            {
-             *slot = create_dwo_unit_in_dwp_v1 (dwp_file, unit_index,
+             *slot = create_dwo_unit_in_dwp_v1 (dwarf2_per_objfile,
+                                                dwp_file, unit_index,
                                                 comp_dir, signature,
                                                 is_debug_types);
            }
          else
            {
-             *slot = create_dwo_unit_in_dwp_v2 (dwp_file, unit_index,
+             *slot = create_dwo_unit_in_dwp_v2 (dwarf2_per_objfile,
+                                                dwp_file, unit_index,
                                                 comp_dir, signature,
                                                 is_debug_types);
            }
@@ -10771,9 +12877,10 @@ lookup_dwo_unit_in_dwp (struct dwp_file *dwp_file, const char *comp_dir,
    NOTE: This function is derived from symfile_bfd_open.  */
 
 static gdb_bfd_ref_ptr
-try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd)
+try_open_dwop_file (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                   const char *file_name, int is_dwp, int search_cwd)
 {
-  int desc, flags;
+  int desc;
   char *absolute_name;
   /* Blech.  OPF_TRY_CWD_FIRST also disables searching the path list if
      FILE_NAME contains a '/'.  So we can't use it.  Instead prepend "."
@@ -10792,7 +12899,7 @@ try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd)
   else
     search_path = xstrdup (debug_file_directory);
 
-  flags = OPF_RETURN_REALPATH;
+  openp_flags flags = OPF_RETURN_REALPATH;
   if (is_dwp)
     flags |= OPF_SEARCH_IN_PATH;
   desc = openp (search_path, flags, file_name,
@@ -10827,10 +12934,12 @@ try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd)
    same as symfile_bfd_open.  */
 
 static gdb_bfd_ref_ptr
-open_dwo_file (const char *file_name, const char *comp_dir)
+open_dwo_file (struct dwarf2_per_objfile *dwarf2_per_objfile,
+              const char *file_name, const char *comp_dir)
 {
   if (IS_ABSOLUTE_PATH (file_name))
-    return try_open_dwop_file (file_name, 0 /*is_dwp*/, 0 /*search_cwd*/);
+    return try_open_dwop_file (dwarf2_per_objfile, file_name,
+                              0 /*is_dwp*/, 0 /*search_cwd*/);
 
   /* Before trying the search path, try DWO_NAME in COMP_DIR.  */
 
@@ -10841,7 +12950,9 @@ open_dwo_file (const char *file_name, const char *comp_dir)
 
       /* NOTE: If comp_dir is a relative path, this will also try the
         search path, which seems useful.  */
-      gdb_bfd_ref_ptr abfd (try_open_dwop_file (path_to_try, 0 /*is_dwp*/,
+      gdb_bfd_ref_ptr abfd (try_open_dwop_file (dwarf2_per_objfile,
+                                               path_to_try,
+                                               0 /*is_dwp*/,
                                                1 /*search_cwd*/));
       xfree (path_to_try);
       if (abfd != NULL)
@@ -10854,7 +12965,8 @@ open_dwo_file (const char *file_name, const char *comp_dir)
   if (*debug_file_directory == '\0')
     return NULL;
 
-  return try_open_dwop_file (file_name, 0 /*is_dwp*/, 1 /*search_cwd*/);
+  return try_open_dwop_file (dwarf2_per_objfile, file_name,
+                            0 /*is_dwp*/, 1 /*search_cwd*/);
 }
 
 /* This function is mapped across the sections and remembers the offset and
@@ -10926,11 +13038,12 @@ static struct dwo_file *
 open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
                        const char *dwo_name, const char *comp_dir)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwo_file *dwo_file;
   struct cleanup *cleanups;
 
-  gdb_bfd_ref_ptr dbfd (open_dwo_file (dwo_name, comp_dir));
+  gdb_bfd_ref_ptr dbfd (open_dwo_file (dwarf2_per_objfile, dwo_name, comp_dir));
   if (dbfd == NULL)
     {
       if (dwarf_read_debug)
@@ -10942,15 +13055,20 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
   dwo_file->comp_dir = comp_dir;
   dwo_file->dbfd = dbfd.release ();
 
-  cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file);
+  free_dwo_file_cleanup_data *cleanup_data = XNEW (free_dwo_file_cleanup_data);
+  cleanup_data->dwo_file = dwo_file;
+  cleanup_data->dwarf2_per_objfile = dwarf2_per_objfile;
+
+  cleanups = make_cleanup (free_dwo_file_cleanup, cleanup_data);
 
   bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections,
                         &dwo_file->sections);
 
-  create_cus_hash_table (*dwo_file, dwo_file->sections.info, dwo_file->cus);
+  create_cus_hash_table (dwarf2_per_objfile, *dwo_file, dwo_file->sections.info,
+                        dwo_file->cus);
 
-  create_debug_types_hash_table (dwo_file, dwo_file->sections.types,
-                                dwo_file->tus);
+  create_debug_types_hash_table (dwarf2_per_objfile, dwo_file,
+                                dwo_file->sections.types, dwo_file->tus);
 
   discard_cleanups (cleanups);
 
@@ -11098,9 +13216,11 @@ allocate_dwp_loaded_cutus_table (struct objfile *objfile)
    same as symfile_bfd_open.  */
 
 static gdb_bfd_ref_ptr
-open_dwp_file (const char *file_name)
+open_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile,
+              const char *file_name)
 {
-  gdb_bfd_ref_ptr abfd (try_open_dwop_file (file_name, 1 /*is_dwp*/,
+  gdb_bfd_ref_ptr abfd (try_open_dwop_file (dwarf2_per_objfile, file_name,
+                                           1 /*is_dwp*/,
                                            1 /*search_cwd*/));
   if (abfd != NULL)
     return abfd;
@@ -11118,7 +13238,8 @@ open_dwp_file (const char *file_name)
       /* Don't implicitly search the current directory here.
         If the user wants to search "." to handle this case,
         it must be added to debug-file-directory.  */
-      return try_open_dwop_file (lbasename (file_name), 1 /*is_dwp*/,
+      return try_open_dwop_file (dwarf2_per_objfile,
+                                lbasename (file_name), 1 /*is_dwp*/,
                                 0 /*search_cwd*/);
     }
 
@@ -11130,7 +13251,7 @@ open_dwp_file (const char *file_name)
    The result is NULL if it can't be found.  */
 
 static struct dwp_file *
-open_and_init_dwp_file (void)
+open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwp_file *dwp_file;
@@ -11153,14 +13274,14 @@ open_and_init_dwp_file (void)
 
   dwp_name += ".dwp";
 
-  gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name.c_str ()));
+  gdb_bfd_ref_ptr dbfd (open_dwp_file (dwarf2_per_objfile, dwp_name.c_str ()));
   if (dbfd == NULL
       && strcmp (objfile->original_name, objfile_name (objfile)) != 0)
     {
       /* Try to find .dwp for the binary file after gdb_realpath resolving.  */
       dwp_name = objfile_name (objfile);
       dwp_name += ".dwp";
-      dbfd = open_dwp_file (dwp_name.c_str ());
+      dbfd = open_dwp_file (dwarf2_per_objfile, dwp_name.c_str ());
     }
 
   if (dbfd == NULL)
@@ -11182,12 +13303,13 @@ open_and_init_dwp_file (void)
   bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_common_dwp_sections,
                         dwp_file);
 
-  dwp_file->cus = create_dwp_hash_table (dwp_file, 0);
+  dwp_file->cus = create_dwp_hash_table (dwarf2_per_objfile, dwp_file, 0);
 
-  dwp_file->tus = create_dwp_hash_table (dwp_file, 1);
+  dwp_file->tus = create_dwp_hash_table (dwarf2_per_objfile, dwp_file, 1);
 
   /* The DWP file version is stored in the hash table.  Oh well.  */
-  if (dwp_file->cus->version != dwp_file->tus->version)
+  if (dwp_file->cus && dwp_file->tus
+      && dwp_file->cus->version != dwp_file->tus->version)
     {
       /* Technically speaking, we should try to limp along, but this is
         pretty bizarre.  We use pulongest here because that's the established
@@ -11197,7 +13319,13 @@ open_and_init_dwp_file (void)
             pulongest (dwp_file->cus->version),
             pulongest (dwp_file->tus->version), dwp_name.c_str ());
     }
-  dwp_file->version = dwp_file->cus->version;
+
+  if (dwp_file->cus)
+    dwp_file->version = dwp_file->cus->version;
+  else if (dwp_file->tus)
+    dwp_file->version = dwp_file->tus->version;
+  else
+    dwp_file->version = 2;
 
   if (dwp_file->version == 2)
     bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_v2_dwp_sections,
@@ -11221,11 +13349,12 @@ open_and_init_dwp_file (void)
 /* Wrapper around open_and_init_dwp_file, only open it once.  */
 
 static struct dwp_file *
-get_dwp_file (void)
+get_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   if (! dwarf2_per_objfile->dwp_checked)
     {
-      dwarf2_per_objfile->dwp_file = open_and_init_dwp_file ();
+      dwarf2_per_objfile->dwp_file
+       = open_and_init_dwp_file (dwarf2_per_objfile);
       dwarf2_per_objfile->dwp_checked = 1;
     }
   return dwarf2_per_objfile->dwp_file;
@@ -11252,6 +13381,7 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
                 const char *dwo_name, const char *comp_dir,
                 ULONGEST signature, int is_debug_types)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile = this_unit->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   const char *kind = is_debug_types ? "TU" : "CU";
   void **dwo_file_slot;
@@ -11263,7 +13393,7 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
      look for the original DWO file.  It makes gdb behave differently
      depending on whether one is debugging in the build tree.  */
 
-  dwp_file = get_dwp_file ();
+  dwp_file = get_dwp_file (dwarf2_per_objfile);
   if (dwp_file != NULL)
     {
       const struct dwp_hash_table *dwp_htab =
@@ -11272,7 +13402,7 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
       if (dwp_htab != NULL)
        {
          struct dwo_unit *dwo_cutu =
-           lookup_dwo_unit_in_dwp (dwp_file, comp_dir,
+           lookup_dwo_unit_in_dwp (dwarf2_per_objfile, dwp_file, comp_dir,
                                    signature, is_debug_types);
 
          if (dwo_cutu != NULL)
@@ -11292,7 +13422,8 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
     {
       /* No DWP file, look for the DWO file.  */
 
-      dwo_file_slot = lookup_dwo_file_slot (dwo_name, comp_dir);
+      dwo_file_slot = lookup_dwo_file_slot (dwarf2_per_objfile,
+                                           dwo_name, comp_dir);
       if (*dwo_file_slot == NULL)
        {
          /* Read in the file and build a table of the CUs/TUs it contains.  */
@@ -11352,21 +13483,18 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
   {
     /* Print the name of the DWP file if we looked there, helps the user
        better diagnose the problem.  */
-    char *dwp_text = NULL;
-    struct cleanup *cleanups;
+    std::string dwp_text;
 
     if (dwp_file != NULL)
-      dwp_text = xstrprintf (" [in DWP file %s]", lbasename (dwp_file->name));
-    cleanups = make_cleanup (xfree, dwp_text);
+      dwp_text = string_printf (" [in DWP file %s]",
+                               lbasename (dwp_file->name));
 
     warning (_("Could not find DWO %s %s(%s)%s referenced by %s at offset 0x%x"
               " [in module %s]"),
             kind, dwo_name, hex_string (signature),
-            dwp_text != NULL ? dwp_text : "",
+            dwp_text.c_str (),
             this_unit->is_debug_types ? "TU" : "CU",
             to_underlying (this_unit->sect_off), objfile_name (objfile));
-
-    do_cleanups (cleanups);
   }
   return NULL;
 }
@@ -11430,7 +13558,7 @@ queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *per_cu)
   struct dwo_file *dwo_file;
 
   gdb_assert (!per_cu->is_debug_types);
-  gdb_assert (get_dwp_file () == NULL);
+  gdb_assert (get_dwp_file (per_cu->dwarf2_per_objfile) == NULL);
   gdb_assert (per_cu->cu != NULL);
 
   dwo_unit = per_cu->cu->dwo_unit;
@@ -11460,10 +13588,13 @@ free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile)
 static void
 free_dwo_file_cleanup (void *arg)
 {
-  struct dwo_file *dwo_file = (struct dwo_file *) arg;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  struct free_dwo_file_cleanup_data *data
+    = (struct free_dwo_file_cleanup_data *) arg;
+  struct objfile *objfile = data->dwarf2_per_objfile->objfile;
 
-  free_dwo_file (dwo_file, objfile);
+  free_dwo_file (data->dwo_file, objfile);
+
+  xfree (data);
 }
 
 /* Traversal function for free_dwo_files.  */
@@ -11489,17 +13620,6 @@ free_dwo_files (htab_t dwo_files, struct objfile *objfile)
 \f
 /* Read in various DIEs.  */
 
-/* qsort helper for inherit_abstract_dies.  */
-
-static int
-unsigned_int_compar (const void *ap, const void *bp)
-{
-  unsigned int a = *(unsigned int *) ap;
-  unsigned int b = *(unsigned int *) bp;
-
-  return (a > b) - (b > a);
-}
-
 /* DW_AT_abstract_origin inherits whole DIEs (not just their attributes).
    Inherit only the children of the DW_AT_abstract_origin DIE not being
    already referenced by DW_AT_abstract_origin from the children of the
@@ -11509,15 +13629,11 @@ static void
 inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct die_info *child_die;
-  unsigned die_children_count;
-  /* CU offsets which were referenced by children of the current DIE.  */
-  sect_offset *offsets;
-  sect_offset *offsets_end, *offsetp;
+  sect_offset *offsetp;
   /* Parent of DIE - referenced by DW_AT_abstract_origin.  */
   struct die_info *origin_die;
   /* Iterator of the ORIGIN_DIE children.  */
   struct die_info *origin_child_die;
-  struct cleanup *cleanups;
   struct attribute *attr;
   struct dwarf2_cu *origin_cu;
   struct pending **origin_previous_list_in_scope;
@@ -11545,17 +13661,8 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
               to_underlying (die->sect_off),
               to_underlying (origin_die->sect_off));
 
-  child_die = die->child;
-  die_children_count = 0;
-  while (child_die && child_die->tag)
-    {
-      child_die = sibling_die (child_die);
-      die_children_count++;
-    }
-  offsets = XNEWVEC (sect_offset, die_children_count);
-  cleanups = make_cleanup (xfree, offsets);
+  std::vector<sect_offset> offsets;
 
-  offsets_end = offsets;
   for (child_die = die->child;
        child_die && child_die->tag;
        child_die = sibling_die (child_die))
@@ -11608,19 +13715,19 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
                       to_underlying (child_die->sect_off),
                       to_underlying (child_origin_die->sect_off));
          else
-           *offsets_end++ = child_origin_die->sect_off;
+           offsets.push_back (child_origin_die->sect_off);
        }
     }
-  qsort (offsets, offsets_end - offsets, sizeof (*offsets),
-        unsigned_int_compar);
-  for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
+  std::sort (offsets.begin (), offsets.end ());
+  sect_offset *offsets_end = offsets.data () + offsets.size ();
+  for (offsetp = offsets.data () + 1; offsetp < offsets_end; offsetp++)
     if (offsetp[-1] == *offsetp)
       complaint (&symfile_complaints,
                 _("Multiple children of DIE 0x%x refer "
                   "to DIE 0x%x as their abstract origin"),
                 to_underlying (die->sect_off), to_underlying (*offsetp));
 
-  offsetp = offsets;
+  offsetp = offsets.data ();
   origin_child_die = origin_die->child;
   while (origin_child_die && origin_child_die->tag)
     {
@@ -11641,14 +13748,12 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
       origin_child_die = sibling_die (origin_child_die);
     }
   origin_cu->list_in_scope = origin_previous_list_in_scope;
-
-  do_cleanups (cleanups);
 }
 
 static void
 read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct context_stack *newobj;
   CORE_ADDR lowpc;
@@ -11659,7 +13764,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   CORE_ADDR baseaddr;
   struct block *block;
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
-  VEC (symbolp) *template_args = NULL;
+  std::vector<struct symbol *> template_args;
   struct template_symbol *templ_func = NULL;
 
   if (inlined_func)
@@ -11714,14 +13819,14 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
          || child_die->tag == DW_TAG_template_value_param)
        {
          templ_func = allocate_template_symbol (objfile);
-         templ_func->base.is_cplus_template_function = 1;
+         templ_func->subclass = SYMBOL_TEMPLATE;
          break;
        }
     }
 
   newobj = push_context (0, lowpc);
-  newobj->name = new_symbol_full (die, read_type_die (die, cu), cu,
-                              (struct symbol *) templ_func);
+  newobj->name = new_symbol (die, read_type_die (die, cu), cu,
+                            (struct symbol *) templ_func);
 
   /* If there is a location expression for DW_AT_frame_base, record
      it.  */
@@ -11752,7 +13857,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
              struct symbol *arg = new_symbol (child_die, NULL, cu);
 
              if (arg != NULL)
-               VEC_safe_push (symbolp, template_args, arg);
+               template_args.push_back (arg);
            }
          else
            process_die (child_die, cu);
@@ -11807,18 +13912,17 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   gdbarch_make_symbol_special (gdbarch, newobj->name, objfile);
 
   /* Attach template arguments to function.  */
-  if (! VEC_empty (symbolp, template_args))
+  if (!template_args.empty ())
     {
       gdb_assert (templ_func != NULL);
 
-      templ_func->n_template_arguments = VEC_length (symbolp, template_args);
+      templ_func->n_template_arguments = template_args.size ();
       templ_func->template_arguments
         = XOBNEWVEC (&objfile->objfile_obstack, struct symbol *,
                     templ_func->n_template_arguments);
       memcpy (templ_func->template_arguments,
-             VEC_address (symbolp, template_args),
+             template_args.data (),
              (templ_func->n_template_arguments * sizeof (struct symbol *)));
-      VEC_free (symbolp, template_args);
     }
 
   /* In C++, we can have functions nested inside functions (e.g., when
@@ -11840,7 +13944,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct context_stack *newobj;
   CORE_ADDR lowpc, highpc;
@@ -11911,7 +14015,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   CORE_ADDR pc, baseaddr;
   struct attribute *attr;
@@ -12065,7 +14169,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       struct die_info *target_die;
 
       target_die = follow_die_ref (die, attr, &target_cu);
-      gdb_assert (target_cu->objfile == objfile);
+      gdb_assert (target_cu->per_cu->dwarf2_per_objfile->objfile == objfile);
       if (die_is_declaration (target_die, target_cu))
        {
          const char *target_physname;
@@ -12229,6 +14333,57 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
+/* Helper function for read_variable.  If DIE represents a virtual
+   table, then return the type of the concrete object that is
+   associated with the virtual table.  Otherwise, return NULL.  */
+
+static struct type *
+rust_containing_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *attr = dwarf2_attr (die, DW_AT_type, cu);
+  if (attr == NULL)
+    return NULL;
+
+  /* Find the type DIE.  */
+  struct die_info *type_die = NULL;
+  struct dwarf2_cu *type_cu = cu;
+
+  if (attr_form_is_ref (attr))
+    type_die = follow_die_ref (die, attr, &type_cu);
+  if (type_die == NULL)
+    return NULL;
+
+  if (dwarf2_attr (type_die, DW_AT_containing_type, type_cu) == NULL)
+    return NULL;
+  return die_containing_type (type_die, type_cu);
+}
+
+/* Read a variable (DW_TAG_variable) DIE and create a new symbol.  */
+
+static void
+read_variable (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct rust_vtable_symbol *storage = NULL;
+
+  if (cu->language == language_rust)
+    {
+      struct type *containing_type = rust_containing_type (die, cu);
+
+      if (containing_type != NULL)
+       {
+         struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+
+         storage = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                                   struct rust_vtable_symbol);
+         initialize_objfile_symbol (storage);
+         storage->concrete_type = containing_type;
+         storage->subclass = SYMBOL_RUST_VTABLE;
+       }
+    }
+
+  new_symbol (die, NULL, cu, storage);
+}
+
 /* Call CALLBACK from DW_AT_ranges attribute value OFFSET
    reading .debug_rnglists.
    Callback's type should be:
@@ -12241,19 +14396,14 @@ static bool
 dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
                         Callback &&callback)
 {
-  struct objfile *objfile = cu->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
-  struct comp_unit_head *cu_header = &cu->header;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *obfd = objfile->obfd;
-  unsigned int addr_size = cu_header->addr_size;
-  CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Base address selection entry.  */
   CORE_ADDR base;
   int found_base;
-  unsigned int dummy;
   const gdb_byte *buffer;
-  CORE_ADDR low = 0;
-  CORE_ADDR high = 0;
   CORE_ADDR baseaddr;
   bool overflow = false;
 
@@ -12414,8 +14564,9 @@ static int
 dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
                       Callback &&callback)
 {
-  struct objfile *objfile = cu->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+      = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct comp_unit_head *cu_header = &cu->header;
   bfd *obfd = objfile->obfd;
   unsigned int addr_size = cu_header->addr_size;
@@ -12522,7 +14673,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
                    CORE_ADDR *high_return, struct dwarf2_cu *cu,
                    struct partial_symtab *ranges_pst)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   const CORE_ADDR baseaddr = ANOFFSET (objfile->section_offsets,
                                       SECT_OFF_TEXT (objfile));
@@ -12589,6 +14740,8 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                      CORE_ADDR *highpc, struct dwarf2_cu *cu,
                      struct partial_symtab *pst)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct attribute *attr;
   struct attribute *attr_high;
   CORE_ADDR low = 0;
@@ -12763,7 +14916,7 @@ static void
 dwarf2_record_block_ranges (struct die_info *die, struct block *block,
                             CORE_ADDR baseaddr, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct attribute *attr;
   struct attribute *attr_high;
@@ -12789,7 +14942,6 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
   attr = dwarf2_attr (die, DW_AT_ranges, cu);
   if (attr)
     {
-      bfd *obfd = objfile->obfd;
       /* DW_AT_ranges_base does not apply to DIEs from the DWO skeleton.
         We take advantage of the fact that DW_AT_ranges does not appear
         in DW_TAG_compile_unit of DWO files.  */
@@ -12854,8 +15006,8 @@ check_producer (struct dwarf2_cu *cu)
       cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
       cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
     }
-  else if (startswith (cu->producer, "Intel(R) C"))
-    cu->producer_is_icc = 1;
+  else if (producer_is_icc (cu->producer, &major, &minor))
+    cu->producer_is_icc_lt_14 = major < 14;
   else
     {
       /* For other non-GCC compilers, expect their behavior is DWARF version
@@ -12948,7 +15100,7 @@ static void
 dwarf2_add_field (struct field_info *fip, struct die_info *die,
                  struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct nextfield *new_field;
   struct attribute *attr;
@@ -13133,33 +15285,81 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     }
 }
 
-/* Add a typedef defined in the scope of the FIP's class.  */
+/* Can the type given by DIE define another type?  */
+
+static bool
+type_can_define_types (const struct die_info *die)
+{
+  switch (die->tag)
+    {
+    case DW_TAG_typedef:
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_enumeration_type:
+      return true;
+
+    default:
+      return false;
+    }
+}
+
+/* Add a type definition defined in the scope of the FIP's class.  */
 
 static void
-dwarf2_add_typedef (struct field_info *fip, struct die_info *die,
-                   struct dwarf2_cu *cu)
+dwarf2_add_type_defn (struct field_info *fip, struct die_info *die,
+                     struct dwarf2_cu *cu)
 {
-  struct typedef_field_list *new_field;
-  struct typedef_field *fp;
+  struct decl_field_list *new_field;
+  struct decl_field *fp;
 
   /* Allocate a new field list entry and link it in.  */
-  new_field = XCNEW (struct typedef_field_list);
+  new_field = XCNEW (struct decl_field_list);
   make_cleanup (xfree, new_field);
 
-  gdb_assert (die->tag == DW_TAG_typedef);
+  gdb_assert (type_can_define_types (die));
 
   fp = &new_field->field;
 
-  /* Get name of field.  */
+  /* Get name of field.  NULL is okay here, meaning an anonymous type.  */
   fp->name = dwarf2_name (die, cu);
-  if (fp->name == NULL)
-    return;
-
   fp->type = read_type_die (die, cu);
 
-  new_field->next = fip->typedef_field_list;
-  fip->typedef_field_list = new_field;
-  fip->typedef_field_list_count++;
+  /* Save accessibility.  */
+  enum dwarf_access_attribute accessibility;
+  struct attribute *attr = dwarf2_attr (die, DW_AT_accessibility, cu);
+  if (attr != NULL)
+    accessibility = (enum dwarf_access_attribute) DW_UNSND (attr);
+  else
+    accessibility = dwarf2_default_access_attribute (die, cu);
+  switch (accessibility)
+    {
+    case DW_ACCESS_public:
+      /* The assumed value if neither private nor protected.  */
+      break;
+    case DW_ACCESS_private:
+      fp->is_private = 1;
+      break;
+    case DW_ACCESS_protected:
+      fp->is_protected = 1;
+      break;
+    default:
+      complaint (&symfile_complaints,
+                _("Unhandled DW_AT_accessibility value (%x)"), accessibility);
+    }
+
+  if (die->tag == DW_TAG_typedef)
+    {
+      new_field->next = fip->typedef_field_list;
+      fip->typedef_field_list = new_field;
+      fip->typedef_field_list_count++;
+    }
+  else
+    {
+      new_field->next = fip->nested_types_list;
+      fip->nested_types_list = new_field;
+      fip->nested_types_list_count++;
+    }
 }
 
 /* Create the vector of fields, and attach it to the type.  */
@@ -13299,7 +15499,7 @@ static void
 dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
                      struct type *type, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct attribute *attr;
   struct fnfieldlist *flp;
   int i;
@@ -13542,7 +15742,6 @@ static int
 is_vtable_name (const char *name, struct dwarf2_cu *cu)
 {
   static const char vptr[] = "_vptr";
-  static const char vtable[] = "vtable";
 
   /* Look for the C++ form of the vtable.  */
   if (startswith (name, vptr) && is_cplus_marker (name[sizeof (vptr) - 1]))
@@ -13596,17 +15795,6 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
   smash_to_methodptr_type (type, new_type);
 }
 
-/* Return non-zero if the CU's PRODUCER string matches the Intel C/C++ compiler
-   (icc).  */
-
-static int
-producer_is_icc (struct dwarf2_cu *cu)
-{
-  if (!cu->checked_producer)
-    check_producer (cu);
-
-  return cu->producer_is_icc;
-}
 
 /* Called when we find the DIE that starts a structure or union scope
    (definition) to create a type for the structure or union.  Fill in
@@ -13623,7 +15811,7 @@ producer_is_icc (struct dwarf2_cu *cu)
 static struct type *
 read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   const char *name;
@@ -13712,10 +15900,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_LENGTH (type) = 0;
     }
 
-  if (producer_is_icc (cu) && (TYPE_LENGTH (type) == 0))
+  if (producer_is_icc_lt_14 (cu) && (TYPE_LENGTH (type) == 0))
     {
-      /* ICC does not output the required DW_AT_declaration
-        on incomplete types, but gives them a size of zero.  */
+      /* ICC<14 does not output the required DW_AT_declaration on
+        incomplete types, but gives them a size of zero.  */
       TYPE_STUB (type) = 1;
     }
   else
@@ -13746,7 +15934,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct die_info *child_die;
   struct type *type;
 
@@ -13757,7 +15945,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (die->child != NULL && ! die_is_declaration (die, cu))
     {
       struct field_info fi;
-      VEC (symbolp) *template_args = NULL;
+      std::vector<struct symbol *> template_args;
       struct cleanup *back_to = make_cleanup (null_cleanup, 0);
 
       memset (&fi, 0, sizeof (struct field_info));
@@ -13794,35 +15982,33 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
              /* C++ base class field.  */
              dwarf2_add_field (&fi, child_die, cu);
            }
-         else if (child_die->tag == DW_TAG_typedef)
-           dwarf2_add_typedef (&fi, child_die, cu);
+         else if (type_can_define_types (child_die))
+           dwarf2_add_type_defn (&fi, child_die, cu);
          else if (child_die->tag == DW_TAG_template_type_param
                   || child_die->tag == DW_TAG_template_value_param)
            {
              struct symbol *arg = new_symbol (child_die, NULL, cu);
 
              if (arg != NULL)
-               VEC_safe_push (symbolp, template_args, arg);
+               template_args.push_back (arg);
            }
 
          child_die = sibling_die (child_die);
        }
 
       /* Attach template arguments to type.  */
-      if (! VEC_empty (symbolp, template_args))
+      if (!template_args.empty ())
        {
          ALLOCATE_CPLUS_STRUCT_TYPE (type);
-         TYPE_N_TEMPLATE_ARGUMENTS (type)
-           = VEC_length (symbolp, template_args);
+         TYPE_N_TEMPLATE_ARGUMENTS (type) = template_args.size ();
          TYPE_TEMPLATE_ARGUMENTS (type)
            = XOBNEWVEC (&objfile->objfile_obstack,
                         struct symbol *,
                         TYPE_N_TEMPLATE_ARGUMENTS (type));
          memcpy (TYPE_TEMPLATE_ARGUMENTS (type),
-                 VEC_address (symbolp, template_args),
+                 template_args.data (),
                  (TYPE_N_TEMPLATE_ARGUMENTS (type)
                   * sizeof (struct symbol *)));
-         VEC_free (symbolp, template_args);
        }
 
       /* Attach fields and member functions to the type.  */
@@ -13904,14 +16090,14 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
 
          ALLOCATE_CPLUS_STRUCT_TYPE (type);
          TYPE_TYPEDEF_FIELD_ARRAY (type)
-           = ((struct typedef_field *)
+           = ((struct decl_field *)
               TYPE_ALLOC (type, sizeof (TYPE_TYPEDEF_FIELD (type, 0)) * i));
          TYPE_TYPEDEF_FIELD_COUNT (type) = i;
 
          /* Reverse the list order to keep the debug info elements order.  */
          while (--i >= 0)
            {
-             struct typedef_field *dest, *src;
+             struct decl_field *dest, *src;
 
              dest = &TYPE_TYPEDEF_FIELD (type, i);
              src = &fi.typedef_field_list->field;
@@ -13920,6 +16106,30 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
            }
        }
 
+      /* Copy fi.nested_types_list linked list elements content into the
+        allocated array TYPE_NESTED_TYPES_ARRAY (type).  */
+      if (fi.nested_types_list != NULL && cu->language != language_ada)
+       {
+         int i = fi.nested_types_list_count;
+
+         ALLOCATE_CPLUS_STRUCT_TYPE (type);
+         TYPE_NESTED_TYPES_ARRAY (type)
+           = ((struct decl_field *)
+              TYPE_ALLOC (type, sizeof (struct decl_field) * i));
+         TYPE_NESTED_TYPES_COUNT (type) = i;
+
+         /* Reverse the list order to keep the debug info elements order.  */
+         while (--i >= 0)
+           {
+             struct decl_field *dest, *src;
+
+             dest = &TYPE_NESTED_TYPES_FIELD (type, i);
+             src = &fi.nested_types_list->field;
+             fi.nested_types_list = fi.nested_types_list->next;
+             *dest = *src;
+           }
+       }
+
       do_cleanups (back_to);
     }
 
@@ -14024,7 +16234,7 @@ update_enumeration_type_from_children (struct die_info *die,
 static struct type *
 read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   const char *name;
@@ -14196,15 +16406,13 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct die_info *child_die;
   struct type *type;
   struct type *element_type, *range_type, *index_type;
-  struct type **range_types = NULL;
   struct attribute *attr;
-  int ndim = 0;
-  struct cleanup *back_to;
   const char *name;
+  struct dynamic_prop *byte_stride_prop = NULL;
   unsigned int bit_stride = 0;
 
   element_type = die_type (die, cu);
@@ -14216,7 +16424,25 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 
   attr = dwarf2_attr (die, DW_AT_byte_stride, cu);
   if (attr != NULL)
-    bit_stride = DW_UNSND (attr) * 8;
+    {
+      int stride_ok;
+
+      byte_stride_prop
+       = (struct dynamic_prop *) alloca (sizeof (struct dynamic_prop));
+      stride_ok = attr_to_dynamic_prop (attr, die, cu, byte_stride_prop);
+      if (!stride_ok)
+       {
+         complaint (&symfile_complaints,
+                    _("unable to read array DW_AT_byte_stride "
+                      " - DIE at 0x%x [in module %s]"),
+                    to_underlying (die->sect_off),
+                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+         /* Ignore this attribute.  We will likely not be able to print
+            arrays of this type correctly, but there is little we can do
+            to help if we cannot read the attribute's value.  */
+         byte_stride_prop = NULL;
+       }
+    }
 
   attr = dwarf2_attr (die, DW_AT_bit_stride, cu);
   if (attr != NULL)
@@ -14229,11 +16455,11 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
       index_type = objfile_type (objfile)->builtin_int;
       range_type = create_static_range_type (NULL, index_type, 0, -1);
       type = create_array_type_with_stride (NULL, element_type, range_type,
-                                           bit_stride);
+                                           byte_stride_prop, bit_stride);
       return set_die_type (die, type, cu);
     }
 
-  back_to = make_cleanup (null_cleanup, NULL);
+  std::vector<struct type *> range_types;
   child_die = die->child;
   while (child_die && child_die->tag)
     {
@@ -14245,15 +16471,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
             {
              /* The range type was succesfully read.  Save it for the
                  array type creation.  */
-              if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
-                {
-                  range_types = (struct type **)
-                    xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
-                              * sizeof (struct type *));
-                  if (ndim == 0)
-                    make_cleanup (free_current_contents, &range_types);
-               }
-             range_types[ndim++] = child_type;
+             range_types.push_back (child_type);
             }
        }
       child_die = sibling_die (child_die);
@@ -14268,15 +16486,16 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       int i = 0;
 
-      while (i < ndim)
+      while (i < range_types.size ())
        type = create_array_type_with_stride (NULL, type, range_types[i++],
-                                             bit_stride);
+                                             byte_stride_prop, bit_stride);
     }
   else
     {
+      size_t ndim = range_types.size ();
       while (ndim-- > 0)
        type = create_array_type_with_stride (NULL, type, range_types[ndim],
-                                             bit_stride);
+                                             byte_stride_prop, bit_stride);
     }
 
   /* Understand Dwarf2 support for vector types (like they occur on
@@ -14313,8 +16532,6 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   /* set_die_type should be already done.  */
   set_descriptive_type (type, die, cu);
 
-  do_cleanups (back_to);
-
   return type;
 }
 
@@ -14392,6 +16609,8 @@ mark_common_block_symbol_computed (struct symbol *sym,
                                   struct attribute *member_loc,
                                   struct dwarf2_cu *cu)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_locexpr_baton *baton;
   gdb_byte *ptr;
@@ -14481,7 +16700,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 
   if (die->child != NULL)
     {
-      struct objfile *objfile = cu->objfile;
+      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
       struct die_info *child_die;
       size_t n_entries = 0, size;
       struct common_block *common_block;
@@ -14526,7 +16745,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
                               "DW_AT_data_member_location "
                               "- DIE at 0x%x [in module %s]"),
                             to_underlying (child_die->sect_off),
-                            objfile_name (cu->objfile));
+                            objfile_name (objfile));
 
                  if (attr_form_is_section_offset (member_loc))
                    dwarf2_complex_location_expr_complaint ();
@@ -14553,7 +16772,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   const char *previous_prefix, *name;
   int is_anonymous;
   struct type *type;
@@ -14593,7 +16812,7 @@ read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   int is_anonymous;
 
   /* Add a symbol associated to this if we haven't seen the namespace
@@ -14638,7 +16857,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_module_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   const char *module_name;
   struct type *type;
 
@@ -14712,7 +16931,8 @@ namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
 static struct type *
 read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
+  struct gdbarch *gdbarch
+    = get_objfile_arch (cu->per_cu->dwarf2_per_objfile->objfile);
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr_byte_size;
@@ -14793,7 +17013,8 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
     type = lookup_methodptr_type (to_type);
   else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC)
     {
-      struct type *new_type = alloc_type (cu->objfile);
+      struct type *new_type
+       = alloc_type (cu->per_cu->dwarf2_per_objfile->objfile);
 
       smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
                            TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type),
@@ -14956,7 +17177,7 @@ read_tag_atomic_type (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct type *type, *range_type, *index_type, *char_type;
   struct attribute *attr;
@@ -15034,7 +17255,7 @@ prototyped_function_p (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct type *type;           /* Type that this function returns.  */
   struct type *ftype;          /* Function that returns above type.  */
   struct attribute *attr;
@@ -15171,7 +17392,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_typedef (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   const char *name = NULL;
   struct type *this_type, *target_type;
 
@@ -15211,7 +17432,7 @@ dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name,
   if (format)
     type = init_float_type (objfile, bits, name, format);
   else
-    type = init_type (objfile, TYPE_CODE_ERROR, bits / TARGET_CHAR_BIT, name);
+    type = init_type (objfile, TYPE_CODE_ERROR, bits, name);
 
   return type;
 }
@@ -15222,7 +17443,7 @@ dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name,
 static struct type *
 read_base_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   int encoding = 0, bits = 0;
@@ -15249,7 +17470,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       case DW_ATE_address:
        /* Turn DW_ATE_address into a void * pointer.  */
-       type = init_type (objfile, TYPE_CODE_VOID, 1, NULL);
+       type = init_type (objfile, TYPE_CODE_VOID, TARGET_CHAR_BIT, NULL);
        type = init_pointer_type (objfile, bits, name, type);
        break;
       case DW_ATE_boolean:
@@ -15315,8 +17536,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
       default:
        complaint (&symfile_complaints, _("unsupported DW_AT_encoding: '%s'"),
                   dwarf_type_encoding_name (encoding));
-       type = init_type (objfile, TYPE_CODE_ERROR,
-                         bits / TARGET_CHAR_BIT, name);
+       type = init_type (objfile, TYPE_CODE_ERROR, bits, name);
        break;
     }
 
@@ -15335,7 +17555,8 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
                      struct dwarf2_cu *cu, struct dynamic_prop *prop)
 {
   struct dwarf2_property_baton *baton;
-  struct obstack *obstack = &cu->objfile->objfile_obstack;
+  struct obstack *obstack
+    = &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
 
   if (attr == NULL || prop == NULL)
     return 0;
@@ -15496,7 +17717,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   else if (!low_default_is_valid)
     complaint (&symfile_complaints, _("Missing DW_AT_lower_bound "
                                      "- DIE at 0x%x [in module %s]"),
-              to_underlying (die->sect_off), objfile_name (cu->objfile));
+              to_underlying (die->sect_off),
+              objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
 
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
   if (!attr_to_dynamic_prop (attr, die, cu, &high))
@@ -15526,7 +17748,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
      high bound or count are not yet handled by this code.  */
   if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
     {
-      struct objfile *objfile = cu->objfile;
+      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
       struct gdbarch *gdbarch = get_objfile_arch (objfile);
       int addr_size = gdbarch_addr_bit (gdbarch) /8;
       struct type *int_type = objfile_type (objfile)->builtin_int;
@@ -15596,11 +17818,17 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *type;
 
-  /* For now, we only support the C meaning of an unspecified type: void.  */
-
-  type = init_type (cu->objfile, TYPE_CODE_VOID, 0, NULL);
+  type = init_type (cu->per_cu->dwarf2_per_objfile->objfile, TYPE_CODE_VOID,0,
+                   NULL);
   TYPE_NAME (type) = dwarf2_name (die, cu);
 
+  /* In Ada, an unspecified type is typically used when the description
+     of the type is defered to a different unit.  When encountering
+     such a type, we treat it as a stub, and try to resolve it later on,
+     when needed.  */
+  if (cu->language == language_ada)
+    TYPE_STUB (type) = 1;
+
   return set_die_type (die, type, cu);
 }
 
@@ -15733,7 +17961,7 @@ read_full_die_1 (const struct die_reader_specs *reader,
       return info_ptr;
     }
 
-  abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number);
+  abbrev = reader->abbrev_table->lookup_abbrev (abbrev_number);
   if (!abbrev)
     error (_("Dwarf Error: could not find abbrev number %d [in module %s]"),
           abbrev_number,
@@ -15794,12 +18022,12 @@ read_full_die (const struct die_reader_specs *reader,
 
 /* Allocate space for a struct abbrev_info object in ABBREV_TABLE.  */
 
-static struct abbrev_info *
-abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table)
+struct abbrev_info *
+abbrev_table::alloc_abbrev ()
 {
   struct abbrev_info *abbrev;
 
-  abbrev = XOBNEW (&abbrev_table->abbrev_obstack, struct abbrev_info);
+  abbrev = XOBNEW (&abbrev_obstack, struct abbrev_info);
   memset (abbrev, 0, sizeof (struct abbrev_info));
 
   return abbrev;
@@ -15807,30 +18035,28 @@ abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table)
 
 /* Add an abbreviation to the table.  */
 
-static void
-abbrev_table_add_abbrev (struct abbrev_table *abbrev_table,
-                        unsigned int abbrev_number,
-                        struct abbrev_info *abbrev)
+void
+abbrev_table::add_abbrev (unsigned int abbrev_number,
+                         struct abbrev_info *abbrev)
 {
   unsigned int hash_number;
 
   hash_number = abbrev_number % ABBREV_HASH_SIZE;
-  abbrev->next = abbrev_table->abbrevs[hash_number];
-  abbrev_table->abbrevs[hash_number] = abbrev;
+  abbrev->next = m_abbrevs[hash_number];
+  m_abbrevs[hash_number] = abbrev;
 }
 
 /* Look up an abbrev in the table.
    Returns NULL if the abbrev is not found.  */
 
-static struct abbrev_info *
-abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table,
-                           unsigned int abbrev_number)
+struct abbrev_info *
+abbrev_table::lookup_abbrev (unsigned int abbrev_number)
 {
   unsigned int hash_number;
   struct abbrev_info *abbrev;
 
   hash_number = abbrev_number % ABBREV_HASH_SIZE;
-  abbrev = abbrev_table->abbrevs[hash_number];
+  abbrev = m_abbrevs[hash_number];
 
   while (abbrev)
     {
@@ -15843,13 +18069,13 @@ abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table,
 
 /* Read in an abbrev table.  */
 
-static struct abbrev_table *
-abbrev_table_read_table (struct dwarf2_section_info *section,
+static abbrev_table_up
+abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                        struct dwarf2_section_info *section,
                         sect_offset sect_off)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *abfd = get_section_bfd_owner (section);
-  struct abbrev_table *abbrev_table;
   const gdb_byte *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
@@ -15857,14 +18083,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
   struct attr_abbrev *cur_attrs;
   unsigned int allocated_attrs;
 
-  abbrev_table = XNEW (struct abbrev_table);
-  abbrev_table->sect_off = sect_off;
-  obstack_init (&abbrev_table->abbrev_obstack);
-  abbrev_table->abbrevs =
-    XOBNEWVEC (&abbrev_table->abbrev_obstack, struct abbrev_info *,
-              ABBREV_HASH_SIZE);
-  memset (abbrev_table->abbrevs, 0,
-         ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
+  abbrev_table_up abbrev_table (new struct abbrev_table (sect_off));
 
   dwarf2_read_section (objfile, section);
   abbrev_ptr = section->buffer + to_underlying (sect_off);
@@ -15877,7 +18096,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
   /* Loop until we reach an abbrev number of 0.  */
   while (abbrev_number)
     {
-      cur_abbrev = abbrev_table_alloc_abbrev (abbrev_table);
+      cur_abbrev = abbrev_table->alloc_abbrev ();
 
       /* read in abbrev header */
       cur_abbrev->number = abbrev_number;
@@ -15932,7 +18151,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
       memcpy (cur_abbrev->attrs, cur_attrs,
              cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
 
-      abbrev_table_add_abbrev (abbrev_table, abbrev_number, cur_abbrev);
+      abbrev_table->add_abbrev (abbrev_number, cur_abbrev);
 
       /* Get next abbreviation.
          Under Irix6 the abbreviations for a compilation unit are not
@@ -15945,7 +18164,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
        break;
       abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
       abbrev_ptr += bytes_read;
-      if (abbrev_table_lookup_abbrev (abbrev_table, abbrev_number) != NULL)
+      if (abbrev_table->lookup_abbrev (abbrev_number) != NULL)
        break;
     }
 
@@ -15953,54 +18172,6 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
   return abbrev_table;
 }
 
-/* Free the resources held by ABBREV_TABLE.  */
-
-static void
-abbrev_table_free (struct abbrev_table *abbrev_table)
-{
-  obstack_free (&abbrev_table->abbrev_obstack, NULL);
-  xfree (abbrev_table);
-}
-
-/* Same as abbrev_table_free but as a cleanup.
-   We pass in a pointer to the pointer to the table so that we can
-   set the pointer to NULL when we're done.  It also simplifies
-   build_type_psymtabs_1.  */
-
-static void
-abbrev_table_free_cleanup (void *table_ptr)
-{
-  struct abbrev_table **abbrev_table_ptr = (struct abbrev_table **) table_ptr;
-
-  if (*abbrev_table_ptr != NULL)
-    abbrev_table_free (*abbrev_table_ptr);
-  *abbrev_table_ptr = NULL;
-}
-
-/* Read the abbrev table for CU from ABBREV_SECTION.  */
-
-static void
-dwarf2_read_abbrevs (struct dwarf2_cu *cu,
-                    struct dwarf2_section_info *abbrev_section)
-{
-  cu->abbrev_table =
-    abbrev_table_read_table (abbrev_section, cu->header.abbrev_sect_off);
-}
-
-/* Release the memory used by the abbrev table for a compilation unit.  */
-
-static void
-dwarf2_free_abbrev_table (void *ptr_to_cu)
-{
-  struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr_to_cu;
-
-  if (cu->abbrev_table != NULL)
-    abbrev_table_free (cu->abbrev_table);
-  /* Set this to NULL so that we SEGV if we try to read it later,
-     and also because free_comp_unit verifies this is NULL.  */
-  cu->abbrev_table = NULL;
-}
-\f
 /* Returns nonzero if TAG represents a type that we might generate a partial
    symbol for.  */
 
@@ -16040,10 +18211,9 @@ load_partial_dies (const struct die_reader_specs *reader,
                   const gdb_byte *info_ptr, int building_psymtab)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct partial_die_info *part_die;
   struct partial_die_info *parent_die, *last_die, *first_die = NULL;
-  struct abbrev_info *abbrev;
   unsigned int bytes_read;
   unsigned int load_all = 0;
   int nesting_level = 1;
@@ -16068,7 +18238,7 @@ load_partial_dies (const struct die_reader_specs *reader,
 
   while (1)
     {
-      abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+      abbrev_info *abbrev = peek_die_abbrev (*reader, info_ptr, &bytes_read);
 
       /* A NULL abbrev means the end of a series of children.  */
       if (abbrev == NULL)
@@ -16126,6 +18296,7 @@ load_partial_dies (const struct die_reader_specs *reader,
          && abbrev->tag != DW_TAG_constant
          && abbrev->tag != DW_TAG_enumerator
          && abbrev->tag != DW_TAG_subprogram
+         && abbrev->tag != DW_TAG_inlined_subroutine
          && abbrev->tag != DW_TAG_lexical_block
          && abbrev->tag != DW_TAG_variable
          && abbrev->tag != DW_TAG_namespace
@@ -16317,7 +18488,9 @@ read_partial_die (const struct die_reader_specs *reader,
                  const gdb_byte *info_ptr)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct objfile *objfile = cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   const gdb_byte *buffer = reader->buffer;
   unsigned int i;
   struct attribute attr;
@@ -16554,7 +18727,9 @@ find_partial_die_in_comp_unit (sect_offset sect_off, struct dwarf2_cu *cu)
 static struct partial_die_info *
 find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *per_cu = NULL;
   struct partial_die_info *pd = NULL;
 
@@ -16579,7 +18754,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
                 bfd_get_filename (objfile->obfd));
        }
       per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
-                                                objfile);
+                                                dwarf2_per_objfile);
 
       if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
        load_partial_comp_unit (per_cu);
@@ -16655,9 +18830,10 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
                                                 child_pdi->linkage_name);
          if (actual_class_name != NULL)
            {
+             struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
              struct_pdi->name
                = ((const char *)
-                  obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
+                  obstack_copy0 (&objfile->per_bfd->storage_obstack,
                                  actual_class_name,
                                  strlen (actual_class_name)));
              xfree (actual_class_name);
@@ -16711,7 +18887,8 @@ fixup_partial_die (struct partial_die_info *part_die,
      children, see if we can determine the namespace from their linkage
      name.  */
   if (cu->language == language_cplus
-      && !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
+      && !VEC_empty (dwarf2_section_info_def,
+                    cu->per_cu->dwarf2_per_objfile->types)
       && part_die->die_parent == NULL
       && part_die->has_children
       && (part_die->tag == DW_TAG_class_type
@@ -16743,9 +18920,10 @@ fixup_partial_die (struct partial_die_info *part_die,
          else
            base = demangled;
 
+         struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
          part_die->name
            = ((const char *)
-              obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
+              obstack_copy0 (&objfile->per_bfd->storage_obstack,
                              base, strlen (base)));
          xfree (demangled);
        }
@@ -16762,7 +18940,9 @@ read_attribute_value (const struct die_reader_specs *reader,
                      LONGEST implicit_const, const gdb_byte *info_ptr)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct objfile *objfile = cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *abfd = reader->abfd;
   struct comp_unit_head *cu_header = &cu->header;
@@ -16836,7 +19016,8 @@ read_attribute_value (const struct die_reader_specs *reader,
     case DW_FORM_strp:
       if (!cu->per_cu->is_dwz)
        {
-         DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
+         DW_STRING (attr) = read_indirect_string (dwarf2_per_objfile,
+                                                  abfd, info_ptr, cu_header,
                                                   &bytes_read);
          DW_STRING_IS_CANONICAL (attr) = 0;
          info_ptr += bytes_read;
@@ -16846,7 +19027,8 @@ read_attribute_value (const struct die_reader_specs *reader,
     case DW_FORM_line_strp:
       if (!cu->per_cu->is_dwz)
        {
-         DW_STRING (attr) = read_indirect_line_string (abfd, info_ptr,
+         DW_STRING (attr) = read_indirect_line_string (dwarf2_per_objfile,
+                                                       abfd, info_ptr,
                                                        cu_header, &bytes_read);
          DW_STRING_IS_CANONICAL (attr) = 0;
          info_ptr += bytes_read;
@@ -16855,11 +19037,12 @@ read_attribute_value (const struct die_reader_specs *reader,
       /* FALLTHROUGH */
     case DW_FORM_GNU_strp_alt:
       {
-       struct dwz_file *dwz = dwarf2_get_dwz_file ();
+       struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
        LONGEST str_offset = read_offset (abfd, info_ptr, cu_header,
                                          &bytes_read);
 
-       DW_STRING (attr) = read_indirect_string_from_dwz (dwz, str_offset);
+       DW_STRING (attr) = read_indirect_string_from_dwz (objfile,
+                                                         dwz, str_offset);
        DW_STRING_IS_CANONICAL (attr) = 0;
        info_ptr += bytes_read;
       }
@@ -17269,12 +19452,13 @@ read_direct_string (bfd *abfd, const gdb_byte *buf,
    reporting strings FORM_NAME and SECT_NAME.  */
 
 static const char *
-read_indirect_string_at_offset_from (bfd *abfd, LONGEST str_offset,
+read_indirect_string_at_offset_from (struct objfile *objfile,
+                                    bfd *abfd, LONGEST str_offset,
                                     struct dwarf2_section_info *sect,
                                     const char *form_name,
                                     const char *sect_name)
 {
-  dwarf2_read_section (dwarf2_per_objfile->objfile, sect);
+  dwarf2_read_section (objfile, sect);
   if (sect->buffer == NULL)
     error (_("%s used without %s section [in module %s]"),
           form_name, sect_name, bfd_get_filename (abfd));
@@ -17290,9 +19474,11 @@ read_indirect_string_at_offset_from (bfd *abfd, LONGEST str_offset,
 /* Return pointer to string at .debug_str offset STR_OFFSET.  */
 
 static const char *
-read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
+read_indirect_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                               bfd *abfd, LONGEST str_offset)
 {
-  return read_indirect_string_at_offset_from (abfd, str_offset,
+  return read_indirect_string_at_offset_from (dwarf2_per_objfile->objfile,
+                                             abfd, str_offset,
                                              &dwarf2_per_objfile->str,
                                              "DW_FORM_strp", ".debug_str");
 }
@@ -17300,9 +19486,11 @@ read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
 /* Return pointer to string at .debug_line_str offset STR_OFFSET.  */
 
 static const char *
-read_indirect_line_string_at_offset (bfd *abfd, LONGEST str_offset)
+read_indirect_line_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                                    bfd *abfd, LONGEST str_offset)
 {
-  return read_indirect_string_at_offset_from (abfd, str_offset,
+  return read_indirect_string_at_offset_from (dwarf2_per_objfile->objfile,
+                                             abfd, str_offset,
                                              &dwarf2_per_objfile->line_str,
                                              "DW_FORM_line_strp",
                                              ".debug_line_str");
@@ -17314,9 +19502,10 @@ read_indirect_line_string_at_offset (bfd *abfd, LONGEST str_offset)
    return a pointer to the string.  */
 
 static const char *
-read_indirect_string_from_dwz (struct dwz_file *dwz, LONGEST str_offset)
+read_indirect_string_from_dwz (struct objfile *objfile, struct dwz_file *dwz,
+                              LONGEST str_offset)
 {
-  dwarf2_read_section (dwarf2_per_objfile->objfile, &dwz->str);
+  dwarf2_read_section (objfile, &dwz->str);
 
   if (dwz->str.buffer == NULL)
     error (_("DW_FORM_GNU_strp_alt used without .debug_str "
@@ -17337,13 +19526,14 @@ read_indirect_string_from_dwz (struct dwz_file *dwz, LONGEST str_offset)
    Return *BYTES_READ_PTR count of bytes read from BUF.  */
 
 static const char *
-read_indirect_string (bfd *abfd, const gdb_byte *buf,
+read_indirect_string (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
+                     const gdb_byte *buf,
                      const struct comp_unit_head *cu_header,
                      unsigned int *bytes_read_ptr)
 {
   LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
 
-  return read_indirect_string_at_offset (abfd, str_offset);
+  return read_indirect_string_at_offset (dwarf2_per_objfile, abfd, str_offset);
 }
 
 /* Return pointer to string at .debug_line_str offset as read from BUF.
@@ -17351,13 +19541,15 @@ read_indirect_string (bfd *abfd, const gdb_byte *buf,
    Return *BYTES_READ_PTR count of bytes read from BUF.  */
 
 static const char *
-read_indirect_line_string (bfd *abfd, const gdb_byte *buf,
+read_indirect_line_string (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                          bfd *abfd, const gdb_byte *buf,
                           const struct comp_unit_head *cu_header,
                           unsigned int *bytes_read_ptr)
 {
   LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
 
-  return read_indirect_line_string_at_offset (abfd, str_offset);
+  return read_indirect_line_string_at_offset (dwarf2_per_objfile, abfd,
+                                             str_offset);
 }
 
 ULONGEST
@@ -17422,7 +19614,8 @@ read_signed_leb128 (bfd *abfd, const gdb_byte *buf,
    ADDR_SIZE is the size of addresses from the CU header.  */
 
 static CORE_ADDR
-read_addr_index_1 (unsigned int addr_index, ULONGEST addr_base, int addr_size)
+read_addr_index_1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                  unsigned int addr_index, ULONGEST addr_base, int addr_size)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *abfd = objfile->obfd;
@@ -17449,7 +19642,8 @@ read_addr_index_1 (unsigned int addr_index, ULONGEST addr_base, int addr_size)
 static CORE_ADDR
 read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
 {
-  return read_addr_index_1 (addr_index, cu->addr_base, cu->header.addr_size);
+  return read_addr_index_1 (cu->per_cu->dwarf2_per_objfile, addr_index,
+                           cu->addr_base, cu->header.addr_size);
 }
 
 /* Given a pointer to an leb128 value, fetch the value from .debug_addr.  */
@@ -17458,7 +19652,7 @@ static CORE_ADDR
 read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
                             unsigned int *bytes_read)
 {
-  bfd *abfd = cu->objfile->obfd;
+  bfd *abfd = cu->per_cu->dwarf2_per_objfile->objfile->obfd;
   unsigned int addr_index = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
 
   return read_addr_index (cu, addr_index);
@@ -17499,14 +19693,12 @@ CORE_ADDR
 dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
                        unsigned int addr_index)
 {
-  struct objfile *objfile = per_cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_cu *cu = per_cu->cu;
   ULONGEST addr_base;
   int addr_size;
 
-  /* This is intended to be called from outside this file.  */
-  dw2_setup (objfile);
-
   /* We need addr_base and addr_size.
      If we don't have PER_CU->cu, we have to get it.
      Nasty, but the alternative is storing the needed info in PER_CU,
@@ -17540,7 +19732,8 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
       addr_size = aidata.addr_size;
     }
 
-  return read_addr_index_1 (addr_index, addr_base, addr_size);
+  return read_addr_index_1 (dwarf2_per_objfile, addr_index, addr_base,
+                           addr_size);
 }
 
 /* Given a DW_FORM_GNU_str_index, fetch the string.
@@ -17549,10 +19742,12 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
 static const char *
 read_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
 {
+  struct dwarf2_cu *cu = reader->cu;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   const char *objf_name = objfile_name (objfile);
   bfd *abfd = objfile->obfd;
-  struct dwarf2_cu *cu = reader->cu;
   struct dwarf2_section_info *str_section = &reader->dwo_file->sections.str;
   struct dwarf2_section_info *str_offsets_section =
     &reader->dwo_file->sections.str_offsets;
@@ -17732,7 +19927,7 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c
                   _("string type expected for attribute %s for "
                     "DIE at 0x%x in module %s"),
                   dwarf_attr_name (name), to_underlying (die->sect_off),
-                  objfile_name (cu->objfile));
+                  objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
     }
 
   return str;
@@ -17824,6 +20019,8 @@ static struct dwarf2_section_info *
 get_debug_line_section (struct dwarf2_cu *cu)
 {
   struct dwarf2_section_info *section;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
 
   /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
      DWO file.  */
@@ -17831,7 +20028,7 @@ get_debug_line_section (struct dwarf2_cu *cu)
     section = &cu->dwo_unit->dwo_file->sections.line;
   else if (cu->per_cu->is_dwz)
     {
-      struct dwz_file *dwz = dwarf2_get_dwz_file ();
+      struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
 
       section = &dwz->line;
     }
@@ -17847,7 +20044,8 @@ get_debug_line_section (struct dwarf2_cu *cu)
    format.  */
 
 static void
-read_formatted_entries (bfd *abfd, const gdb_byte **bufp,
+read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                       bfd *abfd, const gdb_byte **bufp,
                        struct line_header *lh,
                        const struct comp_unit_head *cu_header,
                        void (*callback) (struct line_header *lh,
@@ -17860,7 +20058,6 @@ read_formatted_entries (bfd *abfd, const gdb_byte **bufp,
   ULONGEST data_count, datai;
   const gdb_byte *buf = *bufp;
   const gdb_byte *format_header_data;
-  int i;
   unsigned int bytes_read;
 
   format_count = read_1_byte (abfd, buf);
@@ -17900,7 +20097,8 @@ read_formatted_entries (bfd *abfd, const gdb_byte **bufp,
              break;
 
            case DW_FORM_line_strp:
-             string.emplace (read_indirect_line_string (abfd, buf,
+             string.emplace (read_indirect_line_string (dwarf2_per_objfile,
+                                                        abfd, buf,
                                                         cu_header,
                                                         &bytes_read));
              buf += bytes_read;
@@ -17989,6 +20187,8 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
   const char *cur_dir, *cur_file;
   struct dwarf2_section_info *section;
   bfd *abfd;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
 
   section = get_debug_line_section (cu);
   dwarf2_read_section (dwarf2_per_objfile->objfile, section);
@@ -18100,7 +20300,8 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
   if (lh->version >= 5)
     {
       /* Read directory table.  */
-      read_formatted_entries (abfd, &line_ptr, lh.get (), &cu->header,
+      read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
+                             &cu->header,
                              [] (struct line_header *lh, const char *name,
                                  dir_index d_index, unsigned int mod_time,
                                  unsigned int length)
@@ -18109,7 +20310,8 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
        });
 
       /* Read file name table.  */
-      read_formatted_entries (abfd, &line_ptr, lh.get (), &cu->header,
+      read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
+                             &cu->header,
                              [] (struct line_header *lh, const char *name,
                                  dir_index d_index, unsigned int mod_time,
                                  unsigned int length)
@@ -18159,25 +20361,24 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
    Return the file name of the psymtab for included file FILE_INDEX
    in line header LH of PST.
    COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
-   If space for the result is malloc'd, it will be freed by a cleanup.
-   Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename.
-
-   The function creates dangling cleanup registration.  */
+   If space for the result is malloc'd, *NAME_HOLDER will be set.
+   Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename.  */
 
 static const char *
 psymtab_include_file_name (const struct line_header *lh, int file_index,
                           const struct partial_symtab *pst,
-                          const char *comp_dir)
+                          const char *comp_dir,
+                          gdb::unique_xmalloc_ptr<char> *name_holder)
 {
   const file_entry &fe = lh->file_names[file_index];
   const char *include_name = fe.name;
   const char *include_name_to_compare = include_name;
   const char *pst_filename;
-  char *copied_name = NULL;
   int file_is_pst;
 
   const char *dir_name = fe.include_dir (lh);
 
+  gdb::unique_xmalloc_ptr<char> hold_compare;
   if (!IS_ABSOLUTE_PATH (include_name)
       && (dir_name != NULL || comp_dir != NULL))
     {
@@ -18204,36 +20405,30 @@ psymtab_include_file_name (const struct line_header *lh, int file_index,
 
       if (dir_name != NULL)
        {
-         char *tem = concat (dir_name, SLASH_STRING,
-                             include_name, (char *)NULL);
-
-         make_cleanup (xfree, tem);
-         include_name = tem;
+         name_holder->reset (concat (dir_name, SLASH_STRING,
+                                     include_name, (char *) NULL));
+         include_name = name_holder->get ();
          include_name_to_compare = include_name;
        }
       if (!IS_ABSOLUTE_PATH (include_name) && comp_dir != NULL)
        {
-         char *tem = concat (comp_dir, SLASH_STRING,
-                             include_name, (char *)NULL);
-
-         make_cleanup (xfree, tem);
-         include_name_to_compare = tem;
+         hold_compare.reset (concat (comp_dir, SLASH_STRING,
+                                     include_name, (char *) NULL));
+         include_name_to_compare = hold_compare.get ();
        }
     }
 
   pst_filename = pst->filename;
+  gdb::unique_xmalloc_ptr<char> copied_name;
   if (!IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL)
     {
-      copied_name = concat (pst->dirname, SLASH_STRING,
-                           pst_filename, (char *)NULL);
-      pst_filename = copied_name;
+      copied_name.reset (concat (pst->dirname, SLASH_STRING,
+                                pst_filename, (char *) NULL));
+      pst_filename = copied_name.get ();
     }
 
   file_is_pst = FILENAME_CMP (include_name_to_compare, pst_filename) == 0;
 
-  if (copied_name != NULL)
-    xfree (copied_name);
-
   if (file_is_pst)
     return NULL;
   return include_name;
@@ -18619,7 +20814,7 @@ lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
       /* This line table is for a function which has been
         GCd by the linker.  Ignore it.  PR gdb/12528 */
 
-      struct objfile *objfile = cu->objfile;
+      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
       long line_offset = line_ptr - get_debug_line_section (cu)->buffer;
 
       complaint (&symfile_complaints,
@@ -18645,7 +20840,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
   unsigned int bytes_read, extended_len;
   unsigned char op_code, extended_op;
   CORE_ADDR baseaddr;
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   bfd *abfd = objfile->obfd;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   /* True if we're recording line info (as opposed to building partial
@@ -18876,7 +21071,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
                    struct dwarf2_cu *cu, struct partial_symtab *pst,
                    CORE_ADDR lowpc, int decode_mapping)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   const int decode_for_pst_p = (pst != NULL);
 
   if (decode_mapping)
@@ -18891,8 +21086,10 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
       for (file_index = 0; file_index < lh->file_names.size (); file_index++)
         if (lh->file_names[file_index].included_p == 1)
           {
+           gdb::unique_xmalloc_ptr<char> name_holder;
            const char *include_name =
-             psymtab_include_file_name (lh, file_index, pst, comp_dir);
+             psymtab_include_file_name (lh, file_index, pst, comp_dir,
+                                        &name_holder);
            if (include_name != NULL)
               dwarf2_create_include_psymtab (include_name, pst, objfile);
           }
@@ -18976,7 +21173,8 @@ dwarf2_start_symtab (struct dwarf2_cu *cu,
                     const char *name, const char *comp_dir, CORE_ADDR low_pc)
 {
   struct compunit_symtab *cust
-    = start_symtab (cu->objfile, name, comp_dir, low_pc);
+    = start_symtab (cu->per_cu->dwarf2_per_objfile->objfile, name, comp_dir,
+                   low_pc, cu->language);
 
   record_debugformat ("DWARF 2");
   record_producer (cu->producer);
@@ -18993,7 +21191,7 @@ static void
 var_decode_location (struct attribute *attr, struct symbol *sym,
                     struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct comp_unit_head *cu_header = &cu->header;
 
   /* NOTE drow/2003-01-30: There used to be a comment and some special
@@ -19063,10 +21261,12 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
    NULL, allocate a new symbol on the objfile's obstack.  */
 
 static struct symbol *
-new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
-                struct symbol *space)
+new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
+           struct symbol *space)
 {
-  struct objfile *objfile = cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct symbol *sym = NULL;
   const char *name;
@@ -19444,14 +21644,6 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
   return (sym);
 }
 
-/* A wrapper for new_symbol_full that always allocates a new symbol.  */
-
-static struct symbol *
-new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
-{
-  return new_symbol_full (die, type, cu, NULL);
-}
-
 /* Given an attr with a DW_FORM_dataN value in host byte order,
    zero-extend it as appropriate for the symbol's type.  The DWARF
    standard (v4) is not entirely clear about the meaning of using
@@ -19464,7 +21656,7 @@ static gdb_byte *
 dwarf2_const_value_data (const struct attribute *attr, struct obstack *obstack,
                         struct dwarf2_cu *cu, LONGEST *value, int bits)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   enum bfd_endian byte_order = bfd_big_endian (objfile->obfd) ?
                                BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
   LONGEST l = DW_UNSND (attr);
@@ -19499,7 +21691,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
                         LONGEST *value, const gdb_byte **bytes,
                         struct dwarf2_locexpr_baton **baton)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct comp_unit_head *cu_header = &cu->header;
   struct dwarf_block *blk;
   enum bfd_endian byte_order = (bfd_big_endian (objfile->obfd) ?
@@ -19601,7 +21793,7 @@ static void
 dwarf2_const_value (const struct attribute *attr, struct symbol *sym,
                    struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   LONGEST value;
   const gdb_byte *bytes;
   struct dwarf2_locexpr_baton *baton;
@@ -19638,8 +21830,9 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
   type_attr = dwarf2_attr (die, DW_AT_type, cu);
   if (!type_attr)
     {
+      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
       /* A missing DW_AT_type represents a void type.  */
-      return objfile_type (cu->objfile)->builtin_void;
+      return objfile_type (objfile)->builtin_void;
     }
 
   return lookup_die_type (die, type_attr, cu);
@@ -19652,15 +21845,9 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
 static int
 need_gnat_info (struct dwarf2_cu *cu)
 {
-  /* FIXME: brobecker/2010-10-12: As of now, only the AdaCore version
-     of GNAT produces this auxiliary information, without any indication
-     that it is produced.  Part of enhancing the FSF version of GNAT
-     to produce that information will be to put in place an indicator
-     that we can use in order to determine whether the descriptive type
-     info is available or not.  One suggestion that has been made is
-     to use a new attribute, attached to the CU die.  For now, assume
-     that the descriptive type info is not available.  */
-  return 0;
+  /* Assume that the Ada compiler was GNAT, which always produces
+     the auxiliary information.  */
+  return (cu->language == language_ada);
 }
 
 /* Return the auxiliary type of the die in question using its
@@ -19702,11 +21889,12 @@ static struct type *
 die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *type_attr;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
 
   type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
   if (!type_attr)
     error (_("Dwarf Error: Problem turning containing type into gdb type "
-            "[in module %s]"), objfile_name (cu->objfile));
+            "[in module %s]"), objfile_name (objfile));
 
   return lookup_die_type (die, type_attr, cu);
 }
@@ -19716,6 +21904,8 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   char *message, *saved;
 
@@ -19739,7 +21929,9 @@ static struct type *
 lookup_die_type (struct die_info *die, const struct attribute *attr,
                 struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct type *this_type;
 
   gdb_assert (attr->name == DW_AT_type
@@ -19753,7 +21945,8 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
       struct dwarf2_per_cu_data *per_cu;
       sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
 
-      per_cu = dwarf2_find_containing_comp_unit (sect_off, 1, cu->objfile);
+      per_cu = dwarf2_find_containing_comp_unit (sect_off, 1,
+                                                dwarf2_per_objfile);
       this_type = get_die_type_at_offset (sect_off, per_cu);
     }
   else if (attr_form_is_ref (attr))
@@ -19922,6 +22115,7 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *spec_die;
   struct dwarf2_cu *spec_cu;
   struct die_info *child;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
 
   spec_cu = cu;
   spec_die = die_specification (die, &spec_cu);
@@ -19963,7 +22157,7 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
                          && actual_name[actual_name_len
                                         - die_name_len - 1] == ':')
                        name = (char *) obstack_copy0 (
-                         &cu->objfile->per_bfd->storage_obstack,
+                         &objfile->per_bfd->storage_obstack,
                          actual_name, actual_name_len - die_name_len - 2);
                    }
                }
@@ -20005,7 +22199,8 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
   if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
     return "";
 
-  return (char *) obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  return (char *) obstack_copy0 (&objfile->per_bfd->storage_obstack,
                                 DW_STRING (attr),
                                 &base[-1] - DW_STRING (attr));
 }
@@ -20028,6 +22223,8 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
 static const char *
 determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct die_info *parent, *spec_die;
   struct dwarf2_cu *spec_cu;
   struct type *parent_type;
@@ -20273,6 +22470,7 @@ static const char *
 dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
 
   attr = dwarf2_attr (die, DW_AT_name, cu);
   if ((!attr || !DW_STRING (attr))
@@ -20335,7 +22533,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
              /* FIXME: we already did this for the partial symbol... */
              DW_STRING (attr)
                = ((const char *)
-                  obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
+                  obstack_copy0 (&objfile->per_bfd->storage_obstack,
                                  demangled, strlen (demangled)));
              DW_STRING_IS_CANONICAL (attr) = 1;
              xfree (demangled);
@@ -20359,7 +22557,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     {
       DW_STRING (attr)
        = dwarf2_canonicalize_name (DW_STRING (attr), cu,
-                                   &cu->objfile->per_bfd->storage_obstack);
+                                   &objfile->per_bfd->storage_obstack);
       DW_STRING_IS_CANONICAL (attr) = 1;
     }
   return DW_STRING (attr);
@@ -20693,7 +22891,7 @@ follow_die_ref_or_sig (struct die_info *src_die, const struct attribute *attr,
     {
       dump_die_for_error (src_die);
       error (_("Dwarf Error: Expected reference attribute [in module %s]"),
-            objfile_name ((*ref_cu)->objfile));
+            objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
     }
 
   return die;
@@ -20710,6 +22908,9 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
 {
   struct die_info temp_die;
   struct dwarf2_cu *target_cu, *cu = *ref_cu;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   gdb_assert (cu->per_cu != NULL);
 
@@ -20729,7 +22930,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
       struct dwarf2_per_cu_data *per_cu;
 
       per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
-                                                cu->objfile);
+                                                dwarf2_per_objfile);
 
       /* If necessary, add it to the queue and load its DIEs.  */
       if (maybe_queue_comp_unit (cu, per_cu, cu->language))
@@ -20771,14 +22972,15 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
           "at 0x%x [in module %s]"),
           to_underlying (sect_off), to_underlying (src_die->sect_off),
-          objfile_name (cu->objfile));
+          objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
 
   return die;
 }
 
 /* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU.
    Returned value is intended for DW_OP_call*.  Returned
-   dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE.  */
+   dwarf2_locexpr_baton->data has lifetime of
+   PER_CU->DWARF2_PER_OBJFILE->OBJFILE.  */
 
 struct dwarf2_locexpr_baton
 dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
@@ -20790,8 +22992,9 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
   struct die_info *die;
   struct attribute *attr;
   struct dwarf2_locexpr_baton retval;
-
-  dw2_setup (per_cu->objfile);
+  struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
   if (per_cu->cu == NULL)
     load_cu (per_cu);
@@ -20801,13 +23004,13 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
       /* We shouldn't get here for a dummy CU, but don't crash on the user.
         Instead just throw an error, not much else we can do.  */
       error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"),
-            to_underlying (sect_off), objfile_name (per_cu->objfile));
+            to_underlying (sect_off), objfile_name (objfile));
     }
 
   die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
-          to_underlying (sect_off), objfile_name (per_cu->objfile));
+          to_underlying (sect_off), objfile_name (objfile));
 
   attr = dwarf2_attr (die, DW_AT_location, cu);
   if (!attr)
@@ -20835,14 +23038,14 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
       if (!attr_form_is_block (attr))
        error (_("Dwarf Error: DIE at 0x%x referenced in module %s "
                 "is neither DW_FORM_block* nor DW_FORM_exprloc"),
-              to_underlying (sect_off), objfile_name (per_cu->objfile));
+              to_underlying (sect_off), objfile_name (objfile));
 
       retval.data = DW_BLOCK (attr)->data;
       retval.size = DW_BLOCK (attr)->size;
     }
   retval.per_cu = cu->per_cu;
 
-  age_cached_comp_units ();
+  age_cached_comp_units (dwarf2_per_objfile);
 
   return retval;
 }
@@ -20898,8 +23101,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
   struct type *type;
   LONGEST value;
   enum bfd_endian byte_order;
-
-  dw2_setup (per_cu->objfile);
+  struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
 
   if (per_cu->cu == NULL)
     load_cu (per_cu);
@@ -20909,20 +23111,20 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
       /* We shouldn't get here for a dummy CU, but don't crash on the user.
         Instead just throw an error, not much else we can do.  */
       error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"),
-            to_underlying (sect_off), objfile_name (per_cu->objfile));
+            to_underlying (sect_off), objfile_name (objfile));
     }
 
   die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
-          to_underlying (sect_off), objfile_name (per_cu->objfile));
+          to_underlying (sect_off), objfile_name (objfile));
 
 
   attr = dwarf2_attr (die, DW_AT_const_value, cu);
   if (attr == NULL)
     return NULL;
 
-  byte_order = (bfd_big_endian (per_cu->objfile->obfd)
+  byte_order = (bfd_big_endian (objfile->obfd)
                ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE);
 
   switch (attr->form)
@@ -21024,8 +23226,6 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
   struct dwarf2_cu *cu;
   struct die_info *die;
 
-  dw2_setup (per_cu->objfile);
-
   if (per_cu->cu == NULL)
     load_cu (per_cu);
   cu = per_cu->cu;
@@ -21046,8 +23246,6 @@ struct type *
 dwarf2_get_die_type (cu_offset die_offset,
                     struct dwarf2_per_cu_data *per_cu)
 {
-  dw2_setup (per_cu->objfile);
-
   sect_offset die_offset_sect = per_cu->sect_off + to_underlying (die_offset);
   return get_die_type_at_offset (die_offset_sect, per_cu);
 }
@@ -21082,6 +23280,9 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
                                                 to_underlying (temp_die.sect_off));
   if (die)
     {
+      struct dwarf2_per_objfile *dwarf2_per_objfile
+       = (*ref_cu)->per_cu->dwarf2_per_objfile;
+
       /* For .gdb_index version 7 keep track of included TUs.
         http://sourceware.org/bugzilla/show_bug.cgi?id=15021.  */
       if (dwarf2_per_objfile->index_table != NULL
@@ -21123,7 +23324,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr,
       error (_("Dwarf Error: Cannot find signatured DIE %s referenced"
                " from DIE at 0x%x [in module %s]"),
              hex_string (signature), to_underlying (src_die->sect_off),
-            objfile_name ((*ref_cu)->objfile));
+            objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
     }
 
   die = follow_die_sig_1 (src_die, sig_type, ref_cu);
@@ -21133,7 +23334,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr,
       error (_("Dwarf Error: Problem reading signatured DIE %s referenced"
               " from DIE at 0x%x [in module %s]"),
             hex_string (signature), to_underlying (src_die->sect_off),
-            objfile_name ((*ref_cu)->objfile));
+            objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
     }
 
   return die;
@@ -21146,6 +23347,8 @@ static struct type *
 get_signatured_type (struct die_info *die, ULONGEST signature,
                     struct dwarf2_cu *cu)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct signatured_type *sig_type;
   struct dwarf2_cu *type_cu;
   struct die_info *type_die;
@@ -21221,6 +23424,9 @@ get_DW_AT_signature_type (struct die_info *die, const struct attribute *attr,
     }
   else
     {
+      struct dwarf2_per_objfile *dwarf2_per_objfile
+       = cu->per_cu->dwarf2_per_objfile;
+
       complaint (&symfile_complaints,
                 _("Dwarf Error: DW_AT_signature has bad form %s in DIE"
                   " at 0x%x [in module %s]"),
@@ -21331,7 +23537,7 @@ read_signatured_type (struct signatured_type *sig_type)
 static CORE_ADDR
 decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   size_t i;
   size_t size = blk->size;
   const gdb_byte *data = blk->data;
@@ -21920,7 +24126,6 @@ skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
 
     default:
       {
-      complain:
        complaint (&symfile_complaints,
                   _("invalid form 0x%x in `%s'"),
                   form, get_section_name (section));
@@ -22039,7 +24244,8 @@ dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
    including DW_MACRO_import.  */
 
 static void
-dwarf_decode_macro_bytes (bfd *abfd,
+dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                         bfd *abfd,
                          const gdb_byte *mac_ptr, const gdb_byte *mac_end,
                          struct macro_source_file *current_file,
                          struct line_header *lh,
@@ -22084,6 +24290,8 @@ dwarf_decode_macro_bytes (bfd *abfd,
 
       /* Note that we rely on the fact that the corresponding GNU and
         DWARF constants are the same.  */
+      DIAGNOSTIC_PUSH
+      DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
       switch (macinfo_type)
        {
          /* A zero macinfo type indicates the end of the macro
@@ -22123,12 +24331,15 @@ dwarf_decode_macro_bytes (bfd *abfd,
                    || macinfo_type == DW_MACRO_undef_sup
                    || section_is_dwz)
                  {
-                   struct dwz_file *dwz = dwarf2_get_dwz_file ();
+                   struct dwz_file *dwz
+                     = dwarf2_get_dwz_file (dwarf2_per_objfile);
 
-                   body = read_indirect_string_from_dwz (dwz, str_offset);
+                   body = read_indirect_string_from_dwz (objfile,
+                                                         dwz, str_offset);
                  }
                else
-                 body = read_indirect_string_at_offset (abfd, str_offset);
+                 body = read_indirect_string_at_offset (dwarf2_per_objfile,
+                                                        abfd, str_offset);
              }
 
            is_define = (macinfo_type == DW_MACRO_define
@@ -22248,7 +24459,7 @@ dwarf_decode_macro_bytes (bfd *abfd,
 
            if (macinfo_type == DW_MACRO_import_sup)
              {
-               struct dwz_file *dwz = dwarf2_get_dwz_file ();
+               struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
 
                dwarf2_read_section (objfile, &dwz->macro);
 
@@ -22273,7 +24484,8 @@ dwarf_decode_macro_bytes (bfd *abfd,
              {
                *slot = (void *) new_mac_ptr;
 
-               dwarf_decode_macro_bytes (include_bfd, new_mac_ptr,
+               dwarf_decode_macro_bytes (dwarf2_per_objfile,
+                                         include_bfd, new_mac_ptr,
                                          include_mac_end, current_file, lh,
                                          section, section_is_gnu, is_dwz,
                                          offset_size, include_hash);
@@ -22308,6 +24520,7 @@ dwarf_decode_macro_bytes (bfd *abfd,
            return;
          break;
         }
+      DIAGNOSTIC_POP
     } while (macinfo_type != 0);
 }
 
@@ -22315,6 +24528,8 @@ static void
 dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
                      int section_is_gnu)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct line_header *lh = cu->line_header;
   bfd *abfd;
@@ -22323,7 +24538,6 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
   enum dwarf_macro_record_type macinfo_type;
   unsigned int offset_size = cu->header.offset_size;
   const gdb_byte *opcode_definitions[256];
-  struct cleanup *cleanup;
   void **slot;
   struct dwarf2_section_info *section;
   const char *section_name;
@@ -22401,6 +24615,8 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
 
       /* Note that we rely on the fact that the corresponding GNU and
         DWARF constants are the same.  */
+      DIAGNOSTIC_PUSH
+      DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
       switch (macinfo_type)
         {
           /* A zero macinfo type indicates the end of the macro
@@ -22481,6 +24697,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
            return;
          break;
        }
+      DIAGNOSTIC_POP
     } while (macinfo_type != 0 && current_file == NULL);
 
   /* Second pass: Process all entries.
@@ -22495,7 +24712,8 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
   mac_ptr = section->buffer + offset;
   slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
   *slot = (void *) mac_ptr;
-  dwarf_decode_macro_bytes (abfd, mac_ptr, mac_end,
+  dwarf_decode_macro_bytes (dwarf2_per_objfile,
+                           abfd, mac_ptr, mac_end,
                            current_file, lh, section,
                            section_is_gnu, 0, offset_size,
                            include_hash.get ());
@@ -22594,6 +24812,9 @@ attr_form_is_ref (const struct attribute *attr)
 static struct dwarf2_section_info *
 cu_debug_loc_section (struct dwarf2_cu *cu)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+
   if (cu->dwo_unit)
     {
       struct dwo_sections *sections = &cu->dwo_unit->dwo_file->sections;
@@ -22611,6 +24832,8 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
                       struct dwarf2_loclist_baton *baton,
                       const struct attribute *attr)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct dwarf2_section_info *section = cu_debug_loc_section (cu);
 
   dwarf2_read_section (dwarf2_per_objfile->objfile, section);
@@ -22629,6 +24852,8 @@ static void
 dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
                             struct dwarf2_cu *cu, int is_block)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = cu_debug_loc_section (cu);
 
@@ -22693,7 +24918,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
 struct objfile *
 dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
 {
-  struct objfile *objfile = per_cu->objfile;
+  struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
 
   /* Return the master objfile, so that we can report and look up the
      correct file containing this variable.  */
@@ -22775,7 +25000,7 @@ dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *per_cu)
 CORE_ADDR
 dwarf2_per_cu_text_offset (struct dwarf2_per_cu_data *per_cu)
 {
-  struct objfile *objfile = per_cu->objfile;
+  struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
 
   return ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 }
@@ -22794,7 +25019,7 @@ dwarf2_version (struct dwarf2_per_cu_data *per_cu)
 static struct dwarf2_per_cu_data *
 dwarf2_find_containing_comp_unit (sect_offset sect_off,
                                  unsigned int offset_in_dwz,
-                                 struct objfile *objfile)
+                                 struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct dwarf2_per_cu_data *this_cu;
   int low, high;
@@ -22823,7 +25048,8 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
       if (low == 0 || this_cu->is_dwz != offset_in_dwz)
        error (_("Dwarf Error: could not find partial DIE containing "
               "offset 0x%x [in module %s]"),
-              to_underlying (sect_off), bfd_get_filename (objfile->obfd));
+              to_underlying (sect_off),
+              bfd_get_filename (dwarf2_per_objfile->objfile->obfd));
 
       gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->sect_off
                  <= sect_off);
@@ -22842,14 +25068,24 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
 
 /* Initialize dwarf2_cu CU, owned by PER_CU.  */
 
-static void
-init_one_comp_unit (struct dwarf2_cu *cu, struct dwarf2_per_cu_data *per_cu)
+dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
+  : per_cu (per_cu_),
+    mark (0),
+    has_loclist (0),
+    checked_producer (0),
+    producer_is_gxx_lt_4_6 (0),
+    producer_is_gcc_lt_4_3 (0),
+    producer_is_icc_lt_14 (0),
+    processing_has_namespace_info (0)
 {
-  memset (cu, 0, sizeof (*cu));
-  per_cu->cu = cu;
-  cu->per_cu = per_cu;
-  cu->objfile = per_cu->objfile;
-  obstack_init (&cu->comp_unit_obstack);
+  per_cu->cu = this;
+}
+
+/* Destroy a dwarf2_cu.  */
+
+dwarf2_cu::~dwarf2_cu ()
+{
+  per_cu->cu = NULL;
 }
 
 /* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE.  */
@@ -22867,47 +25103,10 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
   else
     {
       cu->language = pretend_language;
-      cu->language_defn = language_def (cu->language);
-    }
-
-  cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
-}
-
-/* Release one cached compilation unit, CU.  We unlink it from the tree
-   of compilation units, but we don't remove it from the read_in_chain;
-   the caller is responsible for that.
-   NOTE: DATA is a void * because this function is also used as a
-   cleanup routine.  */
-
-static void
-free_heap_comp_unit (void *data)
-{
-  struct dwarf2_cu *cu = (struct dwarf2_cu *) data;
-
-  gdb_assert (cu->per_cu != NULL);
-  cu->per_cu->cu = NULL;
-  cu->per_cu = NULL;
-
-  obstack_free (&cu->comp_unit_obstack, NULL);
-
-  xfree (cu);
-}
-
-/* This cleanup function is passed the address of a dwarf2_cu on the stack
-   when we're finished with it.  We can't free the pointer itself, but be
-   sure to unlink it from the cache.  Also release any associated storage.  */
-
-static void
-free_stack_comp_unit (void *data)
-{
-  struct dwarf2_cu *cu = (struct dwarf2_cu *) data;
-
-  gdb_assert (cu->per_cu != NULL);
-  cu->per_cu->cu = NULL;
-  cu->per_cu = NULL;
+      cu->language_defn = language_def (cu->language);
+    }
 
-  obstack_free (&cu->comp_unit_obstack, NULL);
-  cu->partial_dies = NULL;
+  cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
 }
 
 /* Free all cached compilation units.  */
@@ -22915,6 +25114,9 @@ free_stack_comp_unit (void *data)
 static void
 free_cached_comp_units (void *data)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = (struct dwarf2_per_objfile *) data;
+
   dwarf2_per_objfile->free_cached_comp_units ();
 }
 
@@ -22922,7 +25124,7 @@ free_cached_comp_units (void *data)
    any that are too old.  */
 
 static void
-age_cached_comp_units (void)
+age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct dwarf2_per_cu_data *per_cu, **last_chain;
 
@@ -22946,7 +25148,7 @@ age_cached_comp_units (void)
 
       if (!per_cu->cu->mark)
        {
-         free_heap_comp_unit (per_cu->cu);
+         delete per_cu->cu;
          *last_chain = next_cu;
        }
       else
@@ -22962,6 +25164,8 @@ static void
 free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
 {
   struct dwarf2_per_cu_data *per_cu, **last_chain;
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = target_per_cu->dwarf2_per_objfile;
 
   per_cu = dwarf2_per_objfile->read_in_chain;
   last_chain = &dwarf2_per_objfile->read_in_chain;
@@ -22973,7 +25177,7 @@ free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
 
       if (per_cu == target_per_cu)
        {
-         free_heap_comp_unit (per_cu->cu);
+         delete per_cu->cu;
          per_cu->cu = NULL;
          *last_chain = next_cu;
          break;
@@ -22990,9 +25194,8 @@ free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
 void
 dwarf2_free_objfile (struct objfile *objfile)
 {
-  dwarf2_per_objfile
-    = (struct dwarf2_per_objfile *) objfile_data (objfile,
-                                                 dwarf2_objfile_data_key);
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
 
   if (dwarf2_per_objfile == NULL)
     return;
@@ -23067,8 +25270,10 @@ per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs)
 static struct type *
 set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 {
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
   struct dwarf2_per_cu_offset_and_type **slot, ofs;
-  struct objfile *objfile = cu->objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct attribute *attr;
   struct dynamic_prop prop;
 
@@ -23093,7 +25298,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   if (attr_form_is_block (attr))
     {
       if (attr_to_dynamic_prop (attr, die, cu, &prop))
-        add_dyn_prop (DYN_PROP_ALLOCATED, prop, type, objfile);
+        add_dyn_prop (DYN_PROP_ALLOCATED, prop, type);
     }
   else if (attr != NULL)
     {
@@ -23108,7 +25313,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   if (attr_form_is_block (attr))
     {
       if (attr_to_dynamic_prop (attr, die, cu, &prop))
-        add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type, objfile);
+        add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type);
     }
   else if (attr != NULL)
     {
@@ -23121,7 +25326,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   /* Read DW_AT_data_location and set in type.  */
   attr = dwarf2_attr (die, DW_AT_data_location, cu);
   if (attr_to_dynamic_prop (attr, die, cu, &prop))
-    add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type, objfile);
+    add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type);
 
   if (dwarf2_per_objfile->die_type_hash == NULL)
     {
@@ -23158,6 +25363,7 @@ get_die_type_at_offset (sect_offset sect_off,
                        struct dwarf2_per_cu_data *per_cu)
 {
   struct dwarf2_per_cu_offset_and_type *slot, ofs;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
 
   if (dwarf2_per_objfile->die_type_hash == NULL)
     return NULL;
@@ -23281,52 +25487,39 @@ static struct cmd_list_element *set_dwarf_cmdlist;
 static struct cmd_list_element *show_dwarf_cmdlist;
 
 static void
-set_dwarf_cmd (char *args, int from_tty)
+set_dwarf_cmd (const char *args, int from_tty)
 {
   help_list (set_dwarf_cmdlist, "maintenance set dwarf ", all_commands,
             gdb_stdout);
 }
 
 static void
-show_dwarf_cmd (char *args, int from_tty)
+show_dwarf_cmd (const char *args, int from_tty)
 {
   cmd_show_list (show_dwarf_cmdlist, from_tty, "");
 }
 
-/* Free data associated with OBJFILE, if necessary.  */
+/* The "save gdb-index" command.  */
+
+/* Write SIZE bytes from the buffer pointed to by DATA to FILE, with
+   error checking.  */
 
 static void
-dwarf2_per_objfile_free (struct objfile *objfile, void *d)
+file_write (FILE *file, const void *data, size_t size)
 {
-  struct dwarf2_per_objfile *data = (struct dwarf2_per_objfile *) d;
-  int ix;
-
-  /* Make sure we don't accidentally use dwarf2_per_objfile while
-     cleaning up.  */
-  dwarf2_per_objfile = NULL;
-
-  for (ix = 0; ix < data->n_comp_units; ++ix)
-   VEC_free (dwarf2_per_cu_ptr, data->all_comp_units[ix]->imported_symtabs);
-
-  for (ix = 0; ix < data->n_type_units; ++ix)
-    VEC_free (dwarf2_per_cu_ptr,
-             data->all_type_units[ix]->per_cu.imported_symtabs);
-  xfree (data->all_type_units);
-
-  VEC_free (dwarf2_section_info_def, data->types);
+  if (fwrite (data, 1, size, file) != size)
+    error (_("couldn't data write to file"));
+}
 
-  if (data->dwo_files)
-    free_dwo_files (data->dwo_files, objfile);
-  if (data->dwp_file)
-    gdb_bfd_unref (data->dwp_file->dbfd);
+/* Write the contents of VEC to FILE, with error checking.  */
 
-  if (data->dwz_file && data->dwz_file->dwz_bfd)
-    gdb_bfd_unref (data->dwz_file->dwz_bfd);
+template<typename Elem, typename Alloc>
+static void
+file_write (FILE *file, const std::vector<Elem, Alloc> &vec)
+{
+  file_write (file, vec.data (), vec.size () * sizeof (vec[0]));
 }
 
-\f
-/* The "save gdb-index" command.  */
-
 /* In-memory buffer to prepare data to be written later to a file.  */
 class data_buf
 {
@@ -23348,6 +25541,21 @@ public:
     std::copy (cstr, cstr + size, grow (size));
   }
 
+  /* Store INPUT as ULEB128 to the end of buffer.  */
+  void append_unsigned_leb128 (ULONGEST input)
+  {
+    for (;;)
+      {
+       gdb_byte output = input & 0x7f;
+       input >>= 7;
+       if (input)
+         output |= 0x80;
+       append_data (output);
+       if (input == 0)
+         break;
+      }
+  }
+
   /* Accept a host-format integer in VAL and append it to the buffer
      as a target-format integer which is LEN bytes long.  */
   void append_uint (size_t len, bfd_endian byte_order, ULONGEST val)
@@ -23361,11 +25569,16 @@ public:
     return m_vec.size ();
   }
 
+  /* Return true iff the buffer is empty.  */
+  bool empty () const
+  {
+    return m_vec.empty ();
+  }
+
   /* Write the buffer to FILE.  */
   void file_write (FILE *file) const
   {
-    if (::fwrite (m_vec.data (), 1, m_vec.size (), file) != m_vec.size ())
-      error (_("couldn't write data to file"));
+    ::file_write (file, m_vec);
   }
 
 private:
@@ -23514,6 +25727,13 @@ public:
     return strcmp (m_cstr, other.m_cstr) == 0;
   }
 
+  /* Return the underlying C string.  Note, the returned string is
+     only a reference with lifetime of this object.  */
+  const char *c_str () const
+  {
+    return m_cstr;
+  }
+
 private:
   friend class c_str_view_hasher;
   const char *const m_cstr;
@@ -23773,133 +25993,746 @@ write_psymbols (struct mapped_symtab *symtab,
     }
 }
 
-/* A helper struct used when iterating over debug_types.  */
-struct signatured_type_index_data
-{
-  signatured_type_index_data (data_buf &types_list_,
-                              std::unordered_set<partial_symbol *> &psyms_seen_)
-    : types_list (types_list_), psyms_seen (psyms_seen_)
-  {}
+/* A helper struct used when iterating over debug_types.  */
+struct signatured_type_index_data
+{
+  signatured_type_index_data (data_buf &types_list_,
+                              std::unordered_set<partial_symbol *> &psyms_seen_)
+    : types_list (types_list_), psyms_seen (psyms_seen_)
+  {}
+
+  struct objfile *objfile;
+  struct mapped_symtab *symtab;
+  data_buf &types_list;
+  std::unordered_set<partial_symbol *> &psyms_seen;
+  int cu_index;
+};
+
+/* A helper function that writes a single signatured_type to an
+   obstack.  */
+
+static int
+write_one_signatured_type (void **slot, void *d)
+{
+  struct signatured_type_index_data *info
+    = (struct signatured_type_index_data *) d;
+  struct signatured_type *entry = (struct signatured_type *) *slot;
+  struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
+
+  write_psymbols (info->symtab,
+                 info->psyms_seen,
+                 &info->objfile->global_psymbols[psymtab->globals_offset],
+                 psymtab->n_global_syms, info->cu_index,
+                 0);
+  write_psymbols (info->symtab,
+                 info->psyms_seen,
+                 &info->objfile->static_psymbols[psymtab->statics_offset],
+                 psymtab->n_static_syms, info->cu_index,
+                 1);
+
+  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE,
+                               to_underlying (entry->per_cu.sect_off));
+  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE,
+                               to_underlying (entry->type_offset_in_tu));
+  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE, entry->signature);
+
+  ++info->cu_index;
+
+  return 1;
+}
+
+/* Recurse into all "included" dependencies and count their symbols as
+   if they appeared in this psymtab.  */
+
+static void
+recursively_count_psymbols (struct partial_symtab *psymtab,
+                           size_t &psyms_seen)
+{
+  for (int i = 0; i < psymtab->number_of_dependencies; ++i)
+    if (psymtab->dependencies[i]->user != NULL)
+      recursively_count_psymbols (psymtab->dependencies[i],
+                                 psyms_seen);
+
+  psyms_seen += psymtab->n_global_syms;
+  psyms_seen += psymtab->n_static_syms;
+}
+
+/* Recurse into all "included" dependencies and write their symbols as
+   if they appeared in this psymtab.  */
+
+static void
+recursively_write_psymbols (struct objfile *objfile,
+                           struct partial_symtab *psymtab,
+                           struct mapped_symtab *symtab,
+                           std::unordered_set<partial_symbol *> &psyms_seen,
+                           offset_type cu_index)
+{
+  int i;
+
+  for (i = 0; i < psymtab->number_of_dependencies; ++i)
+    if (psymtab->dependencies[i]->user != NULL)
+      recursively_write_psymbols (objfile, psymtab->dependencies[i],
+                                 symtab, psyms_seen, cu_index);
+
+  write_psymbols (symtab,
+                 psyms_seen,
+                 &objfile->global_psymbols[psymtab->globals_offset],
+                 psymtab->n_global_syms, cu_index,
+                 0);
+  write_psymbols (symtab,
+                 psyms_seen,
+                 &objfile->static_psymbols[psymtab->statics_offset],
+                 psymtab->n_static_syms, cu_index,
+                 1);
+}
+
+/* DWARF-5 .debug_names builder.  */
+class debug_names
+{
+public:
+  debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile, bool is_dwarf64,
+              bfd_endian dwarf5_byte_order)
+    : m_dwarf5_byte_order (dwarf5_byte_order),
+      m_dwarf32 (dwarf5_byte_order),
+      m_dwarf64 (dwarf5_byte_order),
+      m_dwarf (is_dwarf64
+              ? static_cast<dwarf &> (m_dwarf64)
+              : static_cast<dwarf &> (m_dwarf32)),
+      m_name_table_string_offs (m_dwarf.name_table_string_offs),
+      m_name_table_entry_offs (m_dwarf.name_table_entry_offs),
+      m_debugstrlookup (dwarf2_per_objfile)
+  {}
+
+  int dwarf5_offset_size () const
+  {
+    const bool dwarf5_is_dwarf64 = &m_dwarf == &m_dwarf64;
+    return dwarf5_is_dwarf64 ? 8 : 4;
+  }
+
+  /* Is this symbol from DW_TAG_compile_unit or DW_TAG_type_unit?  */
+  enum class unit_kind { cu, tu };
+
+  /* Insert one symbol.  */
+  void insert (const partial_symbol *psym, int cu_index, bool is_static,
+              unit_kind kind)
+  {
+    const int dwarf_tag = psymbol_tag (psym);
+    if (dwarf_tag == 0)
+      return;
+    const char *const name = SYMBOL_SEARCH_NAME (psym);
+    const auto insertpair
+      = m_name_to_value_set.emplace (c_str_view (name),
+                                    std::set<symbol_value> ());
+    std::set<symbol_value> &value_set = insertpair.first->second;
+    value_set.emplace (symbol_value (dwarf_tag, cu_index, is_static, kind));
+  }
+
+  /* Build all the tables.  All symbols must be already inserted.
+     This function does not call file_write, caller has to do it
+     afterwards.  */
+  void build ()
+  {
+    /* Verify the build method has not be called twice.  */
+    gdb_assert (m_abbrev_table.empty ());
+    const size_t name_count = m_name_to_value_set.size ();
+    m_bucket_table.resize
+      (std::pow (2, std::ceil (std::log2 (name_count * 4 / 3))));
+    m_hash_table.reserve (name_count);
+    m_name_table_string_offs.reserve (name_count);
+    m_name_table_entry_offs.reserve (name_count);
+
+    /* Map each hash of symbol to its name and value.  */
+    struct hash_it_pair
+    {
+      uint32_t hash;
+      decltype (m_name_to_value_set)::const_iterator it;
+    };
+    std::vector<std::forward_list<hash_it_pair>> bucket_hash;
+    bucket_hash.resize (m_bucket_table.size ());
+    for (decltype (m_name_to_value_set)::const_iterator it
+          = m_name_to_value_set.cbegin ();
+        it != m_name_to_value_set.cend ();
+        ++it)
+      {
+       const char *const name = it->first.c_str ();
+       const uint32_t hash = dwarf5_djb_hash (name);
+       hash_it_pair hashitpair;
+       hashitpair.hash = hash;
+       hashitpair.it = it;
+       auto &slot = bucket_hash[hash % bucket_hash.size()];
+       slot.push_front (std::move (hashitpair));
+      }
+    for (size_t bucket_ix = 0; bucket_ix < bucket_hash.size (); ++bucket_ix)
+      {
+       const std::forward_list<hash_it_pair> &hashitlist
+         = bucket_hash[bucket_ix];
+       if (hashitlist.empty ())
+         continue;
+       uint32_t &bucket_slot = m_bucket_table[bucket_ix];
+       /* The hashes array is indexed starting at 1.  */
+       store_unsigned_integer (reinterpret_cast<gdb_byte *> (&bucket_slot),
+                               sizeof (bucket_slot), m_dwarf5_byte_order,
+                               m_hash_table.size () + 1);
+       for (const hash_it_pair &hashitpair : hashitlist)
+         {
+           m_hash_table.push_back (0);
+           store_unsigned_integer (reinterpret_cast<gdb_byte *>
+                                                       (&m_hash_table.back ()),
+                                   sizeof (m_hash_table.back ()),
+                                   m_dwarf5_byte_order, hashitpair.hash);
+           const c_str_view &name = hashitpair.it->first;
+           const std::set<symbol_value> &value_set = hashitpair.it->second;
+           m_name_table_string_offs.push_back_reorder
+             (m_debugstrlookup.lookup (name.c_str ()));
+           m_name_table_entry_offs.push_back_reorder (m_entry_pool.size ());
+           gdb_assert (!value_set.empty ());
+           for (const symbol_value &value : value_set)
+             {
+               int &idx = m_indexkey_to_idx[index_key (value.dwarf_tag,
+                                                       value.is_static,
+                                                       value.kind)];
+               if (idx == 0)
+                 {
+                   idx = m_idx_next++;
+                   m_abbrev_table.append_unsigned_leb128 (idx);
+                   m_abbrev_table.append_unsigned_leb128 (value.dwarf_tag);
+                   m_abbrev_table.append_unsigned_leb128
+                             (value.kind == unit_kind::cu ? DW_IDX_compile_unit
+                                                          : DW_IDX_type_unit);
+                   m_abbrev_table.append_unsigned_leb128 (DW_FORM_udata);
+                   m_abbrev_table.append_unsigned_leb128 (value.is_static
+                                                          ? DW_IDX_GNU_internal
+                                                          : DW_IDX_GNU_external);
+                   m_abbrev_table.append_unsigned_leb128 (DW_FORM_flag_present);
+
+                   /* Terminate attributes list.  */
+                   m_abbrev_table.append_unsigned_leb128 (0);
+                   m_abbrev_table.append_unsigned_leb128 (0);
+                 }
+
+               m_entry_pool.append_unsigned_leb128 (idx);
+               m_entry_pool.append_unsigned_leb128 (value.cu_index);
+             }
+
+           /* Terminate the list of CUs.  */
+           m_entry_pool.append_unsigned_leb128 (0);
+         }
+      }
+    gdb_assert (m_hash_table.size () == name_count);
+
+    /* Terminate tags list.  */
+    m_abbrev_table.append_unsigned_leb128 (0);
+  }
+
+  /* Return .debug_names bucket count.  This must be called only after
+     calling the build method.  */
+  uint32_t bucket_count () const
+  {
+    /* Verify the build method has been already called.  */
+    gdb_assert (!m_abbrev_table.empty ());
+    const uint32_t retval = m_bucket_table.size ();
+
+    /* Check for overflow.  */
+    gdb_assert (retval == m_bucket_table.size ());
+    return retval;
+  }
+
+  /* Return .debug_names names count.  This must be called only after
+     calling the build method.  */
+  uint32_t name_count () const
+  {
+    /* Verify the build method has been already called.  */
+    gdb_assert (!m_abbrev_table.empty ());
+    const uint32_t retval = m_hash_table.size ();
+
+    /* Check for overflow.  */
+    gdb_assert (retval == m_hash_table.size ());
+    return retval;
+  }
+
+  /* Return number of bytes of .debug_names abbreviation table.  This
+     must be called only after calling the build method.  */
+  uint32_t abbrev_table_bytes () const
+  {
+    gdb_assert (!m_abbrev_table.empty ());
+    return m_abbrev_table.size ();
+  }
+
+  /* Recurse into all "included" dependencies and store their symbols
+     as if they appeared in this psymtab.  */
+  void recursively_write_psymbols
+    (struct objfile *objfile,
+     struct partial_symtab *psymtab,
+     std::unordered_set<partial_symbol *> &psyms_seen,
+     int cu_index)
+  {
+    for (int i = 0; i < psymtab->number_of_dependencies; ++i)
+      if (psymtab->dependencies[i]->user != NULL)
+       recursively_write_psymbols (objfile, psymtab->dependencies[i],
+                                   psyms_seen, cu_index);
+
+    write_psymbols (psyms_seen,
+                   &objfile->global_psymbols[psymtab->globals_offset],
+                   psymtab->n_global_syms, cu_index, false, unit_kind::cu);
+    write_psymbols (psyms_seen,
+                   &objfile->static_psymbols[psymtab->statics_offset],
+                   psymtab->n_static_syms, cu_index, true, unit_kind::cu);
+  }
+
+  /* Return number of bytes the .debug_names section will have.  This
+     must be called only after calling the build method.  */
+  size_t bytes () const
+  {
+    /* Verify the build method has been already called.  */
+    gdb_assert (!m_abbrev_table.empty ());
+    size_t expected_bytes = 0;
+    expected_bytes += m_bucket_table.size () * sizeof (m_bucket_table[0]);
+    expected_bytes += m_hash_table.size () * sizeof (m_hash_table[0]);
+    expected_bytes += m_name_table_string_offs.bytes ();
+    expected_bytes += m_name_table_entry_offs.bytes ();
+    expected_bytes += m_abbrev_table.size ();
+    expected_bytes += m_entry_pool.size ();
+    return expected_bytes;
+  }
+
+  /* Write .debug_names to FILE_NAMES and .debug_str addition to
+     FILE_STR.  This must be called only after calling the build
+     method.  */
+  void file_write (FILE *file_names, FILE *file_str) const
+  {
+    /* Verify the build method has been already called.  */
+    gdb_assert (!m_abbrev_table.empty ());
+    ::file_write (file_names, m_bucket_table);
+    ::file_write (file_names, m_hash_table);
+    m_name_table_string_offs.file_write (file_names);
+    m_name_table_entry_offs.file_write (file_names);
+    m_abbrev_table.file_write (file_names);
+    m_entry_pool.file_write (file_names);
+    m_debugstrlookup.file_write (file_str);
+  }
+
+  /* A helper user data for write_one_signatured_type.  */
+  class write_one_signatured_type_data
+  {
+  public:
+    write_one_signatured_type_data (debug_names &nametable_,
+                                    signatured_type_index_data &&info_)
+    : nametable (nametable_), info (std::move (info_))
+    {}
+    debug_names &nametable;
+    struct signatured_type_index_data info;
+  };
+
+  /* A helper function to pass write_one_signatured_type to
+     htab_traverse_noresize.  */
+  static int
+  write_one_signatured_type (void **slot, void *d)
+  {
+    write_one_signatured_type_data *data = (write_one_signatured_type_data *) d;
+    struct signatured_type_index_data *info = &data->info;
+    struct signatured_type *entry = (struct signatured_type *) *slot;
+
+    data->nametable.write_one_signatured_type (entry, info);
+
+    return 1;
+  }
+
+private:
+
+  /* Storage for symbol names mapping them to their .debug_str section
+     offsets.  */
+  class debug_str_lookup
+  {
+  public:
+
+    /* Object costructor to be called for current DWARF2_PER_OBJFILE.
+       All .debug_str section strings are automatically stored.  */
+    debug_str_lookup (struct dwarf2_per_objfile *dwarf2_per_objfile)
+      : m_abfd (dwarf2_per_objfile->objfile->obfd),
+       m_dwarf2_per_objfile (dwarf2_per_objfile)
+    {
+      dwarf2_read_section (dwarf2_per_objfile->objfile,
+                          &dwarf2_per_objfile->str);
+      if (dwarf2_per_objfile->str.buffer == NULL)
+       return;
+      for (const gdb_byte *data = dwarf2_per_objfile->str.buffer;
+          data < (dwarf2_per_objfile->str.buffer
+                  + dwarf2_per_objfile->str.size);)
+       {
+         const char *const s = reinterpret_cast<const char *> (data);
+         const auto insertpair
+           = m_str_table.emplace (c_str_view (s),
+                                  data - dwarf2_per_objfile->str.buffer);
+         if (!insertpair.second)
+           complaint (&symfile_complaints,
+                      _("Duplicate string \"%s\" in "
+                        ".debug_str section [in module %s]"),
+                      s, bfd_get_filename (m_abfd));
+         data += strlen (s) + 1;
+       }
+    }
+
+    /* Return offset of symbol name S in the .debug_str section.  Add
+       such symbol to the section's end if it does not exist there
+       yet.  */
+    size_t lookup (const char *s)
+    {
+      const auto it = m_str_table.find (c_str_view (s));
+      if (it != m_str_table.end ())
+       return it->second;
+      const size_t offset = (m_dwarf2_per_objfile->str.size
+                            + m_str_add_buf.size ());
+      m_str_table.emplace (c_str_view (s), offset);
+      m_str_add_buf.append_cstr0 (s);
+      return offset;
+    }
+
+    /* Append the end of the .debug_str section to FILE.  */
+    void file_write (FILE *file) const
+    {
+      m_str_add_buf.file_write (file);
+    }
+
+  private:
+    std::unordered_map<c_str_view, size_t, c_str_view_hasher> m_str_table;
+    bfd *const m_abfd;
+    struct dwarf2_per_objfile *m_dwarf2_per_objfile;
+
+    /* Data to add at the end of .debug_str for new needed symbol names.  */
+    data_buf m_str_add_buf;
+  };
+
+  /* Container to map used DWARF tags to their .debug_names abbreviation
+     tags.  */
+  class index_key
+  {
+  public:
+    index_key (int dwarf_tag_, bool is_static_, unit_kind kind_)
+      : dwarf_tag (dwarf_tag_), is_static (is_static_), kind (kind_)
+    {
+    }
+
+    bool
+    operator== (const index_key &other) const
+    {
+      return (dwarf_tag == other.dwarf_tag && is_static == other.is_static
+             && kind == other.kind);
+    }
+
+    const int dwarf_tag;
+    const bool is_static;
+    const unit_kind kind;
+  };
+
+  /* Provide std::unordered_map::hasher for index_key.  */
+  class index_key_hasher
+  {
+  public:
+    size_t
+    operator () (const index_key &key) const
+    {
+      return (std::hash<int>() (key.dwarf_tag) << 1) | key.is_static;
+    }
+  };
+
+  /* Parameters of one symbol entry.  */
+  class symbol_value
+  {
+  public:
+    const int dwarf_tag, cu_index;
+    const bool is_static;
+    const unit_kind kind;
+
+    symbol_value (int dwarf_tag_, int cu_index_, bool is_static_,
+                 unit_kind kind_)
+      : dwarf_tag (dwarf_tag_), cu_index (cu_index_), is_static (is_static_),
+        kind (kind_)
+    {}
+
+    bool
+    operator< (const symbol_value &other) const
+    {
+#define X(n) \
+  do \
+    { \
+      if (n < other.n) \
+       return true; \
+      if (n > other.n) \
+       return false; \
+    } \
+  while (0)
+      X (dwarf_tag);
+      X (is_static);
+      X (kind);
+      X (cu_index);
+#undef X
+      return false;
+    }
+  };
+
+  /* Abstract base class to unify DWARF-32 and DWARF-64 name table
+     output.  */
+  class offset_vec
+  {
+  protected:
+    const bfd_endian dwarf5_byte_order;
+  public:
+    explicit offset_vec (bfd_endian dwarf5_byte_order_)
+      : dwarf5_byte_order (dwarf5_byte_order_)
+    {}
+
+    /* Call std::vector::reserve for NELEM elements.  */
+    virtual void reserve (size_t nelem) = 0;
+
+    /* Call std::vector::push_back with store_unsigned_integer byte
+       reordering for ELEM.  */
+    virtual void push_back_reorder (size_t elem) = 0;
+
+    /* Return expected output size in bytes.  */
+    virtual size_t bytes () const = 0;
+
+    /* Write name table to FILE.  */
+    virtual void file_write (FILE *file) const = 0;
+  };
+
+  /* Template to unify DWARF-32 and DWARF-64 output.  */
+  template<typename OffsetSize>
+  class offset_vec_tmpl : public offset_vec
+  {
+  public:
+    explicit offset_vec_tmpl (bfd_endian dwarf5_byte_order_)
+      : offset_vec (dwarf5_byte_order_)
+    {}
+
+    /* Implement offset_vec::reserve.  */
+    void reserve (size_t nelem) override
+    {
+      m_vec.reserve (nelem);
+    }
+
+    /* Implement offset_vec::push_back_reorder.  */
+    void push_back_reorder (size_t elem) override
+    {
+      m_vec.push_back (elem);
+      /* Check for overflow.  */
+      gdb_assert (m_vec.back () == elem);
+      store_unsigned_integer (reinterpret_cast<gdb_byte *> (&m_vec.back ()),
+                             sizeof (m_vec.back ()), dwarf5_byte_order, elem);
+    }
+
+    /* Implement offset_vec::bytes.  */
+    size_t bytes () const override
+    {
+      return m_vec.size () * sizeof (m_vec[0]);
+    }
+
+    /* Implement offset_vec::file_write.  */
+    void file_write (FILE *file) const override
+    {
+      ::file_write (file, m_vec);
+    }
+
+  private:
+    std::vector<OffsetSize> m_vec;
+  };
+
+  /* Base class to unify DWARF-32 and DWARF-64 .debug_names output
+     respecting name table width.  */
+  class dwarf
+  {
+  public:
+    offset_vec &name_table_string_offs, &name_table_entry_offs;
+
+    dwarf (offset_vec &name_table_string_offs_,
+          offset_vec &name_table_entry_offs_)
+      : name_table_string_offs (name_table_string_offs_),
+       name_table_entry_offs (name_table_entry_offs_)
+    {
+    }
+  };
+
+  /* Template to unify DWARF-32 and DWARF-64 .debug_names output
+     respecting name table width.  */
+  template<typename OffsetSize>
+  class dwarf_tmpl : public dwarf
+  {
+  public:
+    explicit dwarf_tmpl (bfd_endian dwarf5_byte_order_)
+      : dwarf (m_name_table_string_offs, m_name_table_entry_offs),
+       m_name_table_string_offs (dwarf5_byte_order_),
+       m_name_table_entry_offs (dwarf5_byte_order_)
+    {}
+
+  private:
+    offset_vec_tmpl<OffsetSize> m_name_table_string_offs;
+    offset_vec_tmpl<OffsetSize> m_name_table_entry_offs;
+  };
+
+  /* Try to reconstruct original DWARF tag for given partial_symbol.
+     This function is not DWARF-5 compliant but it is sufficient for
+     GDB as a DWARF-5 index consumer.  */
+  static int psymbol_tag (const struct partial_symbol *psym)
+  {
+    domain_enum domain = PSYMBOL_DOMAIN (psym);
+    enum address_class aclass = PSYMBOL_CLASS (psym);
+
+    switch (domain)
+      {
+      case VAR_DOMAIN:
+       switch (aclass)
+         {
+         case LOC_BLOCK:
+           return DW_TAG_subprogram;
+         case LOC_TYPEDEF:
+           return DW_TAG_typedef;
+         case LOC_COMPUTED:
+         case LOC_CONST_BYTES:
+         case LOC_OPTIMIZED_OUT:
+         case LOC_STATIC:
+           return DW_TAG_variable;
+         case LOC_CONST:
+           /* Note: It's currently impossible to recognize psyms as enum values
+              short of reading the type info.  For now punt.  */
+           return DW_TAG_variable;
+         default:
+           /* There are other LOC_FOO values that one might want to classify
+              as variables, but dwarf2read.c doesn't currently use them.  */
+           return DW_TAG_variable;
+         }
+      case STRUCT_DOMAIN:
+       return DW_TAG_structure_type;
+      default:
+       return 0;
+      }
+  }
 
-  struct objfile *objfile;
-  struct mapped_symtab *symtab;
-  data_buf &types_list;
-  std::unordered_set<partial_symbol *> &psyms_seen;
-  int cu_index;
-};
+  /* Call insert for all partial symbols and mark them in PSYMS_SEEN.  */
+  void write_psymbols (std::unordered_set<partial_symbol *> &psyms_seen,
+                      struct partial_symbol **psymp, int count, int cu_index,
+                      bool is_static, unit_kind kind)
+  {
+    for (; count-- > 0; ++psymp)
+      {
+       struct partial_symbol *psym = *psymp;
 
-/* A helper function that writes a single signatured_type to an
-   obstack.  */
+       if (SYMBOL_LANGUAGE (psym) == language_ada)
+         error (_("Ada is not currently supported by the index"));
 
-static int
-write_one_signatured_type (void **slot, void *d)
-{
-  struct signatured_type_index_data *info
-    = (struct signatured_type_index_data *) d;
-  struct signatured_type *entry = (struct signatured_type *) *slot;
-  struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
+       /* Only add a given psymbol once.  */
+       if (psyms_seen.insert (psym).second)
+         insert (psym, cu_index, is_static, kind);
+      }
+  }
 
-  write_psymbols (info->symtab,
-                 info->psyms_seen,
-                 info->objfile->global_psymbols.list
-                 + psymtab->globals_offset,
-                 psymtab->n_global_syms, info->cu_index,
-                 0);
-  write_psymbols (info->symtab,
-                 info->psyms_seen,
-                 info->objfile->static_psymbols.list
-                 + psymtab->statics_offset,
-                 psymtab->n_static_syms, info->cu_index,
-                 1);
+  /* A helper function that writes a single signatured_type
+     to a debug_names.  */
+  void
+  write_one_signatured_type (struct signatured_type *entry,
+                            struct signatured_type_index_data *info)
+  {
+    struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
 
-  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE,
-                               to_underlying (entry->per_cu.sect_off));
-  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE,
-                               to_underlying (entry->type_offset_in_tu));
-  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE, entry->signature);
+    write_psymbols (info->psyms_seen,
+                   &info->objfile->global_psymbols[psymtab->globals_offset],
+                   psymtab->n_global_syms, info->cu_index, false,
+                   unit_kind::tu);
+    write_psymbols (info->psyms_seen,
+                   &info->objfile->static_psymbols[psymtab->statics_offset],
+                   psymtab->n_static_syms, info->cu_index, true,
+                   unit_kind::tu);
 
-  ++info->cu_index;
+    info->types_list.append_uint (dwarf5_offset_size (), m_dwarf5_byte_order,
+                                 to_underlying (entry->per_cu.sect_off));
 
-  return 1;
-}
+    ++info->cu_index;
+  }
 
-/* Recurse into all "included" dependencies and count their symbols as
-   if they appeared in this psymtab.  */
+  /* Store value of each symbol.  */
+  std::unordered_map<c_str_view, std::set<symbol_value>, c_str_view_hasher>
+    m_name_to_value_set;
 
-static void
-recursively_count_psymbols (struct partial_symtab *psymtab,
-                           size_t &psyms_seen)
-{
-  for (int i = 0; i < psymtab->number_of_dependencies; ++i)
-    if (psymtab->dependencies[i]->user != NULL)
-      recursively_count_psymbols (psymtab->dependencies[i],
-                                 psyms_seen);
+  /* Tables of DWARF-5 .debug_names.  They are in object file byte
+     order.  */
+  std::vector<uint32_t> m_bucket_table;
+  std::vector<uint32_t> m_hash_table;
 
-  psyms_seen += psymtab->n_global_syms;
-  psyms_seen += psymtab->n_static_syms;
-}
+  const bfd_endian m_dwarf5_byte_order;
+  dwarf_tmpl<uint32_t> m_dwarf32;
+  dwarf_tmpl<uint64_t> m_dwarf64;
+  dwarf &m_dwarf;
+  offset_vec &m_name_table_string_offs, &m_name_table_entry_offs;
+  debug_str_lookup m_debugstrlookup;
 
-/* Recurse into all "included" dependencies and write their symbols as
-   if they appeared in this psymtab.  */
+  /* Map each used .debug_names abbreviation tag parameter to its
+     index value.  */
+  std::unordered_map<index_key, int, index_key_hasher> m_indexkey_to_idx;
 
-static void
-recursively_write_psymbols (struct objfile *objfile,
-                           struct partial_symtab *psymtab,
-                           struct mapped_symtab *symtab,
-                           std::unordered_set<partial_symbol *> &psyms_seen,
-                           offset_type cu_index)
-{
-  int i;
+  /* Next unused .debug_names abbreviation tag for
+     m_indexkey_to_idx.  */
+  int m_idx_next = 1;
 
-  for (i = 0; i < psymtab->number_of_dependencies; ++i)
-    if (psymtab->dependencies[i]->user != NULL)
-      recursively_write_psymbols (objfile, psymtab->dependencies[i],
-                                 symtab, psyms_seen, cu_index);
+  /* .debug_names abbreviation table.  */
+  data_buf m_abbrev_table;
 
-  write_psymbols (symtab,
-                 psyms_seen,
-                 objfile->global_psymbols.list + psymtab->globals_offset,
-                 psymtab->n_global_syms, cu_index,
-                 0);
-  write_psymbols (symtab,
-                 psyms_seen,
-                 objfile->static_psymbols.list + psymtab->statics_offset,
-                 psymtab->n_static_syms, cu_index,
-                 1);
-}
+  /* .debug_names entry pool.  */
+  data_buf m_entry_pool;
+};
 
-/* Create an index file for OBJFILE in the directory DIR.  */
+/* Return iff any of the needed offsets does not fit into 32-bit
+   .debug_names section.  */
 
-static void
-write_psymtabs_to_index (struct objfile *objfile, const char *dir)
+static bool
+check_dwarf64_offsets (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  if (dwarf2_per_objfile->using_index)
-    error (_("Cannot use an index to create the index"));
+  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+    {
+      const dwarf2_per_cu_data &per_cu = *dwarf2_per_objfile->all_comp_units[i];
 
-  if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) > 1)
-    error (_("Cannot make an index when the file has multiple .debug_types sections"));
+      if (to_underlying (per_cu.sect_off) >= (static_cast<uint64_t> (1) << 32))
+       return true;
+    }
+  for (int i = 0; i < dwarf2_per_objfile->n_type_units; ++i)
+    {
+      const signatured_type &sigtype = *dwarf2_per_objfile->all_type_units[i];
+      const dwarf2_per_cu_data &per_cu = sigtype.per_cu;
 
-  if (!objfile->psymtabs || !objfile->psymtabs_addrmap)
-    return;
+      if (to_underlying (per_cu.sect_off) >= (static_cast<uint64_t> (1) << 32))
+       return true;
+    }
+  return false;
+}
 
-  struct stat st;
-  if (stat (objfile_name (objfile), &st) < 0)
-    perror_with_name (objfile_name (objfile));
+/* The psyms_seen set is potentially going to be largish (~40k
+   elements when indexing a -g3 build of GDB itself).  Estimate the
+   number of elements in order to avoid too many rehashes, which
+   require rebuilding buckets and thus many trips to
+   malloc/free.  */
 
-  std::string filename (std::string (dir) + SLASH_STRING
-                       + lbasename (objfile_name (objfile)) + INDEX_SUFFIX);
+static size_t
+psyms_seen_size (struct dwarf2_per_objfile *dwarf2_per_objfile)
+{
+  size_t psyms_count = 0;
+  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+    {
+      struct dwarf2_per_cu_data *per_cu
+       = dwarf2_per_objfile->all_comp_units[i];
+      struct partial_symtab *psymtab = per_cu->v.psymtab;
 
-  FILE *out_file = gdb_fopen_cloexec (filename.c_str (), "wb").release ();
-  if (!out_file)
-    error (_("Can't open `%s' for writing"), filename.c_str ());
+      if (psymtab != NULL && psymtab->user == NULL)
+       recursively_count_psymbols (psymtab, psyms_count);
+    }
+  /* Generating an index for gdb itself shows a ratio of
+     TOTAL_SEEN_SYMS/UNIQUE_SYMS or ~5.  4 seems like a good bet.  */
+  return psyms_count / 4;
+}
 
-  /* Order matters here; we want FILE to be closed before FILENAME is
-     unlinked, because on MS-Windows one cannot delete a file that is
-     still open.  (Don't call anything here that might throw until
-     file_closer is created.)  */
-  gdb::unlinker unlink_file (filename.c_str ());
-  gdb_file_up close_out_file (out_file);
+/* Write new .gdb_index section for OBJFILE into OUT_FILE.
+   Return how many bytes were expected to be written into OUT_FILE.  */
 
+static size_t
+write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
   mapped_symtab symtab;
   data_buf cu_list;
 
@@ -23914,24 +26747,8 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
      work here.  Also, the debug_types entries do not appear in
      all_comp_units, but only in their own hash table.  */
 
-  /* The psyms_seen set is potentially going to be largish (~40k
-     elements when indexing a -g3 build of GDB itself).  Estimate the
-     number of elements in order to avoid too many rehashes, which
-     require rebuilding buckets and thus many trips to
-     malloc/free.  */
-  size_t psyms_count = 0;
-  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
-    {
-      struct dwarf2_per_cu_data *per_cu
-       = dwarf2_per_objfile->all_comp_units[i];
-      struct partial_symtab *psymtab = per_cu->v.psymtab;
-
-      if (psymtab != NULL && psymtab->user == NULL)
-       recursively_count_psymbols (psymtab, psyms_count);
-    }
-  /* Generating an index for gdb itself shows a ratio of
-     TOTAL_SEEN_SYMS/UNIQUE_SYMS or ~5.  4 seems like a good bet.  */
-  std::unordered_set<partial_symbol *> psyms_seen (psyms_count / 4);
+  std::unordered_set<partial_symbol *> psyms_seen
+    (psyms_seen_size (dwarf2_per_objfile));
   for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
     {
       struct dwarf2_per_cu_data *per_cu
@@ -24017,22 +26834,244 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
   symtab_vec.file_write (out_file);
   constant_pool.file_write (out_file);
 
+  return total_len;
+}
+
+/* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension.  */
+static const gdb_byte dwarf5_gdb_augmentation[] = { 'G', 'D', 'B', 0 };
+
+/* Write a new .debug_names section for OBJFILE into OUT_FILE, write
+   needed addition to .debug_str section to OUT_FILE_STR.  Return how
+   many bytes were expected to be written into OUT_FILE.  */
+
+static size_t
+write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                  FILE *out_file, FILE *out_file_str)
+{
+  const bool dwarf5_is_dwarf64 = check_dwarf64_offsets (dwarf2_per_objfile);
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  const enum bfd_endian dwarf5_byte_order
+    = gdbarch_byte_order (get_objfile_arch (objfile));
+
+  /* The CU list is already sorted, so we don't need to do additional
+     work here.  Also, the debug_types entries do not appear in
+     all_comp_units, but only in their own hash table.  */
+  data_buf cu_list;
+  debug_names nametable (dwarf2_per_objfile, dwarf5_is_dwarf64,
+                        dwarf5_byte_order);
+  std::unordered_set<partial_symbol *>
+    psyms_seen (psyms_seen_size (dwarf2_per_objfile));
+  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+    {
+      const dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->all_comp_units[i];
+      partial_symtab *psymtab = per_cu->v.psymtab;
+
+      /* CU of a shared file from 'dwz -m' may be unused by this main
+        file.  It may be referenced from a local scope but in such
+        case it does not need to be present in .debug_names.  */
+      if (psymtab == NULL)
+       continue;
+
+      if (psymtab->user == NULL)
+       nametable.recursively_write_psymbols (objfile, psymtab, psyms_seen, i);
+
+      cu_list.append_uint (nametable.dwarf5_offset_size (), dwarf5_byte_order,
+                          to_underlying (per_cu->sect_off));
+    }
+
+  /* Write out the .debug_type entries, if any.  */
+  data_buf types_cu_list;
+  if (dwarf2_per_objfile->signatured_types)
+    {
+      debug_names::write_one_signatured_type_data sig_data (nametable,
+                       signatured_type_index_data (types_cu_list, psyms_seen));
+
+      sig_data.info.objfile = objfile;
+      /* It is used only for gdb_index.  */
+      sig_data.info.symtab = nullptr;
+      sig_data.info.cu_index = 0;
+      htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
+                             debug_names::write_one_signatured_type,
+                             &sig_data);
+    }
+
+  nametable.build ();
+
+  /* No addr_vec - DWARF-5 uses .debug_aranges generated by GCC.  */
+
+  const offset_type bytes_of_header
+    = ((dwarf5_is_dwarf64 ? 12 : 4)
+       + 2 + 2 + 7 * 4
+       + sizeof (dwarf5_gdb_augmentation));
+  size_t expected_bytes = 0;
+  expected_bytes += bytes_of_header;
+  expected_bytes += cu_list.size ();
+  expected_bytes += types_cu_list.size ();
+  expected_bytes += nametable.bytes ();
+  data_buf header;
+
+  if (!dwarf5_is_dwarf64)
+    {
+      const uint64_t size64 = expected_bytes - 4;
+      gdb_assert (size64 < 0xfffffff0);
+      header.append_uint (4, dwarf5_byte_order, size64);
+    }
+  else
+    {
+      header.append_uint (4, dwarf5_byte_order, 0xffffffff);
+      header.append_uint (8, dwarf5_byte_order, expected_bytes - 12);
+    }
+
+  /* The version number.  */
+  header.append_uint (2, dwarf5_byte_order, 5);
+
+  /* Padding.  */
+  header.append_uint (2, dwarf5_byte_order, 0);
+
+  /* comp_unit_count - The number of CUs in the CU list.  */
+  header.append_uint (4, dwarf5_byte_order, dwarf2_per_objfile->n_comp_units);
+
+  /* local_type_unit_count - The number of TUs in the local TU
+     list.  */
+  header.append_uint (4, dwarf5_byte_order, dwarf2_per_objfile->n_type_units);
+
+  /* foreign_type_unit_count - The number of TUs in the foreign TU
+     list.  */
+  header.append_uint (4, dwarf5_byte_order, 0);
+
+  /* bucket_count - The number of hash buckets in the hash lookup
+     table.  */
+  header.append_uint (4, dwarf5_byte_order, nametable.bucket_count ());
+
+  /* name_count - The number of unique names in the index.  */
+  header.append_uint (4, dwarf5_byte_order, nametable.name_count ());
+
+  /* abbrev_table_size - The size in bytes of the abbreviations
+     table.  */
+  header.append_uint (4, dwarf5_byte_order, nametable.abbrev_table_bytes ());
+
+  /* augmentation_string_size - The size in bytes of the augmentation
+     string.  This value is rounded up to a multiple of 4.  */
+  static_assert (sizeof (dwarf5_gdb_augmentation) % 4 == 0, "");
+  header.append_uint (4, dwarf5_byte_order, sizeof (dwarf5_gdb_augmentation));
+  header.append_data (dwarf5_gdb_augmentation);
+
+  gdb_assert (header.size () == bytes_of_header);
+
+  header.file_write (out_file);
+  cu_list.file_write (out_file);
+  types_cu_list.file_write (out_file);
+  nametable.file_write (out_file, out_file_str);
+
+  return expected_bytes;
+}
+
+/* Assert that FILE's size is EXPECTED_SIZE.  Assumes file's seek
+   position is at the end of the file.  */
+
+static void
+assert_file_size (FILE *file, const char *filename, size_t expected_size)
+{
+  const auto file_size = ftell (file);
+  if (file_size == -1)
+    error (_("Can't get `%s' size"), filename);
+  gdb_assert (file_size == expected_size);
+}
+
+/* Create an index file for OBJFILE in the directory DIR.  */
+
+static void
+write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                        const char *dir,
+                        dw_index_kind index_kind)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+
+  if (dwarf2_per_objfile->using_index)
+    error (_("Cannot use an index to create the index"));
+
+  if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) > 1)
+    error (_("Cannot make an index when the file has multiple .debug_types sections"));
+
+  if (!objfile->psymtabs || !objfile->psymtabs_addrmap)
+    return;
+
+  struct stat st;
+  if (stat (objfile_name (objfile), &st) < 0)
+    perror_with_name (objfile_name (objfile));
+
+  std::string filename (std::string (dir) + SLASH_STRING
+                       + lbasename (objfile_name (objfile))
+                       + (index_kind == dw_index_kind::DEBUG_NAMES
+                          ? INDEX5_SUFFIX : INDEX4_SUFFIX));
+
+  FILE *out_file = gdb_fopen_cloexec (filename.c_str (), "wb").release ();
+  if (!out_file)
+    error (_("Can't open `%s' for writing"), filename.c_str ());
+
+  /* Order matters here; we want FILE to be closed before FILENAME is
+     unlinked, because on MS-Windows one cannot delete a file that is
+     still open.  (Don't call anything here that might throw until
+     file_closer is created.)  */
+  gdb::unlinker unlink_file (filename.c_str ());
+  gdb_file_up close_out_file (out_file);
+
+  if (index_kind == dw_index_kind::DEBUG_NAMES)
+    {
+      std::string filename_str (std::string (dir) + SLASH_STRING
+                               + lbasename (objfile_name (objfile))
+                               + DEBUG_STR_SUFFIX);
+      FILE *out_file_str
+       = gdb_fopen_cloexec (filename_str.c_str (), "wb").release ();
+      if (!out_file_str)
+       error (_("Can't open `%s' for writing"), filename_str.c_str ());
+      gdb::unlinker unlink_file_str (filename_str.c_str ());
+      gdb_file_up close_out_file_str (out_file_str);
+
+      const size_t total_len
+       = write_debug_names (dwarf2_per_objfile, out_file, out_file_str);
+      assert_file_size (out_file, filename.c_str (), total_len);
+
+      /* We want to keep the file .debug_str file too.  */
+      unlink_file_str.keep ();
+    }
+  else
+    {
+      const size_t total_len
+       = write_gdbindex (dwarf2_per_objfile, out_file);
+      assert_file_size (out_file, filename.c_str (), total_len);
+    }
+
   /* We want to keep the file.  */
   unlink_file.keep ();
 }
 
 /* Implementation of the `save gdb-index' command.
    
-   Note that the file format used by this command is documented in the
-   GDB manual.  Any changes here must be documented there.  */
+   Note that the .gdb_index file format used by this command is
+   documented in the GDB manual.  Any changes here must be documented
+   there.  */
 
 static void
-save_gdb_index_command (char *arg, int from_tty)
+save_gdb_index_command (const char *arg, int from_tty)
 {
   struct objfile *objfile;
+  const char dwarf5space[] = "-dwarf-5 ";
+  dw_index_kind index_kind = dw_index_kind::GDB_INDEX;
+
+  if (!arg)
+    arg = "";
 
-  if (!arg || !*arg)
-    error (_("usage: save gdb-index DIRECTORY"));
+  arg = skip_spaces (arg);
+  if (strncmp (arg, dwarf5space, strlen (dwarf5space)) == 0)
+    {
+      index_kind = dw_index_kind::DEBUG_NAMES;
+      arg += strlen (dwarf5space);
+      arg = skip_spaces (arg);
+    }
+
+  if (!*arg)
+    error (_("usage: save gdb-index [-dwarf-5] DIRECTORY"));
 
   ALL_OBJFILES (objfile)
   {
@@ -24042,15 +27081,14 @@ save_gdb_index_command (char *arg, int from_tty)
     if (stat (objfile_name (objfile), &st) < 0)
       continue;
 
-    dwarf2_per_objfile
-      = (struct dwarf2_per_objfile *) objfile_data (objfile,
-                                                   dwarf2_objfile_data_key);
-    if (dwarf2_per_objfile)
-      {
+    struct dwarf2_per_objfile *dwarf2_per_objfile
+      = get_dwarf2_per_objfile (objfile);
 
+    if (dwarf2_per_objfile != NULL)
+      {
        TRY
          {
-           write_psymtabs_to_index (objfile, arg);
+           write_psymtabs_to_index (dwarf2_per_objfile, arg, index_kind);
          }
        CATCH (except, RETURN_MASK_ERROR)
          {
@@ -24060,6 +27098,7 @@ save_gdb_index_command (char *arg, int from_tty)
          }
        END_CATCH
       }
+
   }
 }
 
@@ -24091,8 +27130,7 @@ _initialize_dwarf2_read (void)
 {
   struct cmd_list_element *c;
 
-  dwarf2_objfile_data_key
-    = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free);
+  dwarf2_objfile_data_key = register_objfile_data ();
 
   add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
 Set DWARF specific variables.\n\
@@ -24182,7 +27220,11 @@ Warning: This option must be enabled before gdb reads the file."),
   c = add_cmd ("gdb-index", class_files, save_gdb_index_command,
               _("\
 Save a gdb-index file.\n\
-Usage: save gdb-index DIRECTORY"),
+Usage: save gdb-index [-dwarf-5] DIRECTORY\n\
+\n\
+No options create one file with .gdb-index extension for pre-DWARF-5\n\
+compatible .gdb_index section.  With -dwarf-5 creates two files with\n\
+extension .debug_names and .debug_str for DWARF-5 .debug_names section."),
               &save_cmdlist);
   set_cmd_completer (c, filename_completer);
 
@@ -24195,4 +27237,9 @@ Usage: save gdb-index DIRECTORY"),
                                        &dwarf2_block_frame_base_locexpr_funcs);
   dwarf2_loclist_block_index = register_symbol_block_impl (LOC_BLOCK,
                                        &dwarf2_block_frame_base_loclist_funcs);
+
+#if GDB_SELF_TEST
+  selftests::register_test ("dw2_expand_symtabs_matching",
+                           selftests::dw2_expand_symtabs_matching::run_test);
+#endif
 }
This page took 0.188619 seconds and 4 git commands to generate.