]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/dwarf2/read.c
Add dwarf2_per_bfd field to dwarf2_per_cu_data
[thirdparty/binutils-gdb.git] / gdb / dwarf2 / read.c
index dbd5b6a48022c4db062e0961ddb924fb7b8c4368..da1638d3a197bc4216b1e31febeed00582e4759f 100644 (file)
@@ -39,6 +39,8 @@
 #include "dwarf2/line-header.h"
 #include "dwarf2/dwz.h"
 #include "dwarf2/macro.h"
+#include "dwarf2/die.h"
+#include "dwarf2/stringify.h"
 #include "bfd.h"
 #include "elf-bfd.h"
 #include "symtab.h"
@@ -112,6 +114,12 @@ static int dwarf2_loclist_index;
 static int dwarf2_locexpr_block_index;
 static int dwarf2_loclist_block_index;
 
+/* Size of .debug_loclists section header for 32-bit DWARF format.  */
+#define LOCLIST_HEADER_SIZE32 12
+
+/* Size of .debug_loclists section header for 64-bit DWARF format.  */
+#define LOCLIST_HEADER_SIZE64 20
+
 /* 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
@@ -344,6 +352,30 @@ dwop_section_names =
 
 /* local data types */
 
+/* The location list section (.debug_loclists) begins with a header,
+   which contains the following information.  */
+struct loclist_header
+{
+  /* A 4-byte or 12-byte length containing the length of the
+     set of entries for this compilation unit, not including the
+     length field itself.  */
+  unsigned int length;
+
+  /* A 2-byte version identifier.  */
+  short version;
+
+  /* A 1-byte unsigned integer containing the size in bytes of an address on
+     the target system.  */
+  unsigned char addr_size;
+
+  /* A 1-byte unsigned integer containing the size in bytes of a segment selector
+     on the target system.  */
+  unsigned char segment_collector_size;
+
+  /* A 4-byte count of the number of offsets that follow the header.  */
+  unsigned int offset_entry_count;
+};
+
 /* Type used for delaying computation of method physnames.
    See comments for compute_delayed_physnames.  */
 struct delayed_method_info
@@ -367,7 +399,8 @@ struct delayed_method_info
 /* Internal state when decoding a particular compilation unit.  */
 struct dwarf2_cu
 {
-  explicit dwarf2_cu (struct dwarf2_per_cu_data *per_cu);
+  explicit dwarf2_cu (dwarf2_per_cu_data *per_cu,
+                     dwarf2_per_objfile *per_objfile);
   ~dwarf2_cu ();
 
   DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
@@ -392,10 +425,7 @@ struct dwarf2_cu
   struct comp_unit_head header {};
 
   /* Base address of this compilation unit.  */
-  CORE_ADDR base_address = 0;
-
-  /* Non-zero if base_address has been set.  */
-  int base_known = 0;
+  gdb::optional<CORE_ADDR> base_address;
 
   /* The language we are debugging.  */
   enum language language = language_unknown;
@@ -437,6 +467,9 @@ public:
   /* Backlink to our per_cu entry.  */
   struct dwarf2_per_cu_data *per_cu;
 
+  /* The dwarf2_per_objfile that owns this.  */
+  struct dwarf2_per_objfile *per_objfile;
+
   /* How many compilation units ago was this CU last referenced?  */
   int last_used = 0;
 
@@ -455,7 +488,7 @@ public:
   /* Header data from the line table, during full symbol processing.  */
   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,
+     it's owned by dwarf2_per_bfd::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.  */
@@ -494,6 +527,9 @@ public:
      whether the DW_AT_ranges attribute came from the skeleton or DWO.  */
   ULONGEST ranges_base = 0;
 
+  /* The DW_AT_loclists_base attribute if present.  */
+  ULONGEST loclist_base = 0;
+
   /* When reading debug info generated by older versions of rustc, we
      have to rewrite some union types to be struct types with a
      variant part.  This rewriting must be done after the CU is fully
@@ -567,7 +603,7 @@ struct stmt_list_hash
   sect_offset line_sect_off;
 };
 
-/* Each element of dwarf2_per_objfile->type_unit_groups is a pointer to
+/* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
    an object of this type.  */
 
 struct type_unit_group
@@ -896,7 +932,8 @@ public:
   void keep ();
 
 private:
-  void init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
+  void init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
+                                 dwarf2_per_objfile *per_objfile,
                                  int use_existing_cu);
 
   struct dwarf2_per_cu_data *m_this_cu;
@@ -1045,73 +1082,57 @@ struct partial_die_info : public allocate_on_obstack
     }
   };
 
-/* This data structure holds a complete die structure.  */
-struct die_info
-  {
-    /* DWARF-2 tag for this DIE.  */
-    ENUM_BITFIELD(dwarf_tag) tag : 16;
-
-    /* Number of attributes */
-    unsigned char num_attrs;
-
-    /* True if we're presently building the full type name for the
-       type derived from this DIE.  */
-    unsigned char building_fullname : 1;
-
-    /* True if this die is in process.  PR 16581.  */
-    unsigned char in_process : 1;
-
-    /* True if this DIE has children.  */
-    unsigned char has_children : 1;
-
-    /* Abbrev number */
-    unsigned int abbrev;
-
-    /* Offset in .debug_info or .debug_types section.  */
-    sect_offset sect_off;
-
-    /* The dies in a compilation unit form an n-ary tree.  PARENT
-       points to this die's parent; CHILD points to the first child of
-       this node; and all the children of a given node are chained
-       together via their SIBLING fields.  */
-    struct die_info *child;    /* Its first child, if any.  */
-    struct die_info *sibling;  /* Its next sibling, if any.  */
-    struct die_info *parent;   /* Its parent, if any.  */
-
-    /* An array of attributes, with NUM_ATTRS elements.  There may be
-       zero, but it's not common and zero-sized arrays are not
-       sufficiently portable C.  */
-    struct attribute attrs[1];
-  };
-
 /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
    but this would require a corresponding change in unpack_field_as_long
    and friends.  */
 static int bits_per_byte = 8;
 
-/* When reading a variant or variant part, we track a bit more
-   information about the field, and store it in an object of this
-   type.  */
+struct variant_part_builder;
+
+/* When reading a variant, we track a bit more information about the
+   field, and store it in an object of this type.  */
 
 struct variant_field
 {
-  /* If we see a DW_TAG_variant, then this will be the discriminant
-     value.  */
-  ULONGEST discriminant_value;
+  int first_field = -1;
+  int last_field = -1;
+
+  /* A variant can contain other variant parts.  */
+  std::vector<variant_part_builder> variant_parts;
+
   /* If we see a DW_TAG_variant, then this will be set if this is the
      default branch.  */
-  bool default_branch;
-  /* While reading a DW_TAG_variant_part, this will be set if this
-     field is the discriminant.  */
-  bool is_discriminant;
+  bool default_branch = false;
+  /* If we see a DW_AT_discr_value, then this will be the discriminant
+     value.  */
+  ULONGEST discriminant_value = 0;
+  /* If we see a DW_AT_discr_list, then this is a pointer to the list
+     data.  */
+  struct dwarf_block *discr_list_data = nullptr;
+};
+
+/* This represents a DW_TAG_variant_part.  */
+
+struct variant_part_builder
+{
+  /* The offset of the discriminant field.  */
+  sect_offset discriminant_offset {};
+
+  /* Variants that are direct children of this variant part.  */
+  std::vector<variant_field> variants;
+
+  /* True if we're currently reading a variant.  */
+  bool processing_variant = false;
 };
 
 struct nextfield
 {
   int accessibility = 0;
   int virtuality = 0;
-  /* Extra information to describe a variant or variant part.  */
-  struct variant_field variant {};
+  /* Variant parts need to find the discriminant, which is a DIE
+     reference.  We track the section offset of each field to make
+     this link.  */
+  sect_offset offset;
   struct field field {};
 };
 
@@ -1146,6 +1167,13 @@ struct field_info
        list.  */
     std::vector<struct decl_field> nested_types_list;
 
+    /* If non-null, this is the variant part we are currently
+       reading.  */
+    variant_part_builder *current_variant_part = nullptr;
+    /* This holds all the top-level variant parts attached to the type
+       we're reading.  */
+    std::vector<variant_part_builder> variant_parts;
+
     /* Return the total number of fields (including baseclasses).  */
     int nfields () const
     {
@@ -1239,10 +1267,6 @@ static void read_attribute_reprocess (const struct die_reader_specs *reader,
 
 static CORE_ADDR read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index);
 
-static LONGEST read_checked_initial_length_and_offset
-  (bfd *, const gdb_byte *, const struct comp_unit_head *,
-   unsigned int *, unsigned int *);
-
 static sect_offset read_abbrev_offset
   (struct dwarf2_per_objfile *dwarf2_per_objfile,
    struct dwarf2_section_info *, sect_offset);
@@ -1269,9 +1293,6 @@ static void set_cu_language (unsigned int, struct dwarf2_cu *);
 static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
                                      struct dwarf2_cu *);
 
-static struct attribute *dwarf2_attr_no_follow (struct die_info *,
-                                               unsigned int);
-
 static const char *dwarf2_string_attr (struct die_info *die, unsigned int name,
                                        struct dwarf2_cu *cu);
 
@@ -1350,6 +1371,9 @@ 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 *, dwarf2_psymtab *);
 
+/* Return the .debug_loclists section to use for cu.  */
+static struct dwarf2_section_info *cu_debug_loc_section (struct dwarf2_cu *cu);
+
 /* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
    values.  Keep the items ordered with increasing constraints compliance.  */
 enum pc_bounds_kind
@@ -1416,7 +1440,8 @@ static const char *namespace_name (struct die_info *die,
 
 static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
 
-static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *,
+                                bool * = nullptr);
 
 static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
                                                       struct dwarf2_cu *);
@@ -1454,18 +1479,6 @@ static const char *dwarf2_physname (const char *name, struct die_info *die,
 static struct die_info *dwarf2_extension (struct die_info *die,
                                          struct dwarf2_cu **);
 
-static const char *dwarf_tag_name (unsigned int);
-
-static const char *dwarf_attr_name (unsigned int);
-
-static const char *dwarf_form_name (unsigned int);
-
-static const char *dwarf_bool_name (unsigned int);
-
-static const char *dwarf_type_encoding_name (unsigned int);
-
-static struct die_info *sibling_die (struct die_info *);
-
 static void dump_die_shallow (struct ui_file *, int indent, struct die_info *);
 
 static void dump_die_for_error (struct die_info *);
@@ -1478,10 +1491,6 @@ static void dump_die_1 (struct ui_file *, int level, int max_level,
 static void store_in_ref_table (struct die_info *,
                                struct dwarf2_cu *);
 
-static sect_offset dwarf2_get_ref_die_offset (const struct attribute *);
-
-static LONGEST dwarf2_get_attr_constant_value (const struct attribute *, int);
-
 static struct die_info *follow_die_ref_or_sig (struct die_info *,
                                               const struct attribute *,
                                               struct dwarf2_cu **);
@@ -1598,7 +1607,7 @@ public:
   {
     /* Ensure that no memory is allocated by the queue.  */
     std::queue<dwarf2_queue_item> empty;
-    std::swap (m_per_objfile->queue, empty);
+    std::swap (m_per_objfile->per_bfd->queue, empty);
   }
 
   DISABLE_COPY_AND_ASSIGN (dwarf2_queue_guard);
@@ -1673,12 +1682,6 @@ static void free_line_header_voidp (void *arg);
 \f
 /* Various complaints about symbol reading that don't abort the process.  */
 
-static void
-dwarf2_statement_list_fits_in_line_number_section_complaint (void)
-{
-  complaint (_("statement list doesn't fit in .debug_line section"));
-}
-
 static void
 dwarf2_debug_line_missing_file_complaint (void)
 {
@@ -1747,22 +1750,18 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
 
 /* See declaration.  */
 
-dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_,
-                                       const dwarf2_debug_sections *names,
-                                       bool can_copy_)
-  : objfile (objfile_),
-    can_copy (can_copy_)
+dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
+                               bool can_copy_)
+  : can_copy (can_copy_)
 {
   if (names == NULL)
     names = &dwarf2_elf_names;
 
-  bfd *obfd = objfile->obfd;
-
   for (asection *sec = obfd->sections; sec != NULL; sec = sec->next)
     locate_sections (obfd, sec, *names);
 }
 
-dwarf2_per_objfile::~dwarf2_per_objfile ()
+dwarf2_per_bfd::~dwarf2_per_bfd ()
 {
   /* Cached DIE trees use xmalloc and the comp_unit_obstack.  */
   free_cached_comp_units ();
@@ -1773,13 +1772,13 @@ dwarf2_per_objfile::~dwarf2_per_objfile ()
   for (signatured_type *sig_type : all_type_units)
     sig_type->per_cu.imported_symtabs_free ();
 
-  /* Everything else should be on the objfile obstack.  */
+  /* Everything else should be on this->obstack.  */
 }
 
 /* See declaration.  */
 
 void
-dwarf2_per_objfile::free_cached_comp_units ()
+dwarf2_per_bfd::free_cached_comp_units ()
 {
   dwarf2_per_cu_data *per_cu = read_in_chain;
   dwarf2_per_cu_data **last_chain = &read_in_chain;
@@ -1807,7 +1806,7 @@ public:
 
   ~free_cached_comp_units ()
   {
-    m_per_objfile->free_cached_comp_units ();
+    m_per_objfile->per_bfd->free_cached_comp_units ();
   }
 
   DISABLE_COPY_AND_ASSIGN (free_cached_comp_units);
@@ -1817,6 +1816,38 @@ private:
   dwarf2_per_objfile *m_per_objfile;
 };
 
+/* See read.h.  */
+
+bool
+dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
+{
+  gdb_assert (per_cu->index < this->m_symtabs.size ());
+
+  return this->m_symtabs[per_cu->index] != nullptr;
+}
+
+/* See read.h.  */
+
+compunit_symtab *
+dwarf2_per_objfile::get_symtab (const dwarf2_per_cu_data *per_cu) const
+{
+  gdb_assert (per_cu->index < this->m_symtabs.size ());
+
+  return this->m_symtabs[per_cu->index];
+}
+
+/* See read.h.  */
+
+void
+dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
+                               compunit_symtab *symtab)
+{
+  gdb_assert (per_cu->index < this->m_symtabs.size ());
+  gdb_assert (this->m_symtabs[per_cu->index] == nullptr);
+
+  this->m_symtabs[per_cu->index] = symtab;
+}
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.
    NAMES points to the dwarf2 section names, or is NULL if the standard
@@ -1836,14 +1867,18 @@ dwarf2_has_info (struct objfile *objfile,
     = get_dwarf2_per_objfile (objfile);
 
   if (dwarf2_per_objfile == NULL)
-    dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile,
-                                                         names,
-                                                         can_copy);
+    {
+      /* For now, each dwarf2_per_objfile owns its own dwarf2_per_bfd (no
+         sharing yet).  */
+      dwarf2_per_bfd *per_bfd = new dwarf2_per_bfd (objfile->obfd, names, can_copy);
+
+      dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
+    }
 
-  return (!dwarf2_per_objfile->info.is_virtual
-         && dwarf2_per_objfile->info.s.section != NULL
-         && !dwarf2_per_objfile->abbrev.is_virtual
-         && dwarf2_per_objfile->abbrev.s.section != NULL);
+  return (!dwarf2_per_objfile->per_bfd->info.is_virtual
+         && dwarf2_per_objfile->per_bfd->info.s.section != NULL
+         && !dwarf2_per_objfile->per_bfd->abbrev.is_virtual
+         && dwarf2_per_objfile->per_bfd->abbrev.s.section != NULL);
 }
 
 /* When loading sections, we look either for uncompressed section or for
@@ -1865,8 +1900,8 @@ section_is_p (const char *section_name,
 /* See declaration.  */
 
 void
-dwarf2_per_objfile::locate_sections (bfd *abfd, asection *sectp,
-                                    const dwarf2_debug_sections &names)
+dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp,
+                                const dwarf2_debug_sections &names)
 {
   flagword aflag = bfd_section_flags (sectp);
 
@@ -2012,10 +2047,10 @@ dwarf2_get_section_info (struct objfile *objfile,
   switch (sect)
     {
     case DWARF2_DEBUG_FRAME:
-      info = &data->frame;
+      info = &data->per_bfd->frame;
       break;
     case DWARF2_EH_FRAME:
-      info = &data->eh_frame;
+      info = &data->per_bfd->eh_frame;
       break;
     default:
       gdb_assert_not_reached ("unexpected section");
@@ -2084,8 +2119,8 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
   size_t buildid_len;
   bfd_byte *buildid;
 
-  if (dwarf2_per_objfile->dwz_file != NULL)
-    return dwarf2_per_objfile->dwz_file.get ();
+  if (dwarf2_per_objfile->per_bfd->dwz_file != NULL)
+    return dwarf2_per_objfile->per_bfd->dwz_file.get ();
 
   bfd_set_error (bfd_error_no_error);
   gdb::unique_xmalloc_ptr<char> data
@@ -2117,7 +2152,7 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   /* First try the file name given in the section.  If that doesn't
      work, try to use the build-id instead.  */
-  gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget, -1));
+  gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget));
   if (dwz_bfd != NULL)
     {
       if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
@@ -2140,7 +2175,7 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
       if (fd.get () >= 0)
        {
          /* File successfully retrieved from server.  */
-         dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget, -1);
+         dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget);
 
          if (dwz_bfd == nullptr)
            warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
@@ -2162,8 +2197,8 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd,
                            result->dwz_bfd.get ());
-  dwarf2_per_objfile->dwz_file = std::move (result);
-  return dwarf2_per_objfile->dwz_file.get ();
+  dwarf2_per_objfile->per_bfd->dwz_file = std::move (result);
+  return dwarf2_per_objfile->per_bfd->dwz_file.get ();
 }
 \f
 /* DWARF quick_symbols_functions support.  */
@@ -2197,13 +2232,9 @@ struct dwarf2_per_cu_quick_data
 {
   /* The file table.  This can be NULL if there was no file table
      or it's currently not read in.
-     NOTE: This points into dwarf2_per_objfile->quick_file_names_table.  */
+     NOTE: This points into dwarf2_per_objfile->per_bfd->quick_file_names_table.  */
   struct quick_file_names *file_names;
 
-  /* The corresponding symbol table.  This is NULL if symbols for this
-     CU have not yet been read.  */
-  struct compunit_symtab *compunit_symtab;
-
   /* A temporary mark bit used when iterating over all CUs in
      expand_symtabs_matching.  */
   unsigned int mark : 1;
@@ -2278,8 +2309,8 @@ delete_file_name_entry (void *e)
        xfree ((void*) file_data->real_names[i]);
     }
 
-  /* The space for the struct itself lives on objfile_obstack,
-     so we don't free it here.  */
+  /* The space for the struct itself lives on the obstack, so we don't
+     free it here.  */
 }
 
 /* Create a quick_file_names hash table.  */
@@ -2310,13 +2341,13 @@ load_cu (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
   dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
 }
 
-/* Read in the symbols for PER_CU.  */
+/* Read in the symbols for PER_CU in the context of DWARF"_PER_OBJFILE.  */
 
 static void
-dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
+dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
+                          dwarf2_per_objfile *dwarf2_per_objfile,
+                          bool skip_partial)
 {
-  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 (per_cu->type_unit_group_p ())
@@ -2327,9 +2358,7 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
      with the dwarf queue empty.  */
   dwarf2_queue_guard q_guard (dwarf2_per_objfile);
 
-  if (dwarf2_per_objfile->using_index
-      ? per_cu->v.quick->compunit_symtab == NULL
-      : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
+  if (!dwarf2_per_objfile->symtab_set_p (per_cu))
     {
       queue_comp_unit (per_cu, language_minimal);
       load_cu (per_cu, skip_partial);
@@ -2340,8 +2369,8 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
       if (!per_cu->is_debug_types
          && per_cu->cu != NULL
          && per_cu->cu->dwo_unit != NULL
-         && dwarf2_per_objfile->index_table != NULL
-         && dwarf2_per_objfile->index_table->version <= 7
+         && dwarf2_per_objfile->per_bfd->index_table != NULL
+         && dwarf2_per_objfile->per_bfd->index_table->version <= 7
          /* DWP files aren't supported yet.  */
          && get_dwp_file (dwarf2_per_objfile) == NULL)
        queue_and_load_all_dwo_tus (per_cu);
@@ -2354,31 +2383,33 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
   age_cached_comp_units (dwarf2_per_objfile);
 }
 
-/* Ensure that the symbols for PER_CU have been read in.  OBJFILE is
-   the objfile from which this CU came.  Returns the resulting symbol
-   table.  */
+/* Ensure that the symbols for PER_CU have been read in.  DWARF2_PER_OBJFILE is
+   the per-objfile for which this symtab is instantiated.
+
+   Returns the resulting symbol table.  */
 
 static struct compunit_symtab *
-dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
+dw2_instantiate_symtab (dwarf2_per_cu_data *per_cu,
+                       dwarf2_per_objfile *dwarf2_per_objfile,
+                       bool skip_partial)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+  gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
 
-  gdb_assert (dwarf2_per_objfile->using_index);
-  if (!per_cu->v.quick->compunit_symtab)
+  if (!dwarf2_per_objfile->symtab_set_p (per_cu))
     {
       free_cached_comp_units freer (dwarf2_per_objfile);
       scoped_restore decrementer = increment_reading_symtab ();
-      dw2_do_instantiate_symtab (per_cu, skip_partial);
+      dw2_do_instantiate_symtab (per_cu, dwarf2_per_objfile, skip_partial);
       process_cu_includes (dwarf2_per_objfile);
     }
 
-  return per_cu->v.quick->compunit_symtab;
+  return dwarf2_per_objfile->get_symtab (per_cu);
 }
 
 /* See declaration.  */
 
 dwarf2_per_cu_data *
-dwarf2_per_objfile::get_cutu (int index)
+dwarf2_per_bfd::get_cutu (int index)
 {
   if (index >= this->all_comp_units.size ())
     {
@@ -2393,7 +2424,7 @@ dwarf2_per_objfile::get_cutu (int index)
 /* See declaration.  */
 
 dwarf2_per_cu_data *
-dwarf2_per_objfile::get_cu (int index)
+dwarf2_per_bfd::get_cu (int index)
 {
   gdb_assert (index >= 0 && index < this->all_comp_units.size ());
 
@@ -2403,16 +2434,37 @@ dwarf2_per_objfile::get_cu (int index)
 /* See declaration.  */
 
 signatured_type *
-dwarf2_per_objfile::get_tu (int index)
+dwarf2_per_bfd::get_tu (int index)
 {
   gdb_assert (index >= 0 && index < this->all_type_units.size ());
 
   return this->all_type_units[index];
 }
 
-/* Return a new dwarf2_per_cu_data allocated on OBJFILE's
-   objfile_obstack, and constructed with the specified field
-   values.  */
+/* See read.h.  */
+
+dwarf2_per_cu_data *
+dwarf2_per_bfd::allocate_per_cu ()
+{
+  dwarf2_per_cu_data *result = OBSTACK_ZALLOC (&obstack, dwarf2_per_cu_data);
+  result->per_bfd = this;
+  result->index = m_num_psymtabs++;
+  return result;
+}
+
+/* See read.h.  */
+
+signatured_type *
+dwarf2_per_bfd::allocate_signatured_type ()
+{
+  signatured_type *result = OBSTACK_ZALLOC (&obstack, signatured_type);
+  result->per_cu.per_bfd = this;
+  result->per_cu.index = m_num_psymtabs++;
+  return result;
+}
+
+/* Return a new dwarf2_per_cu_data allocated on the dwarf2_per_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,
@@ -2420,16 +2472,13 @@ create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
                           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);
+  dwarf2_per_cu_data *the_cu = dwarf2_per_objfile->per_bfd->allocate_per_cu ();
   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->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
+                                   struct dwarf2_per_cu_quick_data);
   the_cu->is_dwz = is_dwz;
   return the_cu;
 }
@@ -2455,7 +2504,7 @@ create_cus_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwarf2_per_cu_data *per_cu
        = create_cu_from_index_list (dwarf2_per_objfile, section, is_dwz,
                                     sect_off, length);
-      dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+      dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
     }
 }
 
@@ -2467,12 +2516,12 @@ create_cus_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
                       const gdb_byte *cu_list, offset_type cu_list_elements,
                       const gdb_byte *dwz_list, offset_type dwz_elements)
 {
-  gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
-  dwarf2_per_objfile->all_comp_units.reserve
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_comp_units.reserve
     ((cu_list_elements + dwz_elements) / 2);
 
   create_cus_from_index_list (dwarf2_per_objfile, cu_list, cu_list_elements,
-                             &dwarf2_per_objfile->info, 0);
+                             &dwarf2_per_objfile->per_bfd->info, 0);
 
   if (dwz_elements == 0)
     return;
@@ -2491,10 +2540,8 @@ create_signatured_type_table_from_index
    const gdb_byte *bytes,
    offset_type elements)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-
-  gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
-  dwarf2_per_objfile->all_type_units.reserve (elements / 3);
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_type_units.reserve (elements / 3);
 
   htab_up sig_types_hash = allocate_signatured_type_table ();
 
@@ -2514,8 +2561,7 @@ create_signatured_type_table_from_index
       signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
       bytes += 3 * 8;
 
-      sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                                struct signatured_type);
+      sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
       sig_type->signature = signature;
       sig_type->type_offset_in_tu = type_offset_in_tu;
       sig_type->per_cu.is_debug_types = 1;
@@ -2523,16 +2569,16 @@ create_signatured_type_table_from_index
       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,
+       = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
                          struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
       *slot = sig_type;
 
-      dwarf2_per_objfile->all_type_units.push_back (sig_type);
+      dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
     }
 
-  dwarf2_per_objfile->signatured_types = std::move (sig_types_hash);
+  dwarf2_per_objfile->per_bfd->signatured_types = std::move (sig_types_hash);
 }
 
 /* Create the signatured type hash table from .debug_names.  */
@@ -2549,8 +2595,8 @@ create_signatured_type_table_from_debug_names
   section->read (objfile);
   abbrev_section->read (objfile);
 
-  gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
-  dwarf2_per_objfile->all_type_units.reserve (map.tu_count);
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_type_units.reserve (map.tu_count);
 
   htab_up sig_types_hash = allocate_signatured_type_table ();
 
@@ -2571,8 +2617,7 @@ create_signatured_type_table_from_debug_names
                                     section->buffer + to_underlying (sect_off),
                                     rcuh_kind::TYPE);
 
-      sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                                struct signatured_type);
+      sig_type = dwarf2_per_objfile->per_bfd->allocate_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;
@@ -2580,16 +2625,16 @@ create_signatured_type_table_from_debug_names
       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,
+       = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
                          struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
       *slot = sig_type;
 
-      dwarf2_per_objfile->all_type_units.push_back (sig_type);
+      dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
     }
 
-  dwarf2_per_objfile->signatured_types = std::move (sig_types_hash);
+  dwarf2_per_objfile->per_bfd->signatured_types = std::move (sig_types_hash);
 }
 
 /* Read the address map data from the mapped index, and use it to
@@ -2600,7 +2645,7 @@ 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);
+  struct gdbarch *gdbarch = objfile->arch ();
   const gdb_byte *iter, *end;
   struct addrmap *mutable_map;
   CORE_ADDR baseaddr;
@@ -2631,7 +2676,7 @@ create_addrmap_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
          continue;
        }
 
-      if (cu_index >= dwarf2_per_objfile->all_comp_units.size ())
+      if (cu_index >= dwarf2_per_objfile->per_bfd->all_comp_units.size ())
        {
          complaint (_(".gdb_index address table has invalid CU number %u"),
                     (unsigned) cu_index);
@@ -2641,7 +2686,7 @@ create_addrmap_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
       lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr) - baseaddr;
       hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr) - baseaddr;
       addrmap_set_empty (mutable_map, lo, hi - 1,
-                        dwarf2_per_objfile->get_cu (cu_index));
+                        dwarf2_per_objfile->per_bfd->get_cu (cu_index));
     }
 
   objfile->partial_symtabs->psymtabs_addrmap
@@ -2657,7 +2702,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile,
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *abfd = objfile->obfd;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   const CORE_ADDR baseaddr = objfile->text_section_offset ();
 
   auto_obstack temp_obstack;
@@ -2667,7 +2712,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile,
                     dwarf2_per_cu_data *,
                     gdb::hash_enum<sect_offset>>
     debug_info_offset_to_per_cu;
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       const auto insertpair
        = debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu);
@@ -2795,7 +2840,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile,
          addr += address_size;
          if (start == 0 && length == 0)
            break;
-         if (start == 0 && !dwarf2_per_objfile->has_section_at_zero)
+         if (start == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
            {
              /* Symbol was eliminated due to a COMDAT group.  */
              continue;
@@ -2887,8 +2932,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
    Returns true if all went well, false otherwise.  */
 
 static bool
-read_gdb_index_from_buffer (struct objfile *objfile,
-                           const char *filename,
+read_gdb_index_from_buffer (const char *filename,
                            bool deprecated_ok,
                            gdb::array_view<const gdb_byte> buffer,
                            struct mapped_index *map,
@@ -2989,7 +3033,7 @@ to use the section anyway."),
 /* Callback types for dwarf2_read_gdb_index.  */
 
 typedef gdb::function_view
-    <gdb::array_view<const gdb_byte>(objfile *, dwarf2_per_objfile *)>
+    <gdb::array_view<const gdb_byte>(objfile *, dwarf2_per_bfd *)>
     get_gdb_index_contents_ftype;
 typedef gdb::function_view
     <gdb::array_view<const gdb_byte>(objfile *, dwz_file *)>
@@ -3010,13 +3054,13 @@ dwarf2_read_gdb_index
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   gdb::array_view<const gdb_byte> main_index_contents
-    = get_gdb_index_contents (objfile, dwarf2_per_objfile);
+    = get_gdb_index_contents (objfile, dwarf2_per_objfile->per_bfd);
 
   if (main_index_contents.empty ())
     return 0;
 
   std::unique_ptr<struct mapped_index> map (new struct mapped_index);
-  if (!read_gdb_index_from_buffer (objfile, objfile_name (objfile),
+  if (!read_gdb_index_from_buffer (objfile_name (objfile),
                                   use_deprecated_index_sections,
                                   main_index_contents, map.get (), &cu_list,
                                   &cu_list_elements, &types_list,
@@ -3042,8 +3086,7 @@ dwarf2_read_gdb_index
       if (dwz_index_content.empty ())
        return 0;
 
-      if (!read_gdb_index_from_buffer (objfile,
-                                      bfd_get_filename (dwz->dwz_bfd.get ()),
+      if (!read_gdb_index_from_buffer (bfd_get_filename (dwz->dwz_bfd.get ()),
                                       1, dwz_index_content, &dwz_map,
                                       &dwz_list, &dwz_list_elements,
                                       &dwz_types_ignore,
@@ -3062,10 +3105,10 @@ dwarf2_read_gdb_index
     {
       /* We can only handle a single .debug_types when we have an
         index.  */
-      if (dwarf2_per_objfile->types.size () != 1)
+      if (dwarf2_per_objfile->per_bfd->types.size () != 1)
        return 0;
 
-      dwarf2_section_info *section = &dwarf2_per_objfile->types[0];
+      dwarf2_section_info *section = &dwarf2_per_objfile->per_bfd->types[0];
 
       create_signatured_type_table_from_index (dwarf2_per_objfile, section,
                                               types_list, types_list_elements);
@@ -3073,10 +3116,10 @@ dwarf2_read_gdb_index
 
   create_addrmap_from_index (dwarf2_per_objfile, map.get ());
 
-  dwarf2_per_objfile->index_table = std::move (map);
-  dwarf2_per_objfile->using_index = 1;
-  dwarf2_per_objfile->quick_file_names_table =
-    create_quick_file_names_table (dwarf2_per_objfile->all_comp_units.size ());
+  dwarf2_per_objfile->per_bfd->index_table = std::move (map);
+  dwarf2_per_objfile->per_bfd->using_index = 1;
+  dwarf2_per_objfile->per_bfd->quick_file_names_table =
+    create_quick_file_names_table (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
 
   return 1;
 }
@@ -3090,9 +3133,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 {
   struct dwarf2_cu *cu = reader->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_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwarf2_per_cu_data *lh_cu;
   struct attribute *attr;
   void **slot;
@@ -3125,7 +3166,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
         If we have we're done.  */
       find_entry.hash.dwo_unit = cu->dwo_unit;
       find_entry.hash.line_sect_off = line_offset;
-      slot = htab_find_slot (dwarf2_per_objfile->quick_file_names_table.get (),
+      slot = htab_find_slot (dwarf2_per_objfile->per_bfd->quick_file_names_table.get (),
                             &find_entry, INSERT);
       if (*slot != NULL)
        {
@@ -3141,7 +3182,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
       return;
     }
 
-  qfn = XOBNEW (&objfile->objfile_obstack, struct quick_file_names);
+  qfn = XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct quick_file_names);
   qfn->hash.dwo_unit = cu->dwo_unit;
   qfn->hash.line_sect_off = line_offset;
   gdb_assert (slot != NULL);
@@ -3155,7 +3196,8 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 
   qfn->num_file_names = offset + lh->file_names_size ();
   qfn->file_names =
-    XOBNEWVEC (&objfile->objfile_obstack, const char *, qfn->num_file_names);
+    XOBNEWVEC (&dwarf2_per_objfile->per_bfd->obstack, const char *,
+              qfn->num_file_names);
   if (offset != 0)
     qfn->file_names[0] = xstrdup (fnd.name);
   for (int i = 0; i < lh->file_names_size (); ++i)
@@ -3196,11 +3238,11 @@ dw2_get_file_names (struct dwarf2_per_cu_data *this_cu)
    real path for a given file name from the line table.  */
 
 static const char *
-dw2_get_real_path (struct objfile *objfile,
+dw2_get_real_path (struct dwarf2_per_objfile *dwarf2_per_objfile,
                   struct quick_file_names *qfn, int index)
 {
   if (qfn->real_names == NULL)
-    qfn->real_names = OBSTACK_CALLOC (&objfile->objfile_obstack,
+    qfn->real_names = OBSTACK_CALLOC (&dwarf2_per_objfile->per_bfd->obstack,
                                      qfn->num_file_names, const char *);
 
   if (qfn->real_names[index] == NULL)
@@ -3214,8 +3256,9 @@ dw2_find_last_source_symtab (struct objfile *objfile)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
-  dwarf2_per_cu_data *dwarf_cu = dwarf2_per_objfile->all_comp_units.back ();
-  compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu, false);
+  dwarf2_per_cu_data *dwarf_cu = dwarf2_per_objfile->per_bfd->all_comp_units.back ();
+  compunit_symtab *cust
+    = dw2_instantiate_symtab (dwarf_cu, dwarf2_per_objfile, false);
 
   if (cust == NULL)
     return NULL;
@@ -3250,7 +3293,7 @@ dw2_forget_cached_source_info (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  htab_traverse_noresize (dwarf2_per_objfile->quick_file_names_table.get (),
+  htab_traverse_noresize (dwarf2_per_objfile->per_bfd->quick_file_names_table.get (),
                          dw2_free_cached_file_names, NULL);
 }
 
@@ -3266,12 +3309,13 @@ dw2_map_expand_apply (struct objfile *objfile,
   struct compunit_symtab *last_made = objfile->compunit_symtabs;
 
   /* Don't visit already-expanded CUs.  */
-  if (per_cu->v.quick->compunit_symtab)
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  if (per_objfile->symtab_set_p (per_cu))
     return 0;
 
   /* This may expand more than one symtab, and we want to iterate over
      all of them.  */
-  dw2_instantiate_symtab (per_cu, false);
+  dw2_instantiate_symtab (per_cu, per_objfile, false);
 
   return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
                                    last_made, callback);
@@ -3291,10 +3335,10 @@ dw2_map_symtabs_matching_filename
   /* The rule is CUs specify all the files, including those used by
      any TU, so there's no need to scan TUs here.  */
 
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       /* We only need to look at symtabs not already expanded.  */
-      if (per_cu->v.quick->compunit_symtab)
+      if (dwarf2_per_objfile->symtab_set_p (per_cu))
        continue;
 
       quick_file_names *file_data = dw2_get_file_names (per_cu);
@@ -3320,7 +3364,8 @@ dw2_map_symtabs_matching_filename
              && FILENAME_CMP (lbasename (this_name), name_basename) != 0)
            continue;
 
-         this_real_name = dw2_get_real_path (objfile, file_data, j);
+         this_real_name = dw2_get_real_path (dwarf2_per_objfile,
+                                             file_data, j);
          if (compare_filenames_for_search (this_real_name, name))
            {
              if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
@@ -3388,7 +3433,7 @@ dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
   iter->next = 0;
   iter->global_seen = 0;
 
-  mapped_index *index = dwarf2_per_objfile->index_table.get ();
+  mapped_index *index = dwarf2_per_objfile->per_bfd->index_table.get ();
 
   /* index is NULL if OBJF_READNOW.  */
   if (index != NULL && find_slot_in_mapped_hash (index, name, &iter->vec))
@@ -3419,12 +3464,12 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
         and indices >= 7 may elide them for certain symbols
         (gold does this).  */
       int attrs_valid =
-       (dwarf2_per_objfile->index_table->version >= 7
+       (dwarf2_per_objfile->per_bfd->index_table->version >= 7
         && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
 
       /* Don't crash on bad data.  */
-      if (cu_index >= (dwarf2_per_objfile->all_comp_units.size ()
-                      + dwarf2_per_objfile->all_type_units.size ()))
+      if (cu_index >= (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+                      + dwarf2_per_objfile->per_bfd->all_type_units.size ()))
        {
          complaint (_(".gdb_index entry has bad CU index"
                       " [in module %s]"),
@@ -3432,10 +3477,10 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
          continue;
        }
 
-      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (cu_index);
+      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (cu_index);
 
       /* Skip if already read in.  */
-      if (per_cu->v.quick->compunit_symtab)
+      if (dwarf2_per_objfile->symtab_set_p (per_cu))
        continue;
 
       /* Check static vs global.  */
@@ -3512,7 +3557,8 @@ dw2_lookup_symbol (struct objfile *objfile, block_enum 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, false);
+      struct compunit_symtab *stab
+       = dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
       const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
       const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
 
@@ -3542,15 +3588,15 @@ dw2_print_stats (struct objfile *objfile)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
-  int total = (dwarf2_per_objfile->all_comp_units.size ()
-              + dwarf2_per_objfile->all_type_units.size ());
+  int total = (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+              + dwarf2_per_objfile->per_bfd->all_type_units.size ());
   int count = 0;
 
   for (int i = 0; i < total; ++i)
     {
-      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
 
-      if (!per_cu->v.quick->compunit_symtab)
+      if (!dwarf2_per_objfile->symtab_set_p (per_cu))
        ++count;
     }
   printf_filtered (_("  Number of read CUs: %d\n"), total - count);
@@ -3568,12 +3614,12 @@ dw2_dump (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  gdb_assert (dwarf2_per_objfile->using_index);
+  gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
   printf_filtered (".gdb_index:");
-  if (dwarf2_per_objfile->index_table != NULL)
+  if (dwarf2_per_objfile->per_bfd->index_table != NULL)
     {
       printf_filtered (" version %d\n",
-                      dwarf2_per_objfile->index_table->version);
+                      dwarf2_per_objfile->per_bfd->index_table->version);
     }
   else
     printf_filtered (" faked for \"readnow\"\n");
@@ -3593,7 +3639,7 @@ dw2_expand_symtabs_for_function (struct objfile *objfile,
   dw2_symtab_iter_init (&iter, dwarf2_per_objfile, {}, VAR_DOMAIN, func_name);
 
   while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
-    dw2_instantiate_symtab (per_cu, false);
+    dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
 
 }
 
@@ -3602,19 +3648,19 @@ dw2_expand_all_symtabs (struct objfile *objfile)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
-  int total_units = (dwarf2_per_objfile->all_comp_units.size ()
-                    + dwarf2_per_objfile->all_type_units.size ());
+  int total_units = (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+                    + dwarf2_per_objfile->per_bfd->all_type_units.size ());
 
   for (int i = 0; i < total_units; ++i)
     {
-      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
 
       /* We don't want to directly expand a partial CU, because if we
         read it with the wrong language, then assertion failures can
         be triggered later on.  See PR symtab/23010.  So, tell
         dw2_instantiate_symtab to skip partial CUs -- any important
         partial CU will be read via DW_TAG_imported_unit anyway.  */
-      dw2_instantiate_symtab (per_cu, true);
+      dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, true);
     }
 }
 
@@ -3630,10 +3676,10 @@ dw2_expand_symtabs_with_fullname (struct objfile *objfile,
      There can be an order of magnitude (or more) more type units
      than comp units, and we avoid them if we can.  */
 
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       /* We only need to look at symtabs not already expanded.  */
-      if (per_cu->v.quick->compunit_symtab)
+      if (dwarf2_per_objfile->symtab_set_p (per_cu))
        continue;
 
       quick_file_names *file_data = dw2_get_file_names (per_cu);
@@ -3646,13 +3692,28 @@ dw2_expand_symtabs_with_fullname (struct objfile *objfile,
 
          if (filename_cmp (this_fullname, fullname) == 0)
            {
-             dw2_instantiate_symtab (per_cu, false);
+             dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
              break;
            }
        }
     }
 }
 
+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<bool (offset_type)> match_callback);
+
+static void
+dw2_expand_symtabs_matching_one
+  (dwarf2_per_cu_data *per_cu,
+   dwarf2_per_objfile *per_objfile,
+   gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify);
+
 static void
 dw2_map_matching_symbols
   (struct objfile *objfile,
@@ -3661,9 +3722,58 @@ dw2_map_matching_symbols
    gdb::function_view<symbol_found_callback_ftype> callback,
    symbol_compare_ftype *ordered_compare)
 {
-  /* Currently unimplemented; used for Ada.  The function can be called if the
-     current language is Ada for a non-Ada objfile using GNU index.  As Ada
-     does not look for non-Ada symbols this function should just return.  */
+  /* Used for Ada.  */
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
+  const block_enum block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
+
+  if (dwarf2_per_objfile->per_bfd->index_table != nullptr)
+    {
+      /* Ada currently doesn't support .gdb_index (see PR24713).  We can get
+        here though if the current language is Ada for a non-Ada objfile
+        using GNU index.  */
+      mapped_index &index = *dwarf2_per_objfile->per_bfd->index_table;
+
+      const char *match_name = name.ada ().lookup_name ().c_str ();
+      auto matcher = [&] (const char *symname)
+       {
+         if (ordered_compare == nullptr)
+           return true;
+         return ordered_compare (symname, match_name) == 0;
+       };
+
+      dw2_expand_symtabs_matching_symbol (index, name, matcher, ALL_DOMAIN,
+                                         [&] (offset_type namei)
+      {
+       struct dw2_symtab_iterator iter;
+       struct dwarf2_per_cu_data *per_cu;
+
+       dw2_symtab_iter_init (&iter, dwarf2_per_objfile, block_kind, domain,
+                             match_name);
+       while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+         dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, nullptr,
+                                          nullptr);
+       return true;
+      });
+    }
+  else
+    {
+      /* We have -readnow: no .gdb_index, but no partial symtabs either.  So,
+        proceed assuming all symtabs have been read in.  */
+    }
+
+  for (compunit_symtab *cust : objfile->compunits ())
+    {
+      const struct block *block;
+
+      if (cust == NULL)
+       continue;
+      block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), block_kind);
+      if (!iterate_over_symbols_terminated (block, name,
+                                           domain, callback))
+       return;
+    }
 }
 
 /* Starting from a search name, return the string that finds the upper
@@ -3750,7 +3860,7 @@ mapped_index_base::find_name_components_bounds
     = this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
 
   const char *lang_name
-    = lookup_name_without_params.language_lookup_name (lang).c_str ();
+    = lookup_name_without_params.language_lookup_name (lang);
 
   /* Comparison function object for lower_bound that matches against a
      given symbol name.  */
@@ -3920,11 +4030,11 @@ dw2_expand_symtabs_matching_symbol
   struct name_and_matcher
   {
     symbol_name_matcher_ftype *matcher;
-    const std::string &name;
+    const char *name;
 
     bool operator== (const name_and_matcher &other) const
     {
-      return matcher == other.matcher && name == other.name;
+      return matcher == other.matcher && strcmp (name, other.name) == 0;
     }
   };
 
@@ -4426,21 +4536,21 @@ run_test ()
 
 static void
 dw2_expand_symtabs_matching_one
-  (struct dwarf2_per_cu_data *per_cu,
+  (dwarf2_per_cu_data *per_cu,
+   dwarf2_per_objfile *per_objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify)
 {
   if (file_matcher == NULL || per_cu->v.quick->mark)
     {
-      bool symtab_was_null
-       = (per_cu->v.quick->compunit_symtab == NULL);
+      bool symtab_was_null = !per_objfile->symtab_set_p (per_cu);
 
-      dw2_instantiate_symtab (per_cu, false);
+      compunit_symtab *symtab
+       = dw2_instantiate_symtab (per_cu, per_objfile, false);
+      gdb_assert (symtab != nullptr);
 
-      if (expansion_notify != NULL
-         && symtab_was_null
-         && per_cu->v.quick->compunit_symtab != NULL)
-       expansion_notify (per_cu->v.quick->compunit_symtab);
+      if (expansion_notify != NULL && symtab_was_null)
+       expansion_notify (symtab);
     }
 }
 
@@ -4450,14 +4560,14 @@ dw2_expand_symtabs_matching_one
 
 static void
 dw2_expand_marked_cus
-  (struct dwarf2_per_objfile *dwarf2_per_objfile, offset_type idx,
+  (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;
+  mapped_index &index = *dwarf2_per_objfile->per_bfd->index_table;
 
   vec = (offset_type *) (index.constant_pool
                         + MAYBE_SWAP (index.symbol_table[idx].vec));
@@ -4514,8 +4624,8 @@ dw2_expand_marked_cus
        }
 
       /* Don't crash on bad data.  */
-      if (cu_index >= (dwarf2_per_objfile->all_comp_units.size ()
-                      + dwarf2_per_objfile->all_type_units.size ()))
+      if (cu_index >= (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+                      + dwarf2_per_objfile->per_bfd->all_type_units.size ()))
        {
          complaint (_(".gdb_index entry has bad CU index"
                       " [in module %s]"),
@@ -4523,8 +4633,8 @@ dw2_expand_marked_cus
          continue;
        }
 
-      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (cu_index);
-      dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (cu_index);
+      dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, file_matcher,
                                       expansion_notify);
     }
 }
@@ -4541,8 +4651,6 @@ dw_expand_symtabs_matching_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));
@@ -4553,14 +4661,14 @@ dw_expand_symtabs_matching_file_matcher
   /* The rule is CUs specify all the files, including those used by
      any TU, so there's no need to scan TUs here.  */
 
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       QUIT;
 
       per_cu->v.quick->mark = 0;
 
       /* We only need to look at symtabs not already expanded.  */
-      if (per_cu->v.quick->compunit_symtab)
+      if (dwarf2_per_objfile->symtab_set_p (per_cu))
        continue;
 
       quick_file_names *file_data = dw2_get_file_names (per_cu);
@@ -4592,7 +4700,8 @@ dw_expand_symtabs_matching_file_matcher
                                true))
            continue;
 
-         this_real_name = dw2_get_real_path (objfile, file_data, j);
+         this_real_name = dw2_get_real_path (dwarf2_per_objfile,
+                                             file_data, j);
          if (file_matcher (this_real_name, false))
            {
              per_cu->v.quick->mark = 1;
@@ -4612,7 +4721,7 @@ 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,
+   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)
@@ -4621,14 +4730,26 @@ dw2_expand_symtabs_matching
     = get_dwarf2_per_objfile (objfile);
 
   /* index_table is NULL if OBJF_READNOW.  */
-  if (!dwarf2_per_objfile->index_table)
+  if (!dwarf2_per_objfile->per_bfd->index_table)
     return;
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
-  mapped_index &index = *dwarf2_per_objfile->index_table;
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
+       {
+         QUIT;
+
+         dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+                                          file_matcher, expansion_notify);
+       }
+      return;
+    }
 
-  dw2_expand_symtabs_matching_symbol (index, lookup_name,
+  mapped_index &index = *dwarf2_per_objfile->per_bfd->index_table;
+
+  dw2_expand_symtabs_matching_symbol (index, *lookup_name,
                                      symbol_matcher,
                                      kind, [&] (offset_type idx)
     {
@@ -4685,14 +4806,14 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile,
   if (!data)
     return NULL;
 
-  if (warn_if_readin && data->v.quick->compunit_symtab)
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  if (warn_if_readin && per_objfile->symtab_set_p (data))
     warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
-            paddress (get_objfile_arch (objfile), pc));
+            paddress (objfile->arch (), pc));
+
+  result = recursively_find_pc_sect_compunit_symtab
+    (dw2_instantiate_symtab (data, per_objfile, false), pc);
 
-  result
-    = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data,
-                                                                       false),
-                                               pc);
   gdb_assert (result != NULL);
   return result;
 }
@@ -4704,9 +4825,9 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  if (!dwarf2_per_objfile->filenames_cache)
+  if (!dwarf2_per_objfile->per_bfd->filenames_cache)
     {
-      dwarf2_per_objfile->filenames_cache.emplace ();
+      dwarf2_per_objfile->per_bfd->filenames_cache.emplace ();
 
       htab_up visited (htab_create_alloc (10,
                                          htab_hash_pointer, htab_eq_pointer,
@@ -4716,9 +4837,9 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
         by any TU, so there's no need to scan TUs here.  We can
         ignore file names coming from already-expanded CUs.  */
 
-      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
        {
-         if (per_cu->v.quick->compunit_symtab)
+         if (dwarf2_per_objfile->symtab_set_p (per_cu))
            {
              void **slot = htab_find_slot (visited.get (),
                                            per_cu->v.quick->file_names,
@@ -4728,10 +4849,10 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
            }
        }
 
-      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
        {
          /* We only need to look at symtabs not already expanded.  */
-         if (per_cu->v.quick->compunit_symtab)
+         if (dwarf2_per_objfile->symtab_set_p (per_cu))
            continue;
 
          quick_file_names *file_data = dw2_get_file_names (per_cu);
@@ -4749,12 +4870,12 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
          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->per_bfd->filenames_cache->seen (filename);
            }
        }
     }
 
-  dwarf2_per_objfile->filenames_cache->traverse ([&] (const char *filename)
+  dwarf2_per_objfile->per_bfd->filenames_cache->traverse ([&] (const char *filename)
     {
       gdb::unique_xmalloc_ptr<char> this_real_name;
 
@@ -4777,6 +4898,7 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions =
   dw2_forget_cached_source_info,
   dw2_map_symtabs_matching_filename,
   dw2_lookup_symbol,
+  NULL,
   dw2_print_stats,
   dw2_dump,
   dw2_expand_symtabs_for_function,
@@ -4816,7 +4938,7 @@ read_debug_names_from_section (struct objfile *objfile,
 
   section->read (objfile);
 
-  map.dwarf5_byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+  map.dwarf5_byte_order = gdbarch_byte_order (objfile->arch ());
 
   const gdb_byte *addr = section->buffer;
 
@@ -4987,6 +5109,26 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
                                  dwarf2_section_info &section,
                                  bool is_dwz)
 {
+  if (!map.augmentation_is_gdb)
+    {
+    for (uint32_t i = 0; i < map.cu_count; ++i)
+      {
+       sect_offset sect_off
+         = (sect_offset) (extract_unsigned_integer
+                          (map.cu_table_reordered + i * map.offset_size,
+                           map.offset_size,
+                           map.dwarf5_byte_order));
+       /* We don't know the length of the CU, because the CU list in a
+          .debug_names index can be incomplete, so we can't use the start of
+          the next CU as end of this CU.  We create the CUs here with length 0,
+          and in cutu_reader::cutu_reader we'll fill in the actual length.  */
+       dwarf2_per_cu_data *per_cu
+         = create_cu_from_index_list (dwarf2_per_objfile, &section, is_dwz,
+                                      sect_off, 0);
+       dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
+      }
+    }
+
   sect_offset sect_off_prev;
   for (uint32_t i = 0; i <= map.cu_count; ++i)
     {
@@ -5007,7 +5149,7 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
          dwarf2_per_cu_data *per_cu
            = create_cu_from_index_list (dwarf2_per_objfile, &section, is_dwz,
                                         sect_off_prev, length);
-         dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+         dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
        }
       sect_off_prev = sect_off_next;
     }
@@ -5021,11 +5163,11 @@ create_cus_from_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
                             const mapped_debug_names &map,
                             const mapped_debug_names &dwz_map)
 {
-  gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
-  dwarf2_per_objfile->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
 
   create_cus_from_debug_names_list (dwarf2_per_objfile, map,
-                                   dwarf2_per_objfile->info,
+                                   dwarf2_per_objfile->per_bfd->info,
                                    false /* is_dwz */);
 
   if (dwz_map.cu_count == 0)
@@ -5048,7 +5190,7 @@ dwarf2_read_debug_names (struct dwarf2_per_objfile *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,
+                                     &dwarf2_per_objfile->per_bfd->debug_names,
                                      *map))
     return false;
 
@@ -5077,22 +5219,22 @@ dwarf2_read_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile)
     {
       /* We can only handle a single .debug_types when we have an
         index.  */
-      if (dwarf2_per_objfile->types.size () != 1)
+      if (dwarf2_per_objfile->per_bfd->types.size () != 1)
        return false;
 
-      dwarf2_section_info *section = &dwarf2_per_objfile->types[0];
+      dwarf2_section_info *section = &dwarf2_per_objfile->per_bfd->types[0];
 
       create_signatured_type_table_from_debug_names
-       (dwarf2_per_objfile, *map, section, &dwarf2_per_objfile->abbrev);
+       (dwarf2_per_objfile, *map, section, &dwarf2_per_objfile->per_bfd->abbrev);
     }
 
   create_addrmap_from_aranges (dwarf2_per_objfile,
-                              &dwarf2_per_objfile->debug_aranges);
+                              &dwarf2_per_objfile->per_bfd->debug_aranges);
 
-  dwarf2_per_objfile->debug_names_table = std::move (map);
-  dwarf2_per_objfile->using_index = 1;
-  dwarf2_per_objfile->quick_file_names_table =
-    create_quick_file_names_table (dwarf2_per_objfile->all_comp_units.size ());
+  dwarf2_per_objfile->per_bfd->debug_names_table = std::move (map);
+  dwarf2_per_objfile->per_bfd->using_index = 1;
+  dwarf2_per_objfile->per_bfd->quick_file_names_table =
+    create_quick_file_names_table (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
 
   return true;
 }
@@ -5317,6 +5459,18 @@ dw2_debug_names_iterator::next ()
          ull = read_unsigned_leb128 (abfd, m_addr, &bytes_read);
          m_addr += bytes_read;
          break;
+       case DW_FORM_ref4:
+         ull = read_4_bytes (abfd, m_addr);
+         m_addr += 4;
+         break;
+       case DW_FORM_ref8:
+         ull = read_8_bytes (abfd, m_addr);
+         m_addr += 8;
+         break;
+       case DW_FORM_ref_sig8:
+         ull = read_8_bytes (abfd, m_addr);
+         m_addr += 8;
+         break;
        default:
          complaint (_("Unsupported .debug_names form %s [in module %s]"),
                     dwarf_form_name (attr.form),
@@ -5327,7 +5481,7 @@ dw2_debug_names_iterator::next ()
        {
        case DW_IDX_compile_unit:
          /* Don't crash on bad data.  */
-         if (ull >= dwarf2_per_objfile->all_comp_units.size ())
+         if (ull >= dwarf2_per_objfile->per_bfd->all_comp_units.size ())
            {
              complaint (_(".debug_names entry has bad CU index %s"
                           " [in module %s]"),
@@ -5335,11 +5489,11 @@ dw2_debug_names_iterator::next ()
                         objfile_name (dwarf2_per_objfile->objfile));
              continue;
            }
-         per_cu = dwarf2_per_objfile->get_cutu (ull);
+         per_cu = dwarf2_per_objfile->per_bfd->get_cutu (ull);
          break;
        case DW_IDX_type_unit:
          /* Don't crash on bad data.  */
-         if (ull >= dwarf2_per_objfile->all_type_units.size ())
+         if (ull >= dwarf2_per_objfile->per_bfd->all_type_units.size ())
            {
              complaint (_(".debug_names entry has bad TU index %s"
                           " [in module %s]"),
@@ -5347,7 +5501,13 @@ dw2_debug_names_iterator::next ()
                         objfile_name (dwarf2_per_objfile->objfile));
              continue;
            }
-         per_cu = &dwarf2_per_objfile->get_tu (ull)->per_cu;
+         per_cu = &dwarf2_per_objfile->per_bfd->get_tu (ull)->per_cu;
+         break;
+       case DW_IDX_die_offset:
+         /* In a per-CU index (as opposed to a per-module index), index
+            entries without CU attribute implicitly refer to the single CU.  */
+         if (per_cu == NULL)
+           per_cu = dwarf2_per_objfile->per_bfd->get_cu (0);
          break;
        case DW_IDX_GNU_internal:
          if (!m_map.augmentation_is_gdb)
@@ -5363,7 +5523,7 @@ dw2_debug_names_iterator::next ()
     }
 
   /* Skip if already read in.  */
-  if (per_cu->v.quick->compunit_symtab)
+  if (dwarf2_per_objfile->symtab_set_p (per_cu))
     goto again;
 
   /* Check static vs global.  */
@@ -5480,7 +5640,7 @@ dw2_debug_names_lookup_symbol (struct objfile *objfile, block_enum block_index,
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  const auto &mapp = dwarf2_per_objfile->debug_names_table;
+  const auto &mapp = dwarf2_per_objfile->per_bfd->debug_names_table;
   if (!mapp)
     {
       /* index is NULL if OBJF_READNOW.  */
@@ -5495,7 +5655,8 @@ dw2_debug_names_lookup_symbol (struct objfile *objfile, block_enum block_index,
   while ((per_cu = iter.next ()) != NULL)
     {
       struct symbol *sym, *with_opaque = NULL;
-      struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, false);
+      compunit_symtab *stab
+       = dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
       const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
       const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
 
@@ -5530,9 +5691,9 @@ dw2_debug_names_dump (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  gdb_assert (dwarf2_per_objfile->using_index);
+  gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
   printf_filtered (".debug_names:");
-  if (dwarf2_per_objfile->debug_names_table)
+  if (dwarf2_per_objfile->per_bfd->debug_names_table)
     printf_filtered (" exists\n");
   else
     printf_filtered (" faked for \"readnow\"\n");
@@ -5546,16 +5707,16 @@ dw2_debug_names_expand_symtabs_for_function (struct objfile *objfile,
   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)
+  /* dwarf2_per_objfile->per_bfd->debug_names_table is NULL if OBJF_READNOW.  */
+  if (dwarf2_per_objfile->per_bfd->debug_names_table)
     {
-      const mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+      const mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
 
       dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name);
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
-       dw2_instantiate_symtab (per_cu, false);
+       dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
     }
 }
 
@@ -5571,10 +5732,10 @@ dw2_debug_names_map_matching_symbols
     = get_dwarf2_per_objfile (objfile);
 
   /* debug_names_table is NULL if OBJF_READNOW.  */
-  if (!dwarf2_per_objfile->debug_names_table)
+  if (!dwarf2_per_objfile->per_bfd->debug_names_table)
     return;
 
-  mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+  mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
   const block_enum block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
 
   const char *match_name = name.ada ().lookup_name ().c_str ();
@@ -5594,7 +5755,8 @@ dw2_debug_names_map_matching_symbols
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
-       dw2_expand_symtabs_matching_one (per_cu, nullptr, nullptr);
+       dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, nullptr,
+                                        nullptr);
       return true;
     });
 
@@ -5602,13 +5764,13 @@ dw2_debug_names_map_matching_symbols
      dw2_expand_symtabs_matching_symbol callback, but that skips CUs
      that have already been expanded.  Instead, this loop matches what
      the psymtab code does.  */
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
-      struct compunit_symtab *cust = per_cu->v.quick->compunit_symtab;
-      if (cust != nullptr)
+      compunit_symtab *symtab = dwarf2_per_objfile->get_symtab (per_cu);
+      if (symtab != nullptr)
        {
          const struct block *block
-           = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), block_kind);
+           = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (symtab), block_kind);
          if (!iterate_over_symbols_terminated (block, name,
                                                domain, callback))
            break;
@@ -5620,7 +5782,7 @@ 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,
+   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)
@@ -5629,14 +5791,26 @@ dw2_debug_names_expand_symtabs_matching
     = get_dwarf2_per_objfile (objfile);
 
   /* debug_names_table is NULL if OBJF_READNOW.  */
-  if (!dwarf2_per_objfile->debug_names_table)
+  if (!dwarf2_per_objfile->per_bfd->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;
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
+       {
+         QUIT;
+
+         dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+                                          file_matcher, expansion_notify);
+       }
+      return;
+    }
+
+  mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
 
-  dw2_expand_symtabs_matching_symbol (map, lookup_name,
+  dw2_expand_symtabs_matching_symbol (map, *lookup_name,
                                      symbol_matcher,
                                      kind, [&] (offset_type namei)
     {
@@ -5646,8 +5820,8 @@ dw2_debug_names_expand_symtabs_matching
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
-       dw2_expand_symtabs_matching_one (per_cu, file_matcher,
-                                        expansion_notify);
+       dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+                                        file_matcher, expansion_notify);
       return true;
     });
 }
@@ -5659,6 +5833,7 @@ const struct quick_symbol_functions dwarf2_debug_names_functions =
   dw2_forget_cached_source_info,
   dw2_map_symtabs_matching_filename,
   dw2_debug_names_lookup_symbol,
+  NULL,
   dw2_print_stats,
   dw2_debug_names_dump,
   dw2_debug_names_expand_symtabs_for_function,
@@ -5672,7 +5847,7 @@ const struct quick_symbol_functions dwarf2_debug_names_functions =
 };
 
 /* Get the content of the .gdb_index section of OBJ.  SECTION_OWNER should point
-   to either a dwarf2_per_objfile or dwz_file object.  */
+   to either a dwarf2_per_bfd or dwz_file object.  */
 
 template <typename T>
 static gdb::array_view<const gdb_byte>
@@ -5703,14 +5878,14 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
    DWARF2_OBJ.  */
 
 static gdb::array_view<const gdb_byte>
-get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj)
+get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
 {
   const bfd_build_id *build_id = build_id_bfd_get (obj->obfd);
   if (build_id == nullptr)
     return {};
 
   return global_index_cache.lookup_gdb_index (build_id,
-                                             &dwarf2_obj->index_cache_res);
+                                             &dwarf2_per_bfd->index_cache_res);
 }
 
 /* Same as the above, but for DWZ.  */
@@ -5739,19 +5914,20 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
      expanded anyway.  */
   if ((objfile->flags & OBJF_READNOW))
     {
-      dwarf2_per_objfile->using_index = 1;
+      dwarf2_per_objfile->per_bfd->using_index = 1;
       create_all_comp_units (dwarf2_per_objfile);
       create_all_type_units (dwarf2_per_objfile);
-      dwarf2_per_objfile->quick_file_names_table
+      dwarf2_per_objfile->per_bfd->quick_file_names_table
        = create_quick_file_names_table
-           (dwarf2_per_objfile->all_comp_units.size ());
+           (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
+      dwarf2_per_objfile->resize_symtabs ();
 
-      for (int i = 0; i < (dwarf2_per_objfile->all_comp_units.size ()
-                          + dwarf2_per_objfile->all_type_units.size ()); ++i)
+      for (int i = 0; i < (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+                          + dwarf2_per_objfile->per_bfd->all_type_units.size ()); ++i)
        {
-         dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+         dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
 
-         per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+         per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
                                            struct dwarf2_per_cu_quick_data);
        }
 
@@ -5765,14 +5941,16 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
   if (dwarf2_read_debug_names (dwarf2_per_objfile))
     {
       *index_kind = dw_index_kind::DEBUG_NAMES;
+      dwarf2_per_objfile->resize_symtabs ();
       return true;
     }
 
   if (dwarf2_read_gdb_index (dwarf2_per_objfile,
-                            get_gdb_index_contents_from_section<struct dwarf2_per_objfile>,
+                            get_gdb_index_contents_from_section<struct dwarf2_per_bfd>,
                             get_gdb_index_contents_from_section<dwz_file>))
     {
       *index_kind = dw_index_kind::GDB_INDEX;
+      dwarf2_per_objfile->resize_symtabs ();
       return true;
     }
 
@@ -5783,6 +5961,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
     {
       global_index_cache.hit ();
       *index_kind = dw_index_kind::GDB_INDEX;
+      dwarf2_per_objfile->resize_symtabs ();
       return true;
     }
 
@@ -5811,6 +5990,8 @@ dwarf2_build_psymtabs (struct objfile *objfile)
       dwarf2_build_psymtabs_hard (dwarf2_per_objfile);
       psymtabs.keep ();
 
+      dwarf2_per_objfile->resize_symtabs ();
+
       /* (maybe) store an index in the cache.  */
       global_index_cache.store (dwarf2_per_objfile);
     }
@@ -5831,23 +6012,16 @@ dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
 
-  cu->base_known = 0;
-  cu->base_address = 0;
+  cu->base_address.reset ();
 
   attr = dwarf2_attr (die, DW_AT_entry_pc, cu);
   if (attr != nullptr)
-    {
-      cu->base_address = attr->value_as_address ();
-      cu->base_known = 1;
-    }
+    cu->base_address = attr->value_as_address ();
   else
     {
       attr = dwarf2_attr (die, DW_AT_low_pc, cu);
       if (attr != nullptr)
-       {
-         cu->base_address = attr->value_as_address ();
-         cu->base_known = 1;
-       }
+       cu->base_address = attr->value_as_address ();
     }
 }
 
@@ -5863,7 +6037,7 @@ get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
   if (this_cu->is_dwz)
     abbrev = &dwarf2_get_dwz_file (dwarf2_per_objfile)->abbrev;
   else
-    abbrev = &dwarf2_per_objfile->abbrev;
+    abbrev = &dwarf2_per_objfile->per_bfd->abbrev;
 
   return abbrev;
 }
@@ -5907,32 +6081,46 @@ struct dwarf2_include_psymtab : public partial_symtab
 
   void read_symtab (struct objfile *objfile) override
   {
-    expand_psymtab (objfile);
+    /* It's an include file, no symbols to read for it.
+       Everything is in the includer symtab.  */
+
+    /* The expansion of a dwarf2_include_psymtab is just a trigger for
+       expansion of the includer psymtab.  We use the dependencies[0] field to
+       model the includer.  But if we go the regular route of calling
+       expand_psymtab here, and having expand_psymtab call expand_dependencies
+       to expand the includer, we'll only use expand_psymtab on the includer
+       (making it a non-toplevel psymtab), while if we expand the includer via
+       another path, we'll use read_symtab (making it a toplevel psymtab).
+       So, don't pretend a dwarf2_include_psymtab is an actual toplevel
+       psymtab, and trigger read_symtab on the includer here directly.  */
+    includer ()->read_symtab (objfile);
   }
 
   void expand_psymtab (struct objfile *objfile) override
   {
-    if (m_readin)
-      return;
-    /* It's an include file, no symbols to read for it.
-       Everything is in the parent symtab.  */
-    read_dependencies (objfile);
-    m_readin = true;
+    /* This is not called by read_symtab, and should not be called by any
+       expand_dependencies.  */
+    gdb_assert (false);
   }
 
-  bool readin_p () const override
+  bool readin_p (struct objfile *objfile) const override
   {
-    return m_readin;
+    return includer ()->readin_p (objfile);
   }
 
-  struct compunit_symtab *get_compunit_symtab () const override
+  compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override
   {
     return nullptr;
   }
 
 private:
-
-  bool m_readin = false;
+  partial_symtab *includer () const
+  {
+    /* An include psymtab has exactly one dependency: the psymtab that
+       includes it.  */
+    gdb_assert (this->number_of_dependencies == 1);
+    return this->dependencies[0];
+  }
 };
 
 /* Allocate a new partial symtab for file named NAME and mark this new
@@ -5945,10 +6133,7 @@ dwarf2_create_include_psymtab (const char *name, dwarf2_psymtab *pst,
   dwarf2_include_psymtab *subpst = new dwarf2_include_psymtab (name, objfile);
 
   if (!IS_ABSOLUTE_PATH (subpst->filename))
-    {
-      /* It shares objfile->objfile_obstack.  */
-      subpst->dirname = pst->dirname;
-    }
+    subpst->dirname = pst->dirname;
 
   subpst->dependencies = objfile->partial_symtabs->allocate_dependencies (1);
   subpst->dependencies[0] = pst;
@@ -6042,7 +6227,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
   abbrev_section = (dwo_file != NULL
                    ? &dwo_file->sections.abbrev
-                   : &dwarf2_per_objfile->abbrev);
+                   : &dwarf2_per_objfile->per_bfd->abbrev);
 
   if (dwarf_read_debug)
     fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
@@ -6106,7 +6291,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (dwo_file)
        {
          sig_type = NULL;
-         dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+         dwo_tu = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
                                   struct dwo_unit);
          dwo_tu->dwo_file = dwo_file;
          dwo_tu->signature = header.signature;
@@ -6120,8 +6305,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
          /* N.B.: type_offset is not usable if this type uses a DWO file.
             The real type_offset is in the DWO file.  */
          dwo_tu = NULL;
-         sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                                    struct signatured_type);
+         sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
          sig_type->signature = header.signature;
          sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
          sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
@@ -6201,30 +6385,30 @@ create_all_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
   htab_up types_htab;
 
   create_debug_type_hash_table (dwarf2_per_objfile, NULL,
-                               &dwarf2_per_objfile->info, types_htab,
+                               &dwarf2_per_objfile->per_bfd->info, types_htab,
                                rcuh_kind::COMPILE);
   create_debug_types_hash_table (dwarf2_per_objfile, NULL,
-                                dwarf2_per_objfile->types, types_htab);
+                                dwarf2_per_objfile->per_bfd->types, types_htab);
   if (types_htab == NULL)
     {
-      dwarf2_per_objfile->signatured_types = NULL;
+      dwarf2_per_objfile->per_bfd->signatured_types = NULL;
       return 0;
     }
 
-  dwarf2_per_objfile->signatured_types = std::move (types_htab);
+  dwarf2_per_objfile->per_bfd->signatured_types = std::move (types_htab);
 
-  gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
-  dwarf2_per_objfile->all_type_units.reserve
-    (htab_elements (dwarf2_per_objfile->signatured_types.get ()));
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_type_units.reserve
+    (htab_elements (dwarf2_per_objfile->per_bfd->signatured_types.get ()));
 
-  htab_traverse_noresize (dwarf2_per_objfile->signatured_types.get (),
+  htab_traverse_noresize (dwarf2_per_objfile->per_bfd->signatured_types.get (),
                          add_signatured_type_cu_to_table,
-                         &dwarf2_per_objfile->all_type_units);
+                         &dwarf2_per_objfile->per_bfd->all_type_units);
 
   return 1;
 }
 
-/* Add an entry for signature SIG to dwarf2_per_objfile->signatured_types.
+/* Add an entry for signature SIG to dwarf2_per_objfile->per_bfd->signatured_types.
    If SLOT is non-NULL, it is the entry to use in the hash table.
    Otherwise we find one.  */
 
@@ -6232,28 +6416,27 @@ static struct signatured_type *
 add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
               void **slot)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  if (dwarf2_per_objfile->per_bfd->all_type_units.size ()
+      == dwarf2_per_objfile->per_bfd->all_type_units.capacity ())
+    ++dwarf2_per_objfile->per_bfd->tu_stats.nr_all_type_units_reallocs;
 
-  if (dwarf2_per_objfile->all_type_units.size ()
-      == dwarf2_per_objfile->all_type_units.capacity ())
-    ++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
+  signatured_type *sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
 
-  signatured_type *sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                                             struct signatured_type);
+  dwarf2_per_objfile->resize_symtabs ();
 
-  dwarf2_per_objfile->all_type_units.push_back (sig_type);
+  dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
   sig_type->signature = sig;
   sig_type->per_cu.is_debug_types = 1;
-  if (dwarf2_per_objfile->using_index)
+  if (dwarf2_per_objfile->per_bfd->using_index)
     {
       sig_type->per_cu.v.quick =
-       OBSTACK_ZALLOC (&objfile->objfile_obstack,
+       OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
                        struct dwarf2_per_cu_quick_data);
     }
 
   if (slot == NULL)
     {
-      slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+      slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
                             sig_type, INSERT);
     }
   gdb_assert (*slot == NULL);
@@ -6270,13 +6453,15 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
                                  struct signatured_type *sig_entry,
                                  struct dwo_unit *dwo_entry)
 {
+  dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
+
   /* Make sure we're not clobbering something we don't expect to.  */
   gdb_assert (! sig_entry->per_cu.queued);
   gdb_assert (sig_entry->per_cu.cu == NULL);
-  if (dwarf2_per_objfile->using_index)
+  if (per_bfd->using_index)
     {
       gdb_assert (sig_entry->per_cu.v.quick != NULL);
-      gdb_assert (sig_entry->per_cu.v.quick->compunit_symtab == NULL);
+      gdb_assert (!dwarf2_per_objfile->symtab_set_p (&sig_entry->per_cu));
     }
   else
       gdb_assert (sig_entry->per_cu.v.psymtab == NULL);
@@ -6290,6 +6475,7 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
   sig_entry->per_cu.length = dwo_entry->length;
   sig_entry->per_cu.reading_dwo_directly = 1;
   sig_entry->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
+  sig_entry->per_cu.per_bfd = per_bfd;
   sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu;
   sig_entry->dwo_unit = dwo_entry;
 }
@@ -6309,19 +6495,18 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwo_file *dwo_file;
   struct dwo_unit find_dwo_entry, *dwo_entry;
   struct signatured_type find_sig_entry, *sig_entry;
   void **slot;
 
-  gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
+  gdb_assert (cu->dwo_unit && dwarf2_per_objfile->per_bfd->using_index);
 
   /* If TU skeletons have been removed then we may not have read in any
      TUs yet.  */
-  if (dwarf2_per_objfile->signatured_types == NULL)
-    dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+  if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+    dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
 
   /* We only ever need to read in one copy of a signatured type.
      Use the global signatured_types array to do our own comdat-folding
@@ -6330,7 +6515,7 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
      .gdb_index with this TU.  */
 
   find_sig_entry.signature = sig;
-  slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
                         &find_sig_entry, INSERT);
   sig_entry = (struct signatured_type *) *slot;
 
@@ -6376,23 +6561,22 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   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;
 
-  gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
+  gdb_assert (cu->dwo_unit && dwarf2_per_objfile->per_bfd->using_index);
   gdb_assert (dwp_file != NULL);
 
   /* If TU skeletons have been removed then we may not have read in any
      TUs yet.  */
-  if (dwarf2_per_objfile->signatured_types == NULL)
-    dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+  if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+    dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
 
   find_sig_entry.signature = sig;
-  slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
                         &find_sig_entry, INSERT);
   sig_entry = (struct signatured_type *) *slot;
 
@@ -6422,11 +6606,10 @@ 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;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   if (cu->dwo_unit
-      && dwarf2_per_objfile->using_index)
+      && dwarf2_per_objfile->per_bfd->using_index)
     {
       /* We're in a DWO/DWP file, and we're using .gdb_index.
         These cases require special processing.  */
@@ -6439,44 +6622,16 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
     {
       struct signatured_type find_entry, *entry;
 
-      if (dwarf2_per_objfile->signatured_types == NULL)
+      if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
        return NULL;
       find_entry.signature = sig;
       entry = ((struct signatured_type *)
-              htab_find (dwarf2_per_objfile->signatured_types.get (),
+              htab_find (dwarf2_per_objfile->per_bfd->signatured_types.get (),
                          &find_entry));
       return entry;
     }
 }
 
-/* Return the address base of the compile unit, which, if exists, is stored
-   either at the attribute DW_AT_GNU_addr_base, or DW_AT_addr_base.  */
-static gdb::optional<ULONGEST>
-lookup_addr_base (struct die_info *comp_unit_die)
-{
-  struct attribute *attr;
-  attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_addr_base);
-  if (attr == nullptr)
-    attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_GNU_addr_base);
-  if (attr == nullptr)
-    return gdb::optional<ULONGEST> ();
-  return DW_UNSND (attr);
-}
-
-/* Return range lists base of the compile unit, which, if exists, is stored
-   either at the attribute DW_AT_rnglists_base or DW_AT_GNU_ranges_base.  */
-static ULONGEST
-lookup_ranges_base (struct die_info *comp_unit_die)
-{
-  struct attribute *attr;
-  attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_rnglists_base);
-  if (attr == nullptr)
-    attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_GNU_ranges_base);
-  if (attr == nullptr)
-    return 0;
-  return DW_UNSND (attr);
-}
-
 /* Low level DIE reading support.  */
 
 /* Initialize a die_reader_specs struct from a dwarf2_cu struct.  */
@@ -6565,12 +6720,12 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
       ranges = dwarf2_attr (stub_comp_unit_die, DW_AT_ranges, cu);
       comp_dir = dwarf2_attr (stub_comp_unit_die, DW_AT_comp_dir, cu);
 
-      cu->addr_base = lookup_addr_base (stub_comp_unit_die);
+      cu->addr_base = stub_comp_unit_die->addr_base ();
 
       /* There should be a DW_AT_rnglists_base (DW_AT_GNU_ranges_base) attribute
         here (if needed). We need the value before we can process
         DW_AT_ranges.  */
-      cu->ranges_base = lookup_ranges_base (stub_comp_unit_die);
+      cu->ranges_base = stub_comp_unit_die->ranges_base ();
     }
   else if (stub_comp_dir != NULL)
     {
@@ -6746,7 +6901,8 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
    Read a TU directly from a DWO file, bypassing the stub.  */
 
 void
-cutu_reader::init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
+cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
+                                       dwarf2_per_objfile *per_objfile,
                                        int use_existing_cu)
 {
   struct signatured_type *sig_type;
@@ -6767,7 +6923,7 @@ cutu_reader::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);
-      m_new_cu.reset (new dwarf2_cu (this_cu));
+      m_new_cu.reset (new dwarf2_cu (this_cu, per_objfile));
     }
 
   /* A future optimization, if needed, would be to use an existing
@@ -6828,7 +6984,7 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
       /* Narrow down the scope of possibilities to have to understand.  */
       gdb_assert (this_cu->is_debug_types);
       gdb_assert (abbrev_table == NULL);
-      init_tu_and_read_dwo_dies (this_cu, use_existing_cu);
+      init_tu_and_read_dwo_dies (this_cu, dwarf2_per_objfile, use_existing_cu);
       return;
     }
 
@@ -6855,7 +7011,7 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
     {
       /* If !use_existing_cu, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
-      m_new_cu.reset (new dwarf2_cu (this_cu));
+      m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
       cu = m_new_cu.get ();
     }
 
@@ -6901,7 +7057,10 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
                                                    rcuh_kind::COMPILE);
 
          gdb_assert (this_cu->sect_off == cu->header.sect_off);
-         gdb_assert (this_cu->length == cu->header.get_length ());
+         if (this_cu->length == 0)
+           this_cu->length = cu->header.get_length ();
+         else
+           gdb_assert (this_cu->length == cu->header.get_length ());
          this_cu->dwarf_version = cu->header.version;
        }
     }
@@ -6994,8 +7153,8 @@ cutu_reader::keep ()
       struct dwarf2_per_objfile *dwarf2_per_objfile
        = m_this_cu->dwarf2_per_objfile;
       /* Link this CU into read_in_chain.  */
-      m_this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
-      dwarf2_per_objfile->read_in_chain = m_this_cu;
+      m_this_cu->cu->read_in_chain = dwarf2_per_objfile->per_bfd->read_in_chain;
+      dwarf2_per_objfile->per_bfd->read_in_chain = m_this_cu;
       /* The chain owns it now.  */
       m_new_cu.release ();
     }
@@ -7044,7 +7203,7 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
   /* This is cheap if the section is already read in.  */
   section->read (objfile);
 
-  m_new_cu.reset (new dwarf2_cu (this_cu));
+  m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
 
   begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
   info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
@@ -7128,20 +7287,20 @@ allocate_type_unit_groups_table ()
 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_objfile *dwarf2_per_objfile = cu->per_objfile;
+  dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
   struct dwarf2_per_cu_data *per_cu;
   struct type_unit_group *tu_group;
 
-  tu_group = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+  tu_group = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
                             struct type_unit_group);
   per_cu = &tu_group->per_cu;
   per_cu->dwarf2_per_objfile = dwarf2_per_objfile;
+  per_cu->per_bfd = per_bfd;
 
-  if (dwarf2_per_objfile->using_index)
+  if (per_bfd->using_index)
     {
-      per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+      per_cu->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
                                        struct dwarf2_per_cu_quick_data);
     }
   else
@@ -7173,16 +7332,15 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
+  struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
   struct type_unit_group *tu_group;
   void **slot;
   unsigned int line_offset;
   struct type_unit_group type_unit_group_for_lookup;
 
-  if (dwarf2_per_objfile->type_unit_groups == NULL)
-    dwarf2_per_objfile->type_unit_groups = allocate_type_unit_groups_table ();
+  if (dwarf2_per_objfile->per_bfd->type_unit_groups == NULL)
+    dwarf2_per_objfile->per_bfd->type_unit_groups = allocate_type_unit_groups_table ();
 
   /* Do we need to create a new group, or can we use an existing one?  */
 
@@ -7206,7 +7364,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
 
   type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit;
   type_unit_group_for_lookup.hash.line_sect_off = (sect_offset) line_offset;
-  slot = htab_find_slot (dwarf2_per_objfile->type_unit_groups.get (),
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->type_unit_groups.get (),
                         &type_unit_group_for_lookup, INSERT);
   if (*slot != NULL)
     {
@@ -7237,12 +7395,11 @@ create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
   struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
   dwarf2_psymtab *pst;
 
-  pst = new dwarf2_psymtab (name, objfile, 0);
+  pst = new dwarf2_psymtab (name, objfile, per_cu);
 
   pst->psymtabs_addrmap_supported = true;
 
   /* This is the glue that links PST into GDB's symbol API.  */
-  pst->per_cu_data = per_cu;
   per_cu->v.psymtab = pst;
 
   return pst;
@@ -7257,8 +7414,8 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
                                  enum language pretend_language)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct objfile *objfile = cu->per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
   CORE_ADDR baseaddr;
   CORE_ADDR best_lowpc = 0, best_highpc = 0;
@@ -7439,8 +7596,7 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader,
                            const gdb_byte *info_ptr,
                            struct die_info *type_unit_die)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = reader->cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = reader->cu->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;
@@ -7457,7 +7613,7 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader,
   if (! type_unit_die->has_children)
     return;
 
-  attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list);
+  attr = type_unit_die->attr (DW_AT_stmt_list);
   tu_group = get_type_unit_group (cu, attr);
 
   if (tu_group->tus == nullptr)
@@ -7506,7 +7662,7 @@ sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a,
    sharing 8K abbrev tables.
 
    The main purpose of this function is to support building the
-   dwarf2_per_objfile->type_unit_groups table.
+   dwarf2_per_objfile->per_bfd->type_unit_groups table.
    TUs typically share the DW_AT_stmt_list of the CU they came from, so we
    can collapse the search space by grouping them by stmt_list.
    The savings can be significant, in the same program from above the 200K TUs
@@ -7514,19 +7670,19 @@ sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a,
 
    FUNC is expected to call get_type_unit_group, which will create the
    struct type_unit_group if necessary and add it to
-   dwarf2_per_objfile->type_unit_groups.  */
+   dwarf2_per_objfile->per_bfd->type_unit_groups.  */
 
 static void
 build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+  struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
   abbrev_table_up abbrev_table;
   sect_offset abbrev_offset;
 
   /* It's up to the caller to not call us multiple times.  */
-  gdb_assert (dwarf2_per_objfile->type_unit_groups == NULL);
+  gdb_assert (dwarf2_per_objfile->per_bfd->type_unit_groups == NULL);
 
-  if (dwarf2_per_objfile->all_type_units.empty ())
+  if (dwarf2_per_objfile->per_bfd->all_type_units.empty ())
     return;
 
   /* TUs typically share abbrev tables, and there can be way more TUs than
@@ -7554,9 +7710,9 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
   /* Sort in a separate table to maintain the order of all_type_units
      for .gdb_index: TU indices directly index all_type_units.  */
   std::vector<tu_abbrev_offset> sorted_by_abbrev;
-  sorted_by_abbrev.reserve (dwarf2_per_objfile->all_type_units.size ());
+  sorted_by_abbrev.reserve (dwarf2_per_objfile->per_bfd->all_type_units.size ());
 
-  for (signatured_type *sig_type : dwarf2_per_objfile->all_type_units)
+  for (signatured_type *sig_type : dwarf2_per_objfile->per_bfd->all_type_units)
     sorted_by_abbrev.emplace_back
       (sig_type, read_abbrev_offset (dwarf2_per_objfile,
                                     sig_type->per_cu.section,
@@ -7576,7 +7732,7 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
          abbrev_offset = tu.abbrev_offset;
          abbrev_table =
            abbrev_table::read (dwarf2_per_objfile->objfile,
-                               &dwarf2_per_objfile->abbrev,
+                               &dwarf2_per_objfile->per_bfd->abbrev,
                                abbrev_offset);
          ++tu_stats->nr_uniq_abbrev_tables;
        }
@@ -7594,11 +7750,11 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 static void
 print_tu_stats (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+  struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
 
   fprintf_unfiltered (gdb_stdlog, "Type unit statistics:\n");
   fprintf_unfiltered (gdb_stdlog, "  %zu TUs\n",
-                     dwarf2_per_objfile->all_type_units.size ());
+                     dwarf2_per_objfile->per_bfd->all_type_units.size ());
   fprintf_unfiltered (gdb_stdlog, "  %d uniq abbrev tables\n",
                      tu_stats->nr_uniq_abbrev_tables);
   fprintf_unfiltered (gdb_stdlog, "  %d symtabs from stmt_list entries\n",
@@ -7669,11 +7825,11 @@ process_skeletonless_type_unit (void **slot, void *info)
 
   /* If this TU doesn't exist in the global table, add it and read it in.  */
 
-  if (dwarf2_per_objfile->signatured_types == NULL)
-    dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+  if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+    dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
 
   find_entry.signature = dwo_unit->signature;
-  slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
                         &find_entry, INSERT);
   /* If we've already seen this type there's nothing to do.  What's happening
      is we're doing our own version of comdat-folding here.  */
@@ -7718,9 +7874,9 @@ 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 (dwarf2_per_objfile) == NULL
-      && dwarf2_per_objfile->dwo_files != NULL)
+      && dwarf2_per_objfile->per_bfd->dwo_files != NULL)
     {
-      htab_traverse_noresize (dwarf2_per_objfile->dwo_files.get (),
+      htab_traverse_noresize (dwarf2_per_objfile->per_bfd->dwo_files.get (),
                              process_dwo_file_for_skeletonless_type_units,
                              dwarf2_per_objfile);
     }
@@ -7731,7 +7887,7 @@ process_skeletonless_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 static void
 set_partial_user (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       dwarf2_psymtab *pst = per_cu->v.psymtab;
 
@@ -7762,10 +7918,10 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
     }
 
   scoped_restore restore_reading_psyms
-    = make_scoped_restore (&dwarf2_per_objfile->reading_partial_symbols,
+    = make_scoped_restore (&dwarf2_per_objfile->per_bfd->reading_partial_symbols,
                           true);
 
-  dwarf2_per_objfile->info.read (objfile);
+  dwarf2_per_objfile->per_bfd->info.read (objfile);
 
   /* Any cached compilation units will be linked by the per-objfile
      read_in_chain.  Make sure to free them when we're done.  */
@@ -7783,16 +7939,21 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
     = make_scoped_restore (&objfile->partial_symtabs->psymtabs_addrmap,
                           addrmap_create_mutable (&temp_obstack));
 
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
-    process_psymtab_comp_unit (per_cu, false, language_minimal);
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
+    {
+      if (per_cu->v.psymtab != NULL)
+       /* In case a forward DW_TAG_imported_unit has read the CU already.  */
+       continue;
+      process_psymtab_comp_unit (per_cu, false, language_minimal);
+    }
 
   /* This has to wait until we read the CUs, we need the list of DWOs.  */
   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)
+  if (dwarf2_per_objfile->per_bfd->type_unit_groups != NULL)
     {
-      htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups.get (),
+      htab_traverse_noresize (dwarf2_per_objfile->per_bfd->type_unit_groups.get (),
                              build_type_psymtab_dependencies, dwarf2_per_objfile);
     }
 
@@ -7866,16 +8027,10 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
       /* Save the compilation unit for later lookup.  */
       if (cu_header.unit_type != DW_UT_type)
-       {
-         this_cu = XOBNEW (&objfile->objfile_obstack,
-                           struct dwarf2_per_cu_data);
-         memset (this_cu, 0, sizeof (*this_cu));
-       }
+       this_cu = dwarf2_per_objfile->per_bfd->allocate_per_cu ();
       else
        {
-         auto sig_type = XOBNEW (&objfile->objfile_obstack,
-                                 struct signatured_type);
-         memset (sig_type, 0, sizeof (*sig_type));
+         auto sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
          sig_type->signature = cu_header.signature;
          sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
          this_cu = &sig_type->per_cu;
@@ -7887,7 +8042,7 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
       this_cu->dwarf2_per_objfile = dwarf2_per_objfile;
       this_cu->section = section;
 
-      dwarf2_per_objfile->all_comp_units.push_back (this_cu);
+      dwarf2_per_objfile->per_bfd->all_comp_units.push_back (this_cu);
 
       info_ptr = info_ptr + this_cu->length;
     }
@@ -7899,9 +8054,9 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
 static void
 create_all_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
-  read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->info,
-                               &dwarf2_per_objfile->abbrev, 0);
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
+  read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->per_bfd->info,
+                               &dwarf2_per_objfile->per_bfd->abbrev, 0);
 
   dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
   if (dwz != NULL)
@@ -7951,7 +8106,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
            case DW_TAG_variable:
            case DW_TAG_typedef:
            case DW_TAG_union_type:
-             if (!pdi->is_declaration)
+             if (!pdi->is_declaration
+                 || (pdi->tag == DW_TAG_variable && pdi->is_external))
                {
                  add_partial_symbol (pdi, cu);
                }
@@ -7994,12 +8150,11 @@ 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->per_cu->dwarf2_per_objfile->objfile));
+                          objfile_name (cu->per_objfile->objfile));
                  }
 
                per_cu = dwarf2_find_containing_comp_unit
-                          (pdi->d.sect_off, pdi->is_dwz,
-                           cu->per_cu->dwarf2_per_objfile);
+                          (pdi->d.sect_off, pdi->is_dwz, cu->per_objfile);
 
                /* Go read the partial unit, if needed.  */
                if (per_cu->v.psymtab == NULL)
@@ -8169,10 +8324,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 dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR addr = 0;
   const char *actual_name = NULL;
   CORE_ADDR baseaddr;
@@ -8187,6 +8341,15 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
   if (actual_name == NULL)
     actual_name = pdi->name;
 
+  partial_symbol psymbol;
+  memset (&psymbol, 0, sizeof (psymbol));
+  psymbol.ginfo.set_language (cu->language, &objfile->objfile_obstack);
+  psymbol.ginfo.section = -1;
+
+  /* The code below indicates that the psymbol should be installed by
+     setting this.  */
+  gdb::optional<psymbol_placement> where;
+
   switch (pdi->tag)
     {
     case DW_TAG_inlined_subroutine:
@@ -8203,34 +8366,25 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
              But in Ada and Fortran, we want to be able to access nested
              procedures globally.  So all Ada and Fortran subprograms are
              stored in the global scope.  */
-         add_psymbol_to_list (actual_name,
-                              built_actual_name != NULL,
-                              VAR_DOMAIN, LOC_BLOCK,
-                              SECT_OFF_TEXT (objfile),
-                              psymbol_placement::GLOBAL,
-                              addr,
-                              cu->language, objfile);
+         where = psymbol_placement::GLOBAL;
        }
       else
-       {
-         add_psymbol_to_list (actual_name,
-                              built_actual_name != NULL,
-                              VAR_DOMAIN, LOC_BLOCK,
-                              SECT_OFF_TEXT (objfile),
-                              psymbol_placement::STATIC,
-                              addr, cu->language, objfile);
-       }
+       where = psymbol_placement::STATIC;
+
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_BLOCK;
+      psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+      psymbol.ginfo.value.address = addr;
 
       if (pdi->main_subprogram && actual_name != NULL)
        set_objfile_main_name (objfile, actual_name, cu->language);
       break;
     case DW_TAG_constant:
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
-                          -1, (pdi->is_external
-                               ? psymbol_placement::GLOBAL
-                               : psymbol_placement::STATIC),
-                          0, cu->language, objfile);
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_STATIC;
+      where = (pdi->is_external
+              ? psymbol_placement::GLOBAL
+              : psymbol_placement::STATIC);
       break;
     case DW_TAG_variable:
       if (pdi->d.locdesc)
@@ -8238,7 +8392,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
       if (pdi->d.locdesc
          && addr == 0
-         && !dwarf2_per_objfile->has_section_at_zero)
+         && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
        {
          /* A global or static variable may also have been stripped
             out by the linker if unused, in which case its address
@@ -8261,12 +8415,13 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
             table building.  */
 
          if (pdi->d.locdesc || pdi->has_type)
-           add_psymbol_to_list (actual_name,
-                                built_actual_name != NULL,
-                                VAR_DOMAIN, LOC_STATIC,
-                                SECT_OFF_TEXT (objfile),
-                                psymbol_placement::GLOBAL,
-                                addr, cu->language, objfile);
+           {
+             psymbol.domain = VAR_DOMAIN;
+             psymbol.aclass = LOC_STATIC;
+             psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+             psymbol.ginfo.value.address = addr;
+             where = psymbol_placement::GLOBAL;
+           }
        }
       else
        {
@@ -8277,42 +8432,37 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
          if (!has_loc && !pdi->has_const_value)
            return;
 
-         add_psymbol_to_list (actual_name,
-                              built_actual_name != NULL,
-                              VAR_DOMAIN, LOC_STATIC,
-                              SECT_OFF_TEXT (objfile),
-                              psymbol_placement::STATIC,
-                              has_loc ? addr : 0,
-                              cu->language, objfile);
+         psymbol.domain = VAR_DOMAIN;
+         psymbol.aclass = LOC_STATIC;
+         psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+         if (has_loc)
+           psymbol.ginfo.value.address = addr;
+         where = psymbol_placement::STATIC;
        }
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
     case DW_TAG_subrange_type:
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL,
-                          VAR_DOMAIN, LOC_TYPEDEF, -1,
-                          psymbol_placement::STATIC,
-                          0, cu->language, objfile);
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_TYPEDEF;
+      where = psymbol_placement::STATIC;
       break;
     case DW_TAG_imported_declaration:
     case DW_TAG_namespace:
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL,
-                          VAR_DOMAIN, LOC_TYPEDEF, -1,
-                          psymbol_placement::GLOBAL,
-                          0, cu->language, objfile);
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_TYPEDEF;
+      where = psymbol_placement::GLOBAL;
       break;
     case DW_TAG_module:
       /* With Fortran 77 there might be a "BLOCK DATA" module
          available without any name.  If so, we skip the module as it
          doesn't bring any value.  */
       if (actual_name != nullptr)
-       add_psymbol_to_list (actual_name,
-                            built_actual_name != NULL,
-                            MODULE_DOMAIN, LOC_TYPEDEF, -1,
-                            psymbol_placement::GLOBAL,
-                            0, cu->language, objfile);
+       {
+         psymbol.domain = MODULE_DOMAIN;
+         psymbol.aclass = LOC_TYPEDEF;
+         where = psymbol_placement::GLOBAL;
+       }
       break;
     case DW_TAG_class_type:
     case DW_TAG_interface_type:
@@ -8329,27 +8479,37 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
       /* NOTE: carlton/2003-10-07: See comment in new_symbol about
         static vs. global.  */
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL,
-                          STRUCT_DOMAIN, LOC_TYPEDEF, -1,
-                          cu->language == language_cplus
-                          ? psymbol_placement::GLOBAL
-                          : psymbol_placement::STATIC,
-                          0, cu->language, objfile);
-
+      psymbol.domain = STRUCT_DOMAIN;
+      psymbol.aclass = LOC_TYPEDEF;
+      where = (cu->language == language_cplus
+              ? psymbol_placement::GLOBAL
+              : psymbol_placement::STATIC);
       break;
     case DW_TAG_enumerator:
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL,
-                          VAR_DOMAIN, LOC_CONST, -1,
-                          cu->language == language_cplus
-                          ? psymbol_placement::GLOBAL
-                          : psymbol_placement::STATIC,
-                          0, cu->language, objfile);
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_CONST;
+      where = (cu->language == language_cplus
+              ? psymbol_placement::GLOBAL
+              : psymbol_placement::STATIC);
       break;
     default:
       break;
     }
+
+  if (where.has_value ())
+    {
+      if (built_actual_name != nullptr)
+       actual_name = objfile->intern (actual_name);
+      if (pdi->linkage_name == nullptr || cu->language == language_ada)
+       psymbol.ginfo.set_linkage_name (actual_name);
+      else
+       {
+         psymbol.ginfo.set_demangled_name (actual_name,
+                                           &objfile->objfile_obstack);
+         psymbol.ginfo.set_linkage_name (pdi->linkage_name);
+       }
+      add_psymbol_to_list (psymbol, *where, objfile);
+    }
 }
 
 /* Read a partial die corresponding to a namespace; also, add a symbol
@@ -8414,8 +8574,8 @@ add_partial_subprogram (struct partial_die_info *pdi,
             *highpc = pdi->highpc;
          if (set_addrmap)
            {
-             struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-             struct gdbarch *gdbarch = get_objfile_arch (objfile);
+             struct objfile *objfile = cu->per_objfile->objfile;
+             struct gdbarch *gdbarch = objfile->arch ();
              CORE_ADDR baseaddr;
              CORE_ADDR this_highpc;
              CORE_ADDR this_lowpc;
@@ -8508,7 +8668,7 @@ peek_die_abbrev (const die_reader_specs &reader,
                 const gdb_byte *info_ptr, unsigned int *bytes_read)
 {
   dwarf2_cu *cu = reader.cu;
-  bfd *abfd = cu->per_cu->dwarf2_per_objfile->objfile->obfd;
+  bfd *abfd = cu->per_objfile->objfile->obfd;
   unsigned int abbrev_number
     = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
 
@@ -8576,7 +8736,7 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
            complaint (_("ignoring absolute DW_AT_sibling"));
          else
            {
-             sect_offset off = dwarf2_get_ref_die_offset (&attr);
+             sect_offset off = attr.get_ref_die_offset ();
              const gdb_byte *sibling_ptr = buffer + to_underlying (off);
 
              if (sibling_ptr < info_ptr)
@@ -8668,6 +8828,7 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
        case DW_FORM_GNU_addr_index:
        case DW_FORM_GNU_str_index:
        case DW_FORM_rnglistx:
+       case DW_FORM_loclistx:
          info_ptr = safe_skip_leb128 (info_ptr, buffer_end);
          break;
        case DW_FORM_indirect:
@@ -8723,7 +8884,8 @@ dwarf2_psymtab::read_symtab (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  gdb_assert (!readin);
+  gdb_assert (!dwarf2_per_objfile->symtab_set_p (per_cu_data));
+
   /* 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
@@ -8733,8 +8895,8 @@ dwarf2_psymtab::read_symtab (struct objfile *objfile)
       struct dwarf2_per_objfile *dpo_backlink
        = get_dwarf2_per_objfile (objfile->separate_debug_objfile_backlink);
 
-      dwarf2_per_objfile->has_section_at_zero
-       = dpo_backlink->has_section_at_zero;
+      dwarf2_per_objfile->per_bfd->has_section_at_zero
+       = dpo_backlink->per_bfd->has_section_at_zero;
     }
 
   expand_psymtab (objfile);
@@ -8751,7 +8913,7 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
                 enum language pretend_language)
 {
   per_cu->queued = 1;
-  per_cu->dwarf2_per_objfile->queue.emplace (per_cu, pretend_language);
+  per_cu->per_bfd->queue.emplace (per_cu, pretend_language);
 }
 
 /* If PER_CU is not yet queued, add it to the queue.
@@ -8771,7 +8933,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 (per_cu->dwarf2_per_objfile->reading_partial_symbols)
+  if (per_cu->per_bfd->reading_partial_symbols)
     {
       if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
        return 1;
@@ -8815,13 +8977,11 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   /* The queue starts out with one item, but following a DIE reference
      may load a new CU, adding it to the end of the queue.  */
-  while (!dwarf2_per_objfile->queue.empty ())
+  while (!dwarf2_per_objfile->per_bfd->queue.empty ())
     {
-      dwarf2_queue_item &item = dwarf2_per_objfile->queue.front ();
+      dwarf2_queue_item &item = dwarf2_per_objfile->per_bfd->queue.front ();
 
-      if ((dwarf2_per_objfile->using_index
-          ? !item.per_cu->v.quick->compunit_symtab
-          : (item.per_cu->v.psymtab && !item.per_cu->v.psymtab->readin))
+      if (!dwarf2_per_objfile->symtab_set_p (item.per_cu)
          /* Skip dummy CUs.  */
          && item.per_cu->cu != NULL)
        {
@@ -8861,7 +9021,7 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
        }
 
       item.per_cu->queued = 0;
-      dwarf2_per_objfile->queue.pop ();
+      dwarf2_per_objfile->per_bfd->queue.pop ();
     }
 
   if (dwarf_read_debug)
@@ -8876,13 +9036,31 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 void
 dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
 {
-  if (readin)
-    return;
+  gdb_assert (!readin_p (objfile));
+
+  expand_dependencies (objfile);
 
-  read_dependencies (objfile);
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  dw2_do_instantiate_symtab (per_cu_data, per_objfile, false);
+  gdb_assert (get_compunit_symtab (objfile) != nullptr);
+}
+
+/* See psympriv.h.  */
+
+bool
+dwarf2_psymtab::readin_p (struct objfile *objfile) const
+{
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  return per_objfile->symtab_set_p (per_cu_data);
+}
 
-  dw2_do_instantiate_symtab (per_cu_data, false);
-  gdb_assert (get_compunit_symtab () != nullptr);
+/* See psympriv.h.  */
+
+compunit_symtab *
+dwarf2_psymtab::get_compunit_symtab (struct objfile *objfile) const
+{
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  return per_objfile->get_symtab (per_cu_data);
 }
 
 /* Trivial hash function for die_info: the hash value of a DIE
@@ -9071,8 +9249,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
                package_name = std::move (this_package_name);
              else
                {
-                 struct objfile *objfile
-                   = cu->per_cu->dwarf2_per_objfile->objfile;
+                 struct objfile *objfile = cu->per_objfile->objfile;
                  if (strcmp (package_name.get (), this_package_name.get ()) != 0)
                    complaint (_("Symtab %s has objects from two different Go packages: %s and %s"),
                               (symbol_symtab (sym) != NULL
@@ -9087,13 +9264,13 @@ fixup_go_packaging (struct dwarf2_cu *cu)
 
   if (package_name != NULL)
     {
-      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+      struct objfile *objfile = cu->per_objfile->objfile;
       const char *saved_package_name = objfile->intern (package_name.get ());
       struct type *type = init_type (objfile, TYPE_CODE_MODULE, 0,
                                     saved_package_name);
       struct symbol *sym;
 
-      sym = allocate_symbol (objfile);
+      sym = new (&objfile->objfile_obstack) symbol;
       sym->set_language (language_go, &objfile->objfile_obstack);
       sym->compute_and_set_names (saved_package_name, false, objfile->per_bfd);
       /* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
@@ -9115,37 +9292,72 @@ rust_fully_qualify (struct obstack *obstack, const char *p1, const char *p2)
   return obconcat (obstack, p1, "::", p2, (char *) NULL);
 }
 
-/* A helper that allocates a struct discriminant_info to attach to a
-   union type.  */
+/* A helper that allocates a variant part to attach to a Rust enum
+   type.  OBSTACK is where the results should be allocated.  TYPE is
+   the type we're processing.  DISCRIMINANT_INDEX is the index of the
+   discriminant.  It must be the index of one of the fields of TYPE.
+   DEFAULT_INDEX is the index of the default field; or -1 if there is
+   no default.  RANGES is indexed by "effective" field number (the
+   field index, but omitting the discriminant and default fields) and
+   must hold the discriminant values used by the variants.  Note that
+   RANGES must have a lifetime at least as long as OBSTACK -- either
+   already allocated on it, or static.  */
 
-static struct discriminant_info *
-alloc_discriminant_info (struct type *type, int discriminant_index,
-                        int default_index)
-{
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
-  gdb_assert (discriminant_index == -1
-             || (discriminant_index >= 0
-                 && discriminant_index < TYPE_NFIELDS (type)));
+static void
+alloc_rust_variant (struct obstack *obstack, struct type *type,
+                   int discriminant_index, int default_index,
+                   gdb::array_view<discriminant_range> ranges)
+{
+  /* When DISCRIMINANT_INDEX == -1, we have a univariant enum.  Those
+     must be handled by the caller.  */
+  gdb_assert (discriminant_index >= 0
+             && discriminant_index < type->num_fields ());
   gdb_assert (default_index == -1
-             || (default_index >= 0 && default_index < TYPE_NFIELDS (type)));
+             || (default_index >= 0 && default_index < type->num_fields ()));
 
-  TYPE_FLAG_DISCRIMINATED_UNION (type) = 1;
+  /* We have one variant for each non-discriminant field.  */
+  int n_variants = type->num_fields () - 1;
+
+  variant *variants = new (obstack) variant[n_variants];
+  int var_idx = 0;
+  int range_idx = 0;
+  for (int i = 0; i < type->num_fields (); ++i)
+    {
+      if (i == discriminant_index)
+       continue;
 
-  struct discriminant_info *disc
-    = ((struct discriminant_info *)
-       TYPE_ZALLOC (type,
-                   offsetof (struct discriminant_info, discriminants)
-                   + TYPE_NFIELDS (type) * sizeof (disc->discriminants[0])));
-  disc->default_index = default_index;
-  disc->discriminant_index = discriminant_index;
+      variants[var_idx].first_field = i;
+      variants[var_idx].last_field = i + 1;
 
-  struct dynamic_prop prop;
-  prop.kind = PROP_UNDEFINED;
-  prop.data.baton = disc;
+      /* The default field does not need a range, but other fields do.
+        We skipped the discriminant above.  */
+      if (i != default_index)
+       {
+         variants[var_idx].discriminants = ranges.slice (range_idx, 1);
+         ++range_idx;
+       }
 
-  add_dyn_prop (DYN_PROP_DISCRIMINATED, prop, type);
+      ++var_idx;
+    }
+
+  gdb_assert (range_idx == ranges.size ());
+  gdb_assert (var_idx == n_variants);
+
+  variant_part *part = new (obstack) variant_part;
+  part->discriminant_index = discriminant_index;
+  part->is_unsigned = TYPE_UNSIGNED (TYPE_FIELD_TYPE (type,
+                                                     discriminant_index));
+  part->variants = gdb::array_view<variant> (variants, n_variants);
+
+  void *storage = obstack_alloc (obstack, sizeof (gdb::array_view<variant_part>));
+  gdb::array_view<variant_part> *prop_value
+    = new (storage) gdb::array_view<variant_part> (part, 1);
 
-  return disc;
+  struct dynamic_prop prop;
+  prop.kind = PROP_VARIANT_PARTS;
+  prop.data.variant_parts = prop_value;
+
+  type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
 }
 
 /* Some versions of rustc emitted enums in an unusual way.
@@ -9171,14 +9383,14 @@ alloc_discriminant_info (struct type *type, int discriminant_index,
 static void
 quirk_rust_enum (struct type *type, struct objfile *objfile)
 {
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
+  gdb_assert (type->code () == TYPE_CODE_UNION);
 
   /* We don't need to deal with empty enums.  */
-  if (TYPE_NFIELDS (type) == 0)
+  if (type->num_fields () == 0)
     return;
 
 #define RUST_ENUM_PREFIX "RUST$ENCODED$ENUM$"
-  if (TYPE_NFIELDS (type) == 1
+  if (type->num_fields () == 1
       && startswith (TYPE_FIELD_NAME (type, 0), RUST_ENUM_PREFIX))
     {
       const char *name = TYPE_FIELD_NAME (type, 0) + strlen (RUST_ENUM_PREFIX);
@@ -9193,7 +9405,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
          unsigned long index = strtoul (name, &tail, 10);
          name = tail;
          if (*name != '$'
-             || index >= TYPE_NFIELDS (field_type)
+             || index >= field_type->num_fields ()
              || (TYPE_FIELD_LOC_KIND (field_type, index)
                  != FIELD_LOC_KIND_BITPOS))
            {
@@ -9209,103 +9421,74 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
          field_type = TYPE_FIELD_TYPE (field_type, index);
        }
 
-      /* Make a union to hold the variants.  */
-      struct type *union_type = alloc_type (objfile);
-      TYPE_CODE (union_type) = TYPE_CODE_UNION;
-      TYPE_NFIELDS (union_type) = 3;
-      TYPE_FIELDS (union_type)
-       = (struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field));
-      TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
-      set_type_align (union_type, TYPE_RAW_ALIGN (type));
-
-      /* Put the discriminant must at index 0.  */
-      TYPE_FIELD_TYPE (union_type, 0) = field_type;
-      TYPE_FIELD_ARTIFICIAL (union_type, 0) = 1;
-      TYPE_FIELD_NAME (union_type, 0) = "<<discriminant>>";
-      SET_FIELD_BITPOS (TYPE_FIELD (union_type, 0), bit_offset);
+      /* Smash this type to be a structure type.  We have to do this
+        because the type has already been recorded.  */
+      type->set_code (TYPE_CODE_STRUCT);
+      type->set_num_fields (3);
+      /* Save the field we care about.  */
+      struct field saved_field = type->field (0);
+      type->set_fields
+       ((struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field)));
+
+      /* Put the discriminant at index 0.  */
+      TYPE_FIELD_TYPE (type, 0) = field_type;
+      TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
+      TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
+      SET_FIELD_BITPOS (type->field (0), bit_offset);
 
       /* The order of fields doesn't really matter, so put the real
         field at index 1 and the data-less field at index 2.  */
-      struct discriminant_info *disc
-       = alloc_discriminant_info (union_type, 0, 1);
-      TYPE_FIELD (union_type, 1) = TYPE_FIELD (type, 0);
-      TYPE_FIELD_NAME (union_type, 1)
-       = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (union_type, 1)));
-      TYPE_NAME (TYPE_FIELD_TYPE (union_type, 1))
-       = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
-                             TYPE_FIELD_NAME (union_type, 1));
+      type->field (1) = saved_field;
+      TYPE_FIELD_NAME (type, 1)
+       = rust_last_path_segment (TYPE_FIELD_TYPE (type, 1)->name ());
+      TYPE_FIELD_TYPE (type, 1)->set_name
+       (rust_fully_qualify (&objfile->objfile_obstack, type->name (),
+                            TYPE_FIELD_NAME (type, 1)));
 
       const char *dataless_name
-       = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
+       = rust_fully_qualify (&objfile->objfile_obstack, type->name (),
                              name);
       struct type *dataless_type = init_type (objfile, TYPE_CODE_VOID, 0,
                                              dataless_name);
-      TYPE_FIELD_TYPE (union_type, 2) = dataless_type;
+      TYPE_FIELD_TYPE (type, 2) = dataless_type;
       /* NAME points into the original discriminant name, which
         already has the correct lifetime.  */
-      TYPE_FIELD_NAME (union_type, 2) = name;
-      SET_FIELD_BITPOS (TYPE_FIELD (union_type, 2), 0);
-      disc->discriminants[2] = 0;
-
-      /* Smash this type to be a structure type.  We have to do this
-        because the type has already been recorded.  */
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
-      TYPE_NFIELDS (type) = 1;
-      TYPE_FIELDS (type)
-       = (struct field *) TYPE_ZALLOC (type, sizeof (struct field));
+      TYPE_FIELD_NAME (type, 2) = name;
+      SET_FIELD_BITPOS (type->field (2), 0);
 
-      /* Install the variant part.  */
-      TYPE_FIELD_TYPE (type, 0) = union_type;
-      SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
-      TYPE_FIELD_NAME (type, 0) = "<<variants>>";
+      /* Indicate that this is a variant type.  */
+      static discriminant_range ranges[1] = { { 0, 0 } };
+      alloc_rust_variant (&objfile->objfile_obstack, type, 0, 1, ranges);
     }
   /* A union with a single anonymous field is probably an old-style
      univariant enum.  */
-  else if (TYPE_NFIELDS (type) == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
+  else if (type->num_fields () == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
     {
       /* Smash this type to be a structure type.  We have to do this
         because the type has already been recorded.  */
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      type->set_code (TYPE_CODE_STRUCT);
 
-      /* Make a union to hold the variants.  */
-      struct type *union_type = alloc_type (objfile);
-      TYPE_CODE (union_type) = TYPE_CODE_UNION;
-      TYPE_NFIELDS (union_type) = TYPE_NFIELDS (type);
-      TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
-      set_type_align (union_type, TYPE_RAW_ALIGN (type));
-      TYPE_FIELDS (union_type) = TYPE_FIELDS (type);
-
-      struct type *field_type = TYPE_FIELD_TYPE (union_type, 0);
+      struct type *field_type = TYPE_FIELD_TYPE (type, 0);
       const char *variant_name
-       = rust_last_path_segment (TYPE_NAME (field_type));
-      TYPE_FIELD_NAME (union_type, 0) = variant_name;
-      TYPE_NAME (field_type)
-       = rust_fully_qualify (&objfile->objfile_obstack,
-                             TYPE_NAME (type), variant_name);
-
-      /* Install the union in the outer struct type.  */
-      TYPE_NFIELDS (type) = 1;
-      TYPE_FIELDS (type)
-       = (struct field *) TYPE_ZALLOC (union_type, sizeof (struct field));
-      TYPE_FIELD_TYPE (type, 0) = union_type;
-      TYPE_FIELD_NAME (type, 0) = "<<variants>>";
-      SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
-
-      alloc_discriminant_info (union_type, -1, 0);
+       = rust_last_path_segment (field_type->name ());
+      TYPE_FIELD_NAME (type, 0) = variant_name;
+      field_type->set_name
+       (rust_fully_qualify (&objfile->objfile_obstack,
+                            type->name (), variant_name));
     }
   else
     {
       struct type *disr_type = nullptr;
-      for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+      for (int i = 0; i < type->num_fields (); ++i)
        {
          disr_type = TYPE_FIELD_TYPE (type, i);
 
-         if (TYPE_CODE (disr_type) != TYPE_CODE_STRUCT)
+         if (disr_type->code () != TYPE_CODE_STRUCT)
            {
              /* All fields of a true enum will be structs.  */
              return;
            }
-         else if (TYPE_NFIELDS (disr_type) == 0)
+         else if (disr_type->num_fields () == 0)
            {
              /* Could be data-less variant, so keep going.  */
              disr_type = nullptr;
@@ -9330,41 +9513,28 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
 
       /* Smash this type to be a structure type.  We have to do this
         because the type has already been recorded.  */
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
-
-      /* Make a union to hold the variants.  */
-      struct field *disr_field = &TYPE_FIELD (disr_type, 0);
-      struct type *union_type = alloc_type (objfile);
-      TYPE_CODE (union_type) = TYPE_CODE_UNION;
-      TYPE_NFIELDS (union_type) = 1 + TYPE_NFIELDS (type);
-      TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
-      set_type_align (union_type, TYPE_RAW_ALIGN (type));
-      TYPE_FIELDS (union_type)
-       = (struct field *) TYPE_ZALLOC (union_type,
-                                       (TYPE_NFIELDS (union_type)
-                                        * sizeof (struct field)));
-
-      memcpy (TYPE_FIELDS (union_type) + 1, TYPE_FIELDS (type),
-             TYPE_NFIELDS (type) * sizeof (struct field));
+      type->set_code (TYPE_CODE_STRUCT);
+
+      /* Make space for the discriminant field.  */
+      struct field *disr_field = &disr_type->field (0);
+      field *new_fields
+       = (struct field *) TYPE_ZALLOC (type, ((type->num_fields () + 1)
+                                              * sizeof (struct field)));
+      memcpy (new_fields + 1, type->fields (),
+             type->num_fields () * sizeof (struct field));
+      type->set_fields (new_fields);
+      type->set_num_fields (type->num_fields () + 1);
 
       /* Install the discriminant at index 0 in the union.  */
-      TYPE_FIELD (union_type, 0) = *disr_field;
-      TYPE_FIELD_ARTIFICIAL (union_type, 0) = 1;
-      TYPE_FIELD_NAME (union_type, 0) = "<<discriminant>>";
-
-      /* Install the union in the outer struct type.  */
-      TYPE_FIELD_TYPE (type, 0) = union_type;
-      TYPE_FIELD_NAME (type, 0) = "<<variants>>";
-      TYPE_NFIELDS (type) = 1;
-
-      /* Set the size and offset of the union type.  */
-      SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
+      type->field (0) = *disr_field;
+      TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
+      TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
 
       /* We need a way to find the correct discriminant given a
         variant name.  For convenience we build a map here.  */
       struct type *enum_type = FIELD_TYPE (*disr_field);
       std::unordered_map<std::string, ULONGEST> discriminant_map;
-      for (int i = 0; i < TYPE_NFIELDS (enum_type); ++i)
+      for (int i = 0; i < enum_type->num_fields (); ++i)
        {
          if (TYPE_FIELD_LOC_KIND (enum_type, i) == FIELD_LOC_KIND_ENUMVAL)
            {
@@ -9374,9 +9544,13 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
            }
        }
 
-      int n_fields = TYPE_NFIELDS (union_type);
-      struct discriminant_info *disc
-       = alloc_discriminant_info (union_type, 0, -1);
+      int n_fields = type->num_fields ();
+      /* We don't need a range entry for the discriminant, but we do
+        need one for every other field, as there is no default
+        variant.  */
+      discriminant_range *ranges = XOBNEWVEC (&objfile->objfile_obstack,
+                                             discriminant_range,
+                                             n_fields - 1);
       /* Skip the discriminant here.  */
       for (int i = 1; i < n_fields; ++i)
        {
@@ -9384,25 +9558,32 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
             That name can be used to look up the correct
             discriminant.  */
          const char *variant_name
-           = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (union_type,
-                                                                 i)));
+           = rust_last_path_segment (TYPE_FIELD_TYPE (type, i)->name ());
 
          auto iter = discriminant_map.find (variant_name);
          if (iter != discriminant_map.end ())
-           disc->discriminants[i] = iter->second;
+           {
+             ranges[i].low = iter->second;
+             ranges[i].high = iter->second;
+           }
 
          /* Remove the discriminant field, if it exists.  */
-         struct type *sub_type = TYPE_FIELD_TYPE (union_type, i);
-         if (TYPE_NFIELDS (sub_type) > 0)
+         struct type *sub_type = TYPE_FIELD_TYPE (type, i);
+         if (sub_type->num_fields () > 0)
            {
-             --TYPE_NFIELDS (sub_type);
-             ++TYPE_FIELDS (sub_type);
+             sub_type->set_num_fields (sub_type->num_fields () - 1);
+             sub_type->set_fields (sub_type->fields () + 1);
            }
-         TYPE_FIELD_NAME (union_type, i) = variant_name;
-         TYPE_NAME (sub_type)
-           rust_fully_qualify (&objfile->objfile_obstack,
-                                 TYPE_NAME (type), variant_name);
+         TYPE_FIELD_NAME (type, i) = variant_name;
+         sub_type->set_name
+           (rust_fully_qualify (&objfile->objfile_obstack,
+                                type->name (), variant_name));
        }
+
+      /* Indicate that this is a variant type.  */
+      alloc_rust_variant (&objfile->objfile_obstack, type, 0, 1,
+                         gdb::array_view<discriminant_range> (ranges,
+                                                              n_fields - 1));
     }
 }
 
@@ -9413,22 +9594,11 @@ rust_union_quirks (struct dwarf2_cu *cu)
 {
   gdb_assert (cu->language == language_rust);
   for (type *type_ : cu->rust_unions)
-    quirk_rust_enum (type_, cu->per_cu->dwarf2_per_objfile->objfile);
+    quirk_rust_enum (type_, cu->per_objfile->objfile);
   /* We don't need this any more.  */
   cu->rust_unions.clear ();
 }
 
-/* Return the symtab for PER_CU.  This works properly regardless of
-   whether we're using the index or psymtabs.  */
-
-static struct compunit_symtab *
-get_compunit_symtab (struct dwarf2_per_cu_data *per_cu)
-{
-  return (per_cu->dwarf2_per_objfile->using_index
-         ? per_cu->v.quick->compunit_symtab
-         : per_cu->v.psymtab->compunit_symtab);
-}
-
 /* A helper function for computing the list of all symbol tables
    included by PER_CU.  */
 
@@ -9438,10 +9608,7 @@ recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
                                struct dwarf2_per_cu_data *per_cu,
                                struct compunit_symtab *immediate_parent)
 {
-  void **slot;
-  struct compunit_symtab *cust;
-
-  slot = htab_find_slot (all_children, per_cu, INSERT);
+  void **slot = htab_find_slot (all_children, per_cu, INSERT);
   if (*slot != NULL)
     {
       /* This inclusion and its children have been processed.  */
@@ -9449,8 +9616,9 @@ recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
     }
 
   *slot = per_cu;
+
   /* Only add a CU if it has a symbol table.  */
-  cust = get_compunit_symtab (per_cu);
+  compunit_symtab *cust = per_cu->dwarf2_per_objfile->get_symtab (per_cu);
   if (cust != NULL)
     {
       /* If this is a type unit only add its symbol table if we haven't
@@ -9495,7 +9663,7 @@ compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
       int len;
       std::vector<compunit_symtab *> result_symtabs;
       htab_t all_children, all_type_symtabs;
-      struct compunit_symtab *cust = get_compunit_symtab (per_cu);
+      compunit_symtab *cust = per_cu->dwarf2_per_objfile->get_symtab (per_cu);
 
       /* If we don't have a symtab, we can just skip this case.  */
       if (cust == NULL)
@@ -9532,13 +9700,13 @@ compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
 static void
 process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  for (dwarf2_per_cu_data *iter : dwarf2_per_objfile->just_read_cus)
+  for (dwarf2_per_cu_data *iter : dwarf2_per_objfile->per_bfd->just_read_cus)
     {
       if (! iter->is_debug_types)
        compute_compunit_symtab_includes (iter);
     }
 
-  dwarf2_per_objfile->just_read_cus.clear ();
+  dwarf2_per_objfile->per_bfd->just_read_cus.clear ();
 }
 
 /* Generate full symbol information for PER_CU, whose DIEs have
@@ -9551,7 +9719,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
   struct dwarf2_cu *cu = per_cu->cu;
   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);
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc, highpc;
   struct compunit_symtab *cust;
   CORE_ADDR baseaddr;
@@ -9632,17 +9800,10 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
       cust->call_site_htab = cu->call_site_htab;
     }
 
-  if (dwarf2_per_objfile->using_index)
-    per_cu->v.quick->compunit_symtab = cust;
-  else
-    {
-      dwarf2_psymtab *pst = per_cu->v.psymtab;
-      pst->compunit_symtab = cust;
-      pst->readin = true;
-    }
+  dwarf2_per_objfile->set_symtab (per_cu, cust);
 
   /* Push it for inclusion processing later.  */
-  dwarf2_per_objfile->just_read_cus.push_back (per_cu);
+  dwarf2_per_objfile->per_bfd->just_read_cus.push_back (per_cu);
 
   /* Not needed any more.  */
   cu->reset_builder ();
@@ -9712,14 +9873,7 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
       cust = sig_type->type_unit_group->compunit_symtab;
     }
 
-  if (dwarf2_per_objfile->using_index)
-    per_cu->v.quick->compunit_symtab = cust;
-  else
-    {
-      dwarf2_psymtab *pst = per_cu->v.psymtab;
-      pst->compunit_symtab = cust;
-      pst->readin = true;
-    }
+  dwarf2_per_objfile->set_symtab (per_cu, cust);
 
   /* Not needed any more.  */
   cu->reset_builder ();
@@ -9737,17 +9891,16 @@ 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->per_cu->dwarf2_per_objfile->objfile));
+            objfile_name (cu->per_objfile->objfile));
     }
 
   attr = dwarf2_attr (die, DW_AT_import, cu);
   if (attr != NULL)
     {
-      sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+      sect_offset sect_off = attr->get_ref_die_offset ();
       bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
       dwarf2_per_cu_data *per_cu
-       = dwarf2_find_containing_comp_unit (sect_off, is_dwz,
-                                           cu->per_cu->dwarf2_per_objfile);
+       = dwarf2_find_containing_comp_unit (sect_off, is_dwz, cu->per_objfile);
 
       /* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
         into another compilation unit, at root level.  Regard this as a hint,
@@ -9996,6 +10149,12 @@ dw2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
   if (linkage_name == NULL)
     linkage_name = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu);
 
+  /* rustc emits invalid values for DW_AT_linkage_name.  Ignore these.
+     See https://github.com/rust-lang/rust/issues/32925.  */
+  if (cu->language == language_rust && linkage_name != NULL
+      && strchr (linkage_name, '{') != NULL)
+    linkage_name = NULL;
+
   return linkage_name;
 }
 
@@ -10011,14 +10170,15 @@ dw2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
    For Ada, return the DIE's linkage name rather than the fully qualified
    name.  PHYSNAME is ignored..
 
-   The result is allocated on the objfile_obstack and canonicalized.  */
+   The result is allocated on the objfile->per_bfd's obstack and
+   canonicalized.  */
 
 static const char *
 dwarf2_compute_name (const char *name,
                     struct die_info *die, struct dwarf2_cu *cu,
                     int physname)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
 
   if (name == NULL)
     name = dwarf2_name (die, cu);
@@ -10208,9 +10368,9 @@ dwarf2_compute_name (const char *name,
                     marks unnamed (and thus unused) parameters as
                     artificial; there is no way to differentiate
                     the two cases.  */
-                 if (TYPE_NFIELDS (type) > 0
+                 if (type->num_fields () > 0
                      && TYPE_FIELD_ARTIFICIAL (type, 0)
-                     && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR
+                     && TYPE_FIELD_TYPE (type, 0)->code () == TYPE_CODE_PTR
                      && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type,
                                                                        0))))
                    buf.puts (" const");
@@ -10261,7 +10421,7 @@ 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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *retval, *mangled = NULL, *canon = NULL;
   int need_copy = 1;
 
@@ -10270,13 +10430,8 @@ 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);
 
-  mangled = dw2_linkage_name (die, cu);
-
-  /* rustc emits invalid values for DW_AT_linkage_name.  Ignore these.
-     See https://github.com/rust-lang/rust/issues/32925.  */
-  if (cu->language == language_rust && mangled != NULL
-      && strchr (mangled, '{') != NULL)
-    mangled = NULL;
+  if (cu->language != language_rust)
+    mangled = dw2_linkage_name (die, cu);
 
   /* DW_AT_linkage_name is missing in some cases - depend on what GDB
      has computed.  */
@@ -10396,10 +10551,10 @@ read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu)
       if (attr != NULL)
        {
          struct type *type;
-         sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+         sect_offset sect_off = attr->get_ref_die_offset ();
 
          type = get_die_type_at_offset (sect_off, cu->per_cu);
-         if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
+         if (type != NULL && type->code () == TYPE_CODE_NAMESPACE)
            {
              /* This declaration is a global namespace alias.  Add
                 a symbol for it whose type is the aliased namespace.  */
@@ -10436,7 +10591,7 @@ using_directives (struct dwarf2_cu *cu)
 static void
 read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct attribute *import_attr;
   struct die_info *imported_die, *child_die;
   struct dwarf2_cu *imported_cu;
@@ -10522,7 +10677,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
 
   if (die->tag == DW_TAG_imported_module && cu->language == language_fortran)
     for (child_die = die->child; child_die && child_die->tag;
-        child_die = sibling_die (child_die))
+        child_die = child_die->sibling)
       {
        /* DWARF-4: A Fortran use statement with a “rename list” may be
           represented by an imported module entry with an import attribute
@@ -10656,8 +10811,7 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct attribute *attr;
   struct line_header line_header_local;
   hashval_t line_header_local_hash;
@@ -10678,10 +10832,10 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
      compile_unit, then use the line header hash table if it's already
      created, but don't create one just yet.  */
 
-  if (dwarf2_per_objfile->line_header_hash == NULL
+  if (dwarf2_per_objfile->per_bfd->line_header_hash == NULL
       && die->tag == DW_TAG_partial_unit)
     {
-      dwarf2_per_objfile->line_header_hash
+      dwarf2_per_objfile->per_bfd->line_header_hash
        .reset (htab_create_alloc (127, line_header_hash_voidp,
                                   line_header_eq_voidp,
                                   free_line_header_voidp,
@@ -10691,9 +10845,9 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
   line_header_local.sect_off = line_offset;
   line_header_local.offset_in_dwz = cu->per_cu->is_dwz;
   line_header_local_hash = line_header_hash (&line_header_local);
-  if (dwarf2_per_objfile->line_header_hash != NULL)
+  if (dwarf2_per_objfile->per_bfd->line_header_hash != NULL)
     {
-      slot = htab_find_slot_with_hash (dwarf2_per_objfile->line_header_hash.get (),
+      slot = htab_find_slot_with_hash (dwarf2_per_objfile->per_bfd->line_header_hash.get (),
                                       &line_header_local,
                                       line_header_local_hash, NO_INSERT);
 
@@ -10717,11 +10871,11 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
   cu->line_header = lh.release ();
   cu->line_header_die_owner = die;
 
-  if (dwarf2_per_objfile->line_header_hash == NULL)
+  if (dwarf2_per_objfile->per_bfd->line_header_hash == NULL)
     slot = NULL;
   else
     {
-      slot = htab_find_slot_with_hash (dwarf2_per_objfile->line_header_hash.get (),
+      slot = htab_find_slot_with_hash (dwarf2_per_objfile->per_bfd->line_header_hash.get (),
                                       &line_header_local,
                                       line_header_local_hash, INSERT);
       gdb_assert (slot != NULL);
@@ -10753,10 +10907,9 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct attribute *attr;
@@ -10800,7 +10953,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
       while (child_die && child_die->tag)
        {
          process_die (child_die, cu);
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
     }
 
@@ -10878,6 +11031,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
                            COMPUNIT_DIRNAME (cust),
                            compunit_language (cust),
                            0, cust));
+         list_in_scope = get_builder ()->get_file_symbols ();
        }
       return;
     }
@@ -10929,6 +11083,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
                        COMPUNIT_DIRNAME (cust),
                        compunit_language (cust),
                        0, cust));
+      list_in_scope = get_builder ()->get_file_symbols ();
 
       auto &file_names = line_header->file_names ();
       for (i = 0; i < file_names.size (); ++i)
@@ -10968,7 +11123,7 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
       while (child_die && child_die->tag)
        {
          process_die (child_die, cu);
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
     }
 }
@@ -11036,12 +11191,12 @@ lookup_dwo_file_slot (struct dwarf2_per_objfile *dwarf2_per_objfile,
   struct dwo_file find_entry;
   void **slot;
 
-  if (dwarf2_per_objfile->dwo_files == NULL)
-    dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
+  if (dwarf2_per_objfile->per_bfd->dwo_files == NULL)
+    dwarf2_per_objfile->per_bfd->dwo_files = allocate_dwo_file_hash_table ();
 
   find_entry.dwo_name = dwo_name;
   find_entry.comp_dir = comp_dir;
-  slot = htab_find_slot (dwarf2_per_objfile->dwo_files.get (), &find_entry,
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->dwo_files.get (), &find_entry,
                         INSERT);
 
   return slot;
@@ -11126,6 +11281,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
                       dwarf2_section_info &section, htab_up &cus_htab)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
+  dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
   const gdb_byte *info_ptr, *end_ptr;
 
   section.read (objfile);
@@ -11152,6 +11308,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
       memset (&per_cu, 0, sizeof (per_cu));
       per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
+      per_cu.per_bfd = per_bfd;
       per_cu.is_debug_types = 0;
       per_cu.sect_off = sect_offset (info_ptr - section.buffer);
       per_cu.section = &section;
@@ -11169,7 +11326,8 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (cus_htab == NULL)
        cus_htab = allocate_dwo_unit_table ();
 
-      dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+      dwo_unit = OBSTACK_ZALLOC (&per_bfd->obstack,
+                                struct dwo_unit);
       *dwo_unit = read_unit;
       slot = htab_find_slot (cus_htab.get (), dwo_unit, INSERT);
       gdb_assert (slot != NULL);
@@ -11372,7 +11530,7 @@ create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
             pulongest (nr_slots), dwp_file->name);
     }
 
-  htab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_hash_table);
+  htab = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack, struct dwp_hash_table);
   htab->version = version;
   htab->nr_columns = nr_columns;
   htab->nr_units = nr_units;
@@ -11569,7 +11727,6 @@ create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
                           const char *comp_dir,
                           ULONGEST signature, int is_debug_types)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   const struct dwp_hash_table *dwp_htab =
     is_debug_types ? dwp_file->tus : dwp_file->cus;
   bfd *dbfd = dwp_file->dbfd.get ();
@@ -11674,7 +11831,7 @@ create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
                              virtual_dwo_name.c_str ());
        }
       dwo_file = new struct dwo_file;
-      dwo_file->dwo_name = objfile->intern (virtual_dwo_name);
+      dwo_file->dwo_name = dwarf2_per_objfile->objfile->intern (virtual_dwo_name);
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev = sections.abbrev;
       dwo_file->sections.line = sections.line;
@@ -11703,11 +11860,11 @@ create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->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);
+    XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct dwarf2_section_info);
   *dwo_unit->section = sections.info_or_types;
   /* dwo_unit->{offset,length,type_offset_in_tu} are set later.  */
 
@@ -11768,7 +11925,6 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
                           const char *comp_dir,
                           ULONGEST signature, int is_debug_types)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   const struct dwp_hash_table *dwp_htab =
     is_debug_types ? dwp_file->tus : dwp_file->cus;
   bfd *dbfd = dwp_file->dbfd.get ();
@@ -11869,7 +12025,7 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
                              virtual_dwo_name.c_str ());
        }
       dwo_file = new struct dwo_file;
-      dwo_file->dwo_name = objfile->intern (virtual_dwo_name);
+      dwo_file->dwo_name = dwarf2_per_objfile->objfile->intern (virtual_dwo_name);
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev =
        create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.abbrev,
@@ -11912,11 +12068,11 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->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);
+    XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct dwarf2_section_info);
   *dwo_unit->section = create_dwp_v2_section (dwarf2_per_objfile,
                                              is_debug_types
                                              ? &dwp_file->sections.types
@@ -12133,6 +12289,11 @@ dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_sections_ptr)
       dwo_sections->loc.s.section = sectp;
       dwo_sections->loc.size = bfd_section_size (sectp);
     }
+  else if (section_is_p (sectp->name, &names->loclists_dwo))
+    {
+      dwo_sections->loclists.s.section = sectp;
+      dwo_sections->loclists.size = bfd_section_size (sectp);
+    }
   else if (section_is_p (sectp->name, &names->macinfo_dwo))
     {
       dwo_sections->macinfo.s.section = sectp;
@@ -12417,7 +12578,7 @@ open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   dwp_file->num_sections = elf_numsections (dwp_file->dbfd);
   dwp_file->elf_sections =
-    OBSTACK_CALLOC (&objfile->objfile_obstack,
+    OBSTACK_CALLOC (&dwarf2_per_objfile->per_bfd->obstack,
                    dwp_file->num_sections, asection *);
 
   bfd_map_over_sections (dwp_file->dbfd.get (),
@@ -12475,13 +12636,13 @@ open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 static struct dwp_file *
 get_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  if (! dwarf2_per_objfile->dwp_checked)
+  if (! dwarf2_per_objfile->per_bfd->dwp_checked)
     {
-      dwarf2_per_objfile->dwp_file
+      dwarf2_per_objfile->per_bfd->dwp_file
        = open_and_init_dwp_file (dwarf2_per_objfile);
-      dwarf2_per_objfile->dwp_checked = 1;
+      dwarf2_per_objfile->per_bfd->dwp_checked = 1;
     }
-  return dwarf2_per_objfile->dwp_file.get ();
+  return dwarf2_per_objfile->per_bfd->dwp_file.get ();
 }
 
 /* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit.
@@ -12741,7 +12902,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
 
   for (child_die = die->child;
        child_die && child_die->tag;
-       child_die = sibling_die (child_die))
+       child_die = child_die->sibling)
     {
       struct die_info *child_origin_die;
       struct dwarf2_cu *child_origin_cu;
@@ -12818,7 +12979,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
          if (!origin_child_die->in_process)
            process_die (origin_child_die, origin_cu);
        }
-      origin_child_die = sibling_die (origin_child_die);
+      origin_child_die = origin_child_die->sibling;
     }
   origin_cu->list_in_scope = origin_previous_list_in_scope;
 
@@ -12829,8 +12990,8 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct objfile *objfile = cu->per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   struct context_stack *newobj;
   CORE_ADDR lowpc;
   CORE_ADDR highpc;
@@ -12887,12 +13048,12 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   /* If we have any template arguments, then we must allocate a
      different sort of symbol.  */
-  for (child_die = die->child; child_die; child_die = sibling_die (child_die))
+  for (child_die = die->child; child_die; child_die = child_die->sibling)
     {
       if (child_die->tag == DW_TAG_template_type_param
          || child_die->tag == DW_TAG_template_value_param)
        {
-         templ_func = allocate_template_symbol (objfile);
+         templ_func = new (&objfile->objfile_obstack) template_symbol;
          templ_func->subclass = SYMBOL_TEMPLATE;
          break;
        }
@@ -12940,7 +13101,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
            }
          else
            process_die (child_die, cu);
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
     }
 
@@ -12962,7 +13123,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
            {
              if (child_die->tag == DW_TAG_imported_module)
                process_die (child_die, spec_cu);
-             child_die = sibling_die (child_die);
+             child_die = child_die->sibling;
            }
 
          /* In some cases, GCC generates specification DIEs that
@@ -13030,8 +13191,8 @@ 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->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct objfile *objfile = cu->per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
   CORE_ADDR baseaddr;
@@ -13051,8 +13212,17 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
         GCC does no longer produces such DWARF since GCC r224161.  */
       for (child_die = die->child;
           child_die != NULL && child_die->tag;
-          child_die = sibling_die (child_die))
-       process_die (child_die, cu);
+          child_die = child_die->sibling)
+       {
+         /* We might already be processing this DIE.  This can happen
+            in an unusual circumstance -- where a subroutine A
+            appears lexically in another subroutine B, but A actually
+            inlines B.  The recursion is broken here, rather than in
+            inherit_abstract_dies, because it seems better to simply
+            drop concrete children here.  */
+         if (!child_die->in_process)
+           process_die (child_die, cu);
+       }
       return;
     case PC_BOUNDS_INVALID:
       return;
@@ -13067,7 +13237,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
       while (child_die && child_die->tag)
        {
          process_die (child_die, cu);
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
     }
   inherit_abstract_dies (die, cu);
@@ -13101,8 +13271,9 @@ 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->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR pc, baseaddr;
   struct attribute *attr;
   struct call_site *call_site, call_site_local;
@@ -13148,7 +13319,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   nparams = 0;
   for (child_die = die->child; child_die && child_die->tag;
-       child_die = sibling_die (child_die))
+       child_die = child_die->sibling)
     {
       if (child_die->tag != DW_TAG_call_site_parameter
           && child_die->tag != DW_TAG_GNU_call_site_parameter)
@@ -13208,7 +13379,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
            func_type = get_die_type (func_die, cu);
          if (func_type != NULL)
            {
-             gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+             gdb_assert (func_type->code () == TYPE_CODE_FUNC);
 
              /* Enlist this call site to the function.  */
              call_site->tail_call_next = TYPE_TAIL_CALL_LIST (func_type);
@@ -13241,6 +13412,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       dlbaton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
       dlbaton->data = DW_BLOCK (attr)->data;
       dlbaton->size = DW_BLOCK (attr)->size;
+      dlbaton->per_objfile = per_objfile;
       dlbaton->per_cu = cu->per_cu;
 
       SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton);
@@ -13251,7 +13423,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->per_cu->dwarf2_per_objfile->objfile == objfile);
+      gdb_assert (target_cu->per_objfile->objfile == objfile);
       if (die_is_declaration (target_die, target_cu))
        {
          const char *target_physname;
@@ -13293,7 +13465,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   for (child_die = die->child;
        child_die && child_die->tag;
-       child_die = sibling_die (child_die))
+       child_die = child_die->sibling)
     {
       struct call_site_parameter *parameter;
       struct attribute *loc, *origin;
@@ -13324,8 +13496,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
        {
          parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
 
-         sect_offset sect_off
-           = (sect_offset) dwarf2_get_ref_die_offset (origin);
+         sect_offset sect_off = origin->get_ref_die_offset ();
          if (!cu->header.offset_in_cu_p (sect_off))
            {
              /* As DW_OP_GNU_parameter_ref uses CU-relative offset this
@@ -13445,10 +13616,9 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu)
 
       if (containing_type != NULL)
        {
-         struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+         struct objfile *objfile = cu->per_objfile->objfile;
 
-         storage = new (&objfile->objfile_obstack) rust_vtable_symbol ();
-         initialize_objfile_symbol (storage);
+         storage = new (&objfile->objfile_obstack) rust_vtable_symbol;
          storage->concrete_type = containing_type;
          storage->subclass = SYMBOL_RUST_VTABLE;
        }
@@ -13467,8 +13637,9 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu)
       struct dwarf2_cu *origin_cu = cu;
       struct die_info *origin_die
        = follow_die_ref (die, abstract_origin, &origin_cu);
-      dwarf2_per_objfile *dpo = cu->per_cu->dwarf2_per_objfile;
-      dpo->abstract_to_concrete[origin_die->sect_off].push_back (die->sect_off);
+      dwarf2_per_objfile *per_objfile = cu->per_objfile;
+      per_objfile->per_bfd->abstract_to_concrete
+       [origin_die->sect_off].push_back (die->sect_off);
     }
 }
 
@@ -13484,28 +13655,25 @@ static bool
 dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
                         Callback &&callback)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *obfd = objfile->obfd;
   /* Base address selection entry.  */
-  CORE_ADDR base;
-  int found_base;
+  gdb::optional<CORE_ADDR> base;
   const gdb_byte *buffer;
   CORE_ADDR baseaddr;
   bool overflow = false;
 
-  found_base = cu->base_known;
   base = cu->base_address;
 
-  dwarf2_per_objfile->rnglists.read (objfile);
-  if (offset >= dwarf2_per_objfile->rnglists.size)
+  dwarf2_per_objfile->per_bfd->rnglists.read (objfile);
+  if (offset >= dwarf2_per_objfile->per_bfd->rnglists.size)
     {
       complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
                 offset);
       return false;
     }
-  buffer = dwarf2_per_objfile->rnglists.buffer + offset;
+  buffer = dwarf2_per_objfile->per_bfd->rnglists.buffer + offset;
 
   baseaddr = objfile->text_section_offset ();
 
@@ -13513,8 +13681,8 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
     {
       /* Initialize it due to a false compiler warning.  */
       CORE_ADDR range_beginning = 0, range_end = 0;
-      const gdb_byte *buf_end = (dwarf2_per_objfile->rnglists.buffer
-                                + dwarf2_per_objfile->rnglists.size);
+      const gdb_byte *buf_end = (dwarf2_per_objfile->per_bfd->rnglists.buffer
+                                + dwarf2_per_objfile->per_bfd->rnglists.size);
       unsigned int bytes_read;
 
       if (buffer == buf_end)
@@ -13534,7 +13702,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
              break;
            }
          base = cu->header.read_address (obfd, buffer, &bytes_read);
-         found_base = 1;
          buffer += bytes_read;
          break;
        case DW_RLE_start_length:
@@ -13592,7 +13759,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
       if (rlet == DW_RLE_base_address)
        continue;
 
-      if (!found_base)
+      if (!base.has_value ())
        {
          /* We have no valid base address for the ranges
             data.  */
@@ -13611,13 +13778,13 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
       if (range_beginning == range_end)
        continue;
 
-      range_beginning += base;
-      range_end += base;
+      range_beginning += *base;
+      range_end += *base;
 
       /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
       if (range_beginning + baseaddr == 0
-         && !dwarf2_per_objfile->has_section_at_zero)
+         && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_rnglists entry has start address of zero"
                       " [in module %s]"), objfile_name (objfile));
@@ -13648,16 +13815,14 @@ static int
 dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
                       Callback &&callback)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-      = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct comp_unit_head *cu_header = &cu->header;
   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;
+  gdb::optional<CORE_ADDR> base;
   unsigned int dummy;
   const gdb_byte *buffer;
   CORE_ADDR baseaddr;
@@ -13665,17 +13830,16 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
   if (cu_header->version >= 5)
     return dwarf2_rnglists_process (offset, cu, callback);
 
-  found_base = cu->base_known;
   base = cu->base_address;
 
-  dwarf2_per_objfile->ranges.read (objfile);
-  if (offset >= dwarf2_per_objfile->ranges.size)
+  per_objfile->per_bfd->ranges.read (objfile);
+  if (offset >= per_objfile->per_bfd->ranges.size)
     {
       complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
                 offset);
       return 0;
     }
-  buffer = dwarf2_per_objfile->ranges.buffer + offset;
+  buffer = per_objfile->per_bfd->ranges.buffer + offset;
 
   baseaddr = objfile->text_section_offset ();
 
@@ -13702,11 +13866,10 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
          /* If we found the largest possible address, then we already
             have the base address in range_end.  */
          base = range_end;
-         found_base = 1;
          continue;
        }
 
-      if (!found_base)
+      if (!base.has_value ())
        {
          /* We have no valid base address for the ranges
             data.  */
@@ -13725,13 +13888,13 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
       if (range_beginning == range_end)
        continue;
 
-      range_beginning += base;
-      range_end += base;
+      range_beginning += *base;
+      range_end += *base;
 
       /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
       if (range_beginning + baseaddr == 0
-         && !dwarf2_per_objfile->has_section_at_zero)
+         && !per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_ranges entry has start address of zero"
                       " [in module %s]"), objfile_name (objfile));
@@ -13753,8 +13916,8 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
                    CORE_ADDR *high_return, struct dwarf2_cu *cu,
                    dwarf2_psymtab *ranges_pst)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct objfile *objfile = cu->per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   const CORE_ADDR baseaddr = objfile->text_section_offset ();
   int low_set = 0;
   CORE_ADDR low = 0;
@@ -13821,8 +13984,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                      CORE_ADDR *highpc, struct dwarf2_cu *cu,
                      dwarf2_psymtab *pst)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct attribute *attr;
   struct attribute *attr_high;
   CORE_ADDR low = 0;
@@ -13884,7 +14046,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
      labels are not in the output, so the relocs get a value of 0.
      If this is a discarded function, mark the pc bounds as invalid,
      so that GDB will ignore it.  */
-  if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
+  if (low == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
     return PC_BOUNDS_INVALID;
 
   *lowpc = low;
@@ -13926,7 +14088,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
       if (child->tag == DW_TAG_subprogram
           || child->tag == DW_TAG_lexical_block)
         dwarf2_get_subprogram_pc_bounds (child, lowpc, highpc, cu);
-      child = sibling_die (child);
+      child = child->sibling;
     }
 }
 
@@ -13982,7 +14144,7 @@ get_scope_pc_bounds (struct die_info *die,
            break;
          }
 
-         child = sibling_die (child);
+         child = child->sibling;
        }
     }
 
@@ -13997,8 +14159,8 @@ static void
 dwarf2_record_block_ranges (struct die_info *die, struct block *block,
                             CORE_ADDR baseaddr, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct objfile *objfile = cu->per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   struct attribute *attr;
   struct attribute *attr_high;
 
@@ -14165,7 +14327,7 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
         so if we see it, we can assume that a constant form is really
         a constant and not a section offset.  */
       if (attr->form_is_constant ())
-       *offset = dwarf2_get_attr_constant_value (attr, 0);
+       *offset = attr->constant_value (0);
       else if (attr->form_is_section_offset ())
        dwarf2_complex_location_expr_complaint ();
       else if (attr->form_is_block ())
@@ -14179,14 +14341,62 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
   return 0;
 }
 
+/* Look for DW_AT_data_member_location and store the results in FIELD.  */
+
+static void
+handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
+                            struct field *field)
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
+  if (attr != NULL)
+    {
+      if (attr->form_is_constant ())
+       {
+         LONGEST offset = attr->constant_value (0);
+         SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+       }
+      else if (attr->form_is_section_offset ())
+       dwarf2_complex_location_expr_complaint ();
+      else if (attr->form_is_block ())
+       {
+         bool handled;
+         CORE_ADDR offset = decode_locdesc (DW_BLOCK (attr), cu, &handled);
+         if (handled)
+           SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+         else
+           {
+             dwarf2_per_objfile *per_objfile = cu->per_objfile;
+             struct objfile *objfile = per_objfile->objfile;
+             struct dwarf2_locexpr_baton *dlbaton
+               = XOBNEW (&objfile->objfile_obstack,
+                         struct dwarf2_locexpr_baton);
+             dlbaton->data = DW_BLOCK (attr)->data;
+             dlbaton->size = DW_BLOCK (attr)->size;
+             /* When using this baton, we want to compute the address
+                of the field, not the value.  This is why
+                is_reference is set to false here.  */
+             dlbaton->is_reference = false;
+             dlbaton->per_objfile = per_objfile;
+             dlbaton->per_cu = cu->per_cu;
+
+             SET_FIELD_DWARF_BLOCK (*field, dlbaton);
+           }
+       }
+      else
+       dwarf2_complex_location_expr_complaint ();
+    }
+}
+
 /* Add an aggregate field to the field list.  */
 
 static void
 dwarf2_add_field (struct field_info *fip, struct die_info *die,
                  struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct objfile *objfile = cu->per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   struct nextfield *new_field;
   struct attribute *attr;
   struct field *fp;
@@ -14203,6 +14413,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       new_field = &fip->fields.back ();
     }
 
+  new_field->offset = die->sect_off;
+
   attr = dwarf2_attr (die, DW_AT_accessibility, cu);
   if (attr != nullptr)
     new_field->accessibility = DW_UNSND (attr);
@@ -14221,8 +14433,6 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
     {
-      LONGEST offset;
-
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -14242,8 +14452,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get bit offset of field.  */
-      if (handle_data_member_location (die, cu, &offset))
-       SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
+      handle_data_member_location (die, cu, fp);
       attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr != nullptr)
        {
@@ -14292,7 +14501,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
       if (attr != NULL)
        SET_FIELD_BITPOS (*fp, (FIELD_BITPOS (*fp)
-                               + dwarf2_get_attr_constant_value (attr, 0)));
+                               + attr->constant_value (0)));
 
       /* Get name of field.  */
       fieldname = dwarf2_name (die, cu);
@@ -14352,43 +14561,11 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     }
   else if (die->tag == DW_TAG_inheritance)
     {
-      LONGEST offset;
-
       /* C++ base class field.  */
-      if (handle_data_member_location (die, cu, &offset))
-       SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
+      handle_data_member_location (die, cu, fp);
       FIELD_BITSIZE (*fp) = 0;
       FIELD_TYPE (*fp) = die_type (die, cu);
-      FIELD_NAME (*fp) = TYPE_NAME (fp->type);
-    }
-  else if (die->tag == DW_TAG_variant_part)
-    {
-      /* process_structure_scope will treat this DIE as a union.  */
-      process_structure_scope (die, cu);
-
-      /* The variant part is relative to the start of the enclosing
-        structure.  */
-      SET_FIELD_BITPOS (*fp, 0);
-      fp->type = get_die_type (die, cu);
-      fp->artificial = 1;
-      fp->name = "<<variant>>";
-
-      /* Normally a DW_TAG_variant_part won't have a size, but our
-        representation requires one, so set it to the maximum of the
-        child sizes, being sure to account for the offset at which
-        each child is seen.  */
-      if (TYPE_LENGTH (fp->type) == 0)
-       {
-         unsigned max = 0;
-         for (int i = 0; i < TYPE_NFIELDS (fp->type); ++i)
-           {
-             unsigned len = ((TYPE_FIELD_BITPOS (fp->type, i) + 7) / 8
-                             + TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)));
-             if (len > max)
-               max = len;
-           }
-         TYPE_LENGTH (fp->type) = max;
-       }
+      FIELD_NAME (*fp) = fp->type->name ();
     }
   else
     gdb_assert_not_reached ("missing case in dwarf2_add_field");
@@ -14456,6 +14633,202 @@ dwarf2_add_type_defn (struct field_info *fip, struct die_info *die,
     fip->nested_types_list.push_back (fp);
 }
 
+/* A convenience typedef that's used when finding the discriminant
+   field for a variant part.  */
+typedef std::unordered_map<sect_offset, int, gdb::hash_enum<sect_offset>>
+  offset_map_type;
+
+/* Compute the discriminant range for a given variant.  OBSTACK is
+   where the results will be stored.  VARIANT is the variant to
+   process.  IS_UNSIGNED indicates whether the discriminant is signed
+   or unsigned.  */
+
+static const gdb::array_view<discriminant_range>
+convert_variant_range (struct obstack *obstack, const variant_field &variant,
+                      bool is_unsigned)
+{
+  std::vector<discriminant_range> ranges;
+
+  if (variant.default_branch)
+    return {};
+
+  if (variant.discr_list_data == nullptr)
+    {
+      discriminant_range r
+       = {variant.discriminant_value, variant.discriminant_value};
+      ranges.push_back (r);
+    }
+  else
+    {
+      gdb::array_view<const gdb_byte> data (variant.discr_list_data->data,
+                                           variant.discr_list_data->size);
+      while (!data.empty ())
+       {
+         if (data[0] != DW_DSC_range && data[0] != DW_DSC_label)
+           {
+             complaint (_("invalid discriminant marker: %d"), data[0]);
+             break;
+           }
+         bool is_range = data[0] == DW_DSC_range;
+         data = data.slice (1);
+
+         ULONGEST low, high;
+         unsigned int bytes_read;
+
+         if (data.empty ())
+           {
+             complaint (_("DW_AT_discr_list missing low value"));
+             break;
+           }
+         if (is_unsigned)
+           low = read_unsigned_leb128 (nullptr, data.data (), &bytes_read);
+         else
+           low = (ULONGEST) read_signed_leb128 (nullptr, data.data (),
+                                                &bytes_read);
+         data = data.slice (bytes_read);
+
+         if (is_range)
+           {
+             if (data.empty ())
+               {
+                 complaint (_("DW_AT_discr_list missing high value"));
+                 break;
+               }
+             if (is_unsigned)
+               high = read_unsigned_leb128 (nullptr, data.data (),
+                                            &bytes_read);
+             else
+               high = (LONGEST) read_signed_leb128 (nullptr, data.data (),
+                                                    &bytes_read);
+             data = data.slice (bytes_read);
+           }
+         else
+           high = low;
+
+         ranges.push_back ({ low, high });
+       }
+    }
+
+  discriminant_range *result = XOBNEWVEC (obstack, discriminant_range,
+                                         ranges.size ());
+  std::copy (ranges.begin (), ranges.end (), result);
+  return gdb::array_view<discriminant_range> (result, ranges.size ());
+}
+
+static const gdb::array_view<variant_part> create_variant_parts
+  (struct obstack *obstack,
+   const offset_map_type &offset_map,
+   struct field_info *fi,
+   const std::vector<variant_part_builder> &variant_parts);
+
+/* Fill in a "struct variant" for a given variant field.  RESULT is
+   the variant to fill in.  OBSTACK is where any needed allocations
+   will be done.  OFFSET_MAP holds the mapping from section offsets to
+   fields for the type.  FI describes the fields of the type we're
+   processing.  FIELD is the variant field we're converting.  */
+
+static void
+create_one_variant (variant &result, struct obstack *obstack,
+                   const offset_map_type &offset_map,
+                   struct field_info *fi, const variant_field &field)
+{
+  result.discriminants = convert_variant_range (obstack, field, false);
+  result.first_field = field.first_field + fi->baseclasses.size ();
+  result.last_field = field.last_field + fi->baseclasses.size ();
+  result.parts = create_variant_parts (obstack, offset_map, fi,
+                                      field.variant_parts);
+}
+
+/* Fill in a "struct variant_part" for a given variant part.  RESULT
+   is the variant part to fill in.  OBSTACK is where any needed
+   allocations will be done.  OFFSET_MAP holds the mapping from
+   section offsets to fields for the type.  FI describes the fields of
+   the type we're processing.  BUILDER is the variant part to be
+   converted.  */
+
+static void
+create_one_variant_part (variant_part &result,
+                        struct obstack *obstack,
+                        const offset_map_type &offset_map,
+                        struct field_info *fi,
+                        const variant_part_builder &builder)
+{
+  auto iter = offset_map.find (builder.discriminant_offset);
+  if (iter == offset_map.end ())
+    {
+      result.discriminant_index = -1;
+      /* Doesn't matter.  */
+      result.is_unsigned = false;
+    }
+  else
+    {
+      result.discriminant_index = iter->second;
+      result.is_unsigned
+       = TYPE_UNSIGNED (FIELD_TYPE
+                        (fi->fields[result.discriminant_index].field));
+    }
+
+  size_t n = builder.variants.size ();
+  variant *output = new (obstack) variant[n];
+  for (size_t i = 0; i < n; ++i)
+    create_one_variant (output[i], obstack, offset_map, fi,
+                       builder.variants[i]);
+
+  result.variants = gdb::array_view<variant> (output, n);
+}
+
+/* Create a vector of variant parts that can be attached to a type.
+   OBSTACK is where any needed allocations will be done.  OFFSET_MAP
+   holds the mapping from section offsets to fields for the type.  FI
+   describes the fields of the type we're processing.  VARIANT_PARTS
+   is the vector to convert.  */
+
+static const gdb::array_view<variant_part>
+create_variant_parts (struct obstack *obstack,
+                     const offset_map_type &offset_map,
+                     struct field_info *fi,
+                     const std::vector<variant_part_builder> &variant_parts)
+{
+  if (variant_parts.empty ())
+    return {};
+
+  size_t n = variant_parts.size ();
+  variant_part *result = new (obstack) variant_part[n];
+  for (size_t i = 0; i < n; ++i)
+    create_one_variant_part (result[i], obstack, offset_map, fi,
+                            variant_parts[i]);
+
+  return gdb::array_view<variant_part> (result, n);
+}
+
+/* Compute the variant part vector for FIP, attaching it to TYPE when
+   done.  */
+
+static void
+add_variant_property (struct field_info *fip, struct type *type,
+                     struct dwarf2_cu *cu)
+{
+  /* Map section offsets of fields to their field index.  Note the
+     field index here does not take the number of baseclasses into
+     account.  */
+  offset_map_type offset_map;
+  for (int i = 0; i < fip->fields.size (); ++i)
+    offset_map[fip->fields[i].offset] = i;
+
+  struct objfile *objfile = cu->per_objfile->objfile;
+  gdb::array_view<variant_part> parts
+    = create_variant_parts (&objfile->objfile_obstack, offset_map, fip,
+                           fip->variant_parts);
+
+  struct dynamic_prop prop;
+  prop.kind = PROP_VARIANT_PARTS;
+  prop.data.variant_parts
+    = ((gdb::array_view<variant_part> *)
+       obstack_copy (&objfile->objfile_obstack, &parts, sizeof (parts)));
+
+  type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
+}
+
 /* Create the vector of fields, and attach it to the type.  */
 
 static void
@@ -14466,9 +14839,9 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
 
   /* Record the field count, allocate space for the array of fields,
      and create blank accessibility bitfields if necessary.  */
-  TYPE_NFIELDS (type) = nfields;
-  TYPE_FIELDS (type) = (struct field *)
-    TYPE_ZALLOC (type, sizeof (struct field) * nfields);
+  type->set_num_fields (nfields);
+  type->set_fields
+    ((struct field *) TYPE_ZALLOC (type, sizeof (struct field) * nfields));
 
   if (fip->non_public_fields && cu->language != language_ada)
     {
@@ -14501,22 +14874,8 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
       TYPE_N_BASECLASSES (type) = fip->baseclasses.size ();
     }
 
-  if (TYPE_FLAG_DISCRIMINATED_UNION (type))
-    {
-      struct discriminant_info *di = alloc_discriminant_info (type, -1, -1);
-
-      for (int index = 0; index < nfields; ++index)
-       {
-         struct nextfield &field = fip->fields[index];
-
-         if (field.variant.is_discriminant)
-           di->discriminant_index = index;
-         else if (field.variant.default_branch)
-           di->default_index = index;
-         else
-           di->discriminants[index] = field.variant.discriminant_value;
-       }
-    }
+  if (!fip->variant_parts.empty ())
+    add_variant_property (fip, type, cu);
 
   /* Copy the saved-up fields into the field vector.  */
   for (int i = 0; i < nfields; ++i)
@@ -14525,7 +14884,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
        = ((i < fip->baseclasses.size ()) ? fip->baseclasses[i]
           : fip->fields[i - fip->baseclasses.size ()]);
 
-      TYPE_FIELD (type, i) = field.field;
+      type->field (i) = field.field;
       switch (field.accessibility)
        {
        case DW_ACCESS_private:
@@ -14617,7 +14976,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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct attribute *attr;
   int i;
   struct fnfieldlist *flp = nullptr;
@@ -14670,16 +15029,16 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 
   fnp->type = alloc_type (objfile);
   this_type = read_type_die (die, cu);
-  if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
+  if (this_type && this_type->code () == TYPE_CODE_FUNC)
     {
-      int nparams = TYPE_NFIELDS (this_type);
+      int nparams = this_type->num_fields ();
 
       /* TYPE is the domain of this method, and THIS_TYPE is the type
           of the method itself (TYPE_CODE_METHOD).  */
       smash_to_method_type (fnp->type, type,
                            TYPE_TARGET_TYPE (this_type),
-                           TYPE_FIELDS (this_type),
-                           TYPE_NFIELDS (this_type),
+                           this_type->fields (),
+                           this_type->num_fields (),
                            TYPE_VARARGS (this_type));
 
       /* Handle static member functions.
@@ -14771,7 +15130,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
              /* If there is no `this' field and no DW_AT_containing_type,
                 we cannot actually find a base class context for the
                 vtable!  */
-             if (TYPE_NFIELDS (this_type) == 0
+             if (this_type->num_fields () == 0
                  || !TYPE_FIELD_ARTIFICIAL (this_type, 0))
                {
                  complaint (_("cannot determine context for virtual member "
@@ -14868,7 +15227,7 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
   struct type *pfn_type, *self_type, *new_type;
 
   /* Check for a structure with no name and two children.  */
-  if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
+  if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2)
     return;
 
   /* Check for __pfn and __delta members.  */
@@ -14881,21 +15240,21 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
   /* Find the type of the method.  */
   pfn_type = TYPE_FIELD_TYPE (type, 0);
   if (pfn_type == NULL
-      || TYPE_CODE (pfn_type) != TYPE_CODE_PTR
-      || TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
+      || pfn_type->code () != TYPE_CODE_PTR
+      || TYPE_TARGET_TYPE (pfn_type)->code () != TYPE_CODE_FUNC)
     return;
 
   /* Look for the "this" argument.  */
   pfn_type = TYPE_TARGET_TYPE (pfn_type);
-  if (TYPE_NFIELDS (pfn_type) == 0
+  if (pfn_type->num_fields () == 0
       /* || TYPE_FIELD_TYPE (pfn_type, 0) == NULL */
-      || TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
+      || TYPE_FIELD_TYPE (pfn_type, 0)->code () != TYPE_CODE_PTR)
     return;
 
   self_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
   new_type = alloc_type (objfile);
   smash_to_method_type (new_type, self_type, TYPE_TARGET_TYPE (pfn_type),
-                       TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
+                       pfn_type->fields (), pfn_type->num_fields (),
                        TYPE_VARARGS (pfn_type));
   smash_to_methodptr_type (type, new_type);
 }
@@ -14917,7 +15276,7 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
       complaint (_("DW_AT_alignment must have constant form"
                   " - DIE at %s [in module %s]"),
                 sect_offset_str (die->sect_off),
-                objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                objfile_name (cu->per_objfile->objfile));
       return 0;
     }
 
@@ -14930,7 +15289,7 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
          complaint (_("DW_AT_alignment value must not be negative"
                       " - DIE at %s [in module %s]"),
                     sect_offset_str (die->sect_off),
-                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                    objfile_name (cu->per_objfile->objfile));
          return 0;
        }
       align = val;
@@ -14943,7 +15302,7 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
       complaint (_("DW_AT_alignment value must not be zero"
                   " - DIE at %s [in module %s]"),
                 sect_offset_str (die->sect_off),
-                objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                objfile_name (cu->per_objfile->objfile));
       return 0;
     }
   if ((align & (align - 1)) != 0)
@@ -14951,7 +15310,7 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
       complaint (_("DW_AT_alignment value must be a power of 2"
                   " - DIE at %s [in module %s]"),
                 sect_offset_str (die->sect_off),
-                objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                objfile_name (cu->per_objfile->objfile));
       return 0;
     }
 
@@ -14969,7 +15328,7 @@ maybe_set_alignment (struct dwarf2_cu *cu, struct die_info *die,
     complaint (_("DW_AT_alignment value too large"
                 " - DIE at %s [in module %s]"),
               sect_offset_str (die->sect_off),
-              objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+              objfile_name (cu->per_objfile->objfile));
 }
 
 /* Check if the given VALUE is a valid enum dwarf_calling_convention
@@ -15033,7 +15392,7 @@ is_valid_DW_AT_calling_convention_for_subroutine (ULONGEST value)
 static struct type *
 read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   const char *name;
@@ -15041,7 +15400,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   /* If the definition of this type lives in .debug_types, read that type.
      Don't follow DW_AT_specification though, that will take us back up
      the chain and we want to go down.  */
-  attr = dwarf2_attr_no_follow (die, DW_AT_signature);
+  attr = die->attr (DW_AT_signature);
   if (attr != nullptr)
     {
       type = get_DW_AT_signature_type (die, attr, cu);
@@ -15068,32 +15427,27 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
          if (get_die_type (die, cu) != NULL)
            return get_die_type (die, cu);
 
-         TYPE_NAME (type) = full_name;
+         type->set_name (full_name);
        }
       else
        {
          /* The name is already allocated along with this objfile, so
             we don't need to duplicate it for the type.  */
-         TYPE_NAME (type) = name;
+         type->set_name (name);
        }
     }
 
   if (die->tag == DW_TAG_structure_type)
     {
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      type->set_code (TYPE_CODE_STRUCT);
     }
   else if (die->tag == DW_TAG_union_type)
     {
-      TYPE_CODE (type) = TYPE_CODE_UNION;
-    }
-  else if (die->tag == DW_TAG_variant_part)
-    {
-      TYPE_CODE (type) = TYPE_CODE_UNION;
-      TYPE_FLAG_DISCRIMINATED_UNION (type) = 1;
+      type->set_code (TYPE_CODE_UNION);
     }
   else
     {
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      type->set_code (TYPE_CODE_STRUCT);
     }
 
   if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
@@ -15118,14 +15472,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
         TYPE_LENGTH (type) = DW_UNSND (attr);
       else
        {
-         /* For the moment, dynamic type sizes are not supported
-            by GDB's struct type.  The actual size is determined
-            on-demand when resolving the type of a given object,
-            so set the type's length to zero for now.  Otherwise,
-            we record an expression as the length, and that expression
-            could lead to a very large value, which could eventually
-            lead to us trying to allocate that much memory when creating
-            a value of that type.  */
+         struct dynamic_prop prop;
+         if (attr_to_dynamic_prop (attr, die, cu, &prop,
+                                   cu->per_cu->addr_type ()))
+           type->add_dyn_prop (DYN_PROP_BYTE_SIZE, prop);
           TYPE_LENGTH (type) = 0;
        }
     }
@@ -15164,6 +15514,130 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   return type;
 }
 
+static void handle_struct_member_die
+  (struct die_info *child_die,
+   struct type *type,
+   struct field_info *fi,
+   std::vector<struct symbol *> *template_args,
+   struct dwarf2_cu *cu);
+
+/* A helper for handle_struct_member_die that handles
+   DW_TAG_variant_part.  */
+
+static void
+handle_variant_part (struct die_info *die, struct type *type,
+                    struct field_info *fi,
+                    std::vector<struct symbol *> *template_args,
+                    struct dwarf2_cu *cu)
+{
+  variant_part_builder *new_part;
+  if (fi->current_variant_part == nullptr)
+    {
+      fi->variant_parts.emplace_back ();
+      new_part = &fi->variant_parts.back ();
+    }
+  else if (!fi->current_variant_part->processing_variant)
+    {
+      complaint (_("nested DW_TAG_variant_part seen "
+                  "- DIE at %s [in module %s]"),
+                sect_offset_str (die->sect_off),
+                objfile_name (cu->per_objfile->objfile));
+      return;
+    }
+  else
+    {
+      variant_field &current = fi->current_variant_part->variants.back ();
+      current.variant_parts.emplace_back ();
+      new_part = &current.variant_parts.back ();
+    }
+
+  /* When we recurse, we want callees to add to this new variant
+     part.  */
+  scoped_restore save_current_variant_part
+    = make_scoped_restore (&fi->current_variant_part, new_part);
+
+  struct attribute *discr = dwarf2_attr (die, DW_AT_discr, cu);
+  if (discr == NULL)
+    {
+      /* It's a univariant form, an extension we support.  */
+    }
+  else if (discr->form_is_ref ())
+    {
+      struct dwarf2_cu *target_cu = cu;
+      struct die_info *target_die = follow_die_ref (die, discr, &target_cu);
+
+      new_part->discriminant_offset = target_die->sect_off;
+    }
+  else
+    {
+      complaint (_("DW_AT_discr does not have DIE reference form"
+                  " - DIE at %s [in module %s]"),
+                sect_offset_str (die->sect_off),
+                objfile_name (cu->per_objfile->objfile));
+    }
+
+  for (die_info *child_die = die->child;
+       child_die != NULL;
+       child_die = child_die->sibling)
+    handle_struct_member_die (child_die, type, fi, template_args, cu);
+}
+
+/* A helper for handle_struct_member_die that handles
+   DW_TAG_variant.  */
+
+static void
+handle_variant (struct die_info *die, struct type *type,
+               struct field_info *fi,
+               std::vector<struct symbol *> *template_args,
+               struct dwarf2_cu *cu)
+{
+  if (fi->current_variant_part == nullptr)
+    {
+      complaint (_("saw DW_TAG_variant outside DW_TAG_variant_part "
+                  "- DIE at %s [in module %s]"),
+                sect_offset_str (die->sect_off),
+                objfile_name (cu->per_objfile->objfile));
+      return;
+    }
+  if (fi->current_variant_part->processing_variant)
+    {
+      complaint (_("nested DW_TAG_variant seen "
+                  "- DIE at %s [in module %s]"),
+                sect_offset_str (die->sect_off),
+                objfile_name (cu->per_objfile->objfile));
+      return;
+    }
+
+  scoped_restore save_processing_variant
+    = make_scoped_restore (&fi->current_variant_part->processing_variant,
+                          true);
+
+  fi->current_variant_part->variants.emplace_back ();
+  variant_field &variant = fi->current_variant_part->variants.back ();
+  variant.first_field = fi->fields.size ();
+
+  /* In a variant we want to get the discriminant and also add a
+     field for our sole member child.  */
+  struct attribute *discr = dwarf2_attr (die, DW_AT_discr_value, cu);
+  if (discr == nullptr)
+    {
+      discr = dwarf2_attr (die, DW_AT_discr_list, cu);
+      if (discr == nullptr || DW_BLOCK (discr)->size == 0)
+       variant.default_branch = true;
+      else
+       variant.discr_list_data = DW_BLOCK (discr);
+    }
+  else
+    variant.discriminant_value = DW_UNSND (discr);
+
+  for (die_info *variant_child = die->child;
+       variant_child != NULL;
+       variant_child = variant_child->sibling)
+    handle_struct_member_die (variant_child, type, fi, template_args, cu);
+
+  variant.last_field = fi->fields.size ();
+}
+
 /* A helper for process_structure_scope that handles a single member
    DIE.  */
 
@@ -15174,8 +15648,7 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
                          struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable
-      || child_die->tag == DW_TAG_variant_part)
+      || child_die->tag == DW_TAG_variable)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
         should be a DW_TAG_member that is a declaration, but
@@ -15212,41 +15685,10 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
       if (arg != NULL)
        template_args->push_back (arg);
     }
+  else if (child_die->tag == DW_TAG_variant_part)
+    handle_variant_part (child_die, type, fi, template_args, cu);
   else if (child_die->tag == DW_TAG_variant)
-    {
-      /* In a variant we want to get the discriminant and also add a
-        field for our sole member child.  */
-      struct attribute *discr = dwarf2_attr (child_die, DW_AT_discr_value, cu);
-
-      for (die_info *variant_child = child_die->child;
-          variant_child != NULL;
-          variant_child = sibling_die (variant_child))
-       {
-         if (variant_child->tag == DW_TAG_member)
-           {
-             handle_struct_member_die (variant_child, type, fi,
-                                       template_args, cu);
-             /* Only handle the one.  */
-             break;
-           }
-       }
-
-      /* We don't handle this but we might as well report it if we see
-        it.  */
-      if (dwarf2_attr (child_die, DW_AT_discr_list, cu) != nullptr)
-         complaint (_("DW_AT_discr_list is not supported yet"
-                      " - DIE at %s [in module %s]"),
-                    sect_offset_str (child_die->sect_off),
-                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
-
-      /* The first field was just added, so we can stash the
-        discriminant there.  */
-      gdb_assert (!fi->fields.empty ());
-      if (discr == NULL)
-       fi->fields.back ().variant.default_branch = true;
-      else
-       fi->fields.back ().variant.discriminant_value = DW_UNSND (discr);
-    }
+    handle_variant (child_die, type, fi, template_args, cu);
 }
 
 /* Finish creating a structure or union type, including filling in
@@ -15255,7 +15697,7 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct die_info *child_die;
   struct type *type;
 
@@ -15263,39 +15705,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (type == NULL)
     type = read_structure_type (die, cu);
 
-  /* When reading a DW_TAG_variant_part, we need to notice when we
-     read the discriminant member, so we can record it later in the
-     discriminant_info.  */
-  bool is_variant_part = TYPE_FLAG_DISCRIMINATED_UNION (type);
-  sect_offset discr_offset {};
   bool has_template_parameters = false;
-
-  if (is_variant_part)
-    {
-      struct attribute *discr = dwarf2_attr (die, DW_AT_discr, cu);
-      if (discr == NULL)
-       {
-         /* Maybe it's a univariant form, an extension we support.
-            In this case arrange not to check the offset.  */
-         is_variant_part = false;
-       }
-      else if (discr->form_is_ref ())
-       {
-         struct dwarf2_cu *target_cu = cu;
-         struct die_info *target_die = follow_die_ref (die, discr, &target_cu);
-
-         discr_offset = target_die->sect_off;
-       }
-      else
-       {
-         complaint (_("DW_AT_discr does not have DIE reference form"
-                      " - DIE at %s [in module %s]"),
-                    sect_offset_str (die->sect_off),
-                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
-         is_variant_part = false;
-       }
-    }
-
   if (die->child != NULL && ! die_is_declaration (die, cu))
     {
       struct field_info fi;
@@ -15306,11 +15716,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       while (child_die && child_die->tag)
        {
          handle_struct_member_die (child_die, type, &fi, &template_args, cu);
-
-         if (is_variant_part && discr_offset == child_die->sect_off)
-           fi.fields.back ().variant.is_discriminant = true;
-
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
 
       /* Attach template arguments to type.  */
@@ -15351,7 +15757,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
                  int i;
 
                  /* Our own class provides vtbl ptr.  */
-                 for (i = TYPE_NFIELDS (t) - 1;
+                 for (i = t->num_fields () - 1;
                       i >= TYPE_N_BASECLASSES (t);
                       --i)
                    {
@@ -15368,7 +15774,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
                  if (i < TYPE_N_BASECLASSES (t))
                    complaint (_("virtual function table pointer "
                                 "not found when defining class '%s'"),
-                              TYPE_NAME (type) ? TYPE_NAME (type) : "");
+                              type->name () ? type->name () : "");
                }
              else
                {
@@ -15384,7 +15790,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
 
              int i;
 
-             for (i = TYPE_NFIELDS (type) - 1;
+             for (i = type->num_fields () - 1;
                   i >= TYPE_N_BASECLASSES (type);
                   --i)
                {
@@ -15458,14 +15864,15 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       else
        process_die (child_die, cu);
 
-      child_die = sibling_die (child_die);
+      child_die = child_die->sibling;
     }
 
   /* Do not consider external references.  According to the DWARF standard,
      these DIEs are identified by the fact that they have no byte_size
      attribute, and a declaration attribute.  */
   if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
-      || !die_is_declaration (die, cu))
+      || !die_is_declaration (die, cu)
+      || dwarf2_attr (die, DW_AT_signature, cu) != NULL)
     {
       struct symbol *sym = new_symbol (die, type, cu);
 
@@ -15503,8 +15910,9 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
-/* Assuming DIE is an enumeration type, and TYPE is its associated type,
-   update TYPE using some information only available in DIE's children.  */
+/* Assuming DIE is an enumeration type, and TYPE is its associated
+   type, update TYPE using some information only available in DIE's
+   children.  In particular, the fields are computed.  */
 
 static void
 update_enumeration_type_from_children (struct die_info *die,
@@ -15516,10 +15924,11 @@ update_enumeration_type_from_children (struct die_info *die,
   int flag_enum = 1;
 
   auto_obstack obstack;
+  std::vector<struct field> fields;
 
   for (child_die = die->child;
        child_die != NULL && child_die->tag;
-       child_die = sibling_die (child_die))
+       child_die = child_die->sibling)
     {
       struct attribute *attr;
       LONGEST value;
@@ -15551,10 +15960,20 @@ update_enumeration_type_from_children (struct die_info *die,
            flag_enum = 0;
        }
 
-      /* If we already know that the enum type is neither unsigned, nor
-        a flag type, no need to look at the rest of the enumerates.  */
-      if (!unsigned_enum && !flag_enum)
-       break;
+      fields.emplace_back ();
+      struct field &field = fields.back ();
+      FIELD_NAME (field) = dwarf2_physname (name, child_die, cu);
+      SET_FIELD_ENUMVAL (field, value);
+    }
+
+  if (!fields.empty ())
+    {
+      type->set_num_fields (fields.size ());
+      type->set_fields
+       ((struct field *)
+        TYPE_ALLOC (type, sizeof (struct field) * fields.size ()));
+      memcpy (type->fields (), fields.data (),
+             sizeof (struct field) * fields.size ());
     }
 
   if (unsigned_enum)
@@ -15569,7 +15988,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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   const char *name;
@@ -15577,7 +15996,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
   /* If the definition of this type lives in .debug_types, read that type.
      Don't follow DW_AT_specification though, that will take us back up
      the chain and we want to go down.  */
-  attr = dwarf2_attr_no_follow (die, DW_AT_signature);
+  attr = die->attr (DW_AT_signature);
   if (attr != nullptr)
     {
       type = get_DW_AT_signature_type (die, attr, cu);
@@ -15589,10 +16008,10 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
 
   type = alloc_type (objfile);
 
-  TYPE_CODE (type) = TYPE_CODE_ENUM;
+  type->set_code (TYPE_CODE_ENUM);
   name = dwarf2_full_name (NULL, die, cu);
   if (name != NULL)
-    TYPE_NAME (type) = name;
+    type->set_name (name);
 
   attr = dwarf2_attr (die, DW_AT_type, cu);
   if (attr != NULL)
@@ -15622,11 +16041,6 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
   if (die_is_declaration (die, cu))
     TYPE_STUB (type) = 1;
 
-  /* Finish the creation of this type by using the enum's children.
-     We must call this even when the underlying type has been provided
-     so that we can determine if we're looking at a "flag" enum.  */
-  update_enumeration_type_from_children (die, type, cu);
-
   /* If this type has an underlying type that is not a stub, then we
      may use its attributes.  We always use the "unsigned" attribute
      in this situation, because ordinarily we guess whether the type
@@ -15636,17 +16050,27 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
      the underlying type if needed.  */
   if (TYPE_TARGET_TYPE (type) != NULL && !TYPE_STUB (TYPE_TARGET_TYPE (type)))
     {
-      TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TYPE_TARGET_TYPE (type));
+      struct type *underlying_type = TYPE_TARGET_TYPE (type);
+      underlying_type = check_typedef (underlying_type);
+      TYPE_UNSIGNED (type) = TYPE_UNSIGNED (underlying_type);
       if (TYPE_LENGTH (type) == 0)
-       TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type));
+       TYPE_LENGTH (type) = TYPE_LENGTH (underlying_type);
       if (TYPE_RAW_ALIGN (type) == 0
-         && TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)) != 0)
-       set_type_align (type, TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)));
+         && TYPE_RAW_ALIGN (underlying_type) != 0)
+       set_type_align (type, TYPE_RAW_ALIGN (underlying_type));
     }
 
   TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
 
-  return set_die_type (die, type, cu);
+  set_die_type (die, type, cu);
+
+  /* Finish the creation of this type by using the enum's children.
+     Note that, as usual, this must come after set_die_type to avoid
+     infinite recursion when trying to compute the names of the
+     enumerators.  */
+  update_enumeration_type_from_children (die, type, cu);
+
+  return type;
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -15667,8 +16091,6 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (die->child != NULL)
     {
       struct die_info *child_die;
-      struct symbol *sym;
-      std::vector<struct field> fields;
       const char *name;
 
       child_die = die->child;
@@ -15682,29 +16104,10 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
            {
              name = dwarf2_name (child_die, cu);
              if (name)
-               {
-                 sym = new_symbol (child_die, this_type, cu);
-
-                 fields.emplace_back ();
-                 struct field &field = fields.back ();
-
-                 FIELD_NAME (field) = sym->linkage_name ();
-                 FIELD_TYPE (field) = NULL;
-                 SET_FIELD_ENUMVAL (field, SYMBOL_VALUE (sym));
-                 FIELD_BITSIZE (field) = 0;
-               }
+               new_symbol (child_die, this_type, cu);
            }
 
-         child_die = sibling_die (child_die);
-       }
-
-      if (!fields.empty ())
-       {
-         TYPE_NFIELDS (this_type) = fields.size ();
-         TYPE_FIELDS (this_type) = (struct field *)
-           TYPE_ALLOC (this_type, sizeof (struct field) * fields.size ());
-         memcpy (TYPE_FIELDS (this_type), fields.data (),
-                 sizeof (struct field) * fields.size ());
+         child_die = child_die->sibling;
        }
     }
 
@@ -15737,7 +16140,7 @@ 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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct die_info *child_die;
   struct type *type;
   struct type *element_type, *range_type, *index_type;
@@ -15768,7 +16171,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
          complaint (_("unable to read array DW_AT_byte_stride "
                       " - DIE at %s [in module %s]"),
                     sect_offset_str (die->sect_off),
-                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                    objfile_name (cu->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.  */
@@ -15806,7 +16209,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
              range_types.push_back (child_type);
             }
        }
-      child_die = sibling_die (child_die);
+      child_die = child_die->sibling;
     }
 
   /* Dwarf2 dimensions are output from left to right, create the
@@ -15855,7 +16258,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 
   name = dwarf2_name (die, cu);
   if (name)
-    TYPE_NAME (type) = name;
+    type->set_name (name);
 
   maybe_set_alignment (cu, die, type);
 
@@ -15944,13 +16347,12 @@ 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;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct dwarf2_locexpr_baton *baton;
   gdb_byte *ptr;
   unsigned int cu_off;
-  enum bfd_endian byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+  enum bfd_endian byte_order = gdbarch_byte_order (objfile->arch ());
   LONGEST offset = 0;
 
   gdb_assert (common_loc && member_loc);
@@ -15959,6 +16361,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
              || member_loc->form_is_constant ());
 
   baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+  baton->per_objfile = per_objfile;
   baton->per_cu = cu->per_cu;
   gdb_assert (baton->per_cu);
 
@@ -15966,7 +16369,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
 
   if (member_loc->form_is_constant ())
     {
-      offset = dwarf2_get_attr_constant_value (member_loc, 0);
+      offset = member_loc->constant_value (0);
       baton->size += 1 /* DW_OP_addr */ + cu->header.addr_size;
     }
   else
@@ -16035,7 +16438,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 
   if (die->child != NULL)
     {
-      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+      struct objfile *objfile = cu->per_objfile->objfile;
       struct die_info *child_die;
       size_t n_entries = 0, size;
       struct common_block *common_block;
@@ -16043,7 +16446,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 
       for (child_die = die->child;
           child_die && child_die->tag;
-          child_die = sibling_die (child_die))
+          child_die = child_die->sibling)
        ++n_entries;
 
       size = (sizeof (struct common_block)
@@ -16056,7 +16459,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 
       for (child_die = die->child;
           child_die && child_die->tag;
-          child_die = sibling_die (child_die))
+          child_die = child_die->sibling)
        {
          /* Create the symbol in the DW_TAG_common_block block in the current
             symbol scope.  */
@@ -16106,7 +16509,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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *previous_prefix, *name;
   int is_anonymous;
   struct type *type;
@@ -16145,7 +16548,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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   int is_anonymous;
 
   /* Add a symbol associated to this if we haven't seen the namespace
@@ -16166,7 +16569,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 
          std::vector<const char *> excludes;
          add_using_directive (using_directives (cu),
-                              previous_prefix, TYPE_NAME (type), NULL,
+                              previous_prefix, type->name (), NULL,
                               NULL, excludes, 0, &objfile->objfile_obstack);
        }
     }
@@ -16178,7 +16581,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
       while (child_die && child_die->tag)
        {
          process_die (child_die, cu);
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
     }
 }
@@ -16190,7 +16593,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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *module_name;
   struct type *type;
 
@@ -16214,7 +16617,7 @@ read_module (struct die_info *die, struct dwarf2_cu *cu)
   while (child_die && child_die->tag)
     {
       process_die (child_die, cu);
-      child_die = sibling_die (child_die);
+      child_die = child_die->sibling;
     }
 }
 
@@ -16257,8 +16660,7 @@ 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->per_cu->dwarf2_per_objfile->objfile);
+  struct gdbarch *gdbarch = cu->per_objfile->objfile->arch ();
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr_byte_size;
@@ -16316,7 +16718,7 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
          complaint (_("Invalid DW_AT_alignment"
                       " - DIE at %s [in module %s]"),
                     sect_offset_str (die->sect_off),
-                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                    objfile_name (cu->per_objfile->objfile));
        }
       else
        {
@@ -16347,15 +16749,14 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD)
+  if (check_typedef (to_type)->code () == TYPE_CODE_METHOD)
     type = lookup_methodptr_type (to_type);
-  else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC)
+  else if (check_typedef (to_type)->code () == TYPE_CODE_FUNC)
     {
-      struct type *new_type
-       = alloc_type (cu->per_cu->dwarf2_per_objfile->objfile);
+      struct type *new_type = alloc_type (cu->per_objfile->objfile);
 
       smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
-                           TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type),
+                           to_type->fields (), to_type->num_fields (),
                            TYPE_VARARGS (to_type));
       type = lookup_methodptr_type (new_type);
     }
@@ -16414,7 +16815,7 @@ add_array_cv_type (struct die_info *die, struct dwarf2_cu *cu,
   base_type = copy_type (base_type);
   inner_array = base_type;
 
-  while (TYPE_CODE (TYPE_TARGET_TYPE (inner_array)) == TYPE_CODE_ARRAY)
+  while (TYPE_TARGET_TYPE (inner_array)->code () == TYPE_CODE_ARRAY)
     {
       TYPE_TARGET_TYPE (inner_array) =
        copy_type (TYPE_TARGET_TYPE (inner_array));
@@ -16443,7 +16844,7 @@ read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
 
   /* In case the const qualifier is applied to an array type, the element type
      is so qualified, not the array type (section 6.7.3 of C99).  */
-  if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+  if (base_type->code () == TYPE_CODE_ARRAY)
     return add_array_cv_type (die, cu, base_type, 1, 0);
 
   cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
@@ -16465,7 +16866,7 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
   /* In case the volatile qualifier is applied to an array type, the
      element type is so qualified, not the array type (section 6.7.3
      of C99).  */
-  if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+  if (base_type->code () == TYPE_CODE_ARRAY)
     return add_array_cv_type (die, cu, base_type, 0, 1);
 
   cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
@@ -16516,8 +16917,8 @@ 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->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct objfile *objfile = cu->per_objfile->objfile;
+  struct gdbarch *gdbarch = objfile->arch ();
   struct type *type, *range_type, *index_type, *char_type;
   struct attribute *attr;
   struct dynamic_prop prop;
@@ -16558,7 +16959,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
        {
          /* Pass 0 as the default as we know this attribute is constant
             and the default value will not be returned.  */
-         LONGEST sz = dwarf2_get_attr_constant_value (len, 0);
+         LONGEST sz = len->constant_value (0);
          prop_type = cu->per_cu->int_type (sz, true);
        }
       else
@@ -16580,12 +16981,12 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
         indirection.  There's no need to create a dynamic property in this
         case.  Pass 0 for the default value as we know it will not be
         returned in this case.  */
-      length = dwarf2_get_attr_constant_value (attr, 0);
+      length = attr->constant_value (0);
     }
   else if ((attr = dwarf2_attr (die, DW_AT_byte_size, cu)) != nullptr)
     {
       /* We don't currently support non-constant byte sizes for strings.  */
-      length = dwarf2_get_attr_constant_value (attr, 1);
+      length = attr->constant_value (1);
     }
   else
     {
@@ -16655,7 +17056,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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct type *type;           /* Type that this function returns.  */
   struct type *ftype;          /* Function that returns above type.  */
   struct attribute *attr;
@@ -16713,13 +17114,13 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
            nparams++;
          else if (child_die->tag == DW_TAG_unspecified_parameters)
            TYPE_VARARGS (ftype) = 1;
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
 
       /* Allocate storage for parameters and fill them in.  */
-      TYPE_NFIELDS (ftype) = nparams;
-      TYPE_FIELDS (ftype) = (struct field *)
-       TYPE_ZALLOC (ftype, nparams * sizeof (struct field));
+      ftype->set_num_fields (nparams);
+      ftype->set_fields
+       ((struct field *) TYPE_ZALLOC (ftype, nparams * sizeof (struct field)));
 
       /* TYPE_FIELD_TYPE must never be NULL.  Pre-fill the array to ensure it
         even if we error out during the parameters reading below.  */
@@ -16784,7 +17185,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
              TYPE_FIELD_TYPE (ftype, iparams) = arg_type;
              iparams++;
            }
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
     }
 
@@ -16794,7 +17195,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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *name = NULL;
   struct type *this_type, *target_type;
 
@@ -16835,7 +17236,7 @@ static struct type *
 dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name,
                        const char *name_hint, enum bfd_endian byte_order)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   const struct floatformat **format;
   struct type *type;
 
@@ -16883,7 +17284,7 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
                                 int bits, const char *name_hint,
                                 enum bfd_endian byte_order)
 {
-  gdbarch *gdbarch = get_objfile_arch (objfile);
+  gdbarch *gdbarch = objfile->arch ();
   struct type *tt = nullptr;
 
   /* Try to find a suitable floating point builtin type of size BITS.
@@ -16929,7 +17330,7 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
   if (tt != nullptr && TYPE_LENGTH (tt) * TARGET_CHAR_BIT != bits)
     tt = nullptr;
 
-  const char *name = (tt == nullptr) ? nullptr : TYPE_NAME (tt);
+  const char *name = (tt == nullptr) ? nullptr : tt->name ();
   return dwarf2_init_float_type (objfile, bits, name, name_hint, byte_order);
 }
 
@@ -16939,7 +17340,7 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
 static struct type *
 read_base_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   int encoding = 0, bits = 0;
@@ -16956,7 +17357,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
   if (!name)
     complaint (_("DW_AT_name missing from DW_TAG_base_type"));
 
-  arch = get_objfile_arch (objfile);
+  arch = objfile->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (arch);
 
   attr = dwarf2_attr (die, DW_AT_endianity, cu);
@@ -16991,7 +17392,19 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
       case DW_ATE_complex_float:
        type = dwarf2_init_complex_target_type (cu, objfile, bits / 2, name,
                                                byte_order);
-       type = init_complex_type (objfile, name, type);
+       if (type->code () == TYPE_CODE_ERROR)
+         {
+           if (name == nullptr)
+             {
+               struct obstack *obstack
+                 = &cu->per_objfile->objfile->objfile_obstack;
+               name = obconcat (obstack, "_Complex ", type->name (),
+                                nullptr);
+             }
+           type = init_type (objfile, TYPE_CODE_ERROR, bits, name);
+         }
+       else
+         type = init_complex_type (name, type);
        break;
       case DW_ATE_decimal_float:
        type = init_decfloat_type (objfile, bits, name);
@@ -17070,8 +17483,9 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
                      struct type *default_type)
 {
   struct dwarf2_property_baton *baton;
-  struct obstack *obstack
-    = &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
+  struct obstack *obstack = &objfile->objfile_obstack;
 
   gdb_assert (default_type != NULL);
 
@@ -17083,6 +17497,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
       baton = XOBNEW (obstack, struct dwarf2_property_baton);
       baton->property_type = default_type;
       baton->locexpr.per_cu = cu->per_cu;
+      baton->locexpr.per_objfile = per_objfile;
       baton->locexpr.size = DW_BLOCK (attr)->size;
       baton->locexpr.data = DW_BLOCK (attr)->data;
       switch (attr->name)
@@ -17129,6 +17544,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
                baton = XOBNEW (obstack, struct dwarf2_property_baton);
                baton->property_type = die_type (target_die, target_cu);
                baton->locexpr.per_cu = cu->per_cu;
+               baton->locexpr.per_objfile = per_objfile;
                baton->locexpr.size = DW_BLOCK (target_attr)->size;
                baton->locexpr.data = DW_BLOCK (target_attr)->data;
                baton->locexpr.is_reference = true;
@@ -17164,7 +17580,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
     }
   else if (attr->form_is_constant ())
     {
-      prop->data.const_val = dwarf2_get_attr_constant_value (attr, 0);
+      prop->data.const_val = attr->constant_value (0);
       prop->kind = PROP_CONST;
     }
   else
@@ -17234,7 +17650,7 @@ read_subrange_index_type (struct die_info *die, struct dwarf2_cu *cu)
      GCC produces an empty range DIE.
      FIXME: muller/2010-05-28: Possible references to object for low bound,
      high bound or count are not yet handled by this code.  */
-  if (TYPE_CODE (index_type) == TYPE_CODE_VOID)
+  if (index_type->code () == TYPE_CODE_VOID)
     index_type = cu->per_cu->addr_sized_int_type (false);
 
   return index_type;
@@ -17309,7 +17725,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
     complaint (_("Missing DW_AT_lower_bound "
                                      "- DIE at %s [in module %s]"),
               sect_offset_str (die->sect_off),
-              objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+              objfile_name (cu->per_objfile->objfile));
 
   struct attribute *attr_ub, *attr_count;
   attr = attr_ub = dwarf2_attr (die, DW_AT_upper_bound, cu);
@@ -17330,19 +17746,19 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
            complaint (_("Unresolved DW_AT_upper_bound "
                         "- DIE at %s [in module %s]"),
                       sect_offset_str (die->sect_off),
-                      objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                      objfile_name (cu->per_objfile->objfile));
          if (attr_count != NULL)
            complaint (_("Unresolved DW_AT_count "
                         "- DIE at %s [in module %s]"),
                       sect_offset_str (die->sect_off),
-                      objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                      objfile_name (cu->per_objfile->objfile));
        }
     }
 
   LONGEST bias = 0;
   struct attribute *bias_attr = dwarf2_attr (die, DW_AT_GNU_bias, cu);
   if (bias_attr != nullptr && bias_attr->form_is_constant ())
-    bias = dwarf2_get_attr_constant_value (bias_attr, 0);
+    bias = bias_attr->constant_value (0);
 
   /* Normally, the DWARF producers are expected to use a signed
      constant form (Eg. DW_FORM_sdata) to express negative bounds.
@@ -17380,7 +17796,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
          complaint (_("Found DW_AT_bit_stride and DW_AT_byte_stride "
                       "- DIE at %s [in module %s]"),
                     sect_offset_str (die->sect_off),
-                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                    objfile_name (cu->per_objfile->objfile));
          attr_bit_stride = nullptr;
        }
       else
@@ -17414,7 +17830,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   name = dwarf2_name (die, cu);
   if (name)
-    TYPE_NAME (range_type) = name;
+    range_type->set_name (name);
 
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr != nullptr)
@@ -17435,9 +17851,8 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *type;
 
-  type = init_type (cu->per_cu->dwarf2_per_objfile->objfile, TYPE_CODE_VOID,0,
-                   NULL);
-  TYPE_NAME (type) = dwarf2_name (die, cu);
+  type = init_type (cu->per_objfile->objfile, TYPE_CODE_VOID, 0, NULL);
+  type->set_name (dwarf2_name (die, cu));
 
   /* In Ada, an unspecified type is typically used when the description
      of the type is deferred to a different unit.  When encountering
@@ -17603,11 +18018,15 @@ read_full_die_1 (const struct die_reader_specs *reader,
         indexes_that_need_reprocess.push_back (i);
     }
 
-  struct attribute *attr = dwarf2_attr_no_follow (die, DW_AT_str_offsets_base);
+  struct attribute *attr = die->attr (DW_AT_str_offsets_base);
   if (attr != nullptr)
     cu->str_offsets_base = DW_UNSND (attr);
 
-  auto maybe_addr_base = lookup_addr_base(die);
+  attr = die->attr (DW_AT_loclists_base);
+  if (attr != nullptr)
+    cu->loclist_base = DW_UNSND (attr);
+
+  auto maybe_addr_base = die->addr_base ();
   if (maybe_addr_base.has_value ())
     cu->addr_base = *maybe_addr_base;
   for (int index : indexes_that_need_reprocess)
@@ -17681,7 +18100,7 @@ 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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct partial_die_info *parent_die, *last_die, *first_die = NULL;
   unsigned int bytes_read;
   unsigned int load_all = 0;
@@ -17955,25 +18374,23 @@ partial_die_info::read (const struct die_reader_specs *reader,
                        const struct abbrev_info &abbrev, const gdb_byte *info_ptr)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   unsigned int i;
   int has_low_pc_attr = 0;
   int has_high_pc_attr = 0;
   int high_pc_relative = 0;
 
-  std::vector<struct attribute> attr_vec (abbrev.num_attrs);
   for (i = 0; i < abbrev.num_attrs; ++i)
     {
+      attribute attr;
       bool need_reprocess;
-      info_ptr = read_attribute (reader, &attr_vec[i], &abbrev.attrs[i],
+      info_ptr = read_attribute (reader, &attr, &abbrev.attrs[i],
                                 info_ptr, &need_reprocess);
       /* String and address offsets that need to do the reprocessing have
          already been read at this point, so there is no need to wait until
         the loop terminates to do the reprocessing.  */
       if (need_reprocess)
-       read_attribute_reprocess (reader, &attr_vec[i]);
-      attribute &attr = attr_vec[i];
+       read_attribute_reprocess (reader, &attr);
       /* Store the data if it is of an attribute we want to keep in a
          partial symbol table.  */
       switch (attr.name)
@@ -18007,7 +18424,12 @@ partial_die_info::read (const struct die_reader_specs *reader,
          /* Note that both forms of linkage name might appear.  We
             assume they will be the same, and we only store the last
             one we see.  */
-         linkage_name = DW_STRING (&attr);
+         linkage_name = attr.value_as_string ();
+         /* rustc emits invalid values for DW_AT_linkage_name.  Ignore these.
+            See https://github.com/rust-lang/rust/issues/32925.  */
+         if (cu->language == language_rust && linkage_name != NULL
+             && strchr (linkage_name, '{') != NULL)
+           linkage_name = NULL;
          break;
        case DW_AT_low_pc:
          has_low_pc_attr = 1;
@@ -18048,7 +18470,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
        case DW_AT_specification:
        case DW_AT_extension:
          has_specification = 1;
-         spec_offset = dwarf2_get_ref_die_offset (&attr);
+         spec_offset = attr.get_ref_die_offset ();
          spec_is_dwz = (attr.form == DW_FORM_GNU_ref_alt
                                   || cu->per_cu->is_dwz);
          break;
@@ -18060,7 +18482,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
          else
            {
              const gdb_byte *buffer = reader->buffer;
-             sect_offset off = dwarf2_get_ref_die_offset (&attr);
+             sect_offset off = attr.get_ref_die_offset ();
              const gdb_byte *sibling_ptr = buffer + to_underlying (off);
 
              if (sibling_ptr < info_ptr)
@@ -18105,7 +18527,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
        case DW_AT_import:
          if (tag == DW_TAG_imported_unit)
            {
-             d.sect_off = dwarf2_get_ref_die_offset (&attr);
+             d.sect_off = attr.get_ref_die_offset ();
              is_dwz = (attr.form == DW_FORM_GNU_ref_alt
                                  || cu->per_cu->is_dwz);
            }
@@ -18160,10 +18582,10 @@ partial_die_info::read (const struct die_reader_specs *reader,
         labels are not in the output, so the relocs get a value of 0.
         If this is a discarded function, mark the pc bounds as invalid,
         so that GDB will ignore it.  */
-      if (lowpc == 0 && !dwarf2_per_objfile->has_section_at_zero)
+      if (lowpc == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
        {
          struct objfile *objfile = dwarf2_per_objfile->objfile;
-         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         struct gdbarch *gdbarch = objfile->arch ();
 
          complaint (_("DW_AT_low_pc %s is zero "
                       "for DIE at %s [in module %s]"),
@@ -18175,7 +18597,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
       else if (lowpc >= highpc)
        {
          struct objfile *objfile = dwarf2_per_objfile->objfile;
-         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         struct gdbarch *gdbarch = objfile->arch ();
 
          complaint (_("DW_AT_low_pc %s is not < DW_AT_high_pc %s "
                       "for DIE at %s [in module %s]"),
@@ -18214,8 +18636,7 @@ dwarf2_cu::find_partial_die (sect_offset sect_off)
 static const struct cu_partial_die_info
 find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *per_cu = NULL;
   struct partial_die_info *pd = NULL;
@@ -18321,7 +18742,7 @@ 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 objfile *objfile = cu->per_objfile->objfile;
              struct_pdi->name = objfile->intern (actual_class_name.get ());
            }
          break;
@@ -18329,6 +18750,25 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
     }
 }
 
+/* Return true if a DIE with TAG may have the DW_AT_const_value
+   attribute.  */
+
+static bool
+can_have_DW_AT_const_value_p (enum dwarf_tag tag)
+{
+  switch (tag)
+    {
+    case DW_TAG_constant:
+    case DW_TAG_enumerator:
+    case DW_TAG_formal_parameter:
+    case DW_TAG_template_value_param:
+    case DW_TAG_variable:
+      return true;
+    }
+
+  return false;
+}
+
 void
 partial_die_info::fixup (struct dwarf2_cu *cu)
 {
@@ -18361,6 +18801,24 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
        }
     }
 
+  if (!has_const_value && has_specification
+      && can_have_DW_AT_const_value_p (tag))
+    {
+      struct partial_die_info *spec_die;
+
+      auto res = find_partial_die (spec_offset, spec_is_dwz, cu);
+      spec_die = res.pdi;
+      cu = res.cu;
+
+      spec_die->fixup (cu);
+
+      if (spec_die->has_const_value)
+       {
+         /* Copy DW_AT_const_value attribute if it is set.  */
+         has_const_value = spec_die->has_const_value;
+       }
+    }
+
   /* Set default names for some unnamed DIEs.  */
 
   if (name == NULL && tag == DW_TAG_namespace)
@@ -18370,7 +18828,7 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
      children, see if we can determine the namespace from their linkage
      name.  */
   if (cu->language == language_cplus
-      && !cu->per_cu->dwarf2_per_objfile->types.empty ()
+      && !cu->per_objfile->per_bfd->types.empty ()
       && die_parent == NULL
       && has_children
       && (tag == DW_TAG_class_type
@@ -18401,7 +18859,7 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
          else
            base = demangled.get ();
 
-         struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+         struct objfile *objfile = cu->per_objfile->objfile;
          name = objfile->intern (base);
        }
     }
@@ -18409,12 +18867,90 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
   fixup_called = 1;
 }
 
+/* Read the .debug_loclists header contents from the given SECTION in the
+   HEADER.  */
+static void
+read_loclist_header (struct loclist_header *header,
+                     struct dwarf2_section_info *section)
+{
+  unsigned int bytes_read;
+  bfd *abfd = section->get_bfd_owner ();
+  const gdb_byte *info_ptr = section->buffer;
+  header->length = read_initial_length (abfd, info_ptr, &bytes_read);
+  info_ptr += bytes_read;
+  header->version = read_2_bytes (abfd, info_ptr);
+  info_ptr += 2;
+  header->addr_size = read_1_byte (abfd, info_ptr);
+  info_ptr += 1;
+  header->segment_collector_size = read_1_byte (abfd, info_ptr);
+  info_ptr += 1;
+  header->offset_entry_count = read_4_bytes (abfd, info_ptr);
+}
+
+/* Return the DW_AT_loclists_base value for the CU.  */
+static ULONGEST
+lookup_loclist_base (struct dwarf2_cu *cu)
+{
+  /* For the .dwo unit, the loclist_base points to the first offset following
+     the header. The header consists of the following entities-
+     1. Unit Length (4 bytes for 32 bit DWARF format, and 12 bytes for the 64
+        bit format)
+     2. version (2 bytes)
+     3. address size (1 byte)
+     4. segment selector size (1 byte)
+     5. offset entry count (4 bytes)
+     These sizes are derived as per the DWARFv5 standard.  */
+  if (cu->dwo_unit != nullptr)
+    {
+      if (cu->header.initial_length_size == 4)
+        return LOCLIST_HEADER_SIZE32;
+      return LOCLIST_HEADER_SIZE64;
+    }
+  return cu->loclist_base;
+}
+
+/* Given a DW_FORM_loclistx value LOCLIST_INDEX, fetch the offset from the
+   array of offsets in the .debug_loclists section.  */
+static CORE_ADDR
+read_loclist_index (struct dwarf2_cu *cu, ULONGEST loclist_index)
+{
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  bfd *abfd = objfile->obfd;
+  ULONGEST loclist_base = lookup_loclist_base (cu);
+  struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+
+  section->read (objfile);
+  if (section->buffer == NULL)
+    complaint (_("DW_FORM_loclistx used without .debug_loclists "
+               "section [in module %s]"), objfile_name (objfile));
+  struct loclist_header header;
+  read_loclist_header (&header, section);
+  if (loclist_index >= header.offset_entry_count)
+    complaint (_("DW_FORM_loclistx pointing outside of "
+               ".debug_loclists offset array [in module %s]"),
+               objfile_name (objfile));
+  if (loclist_base + loclist_index * cu->header.offset_size
+       >= section->size)
+    complaint (_("DW_FORM_loclistx pointing outside of "
+               ".debug_loclists section [in module %s]"),
+               objfile_name (objfile));
+  const gdb_byte *info_ptr
+    = section->buffer + loclist_base + loclist_index * cu->header.offset_size;
+
+  if (cu->header.offset_size == 4)
+    return bfd_get_32 (abfd, info_ptr) + loclist_base;
+  else
+    return bfd_get_64 (abfd, info_ptr) + loclist_base;
+}
+
 /* Process the attributes that had to be skipped in the first round. These
    attributes are the ones that need str_offsets_base or addr_base attributes.
    They could not have been processed in the first round, because at the time
    the values of str_offsets_base or addr_base may not have been known.  */
-void read_attribute_reprocess (const struct die_reader_specs *reader,
-                              struct attribute *attr)
+static void
+read_attribute_reprocess (const struct die_reader_specs *reader,
+                         struct attribute *attr)
 {
   struct dwarf2_cu *cu = reader->cu;
   switch (attr->form)
@@ -18423,6 +18959,9 @@ void read_attribute_reprocess (const struct die_reader_specs *reader,
       case DW_FORM_GNU_addr_index:
         DW_ADDR (attr) = read_addr_index (cu, DW_UNSND (attr));
         break;
+      case DW_FORM_loclistx:
+        DW_UNSND (attr) = read_loclist_index (cu, DW_UNSND (attr));
+        break;
       case DW_FORM_strx:
       case DW_FORM_strx1:
       case DW_FORM_strx2:
@@ -18457,10 +18996,8 @@ read_attribute_value (const struct die_reader_specs *reader,
                      bool *need_reprocess)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->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;
   unsigned int bytes_read;
@@ -18484,9 +19021,12 @@ read_attribute_value (const struct die_reader_specs *reader,
       info_ptr += bytes_read;
       break;
     case DW_FORM_addr:
-      DW_ADDR (attr) = cu->header.read_address (abfd, info_ptr, &bytes_read);
-      DW_ADDR (attr) = gdbarch_adjust_dwarf2_addr (gdbarch, DW_ADDR (attr));
-      info_ptr += bytes_read;
+      {
+       struct gdbarch *gdbarch = objfile->arch ();
+       DW_ADDR (attr) = cu->header.read_address (abfd, info_ptr, &bytes_read);
+       DW_ADDR (attr) = gdbarch_adjust_dwarf2_addr (gdbarch, DW_ADDR (attr));
+       info_ptr += bytes_read;
+      }
       break;
     case DW_FORM_block2:
       blk = dwarf_alloc_block (cu);
@@ -18527,6 +19067,13 @@ read_attribute_value (const struct die_reader_specs *reader,
       DW_UNSND (attr) = cu->header.read_offset (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
       break;
+    case DW_FORM_loclistx:
+      {
+        *need_reprocess = true;
+        DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+        info_ptr += bytes_read;
+      }
+      break;
     case DW_FORM_string:
       DW_STRING (attr) = read_direct_string (abfd, info_ptr, &bytes_read);
       DW_STRING_IS_CANONICAL (attr) = 0;
@@ -18730,41 +19277,14 @@ read_attribute (const struct die_reader_specs *reader,
                               need_reprocess);
 }
 
-/* Cover function for read_initial_length.
-   Returns the length of the object at BUF, and stores the size of the
-   initial length in *BYTES_READ and stores the size that offsets will be in
-   *OFFSET_SIZE.
-   If the initial length size is not equivalent to that specified in
-   CU_HEADER then issue a complaint.
-   This is useful when reading non-comp-unit headers.  */
-
-static LONGEST
-read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf,
-                                       const struct comp_unit_head *cu_header,
-                                       unsigned int *bytes_read,
-                                       unsigned int *offset_size)
-{
-  LONGEST length = read_initial_length (abfd, buf, bytes_read);
-
-  gdb_assert (cu_header->initial_length_size == 4
-             || cu_header->initial_length_size == 8
-             || cu_header->initial_length_size == 12);
-
-  if (cu_header->initial_length_size != *bytes_read)
-    complaint (_("intermixed 32-bit and 64-bit DWARF sections"));
-
-  *offset_size = (*bytes_read == 4) ? 4 : 8;
-  return length;
-}
-
 /* Return pointer to string at .debug_str offset STR_OFFSET.  */
 
 static const char *
 read_indirect_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
                                LONGEST str_offset)
 {
-  return dwarf2_per_objfile->str.read_string (dwarf2_per_objfile->objfile,
-                                             str_offset, "DW_FORM_strp");
+  return dwarf2_per_objfile->per_bfd->str.read_string
+    (dwarf2_per_objfile->objfile, str_offset, "DW_FORM_strp");
 }
 
 /* Return pointer to string at .debug_str offset as read from BUF.
@@ -18786,13 +19306,13 @@ read_indirect_string (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
 
 const char *
 dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
-                          const struct comp_unit_head *cu_header,
-                          unsigned int *bytes_read_ptr)
+                                     const struct comp_unit_head *cu_header,
+                                     unsigned int *bytes_read_ptr)
 {
   bfd *abfd = objfile->obfd;
   LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr);
 
-  return line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
+  return per_bfd->line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
 }
 
 /* Given index ADDR_INDEX in .debug_addr, fetch the value.
@@ -18809,16 +19329,16 @@ read_addr_index_1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
   const gdb_byte *info_ptr;
   ULONGEST addr_base_or_zero = addr_base.has_value () ? *addr_base : 0;
 
-  dwarf2_per_objfile->addr.read (objfile);
-  if (dwarf2_per_objfile->addr.buffer == NULL)
+  dwarf2_per_objfile->per_bfd->addr.read (objfile);
+  if (dwarf2_per_objfile->per_bfd->addr.buffer == NULL)
     error (_("DW_FORM_addr_index used without .debug_addr section [in module %s]"),
           objfile_name (objfile));
   if (addr_base_or_zero + addr_index * addr_size
-      >= dwarf2_per_objfile->addr.size)
+      >= dwarf2_per_objfile->per_bfd->addr.size)
     error (_("DW_FORM_addr_index pointing outside of "
             ".debug_addr section [in module %s]"),
           objfile_name (objfile));
-  info_ptr = (dwarf2_per_objfile->addr.buffer
+  info_ptr = (dwarf2_per_objfile->per_bfd->addr.buffer
              + addr_base_or_zero + addr_index * addr_size);
   if (addr_size == 4)
     return bfd_get_32 (abfd, info_ptr);
@@ -18831,7 +19351,7 @@ read_addr_index_1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 static CORE_ADDR
 read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
 {
-  return read_addr_index_1 (cu->per_cu->dwarf2_per_objfile, addr_index,
+  return read_addr_index_1 (cu->per_objfile, addr_index,
                            cu->addr_base, cu->header.addr_size);
 }
 
@@ -18841,7 +19361,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->per_cu->dwarf2_per_objfile->objfile->obfd;
+  bfd *abfd = cu->per_objfile->objfile->obfd;
   unsigned int addr_index = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
 
   return read_addr_index (cu, addr_index);
@@ -18899,8 +19419,7 @@ read_str_index (struct dwarf2_cu *cu,
                struct dwarf2_section_info *str_offsets_section,
                ULONGEST str_offsets_base, ULONGEST str_index)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   const char *objf_name = objfile_name (objfile);
   bfd *abfd = objfile->obfd;
@@ -18952,7 +19471,7 @@ read_dwo_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
 static const char *
 read_stub_str_index (struct dwarf2_cu *cu, ULONGEST str_index)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *objf_name = objfile_name (objfile);
   static const char form_name[] = "DW_FORM_GNU_str_index";
   static const char str_offsets_attr_name[] = "DW_AT_str_offsets";
@@ -18964,8 +19483,8 @@ read_stub_str_index (struct dwarf2_cu *cu, ULONGEST str_index)
           (long) cu->header.offset_size, objf_name);
 
   return read_str_index (cu,
-                        &cu->per_cu->dwarf2_per_objfile->str,
-                        &cu->per_cu->dwarf2_per_objfile->str_offsets,
+                        &cu->per_objfile->per_bfd->str,
+                        &cu->per_objfile->per_bfd->str_offsets,
                         *cu->str_offsets_base, str_index);
 }
 
@@ -19073,24 +19592,6 @@ dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
   return NULL;
 }
 
-/* Return the named attribute or NULL if not there,
-   but do not follow DW_AT_specification, etc.
-   This is for use in contexts where we're reading .debug_types dies.
-   Following DW_AT_specification, DW_AT_abstract_origin will take us
-   back up the chain, and we want to go down.  */
-
-static struct attribute *
-dwarf2_attr_no_follow (struct die_info *die, unsigned int name)
-{
-  unsigned int i;
-
-  for (i = 0; i < die->num_attrs; ++i)
-    if (die->attrs[i].name == name)
-      return &die->attrs[i];
-
-  return NULL;
-}
-
 /* Return the string associated with a string-typed attribute, or NULL if it
    is either not found or is of an incorrect type.  */
 
@@ -19104,21 +19605,12 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c
 
   if (attr != NULL)
     {
-      if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp
-         || attr->form == DW_FORM_string
-         || attr->form == DW_FORM_strx
-         || attr->form == DW_FORM_strx1
-         || attr->form == DW_FORM_strx2
-         || attr->form == DW_FORM_strx3
-         || attr->form == DW_FORM_strx4
-         || attr->form == DW_FORM_GNU_str_index
-         || attr->form == DW_FORM_GNU_strp_alt)
-       str = DW_STRING (attr);
-      else
+      str = attr->value_as_string ();
+      if (str == nullptr)
         complaint (_("string type expected for attribute %s for "
                     "DIE at %s in module %s"),
                   dwarf_attr_name (name), sect_offset_str (die->sect_off),
-                  objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+                  objfile_name (cu->per_objfile->objfile));
     }
 
   return str;
@@ -19198,8 +19690,7 @@ 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;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
      DWO file.  */
@@ -19212,145 +19703,11 @@ get_debug_line_section (struct dwarf2_cu *cu)
       section = &dwz->line;
     }
   else
-    section = &dwarf2_per_objfile->line;
+    section = &dwarf2_per_objfile->per_bfd->line;
 
   return section;
 }
 
-/* Read directory or file name entry format, starting with byte of
-   format count entries, ULEB128 pairs of entry formats, ULEB128 of
-   entries count and the entries themselves in the described entry
-   format.  */
-
-static void
-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,
-                                         const char *name,
-                                         dir_index d_index,
-                                         unsigned int mod_time,
-                                         unsigned int length))
-{
-  gdb_byte format_count, formati;
-  ULONGEST data_count, datai;
-  const gdb_byte *buf = *bufp;
-  const gdb_byte *format_header_data;
-  unsigned int bytes_read;
-
-  format_count = read_1_byte (abfd, buf);
-  buf += 1;
-  format_header_data = buf;
-  for (formati = 0; formati < format_count; formati++)
-    {
-      read_unsigned_leb128 (abfd, buf, &bytes_read);
-      buf += bytes_read;
-      read_unsigned_leb128 (abfd, buf, &bytes_read);
-      buf += bytes_read;
-    }
-
-  data_count = read_unsigned_leb128 (abfd, buf, &bytes_read);
-  buf += bytes_read;
-  for (datai = 0; datai < data_count; datai++)
-    {
-      const gdb_byte *format = format_header_data;
-      struct file_entry fe;
-
-      for (formati = 0; formati < format_count; formati++)
-       {
-         ULONGEST content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
-         format += bytes_read;
-
-         ULONGEST form  = read_unsigned_leb128 (abfd, format, &bytes_read);
-         format += bytes_read;
-
-         gdb::optional<const char *> string;
-         gdb::optional<unsigned int> uint;
-
-         switch (form)
-           {
-           case DW_FORM_string:
-             string.emplace (read_direct_string (abfd, buf, &bytes_read));
-             buf += bytes_read;
-             break;
-
-           case DW_FORM_line_strp:
-             string.emplace
-               (dwarf2_per_objfile->read_line_string (buf,
-                                                      cu_header,
-                                                      &bytes_read));
-             buf += bytes_read;
-             break;
-
-           case DW_FORM_data1:
-             uint.emplace (read_1_byte (abfd, buf));
-             buf += 1;
-             break;
-
-           case DW_FORM_data2:
-             uint.emplace (read_2_bytes (abfd, buf));
-             buf += 2;
-             break;
-
-           case DW_FORM_data4:
-             uint.emplace (read_4_bytes (abfd, buf));
-             buf += 4;
-             break;
-
-           case DW_FORM_data8:
-             uint.emplace (read_8_bytes (abfd, buf));
-             buf += 8;
-             break;
-
-           case DW_FORM_data16:
-             /*  This is used for MD5, but file_entry does not record MD5s. */
-             buf += 16;
-             break;
-
-           case DW_FORM_udata:
-             uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read));
-             buf += bytes_read;
-             break;
-
-           case DW_FORM_block:
-             /* It is valid only for DW_LNCT_timestamp which is ignored by
-                current GDB.  */
-             break;
-           }
-
-         switch (content_type)
-           {
-           case DW_LNCT_path:
-             if (string.has_value ())
-               fe.name = *string;
-             break;
-           case DW_LNCT_directory_index:
-             if (uint.has_value ())
-               fe.d_index = (dir_index) *uint;
-             break;
-           case DW_LNCT_timestamp:
-             if (uint.has_value ())
-               fe.mod_time = *uint;
-             break;
-           case DW_LNCT_size:
-             if (uint.has_value ())
-               fe.length = *uint;
-             break;
-           case DW_LNCT_MD5:
-             break;
-           default:
-             complaint (_("Unknown format content type %s"),
-                        pulongest (content_type));
-           }
-       }
-
-      callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
-    }
-
-  *bufp = buf;
-}
-
 /* Read the statement program header starting at OFFSET in
    .debug_line, or .debug_line.dwo.  Return a pointer
    to a struct line_header, allocated using xmalloc.
@@ -19364,14 +19721,8 @@ read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
 static line_header_up
 dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
 {
-  const gdb_byte *line_ptr;
-  unsigned int bytes_read, offset_size;
-  int i;
-  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;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   section = get_debug_line_section (cu);
   section->read (dwarf2_per_objfile->objfile);
@@ -19384,159 +19735,9 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
       return 0;
     }
 
-  /* We can't do this until we know the section is non-empty.
-     Only then do we know we have such a section.  */
-  abfd = section->get_bfd_owner ();
-
-  /* Make sure that at least there's room for the total_length field.
-     That could be 12 bytes long, but we're just going to fudge that.  */
-  if (to_underlying (sect_off) + 4 >= section->size)
-    {
-      dwarf2_statement_list_fits_in_line_number_section_complaint ();
-      return 0;
-    }
-
-  line_header_up lh (new line_header ());
-
-  lh->sect_off = sect_off;
-  lh->offset_in_dwz = cu->per_cu->is_dwz;
-
-  line_ptr = section->buffer + to_underlying (sect_off);
-
-  /* Read in the header.  */
-  lh->total_length =
-    read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header,
-                                           &bytes_read, &offset_size);
-  line_ptr += bytes_read;
-
-  const gdb_byte *start_here = line_ptr;
-
-  if (line_ptr + lh->total_length > (section->buffer + section->size))
-    {
-      dwarf2_statement_list_fits_in_line_number_section_complaint ();
-      return 0;
-    }
-  lh->statement_program_end = start_here + lh->total_length;
-  lh->version = read_2_bytes (abfd, line_ptr);
-  line_ptr += 2;
-  if (lh->version > 5)
-    {
-      /* This is a version we don't understand.  The format could have
-        changed in ways we don't handle properly so just punt.  */
-      complaint (_("unsupported version in .debug_line section"));
-      return NULL;
-    }
-  if (lh->version >= 5)
-    {
-      gdb_byte segment_selector_size;
-
-      /* Skip address size.  */
-      read_1_byte (abfd, line_ptr);
-      line_ptr += 1;
-
-      segment_selector_size = read_1_byte (abfd, line_ptr);
-      line_ptr += 1;
-      if (segment_selector_size != 0)
-       {
-         complaint (_("unsupported segment selector size %u "
-                      "in .debug_line section"),
-                    segment_selector_size);
-         return NULL;
-       }
-    }
-  lh->header_length = read_offset (abfd, line_ptr, offset_size);
-  line_ptr += offset_size;
-  lh->statement_program_start = line_ptr + lh->header_length;
-  lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
-  line_ptr += 1;
-  if (lh->version >= 4)
-    {
-      lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr);
-      line_ptr += 1;
-    }
-  else
-    lh->maximum_ops_per_instruction = 1;
-
-  if (lh->maximum_ops_per_instruction == 0)
-    {
-      lh->maximum_ops_per_instruction = 1;
-      complaint (_("invalid maximum_ops_per_instruction "
-                  "in `.debug_line' section"));
-    }
-
-  lh->default_is_stmt = read_1_byte (abfd, line_ptr);
-  line_ptr += 1;
-  lh->line_base = read_1_signed_byte (abfd, line_ptr);
-  line_ptr += 1;
-  lh->line_range = read_1_byte (abfd, line_ptr);
-  line_ptr += 1;
-  lh->opcode_base = read_1_byte (abfd, line_ptr);
-  line_ptr += 1;
-  lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
-
-  lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
-  for (i = 1; i < lh->opcode_base; ++i)
-    {
-      lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
-      line_ptr += 1;
-    }
-
-  if (lh->version >= 5)
-    {
-      /* Read directory table.  */
-      read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
-                             &cu->header,
-                             [] (struct line_header *header, const char *name,
-                                 dir_index d_index, unsigned int mod_time,
-                                 unsigned int length)
-       {
-         header->add_include_dir (name);
-       });
-
-      /* Read file name table.  */
-      read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
-                             &cu->header,
-                             [] (struct line_header *header, const char *name,
-                                 dir_index d_index, unsigned int mod_time,
-                                 unsigned int length)
-       {
-         header->add_file_name (name, d_index, mod_time, length);
-       });
-    }
-  else
-    {
-      /* Read directory table.  */
-      while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
-       {
-         line_ptr += bytes_read;
-         lh->add_include_dir (cur_dir);
-       }
-      line_ptr += bytes_read;
-
-      /* Read file name table.  */
-      while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
-       {
-         unsigned int mod_time, length;
-         dir_index d_index;
-
-         line_ptr += bytes_read;
-         d_index = (dir_index) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-         line_ptr += bytes_read;
-         mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-         line_ptr += bytes_read;
-         length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-         line_ptr += bytes_read;
-
-         lh->add_file_name (cur_file, d_index, mod_time, length);
-       }
-      line_ptr += bytes_read;
-    }
-
-  if (line_ptr > (section->buffer + section->size))
-    complaint (_("line number info header doesn't "
-                "fit in `.debug_line' section"));
-
-  return lh;
+  return dwarf_decode_line_header (sect_off, cu->per_cu->is_dwz,
+                                  dwarf2_per_objfile, section,
+                                  &cu->header);
 }
 
 /* Subroutine of dwarf_decode_lines to simplify it.
@@ -19998,7 +20199,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->per_cu->dwarf2_per_objfile->objfile;
+      struct objfile *objfile = cu->per_objfile->objfile;
       long line_offset = line_ptr - get_debug_line_section (cu)->buffer;
 
       complaint (_(".debug_line address at offset 0x%lx is 0 [in module %s]"),
@@ -20023,9 +20224,9 @@ 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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   bfd *abfd = objfile->obfd;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   /* True if we're recording line info (as opposed to building partial
      symtabs and just interested in finding include files mentioned by
      the line number program).  */
@@ -20252,7 +20453,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
                    struct dwarf2_cu *cu, dwarf2_psymtab *pst,
                    CORE_ADDR lowpc, int decode_mapping)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const int decode_for_pst_p = (pst != NULL);
 
   if (decode_mapping)
@@ -20367,7 +20568,7 @@ static void
 var_decode_location (struct attribute *attr, struct symbol *sym,
                     struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->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
@@ -20446,10 +20647,9 @@ static struct symbol *
 new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
            struct symbol *space)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct symbol *sym = NULL;
   const char *name;
   struct attribute *attr = NULL;
@@ -20464,27 +20664,31 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
   name = dwarf2_name (die, cu);
   if (name)
     {
-      const char *linkagename;
       int suppress_add = 0;
 
       if (space)
        sym = space;
       else
-       sym = allocate_symbol (objfile);
+       sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
       sym->set_language (cu->language, &objfile->objfile_obstack);
-      linkagename = dwarf2_physname (name, die, cu);
-      sym->compute_and_set_names (linkagename, false, objfile->per_bfd);
-
       /* Fortran does not have mangling standard and the mangling does differ
         between gfortran, iFort etc.  */
-      if (cu->language == language_fortran
-          && symbol_get_demangled_name (sym) == NULL)
-       symbol_set_demangled_name (sym,
-                                  dwarf2_full_name (name, die, cu),
-                                  NULL);
+      const char *physname
+       = (cu->language == language_fortran
+          ? dwarf2_full_name (name, die, cu)
+          : dwarf2_physname (name, die, cu));
+      const char *linkagename = dw2_linkage_name (die, cu);
+
+      if (linkagename == nullptr || cu->language == language_ada)
+       sym->set_linkage_name (physname);
+      else
+       {
+         sym->set_demangled_name (physname, &objfile->objfile_obstack);
+         sym->set_linkage_name (linkagename);
+       }
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -20576,7 +20780,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
          /* Compilation with minimal debug info may result in
             variables with missing type entries.  Change the
             misleading `void' type to something sensible.  */
-         if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
+         if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_VOID)
            SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_int;
 
          attr = dwarf2_attr (die, DW_AT_const_value, cu);
@@ -20616,7 +20820,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 
              if (SYMBOL_CLASS (sym) == LOC_STATIC
                  && SYMBOL_VALUE_ADDRESS (sym) == 0
-                 && !dwarf2_per_objfile->has_section_at_zero)
+                 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
                {
                  /* When a static variable is eliminated by the linker,
                     the corresponding debug information is not stripped
@@ -20627,7 +20831,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
                {
                  if (SYMBOL_CLASS (sym) == LOC_STATIC
                      && (objfile->flags & OBJF_MAINLINE) == 0
-                     && dwarf2_per_objfile->can_copy)
+                     && dwarf2_per_objfile->per_bfd->can_copy)
                    {
                      /* A global static variable might be subject to
                         copy relocation.  We first check for a local
@@ -20764,8 +20968,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
                    /* The symbol's name is already allocated along
                       with this objfile, so we don't need to
                       duplicate it for the type.  */
-                   if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-                     TYPE_NAME (SYMBOL_TYPE (sym)) = sym->search_name ();
+                   if (SYMBOL_TYPE (sym)->name () == 0)
+                     SYMBOL_TYPE (sym)->set_name (sym->search_name ());
                  }
              }
          }
@@ -20854,7 +21058,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->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   enum bfd_endian byte_order = bfd_big_endian (objfile->obfd) ?
                                BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
   LONGEST l = DW_UNSND (attr);
@@ -20889,7 +21093,8 @@ 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->per_cu->dwarf2_per_objfile->objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = 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) ?
@@ -20915,6 +21120,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
           piggyback on the existing location code rather than writing
           a new implementation of symbol_computed_ops.  */
        *baton = XOBNEW (obstack, struct dwarf2_locexpr_baton);
+       (*baton)->per_objfile = per_objfile;
        (*baton)->per_cu = cu->per_cu;
        gdb_assert ((*baton)->per_cu);
 
@@ -20992,7 +21198,7 @@ static void
 dwarf2_const_value (const struct attribute *attr, struct symbol *sym,
                    struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   LONGEST value;
   const gdb_byte *bytes;
   struct dwarf2_locexpr_baton *baton;
@@ -21029,7 +21235,7 @@ 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;
+      struct objfile *objfile = cu->per_objfile->objfile;
       /* A missing DW_AT_type represents a void type.  */
       return objfile_type (objfile)->builtin_void;
     }
@@ -21088,7 +21294,7 @@ 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;
+  struct objfile *objfile = cu->per_objfile->objfile;
 
   type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
   if (!type_attr)
@@ -21103,8 +21309,7 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   char *saved;
 
@@ -21127,8 +21332,7 @@ static struct type *
 lookup_die_type (struct die_info *die, const struct attribute *attr,
                 struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct type *this_type;
 
@@ -21141,7 +21345,7 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
   if (attr->form == DW_FORM_GNU_ref_alt)
     {
       struct dwarf2_per_cu_data *per_cu;
-      sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+      sect_offset sect_off = attr->get_ref_die_offset ();
 
       per_cu = dwarf2_find_containing_comp_unit (sect_off, 1,
                                                 dwarf2_per_objfile);
@@ -21149,7 +21353,7 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
     }
   else if (attr->form_is_ref ())
     {
-      sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+      sect_offset sect_off = attr->get_ref_die_offset ();
 
       this_type = get_die_type_at_offset (sect_off, cu->per_cu);
     }
@@ -21311,7 +21515,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;
+  struct objfile *objfile = cu->per_objfile->objfile;
 
   spec_cu = cu;
   spec_die = die_specification (die, &spec_cu);
@@ -21394,7 +21598,7 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
   if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
     return "";
 
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   return obstack_strndup (&objfile->per_bfd->storage_obstack,
                          DW_STRING (attr),
                          &base[-1] - DW_STRING (attr));
@@ -21418,8 +21622,7 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct die_info *parent, *spec_die;
   struct dwarf2_cu *spec_cu;
   struct type *parent_type;
@@ -21516,18 +21719,18 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
           DW_TAG_namespace DIEs with a name of "::" for the global namespace.
           Work around this problem here.  */
        if (cu->language == language_cplus
-           && strcmp (TYPE_NAME (parent_type), "::") == 0)
+           && strcmp (parent_type->name (), "::") == 0)
          return "";
        /* We give a name to even anonymous namespaces.  */
-       return TYPE_NAME (parent_type);
+       return parent_type->name ();
       case DW_TAG_class_type:
       case DW_TAG_interface_type:
       case DW_TAG_structure_type:
       case DW_TAG_union_type:
       case DW_TAG_module:
        parent_type = read_type_die (parent, cu);
-       if (TYPE_NAME (parent_type) != NULL)
-         return TYPE_NAME (parent_type);
+       if (parent_type->name () != NULL)
+         return parent_type->name ();
        else
          /* An anonymous structure is only allowed non-static data
             members; no typedefs, no member functions, et cetera.
@@ -21537,7 +21740,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
       case DW_TAG_partial_unit:
        /* gcc-4.5 -gdwarf-4 can drop the enclosing namespace.  Cope.  */
        if (cu->language == language_cplus
-           && !dwarf2_per_objfile->types.empty ()
+           && !dwarf2_per_objfile->per_bfd->types.empty ()
            && die->child != NULL
            && (die->tag == DW_TAG_class_type
                || die->tag == DW_TAG_structure_type
@@ -21562,8 +21765,8 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
        parent_type = read_type_die (parent, cu);
        if (TYPE_DECLARED_CLASS (parent_type))
          {
-           if (TYPE_NAME (parent_type) != NULL)
-             return TYPE_NAME (parent_type);
+           if (parent_type->name () != NULL)
+             return parent_type->name ();
            return "";
          }
        /* Fall through.  */
@@ -21637,14 +21840,6 @@ typename_concat (struct obstack *obs, const char *prefix, const char *suffix,
     }
 }
 
-/* Return sibling of die, NULL if no sibling.  */
-
-static struct die_info *
-sibling_die (struct die_info *die)
-{
-  return die->sibling;
-}
-
 /* Get name of a die, return NULL if not found.  */
 
 static const char *
@@ -21653,13 +21848,11 @@ dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
 {
   if (name && cu->language == language_cplus)
     {
-      std::string canon_name = cp_canonicalize_string (name);
+      gdb::unique_xmalloc_ptr<char> canon_name
+       = cp_canonicalize_string (name);
 
-      if (!canon_name.empty ())
-       {
-         if (canon_name != name)
-           name = objfile->intern (canon_name);
-       }
+      if (canon_name != nullptr)
+       name = objfile->intern (canon_name.get ());
     }
 
   return name;
@@ -21672,7 +21865,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;
+  struct objfile *objfile = cu->per_objfile->objfile;
 
   attr = dwarf2_attr (die, DW_AT_name, cu);
   if ((!attr || !DW_STRING (attr))
@@ -21773,89 +21966,6 @@ dwarf2_extension (struct die_info *die, struct dwarf2_cu **ext_cu)
   return follow_die_ref (die, attr, ext_cu);
 }
 
-/* A convenience function that returns an "unknown" DWARF name,
-   including the value of V.  STR is the name of the entity being
-   printed, e.g., "TAG".  */
-
-static const char *
-dwarf_unknown (const char *str, unsigned v)
-{
-  char *cell = get_print_cell ();
-  xsnprintf (cell, PRINT_CELL_SIZE, "DW_%s_<unknown: %u>", str, v);
-  return cell;
-}
-
-/* Convert a DIE tag into its string name.  */
-
-static const char *
-dwarf_tag_name (unsigned tag)
-{
-  const char *name = get_DW_TAG_name (tag);
-
-  if (name == NULL)
-    return dwarf_unknown ("TAG", tag);
-
-  return name;
-}
-
-/* Convert a DWARF attribute code into its string name.  */
-
-static const char *
-dwarf_attr_name (unsigned attr)
-{
-  const char *name;
-
-#ifdef MIPS /* collides with DW_AT_HP_block_index */
-  if (attr == DW_AT_MIPS_fde)
-    return "DW_AT_MIPS_fde";
-#else
-  if (attr == DW_AT_HP_block_index)
-    return "DW_AT_HP_block_index";
-#endif
-
-  name = get_DW_AT_name (attr);
-
-  if (name == NULL)
-    return dwarf_unknown ("AT", attr);
-
-  return name;
-}
-
-/* Convert a DWARF value form code into its string name.  */
-
-static const char *
-dwarf_form_name (unsigned form)
-{
-  const char *name = get_DW_FORM_name (form);
-
-  if (name == NULL)
-    return dwarf_unknown ("FORM", form);
-
-  return name;
-}
-
-static const char *
-dwarf_bool_name (unsigned mybool)
-{
-  if (mybool)
-    return "TRUE";
-  else
-    return "FALSE";
-}
-
-/* Convert a DWARF type code into its string name.  */
-
-static const char *
-dwarf_type_encoding_name (unsigned enc)
-{
-  const char *name = get_DW_ATE_name (enc);
-
-  if (name == NULL)
-    return dwarf_unknown ("ATE", enc);
-
-  return name;
-}
-
 static void
 dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
 {
@@ -22042,43 +22152,6 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
   *slot = die;
 }
 
-/* Return DIE offset of ATTR.  Return 0 with complaint if ATTR is not of the
-   required kind.  */
-
-static sect_offset
-dwarf2_get_ref_die_offset (const struct attribute *attr)
-{
-  if (attr->form_is_ref ())
-    return (sect_offset) DW_UNSND (attr);
-
-  complaint (_("unsupported die ref attribute form: '%s'"),
-            dwarf_form_name (attr->form));
-  return {};
-}
-
-/* Return the constant value held by ATTR.  Return DEFAULT_VALUE if
- * the value held by the attribute is not constant.  */
-
-static LONGEST
-dwarf2_get_attr_constant_value (const struct attribute *attr, int default_value)
-{
-  if (attr->form == DW_FORM_sdata || attr->form == DW_FORM_implicit_const)
-    return DW_SND (attr);
-  else if (attr->form == DW_FORM_udata
-           || attr->form == DW_FORM_data1
-           || attr->form == DW_FORM_data2
-           || attr->form == DW_FORM_data4
-           || attr->form == DW_FORM_data8)
-    return DW_UNSND (attr);
-  else
-    {
-      /* For DW_FORM_data16 see attribute::form_is_constant.  */
-      complaint (_("Attribute value is not a constant (%s)"),
-                 dwarf_form_name (attr->form));
-      return default_value;
-    }
-}
-
 /* Follow reference or signature attribute ATTR of SRC_DIE.
    On entry *REF_CU is the CU of SRC_DIE.
    On exit *REF_CU is the CU of the result.  */
@@ -22097,7 +22170,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)->per_cu->dwarf2_per_objfile->objfile));
+            objfile_name ((*ref_cu)->per_objfile->objfile));
     }
 
   return die;
@@ -22114,8 +22187,7 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   gdb_assert (cu->per_cu != NULL);
 
@@ -22146,7 +22218,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
   else if (cu->dies == NULL)
     {
       /* We're loading full DIEs during partial symbol reading.  */
-      gdb_assert (dwarf2_per_objfile->reading_partial_symbols);
+      gdb_assert (dwarf2_per_objfile->per_bfd->reading_partial_symbols);
       load_full_comp_unit (cu->per_cu, false, language_minimal);
     }
 
@@ -22169,7 +22241,7 @@ static struct die_info *
 follow_die_ref (struct die_info *src_die, const struct attribute *attr,
                struct dwarf2_cu **ref_cu)
 {
-  sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+  sect_offset sect_off = attr->get_ref_die_offset ();
   struct dwarf2_cu *cu = *ref_cu;
   struct die_info *die;
 
@@ -22181,7 +22253,7 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
     error (_("Dwarf Error: Cannot find DIE at %s referenced from DIE "
           "at %s [in module %s]"),
           sect_offset_str (sect_off), sect_offset_str (src_die->sect_off),
-          objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+          objfile_name (cu->per_objfile->objfile));
 
   return die;
 }
@@ -22219,15 +22291,15 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
 
   attr = dwarf2_attr (die, DW_AT_location, cu);
   if (!attr && resolve_abstract_p
-      && (dwarf2_per_objfile->abstract_to_concrete.find (die->sect_off)
-         != dwarf2_per_objfile->abstract_to_concrete.end ()))
+      && (dwarf2_per_objfile->per_bfd->abstract_to_concrete.find (die->sect_off)
+         != dwarf2_per_objfile->per_bfd->abstract_to_concrete.end ()))
     {
       CORE_ADDR pc = (*get_frame_pc) (baton);
       CORE_ADDR baseaddr = objfile->text_section_offset ();
-      struct gdbarch *gdbarch = get_objfile_arch (objfile);
+      struct gdbarch *gdbarch = objfile->arch ();
 
       for (const auto &cand_off
-            : dwarf2_per_objfile->abstract_to_concrete[die->sect_off])
+            : dwarf2_per_objfile->per_bfd->abstract_to_concrete[die->sect_off])
        {
          struct dwarf2_cu *cand_cu = cu;
          struct die_info *cand
@@ -22282,6 +22354,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
       retval.data = DW_BLOCK (attr)->data;
       retval.size = DW_BLOCK (attr)->size;
     }
+  retval.per_objfile = dwarf2_per_objfile;
   retval.per_cu = cu->per_cu;
 
   age_cached_comp_units (dwarf2_per_objfile);
@@ -22513,13 +22586,12 @@ 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;
+      struct dwarf2_per_objfile *dwarf2_per_objfile = (*ref_cu)->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
-         && dwarf2_per_objfile->index_table->version <= 7)
+      if (dwarf2_per_objfile->per_bfd->index_table != NULL
+         && dwarf2_per_objfile->per_bfd->index_table->version <= 7)
        {
          (*ref_cu)->per_cu->imported_symtabs_push (sig_cu->per_cu);
        }
@@ -22558,7 +22630,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 %s [in module %s]"),
              hex_string (signature), sect_offset_str (src_die->sect_off),
-            objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
+            objfile_name ((*ref_cu)->per_objfile->objfile));
     }
 
   die = follow_die_sig_1 (src_die, sig_type, ref_cu);
@@ -22568,7 +22640,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 %s [in module %s]"),
             hex_string (signature), sect_offset_str (src_die->sect_off),
-            objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
+            objfile_name ((*ref_cu)->per_objfile->objfile));
     }
 
   return die;
@@ -22581,8 +22653,7 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct signatured_type *sig_type;
   struct dwarf2_cu *type_cu;
   struct die_info *type_die;
@@ -22655,8 +22726,7 @@ 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;
+      struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
       complaint (_("Dwarf Error: DW_AT_signature has bad form %s in DIE"
                   " at %s [in module %s]"),
@@ -22740,29 +22810,15 @@ read_signatured_type (struct signatured_type *sig_type)
 
 /* Decode simple location descriptions.
    Given a pointer to a dwarf block that defines a location, compute
-   the location and return the value.
-
-   NOTE drow/2003-11-18: This function is called in two situations
-   now: for the address of static or global variables (partial symbols
-   only) and for offsets into structures which are expected to be
-   (more or less) constant.  The partial symbol case should go away,
-   and only the constant case should remain.  That will let this
-   function complain more accurately.  A few special modes are allowed
-   without complaint for global variables (for instance, global
-   register values and thread-local values).
-
-   A location description containing no operations indicates that the
-   object is optimized out.  The return value is 0 for that case.
-   FIXME drow/2003-11-16: No callers check for this case any more; soon all
-   callers will only want a very basic result and this can become a
-   complaint.
-
-   Note that stack[0] is unused except as a default error return.  */
+   the location and return the value.  If COMPUTED is non-null, it is
+   set to true to indicate that decoding was successful, and false
+   otherwise.  If COMPUTED is null, then this function may emit a
+   complaint.  */
 
 static CORE_ADDR
-decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
+decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu, bool *computed)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   size_t i;
   size_t size = blk->size;
   const gdb_byte *data = blk->data;
@@ -22771,6 +22827,9 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
   unsigned int bytes_read, unsnd;
   gdb_byte op;
 
+  if (computed != nullptr)
+    *computed = false;
+
   i = 0;
   stacki = 0;
   stack[stacki] = 0;
@@ -22850,7 +22909,12 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
        case DW_OP_reg31:
          stack[++stacki] = op - DW_OP_reg0;
          if (i < size)
-           dwarf2_complex_location_expr_complaint ();
+           {
+             if (computed == nullptr)
+               dwarf2_complex_location_expr_complaint ();
+             else
+               return 0;
+           }
          break;
 
        case DW_OP_regx:
@@ -22858,7 +22922,12 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
          i += bytes_read;
          stack[++stacki] = unsnd;
          if (i < size)
-           dwarf2_complex_location_expr_complaint ();
+           {
+             if (computed == nullptr)
+               dwarf2_complex_location_expr_complaint ();
+             else
+               return 0;
+           }
          break;
 
        case DW_OP_addr:
@@ -22940,7 +23009,12 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
             global symbols, although the variable's address will be bogus
             in the psymtab.  */
          if (i < size)
-           dwarf2_complex_location_expr_complaint ();
+           {
+             if (computed == nullptr)
+               dwarf2_complex_location_expr_complaint ();
+             else
+               return 0;
+           }
          break;
 
         case DW_OP_GNU_push_tls_address:
@@ -22954,11 +23028,18 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
             non-zero to not look as a variable garbage collected by linker
             which have DW_OP_addr 0.  */
          if (i < size)
-           dwarf2_complex_location_expr_complaint ();
+           {
+             if (computed == nullptr)
+               dwarf2_complex_location_expr_complaint ();
+             else
+               return 0;
+           }
          stack[stacki]++;
           break;
 
        case DW_OP_GNU_uninit:
+         if (computed != nullptr)
+           return 0;
          break;
 
        case DW_OP_addrx:
@@ -22970,16 +23051,17 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
          break;
 
        default:
-         {
-           const char *name = get_DW_OP_name (op);
+         if (computed == nullptr)
+           {
+             const char *name = get_DW_OP_name (op);
 
-           if (name)
-             complaint (_("unsupported stack op: '%s'"),
-                        name);
-           else
-             complaint (_("unsupported stack op: '%02x'"),
-                        op);
-         }
+             if (name)
+               complaint (_("unsupported stack op: '%s'"),
+                          name);
+             else
+               complaint (_("unsupported stack op: '%02x'"),
+                          op);
+           }
 
          return (stack[stacki]);
        }
@@ -22988,16 +23070,21 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
          outside of the allocated space.  Also enforce minimum>0.  */
       if (stacki >= ARRAY_SIZE (stack) - 1)
        {
-         complaint (_("location description stack overflow"));
+         if (computed == nullptr)
+           complaint (_("location description stack overflow"));
          return 0;
        }
 
       if (stacki <= 0)
        {
-         complaint (_("location description stack underflow"));
+         if (computed == nullptr)
+           complaint (_("location description stack underflow"));
          return 0;
        }
     }
+
+  if (computed != nullptr)
+    *computed = true;
   return (stack[stacki]);
 }
 
@@ -23034,8 +23121,7 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   const struct line_header *lh = cu->line_header;
   unsigned int offset_size = cu->header.offset_size;
@@ -23059,12 +23145,12 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
     {
       if (section_is_gnu)
        {
-         section = &dwarf2_per_objfile->macro;
+         section = &dwarf2_per_objfile->per_bfd->macro;
          section_name = ".debug_macro";
        }
       else
        {
-         section = &dwarf2_per_objfile->macinfo;
+         section = &dwarf2_per_objfile->per_bfd->macinfo;
          section_name = ".debug_macinfo";
        }
     }
@@ -23088,8 +23174,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
 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;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   if (cu->dwo_unit)
     {
@@ -23097,8 +23182,8 @@ cu_debug_loc_section (struct dwarf2_cu *cu)
 
       return cu->header.version >= 5 ? &sections->loclists : &sections->loc;
     }
-  return (cu->header.version >= 5 ? &dwarf2_per_objfile->loclists
-                                 : &dwarf2_per_objfile->loc);
+  return (cu->header.version >= 5 ? &dwarf2_per_objfile->per_bfd->loclists
+                                 : &dwarf2_per_objfile->per_bfd->loc);
 }
 
 /* A helper function that fills in a dwarf2_loclist_baton.  */
@@ -23108,19 +23193,22 @@ 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_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwarf2_section_info *section = cu_debug_loc_section (cu);
 
   section->read (dwarf2_per_objfile->objfile);
 
+  baton->per_objfile = dwarf2_per_objfile;
   baton->per_cu = cu->per_cu;
   gdb_assert (baton->per_cu);
   /* We don't know how long the location list is, but make sure we
      don't run off the edge of the section.  */
   baton->size = section->size - DW_UNSND (attr);
   baton->data = section->buffer + DW_UNSND (attr);
-  baton->base_address = cu->base_address;
+  if (cu->base_address.has_value ())
+    baton->base_address = *cu->base_address;
+  else
+    baton->base_address = 0;
   baton->from_dwo = cu->dwo_unit != NULL;
 }
 
@@ -23128,8 +23216,7 @@ 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 dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = cu_debug_loc_section (cu);
 
@@ -23145,7 +23232,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
 
       fill_in_loclist_baton (cu, baton, attr);
 
-      if (cu->base_known == 0)
+      if (!cu->base_address.has_value ())
        complaint (_("Location list used without "
                     "specifying the CU base address."));
 
@@ -23159,6 +23246,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
       struct dwarf2_locexpr_baton *baton;
 
       baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+      baton->per_objfile = dwarf2_per_objfile;
       baton->per_cu = cu->per_cu;
       gdb_assert (baton->per_cu);
 
@@ -23335,9 +23423,9 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
 {
   int low
     = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
-                                       dwarf2_per_objfile->all_comp_units);
+                                       dwarf2_per_objfile->per_bfd->all_comp_units);
   struct dwarf2_per_cu_data *this_cu
-    = dwarf2_per_objfile->all_comp_units[low];
+    = dwarf2_per_objfile->per_bfd->all_comp_units[low];
 
   if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
     {
@@ -23347,13 +23435,13 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
               sect_offset_str (sect_off),
               bfd_get_filename (dwarf2_per_objfile->objfile->obfd));
 
-      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->sect_off
+      gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units[low-1]->sect_off
                  <= sect_off);
-      return dwarf2_per_objfile->all_comp_units[low-1];
+      return dwarf2_per_objfile->per_bfd->all_comp_units[low-1];
     }
   else
     {
-      if (low == dwarf2_per_objfile->all_comp_units.size () - 1
+      if (low == dwarf2_per_objfile->per_bfd->all_comp_units.size () - 1
          && sect_off >= this_cu->sect_off + this_cu->length)
        error (_("invalid dwarf2 offset %s"), sect_offset_str (sect_off));
       gdb_assert (sect_off < this_cu->sect_off + this_cu->length);
@@ -23412,10 +23500,12 @@ run_test ()
 
 #endif /* GDB_SELF_TEST */
 
-/* Initialize dwarf2_cu CU, owned by PER_CU.  */
+/* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE.  */
 
-dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
-  : per_cu (per_cu_),
+dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
+                     dwarf2_per_objfile *per_objfile)
+  : per_cu (per_cu),
+    per_objfile (per_objfile),
     mark (false),
     has_loclist (false),
     checked_producer (false),
@@ -23465,8 +23555,8 @@ age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct dwarf2_per_cu_data *per_cu, **last_chain;
 
-  dwarf2_clear_marks (dwarf2_per_objfile->read_in_chain);
-  per_cu = dwarf2_per_objfile->read_in_chain;
+  dwarf2_clear_marks (dwarf2_per_objfile->per_bfd->read_in_chain);
+  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
   while (per_cu != NULL)
     {
       per_cu->cu->last_used ++;
@@ -23475,8 +23565,8 @@ age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
       per_cu = per_cu->cu->read_in_chain;
     }
 
-  per_cu = dwarf2_per_objfile->read_in_chain;
-  last_chain = &dwarf2_per_objfile->read_in_chain;
+  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
+  last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
   while (per_cu != NULL)
     {
       struct dwarf2_per_cu_data *next_cu;
@@ -23504,8 +23594,8 @@ free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
   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;
+  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
+  last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
   while (per_cu != NULL)
     {
       struct dwarf2_per_cu_data *next_cu;
@@ -23593,8 +23683,7 @@ 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_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwarf2_per_cu_offset_and_type **slot, ofs;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct attribute *attr;
@@ -23608,11 +23697,11 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
      But this is not a problem, because the gnat-specific information
      is actually not needed for these types.  */
   if (need_gnat_info (cu)
-      && TYPE_CODE (type) != TYPE_CODE_FUNC
-      && TYPE_CODE (type) != TYPE_CODE_FLT
-      && TYPE_CODE (type) != TYPE_CODE_METHODPTR
-      && TYPE_CODE (type) != TYPE_CODE_MEMBERPTR
-      && TYPE_CODE (type) != TYPE_CODE_METHOD
+      && type->code () != TYPE_CODE_FUNC
+      && type->code () != TYPE_CODE_FLT
+      && type->code () != TYPE_CODE_METHODPTR
+      && type->code () != TYPE_CODE_MEMBERPTR
+      && type->code () != TYPE_CODE_METHOD
       && !HAVE_GNAT_AUX_INFO (type))
     INIT_GNAT_SPECIFIC (type);
 
@@ -23622,7 +23711,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
     {
       struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
       if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
-        add_dyn_prop (DYN_PROP_ALLOCATED, prop, type);
+        type->add_dyn_prop (DYN_PROP_ALLOCATED, prop);
     }
   else if (attr != NULL)
     {
@@ -23637,7 +23726,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
     {
       struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
       if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
-        add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type);
+        type->add_dyn_prop (DYN_PROP_ASSOCIATED, prop);
     }
   else if (attr != NULL)
     {
@@ -23650,7 +23739,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_data_location, cu);
   if (attr_to_dynamic_prop (attr, die, cu, &prop,
                            cu->per_cu->addr_type ()))
-    add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type);
+    type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
 
   if (dwarf2_per_objfile->die_type_hash == NULL)
     dwarf2_per_objfile->die_type_hash
@@ -23804,19 +23893,6 @@ partial_die_eq (const void *item_lhs, const void *item_rhs)
 struct cmd_list_element *set_dwarf_cmdlist;
 struct cmd_list_element *show_dwarf_cmdlist;
 
-static void
-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 (const char *args, int from_tty)
-{
-  cmd_show_list (show_dwarf_cmdlist, from_tty, "");
-}
-
 static void
 show_check_physname (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
@@ -23830,17 +23906,17 @@ void _initialize_dwarf2_read ();
 void
 _initialize_dwarf2_read ()
 {
-  add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
+  add_basic_prefix_cmd ("dwarf", class_maintenance, _("\
 Set DWARF specific variables.\n\
 Configure DWARF variables such as the cache size."),
-                  &set_dwarf_cmdlist, "maintenance set dwarf ",
-                  0/*allow-unknown*/, &maintenance_set_cmdlist);
+                       &set_dwarf_cmdlist, "maintenance set dwarf ",
+                       0/*allow-unknown*/, &maintenance_set_cmdlist);
 
-  add_prefix_cmd ("dwarf", class_maintenance, show_dwarf_cmd, _("\
+  add_show_prefix_cmd ("dwarf", class_maintenance, _("\
 Show DWARF specific variables.\n\
 Show DWARF variables such as the cache size."),
-                  &show_dwarf_cmdlist, "maintenance show dwarf ",
-                  0/*allow-unknown*/, &maintenance_show_cmdlist);
+                      &show_dwarf_cmdlist, "maintenance show dwarf ",
+                      0/*allow-unknown*/, &maintenance_show_cmdlist);
 
   add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
                            &dwarf_max_cache_age, _("\