Remove objfile parameter from read_gdb_index_from_buffer
[deliverable/binutils-gdb.git] / gdb / dwarf2 / read.c
index 9e66e613cd63b788b9e39d0e8ed86732906e2f01..da702205c60c3ae8abf1d59b5ad60d4d8d5d92e3 100644 (file)
 #include "dwarf2/index-common.h"
 #include "dwarf2/leb.h"
 #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"
@@ -47,7 +51,6 @@
 #include "demangle.h"
 #include "gdb-demangle.h"
 #include "filenames.h" /* for DOSish file names */
-#include "macrotab.h"
 #include "language.h"
 #include "complaints.h"
 #include "dwarf2/expr.h"
@@ -82,6 +85,8 @@
 #include "gdbsupport/selftest.h"
 #include "rust-lang.h"
 #include "gdbsupport/pathstuff.h"
+#include "count-one-bits.h"
+#include "debuginfod-support.h"
 
 /* When == 1, print basic high level tracing messages.
    When > 1, be more verbose.
@@ -109,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
@@ -341,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
@@ -389,10 +424,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;
@@ -491,6 +523,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
@@ -572,9 +607,7 @@ struct type_unit_group
   /* dwarf2read.c's main "handle" on a TU symtab.
      To simplify things we create an artificial CU that "includes" all the
      type units using this stmt_list so that the rest of the code still has
-     a "per_cu" handle on the symtab.
-     This PER_CU is recognized by having no section.  */
-#define IS_TYPE_UNIT_GROUP(per_cu) ((per_cu)->section == NULL)
+     a "per_cu" handle on the symtab.  */
   struct dwarf2_per_cu_data per_cu;
 
   /* The TUs that share this DW_AT_stmt_list entry.
@@ -590,10 +623,6 @@ struct type_unit_group
   /* The data used to construct the hash key.  */
   struct stmt_list_hash hash;
 
-  /* The number of symtabs from the line header.
-     The value here must match line_header.num_file_names.  */
-  unsigned int num_symtabs;
-
   /* The symbol tables for this TU (obtained from the files listed in
      DW_AT_stmt_list).
      WARNING: The order of entries here must match the order of entries
@@ -1048,45 +1077,6 @@ 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.  */
@@ -1133,9 +1123,6 @@ struct field_info
     std::vector<struct nextfield> fields;
     std::vector<struct nextfield> baseclasses;
 
-    /* Number of fields (including baseclasses).  */
-    int nfields = 0;
-
     /* Set if the accessibility of one of the fields is not public.  */
     int non_public_fields = 0;
 
@@ -1151,6 +1138,12 @@ struct field_info
     /* Nested types defined by this class and the number of elements in this
        list.  */
     std::vector<struct decl_field> nested_types_list;
+
+    /* Return the total number of fields (including baseclasses).  */
+    int nfields () const
+    {
+      return fields.size () + baseclasses.size ();
+    }
   };
 
 /* Loaded secondary compilation units are kept in memory until they
@@ -1239,10 +1232,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);
@@ -1251,16 +1240,8 @@ static const char *read_indirect_string
   (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *, const gdb_byte *,
    const struct comp_unit_head *, unsigned int *);
 
-static const char *read_indirect_line_string
-  (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *, const gdb_byte *,
-   const struct comp_unit_head *, unsigned int *);
-
 static const char *read_indirect_string_at_offset
-  (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
-   LONGEST str_offset);
-
-static const char *read_indirect_string_from_dwz
-  (struct objfile *objfile, struct dwz_file *, LONGEST);
+  (struct dwarf2_per_objfile *dwarf2_per_objfile, LONGEST str_offset);
 
 static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *,
                                              const gdb_byte *,
@@ -1277,9 +1258,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);
 
@@ -1358,6 +1336,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
@@ -1448,7 +1429,7 @@ static const gdb_byte *read_full_die (const struct die_reader_specs *,
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
 static const char *dwarf2_canonicalize_name (const char *, struct dwarf2_cu *,
-                                            struct obstack *);
+                                            struct objfile *);
 
 static const char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
 
@@ -1462,18 +1443,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 *);
@@ -1486,10 +1455,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 **);
@@ -1649,9 +1614,9 @@ struct file_and_directory
 static file_and_directory find_file_and_directory (struct die_info *die,
                                                   struct dwarf2_cu *cu);
 
-static htab_up allocate_signatured_type_table (struct objfile *objfile);
+static htab_up allocate_signatured_type_table ();
 
-static htab_up allocate_dwo_unit_table (struct objfile *objfile);
+static htab_up allocate_dwo_unit_table ();
 
 static struct dwo_unit *lookup_dwo_unit_in_dwp
   (struct dwarf2_per_objfile *dwarf2_per_objfile,
@@ -1681,12 +1646,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)
 {
@@ -1714,23 +1673,6 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
             arg1, arg2, arg3);
 }
 
-static void
-dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section)
-{
-  complaint (_("debug info runs off end of %s section"
-              " [in module %s]"),
-            section->get_name (),
-            section->get_file_name ());
-}
-
-static void
-dwarf2_macro_malformed_definition_complaint (const char *arg1)
-{
-  complaint (_("macro debug info contains a "
-              "malformed macro definition:\n`%s'"),
-            arg1);
-}
-
 static void
 dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
 {
@@ -2152,6 +2094,29 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
   if (dwz_bfd == NULL)
     dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid);
 
+  if (dwz_bfd == nullptr)
+    {
+      gdb::unique_xmalloc_ptr<char> alt_filename;
+      const char *origname = dwarf2_per_objfile->objfile->original_name;
+
+      scoped_fd fd (debuginfod_debuginfo_query (buildid,
+                                               buildid_len,
+                                               origname,
+                                               &alt_filename));
+
+      if (fd.get () >= 0)
+       {
+         /* File successfully retrieved from server.  */
+         dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget, -1);
+
+         if (dwz_bfd == nullptr)
+           warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
+                    alt_filename.get ());
+         else if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
+           dwz_bfd.reset (nullptr);
+       }
+    }
+
   if (dwz_bfd == NULL)
     error (_("could not find '.gnu_debugaltlink' file for %s"),
           objfile_name (dwarf2_per_objfile->objfile));
@@ -2321,7 +2286,7 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
 
   /* Skip type_unit_groups, reading the type units they contain
      is handled elsewhere.  */
-  if (IS_TYPE_UNIT_GROUP (per_cu))
+  if (per_cu->type_unit_group_p ())
     return;
 
   /* The destructor of dwarf2_queue_guard frees any entries left on
@@ -2498,7 +2463,7 @@ create_signatured_type_table_from_index
   gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
   dwarf2_per_objfile->all_type_units.reserve (elements / 3);
 
-  htab_up sig_types_hash = allocate_signatured_type_table (objfile);
+  htab_up sig_types_hash = allocate_signatured_type_table ();
 
   for (offset_type i = 0; i < elements; i += 3)
     {
@@ -2554,7 +2519,7 @@ create_signatured_type_table_from_debug_names
   gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
   dwarf2_per_objfile->all_type_units.reserve (map.tu_count);
 
-  htab_up sig_types_hash = allocate_signatured_type_table (objfile);
+  htab_up sig_types_hash = allocate_signatured_type_table ();
 
   for (uint32_t i = 0; i < map.tu_count; ++i)
     {
@@ -2889,8 +2854,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,
@@ -3018,7 +2982,7 @@ dwarf2_read_gdb_index
     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,
@@ -3044,8 +3008,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,
@@ -3177,7 +3140,7 @@ dw2_get_file_names (struct dwarf2_per_cu_data *this_cu)
   /* This should never be called for TUs.  */
   gdb_assert (! this_cu->is_debug_types);
   /* Nor type unit groups.  */
-  gdb_assert (! IS_TYPE_UNIT_GROUP (this_cu));
+  gdb_assert (! this_cu->type_unit_group_p ());
 
   if (this_cu->v.quick->file_names != NULL)
     return this_cu->v.quick->file_names;
@@ -3663,9 +3626,35 @@ 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);
+
+  if (dwarf2_per_objfile->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.  As Ada does not look for non-Ada symbols this
+        function should just return.  */
+      return;
+    }
+
+  /* We have -readnow: no .gdb_index, but no partial symtabs either.  So,
+     inline psym_map_matching_symbols here, assuming all partial symtabs have
+     been read in.  */
+  const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
+
+  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
@@ -3752,7 +3741,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.  */
@@ -4779,6 +4768,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,
@@ -5160,8 +5150,8 @@ mapped_debug_names::namei_to_name (uint32_t namei) const
                                 + namei * offset_size),
                                offset_size,
                                dwarf5_byte_order);
-  return read_indirect_string_at_offset
-    (dwarf2_per_objfile, dwarf2_per_objfile->objfile->obfd, namei_string_offs);
+  return read_indirect_string_at_offset (dwarf2_per_objfile,
+                                        namei_string_offs);
 }
 
 /* Find a slot in .debug_names for the object named NAME.  If NAME is
@@ -5661,6 +5651,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,
@@ -5833,23 +5824,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 ();
     }
 }
 
@@ -5899,6 +5883,44 @@ read_abbrev_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
   return (sect_offset) read_offset (abfd, info_ptr, offset_size);
 }
 
+/* A partial symtab that is used only for include files.  */
+struct dwarf2_include_psymtab : public partial_symtab
+{
+  dwarf2_include_psymtab (const char *filename, struct objfile *objfile)
+    : partial_symtab (filename, objfile)
+  {
+  }
+
+  void read_symtab (struct objfile *objfile) override
+  {
+    expand_psymtab (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.  */
+    expand_dependencies (objfile);
+    m_readin = true;
+  }
+
+  bool readin_p () const override
+  {
+    return m_readin;
+  }
+
+  struct compunit_symtab *get_compunit_symtab () const override
+  {
+    return nullptr;
+  }
+
+private:
+
+  bool m_readin = false;
+};
+
 /* Allocate a new partial symtab for file named NAME and mark this new
    partial symtab as being an include of PST.  */
 
@@ -5906,7 +5928,7 @@ static void
 dwarf2_create_include_psymtab (const char *name, dwarf2_psymtab *pst,
                                struct objfile *objfile)
 {
-  dwarf2_psymtab *subpst = new dwarf2_psymtab (name, objfile);
+  dwarf2_include_psymtab *subpst = new dwarf2_include_psymtab (name, objfile);
 
   if (!IS_ABSOLUTE_PATH (subpst->filename))
     {
@@ -5917,11 +5939,6 @@ dwarf2_create_include_psymtab (const char *name, dwarf2_psymtab *pst,
   subpst->dependencies = objfile->partial_symtabs->allocate_dependencies (1);
   subpst->dependencies[0] = pst;
   subpst->number_of_dependencies = 1;
-
-  /* No private part is necessary for include psymtabs.  This property
-     can be used to differentiate between such include psymtabs and
-     the regular ones.  */
-  subpst->per_cu_data = nullptr;
 }
 
 /* Read the Line Number Program data and extract the list of files
@@ -5972,7 +5989,7 @@ eq_signatured_type (const void *item_lhs, const void *item_rhs)
 /* Allocate a hash table for signatured types.  */
 
 static htab_up
-allocate_signatured_type_table (struct objfile *objfile)
+allocate_signatured_type_table ()
 {
   return htab_up (htab_create_alloc (41,
                                     hash_signatured_type,
@@ -6067,9 +6084,9 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (types_htab == NULL)
        {
          if (dwo_file)
-           types_htab = allocate_dwo_unit_table (objfile);
+           types_htab = allocate_dwo_unit_table ();
          else
-           types_htab = allocate_signatured_type_table (objfile);
+           types_htab = allocate_signatured_type_table ();
        }
 
       if (dwo_file)
@@ -6280,7 +6297,6 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwo_file *dwo_file;
   struct dwo_unit find_dwo_entry, *dwo_entry;
   struct signatured_type find_sig_entry, *sig_entry;
@@ -6291,10 +6307,7 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
   /* 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 (objfile);
-    }
+    dwarf2_per_objfile->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
@@ -6351,7 +6364,6 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwp_file *dwp_file = get_dwp_file (dwarf2_per_objfile);
   struct dwo_unit *dwo_entry;
   struct signatured_type find_sig_entry, *sig_entry;
@@ -6363,10 +6375,7 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
   /* 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 (objfile);
-    }
+    dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
 
   find_sig_entry.signature = sig;
   slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
@@ -6426,34 +6435,6 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
     }
 }
 
-/* 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.  */
@@ -6542,12 +6523,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)
     {
@@ -6727,7 +6708,6 @@ cutu_reader::init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
                                        int use_existing_cu)
 {
   struct signatured_type *sig_type;
-  struct die_reader_specs reader;
 
   /* Verify we can do the following downcast, and that we have the
      data we need.  */
@@ -6755,7 +6735,7 @@ cutu_reader::init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
   if (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit,
                              NULL /* stub_comp_unit_die */,
                              sig_type->dwo_unit->dwo_file->comp_dir,
-                             &reader, &info_ptr,
+                             this, &info_ptr,
                              &comp_unit_die,
                              &m_dwo_abbrev_table) == 0)
     {
@@ -7086,7 +7066,7 @@ eq_type_unit_group (const void *item_lhs, const void *item_rhs)
 /* Allocate a hash table for type unit groups.  */
 
 static htab_up
-allocate_type_unit_groups_table (struct objfile *objfile)
+allocate_type_unit_groups_table ()
 {
   return htab_up (htab_create_alloc (3,
                                     hash_type_unit_group,
@@ -7160,10 +7140,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
   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 (dwarf2_per_objfile->objfile);
-    }
+    dwarf2_per_objfile->type_unit_groups = allocate_type_unit_groups_table ();
 
   /* Do we need to create a new group, or can we use an existing one?  */
 
@@ -7218,12 +7195,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;
@@ -7260,7 +7236,8 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
   else if (strcmp (filename, artificial) == 0)
     {
       debug_filename.reset (concat (artificial, "@",
-                                   sect_offset_str (per_cu->sect_off), NULL));
+                                   sect_offset_str (per_cu->sect_off),
+                                   (char *) NULL));
       filename = debug_filename.get ();
     }
 
@@ -7381,6 +7358,18 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
 
   cutu_reader reader (this_cu, NULL, 0, false);
 
+  switch (reader.comp_unit_die->tag)
+    {
+    case DW_TAG_compile_unit:
+      this_cu->unit_type = DW_UT_compile;
+      break;
+    case DW_TAG_partial_unit:
+      this_cu->unit_type = DW_UT_partial;
+      break;
+    default:
+      abort ();
+    }
+
   if (reader.dummy_p)
     {
       /* Nothing.  */
@@ -7394,6 +7383,8 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
                                      reader.comp_unit_die,
                                      pretend_language);
 
+  this_cu->lang = this_cu->cu->language;
+
   /* Age out any secondary CUs.  */
   age_cached_comp_units (this_cu->dwarf2_per_objfile);
 }
@@ -7423,7 +7414,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)
@@ -7592,7 +7583,7 @@ build_type_psymtab_dependencies (void **slot, void *info)
   int i;
 
   gdb_assert (len > 0);
-  gdb_assert (IS_TYPE_UNIT_GROUP (per_cu));
+  gdb_assert (per_cu->type_unit_group_p ());
 
   pst->number_of_dependencies = len;
   pst->dependencies = objfile->partial_symtabs->allocate_dependencies (len);
@@ -7636,10 +7627,7 @@ 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 (dwarf2_per_objfile->objfile);
-    }
+    dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
 
   find_entry.signature = dwo_unit->signature;
   slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
@@ -7730,7 +7718,9 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
                          objfile_name (objfile));
     }
 
-  dwarf2_per_objfile->reading_partial_symbols = 1;
+  scoped_restore restore_reading_psyms
+    = make_scoped_restore (&dwarf2_per_objfile->reading_partial_symbols,
+                          true);
 
   dwarf2_per_objfile->info.read (objfile);
 
@@ -8543,13 +8533,13 @@ 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)
                complaint (_("DW_AT_sibling points backwards"));
              else if (sibling_ptr > reader->buffer_end)
-               dwarf2_section_buffer_overflow_complaint (reader->die_section);
+               reader->die_section->overflow_complaint ();
              else
                return sibling_ptr;
            }
@@ -8635,6 +8625,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:
@@ -8704,8 +8695,6 @@ dwarf2_psymtab::read_symtab (struct objfile *objfile)
        = dpo_backlink->has_section_at_zero;
     }
 
-  dwarf2_per_objfile->reading_partial_symbols = 0;
-
   expand_psymtab (objfile);
 
   process_cu_includes (dwarf2_per_objfile);
@@ -8845,24 +8834,13 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 void
 dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
 {
-  struct dwarf2_per_cu_data *per_cu;
-
   if (readin)
     return;
 
-  read_dependencies (objfile);
-
-  per_cu = per_cu_data;
-
-  if (per_cu == NULL)
-    {
-      /* It's an include file, no symbols to read for it.
-         Everything is in the parent symtab.  */
-      readin = true;
-      return;
-    }
+  expand_dependencies (objfile);
 
-  dw2_do_instantiate_symtab (per_cu, false);
+  dw2_do_instantiate_symtab (per_cu_data, false);
+  gdb_assert (get_compunit_symtab () != nullptr);
 }
 
 /* Trivial hash function for die_info: the hash value of a DIE
@@ -9068,8 +9046,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
   if (package_name != NULL)
     {
       struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-      const char *saved_package_name
-       = obstack_strdup (&objfile->per_bfd->storage_obstack, package_name.get ());
+      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;
@@ -9724,12 +9701,20 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
   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);
 
+      /* 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,
+        and ignore it.  */
+      if (die->parent && die->parent->parent == NULL
+         && per_cu->unit_type == DW_UT_compile
+         && per_cu->lang == language_cplus)
+       return;
+
       /* If necessary, add it to the queue and load its DIEs.  */
       if (maybe_queue_comp_unit (cu, per_cu, cu->language))
        load_full_comp_unit (per_cu, false, cu->language);
@@ -10195,14 +10180,13 @@ dwarf2_compute_name (const char *name,
          if (cu->language == language_cplus)
            canonical_name
              = dwarf2_canonicalize_name (intermediate_name.c_str (), cu,
-                                         &objfile->per_bfd->storage_obstack);
+                                         objfile);
 
          /* If we only computed INTERMEDIATE_NAME, or if
             INTERMEDIATE_NAME is already canonical, then we need to
-            copy it to the appropriate obstack.  */
+            intern it.  */
          if (canonical_name == NULL || canonical_name == intermediate_name.c_str ())
-           name = obstack_strdup (&objfile->per_bfd->storage_obstack,
-                                  intermediate_name);
+           name = objfile->intern (intermediate_name);
          else
            name = canonical_name;
        }
@@ -10322,7 +10306,7 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
     retval = canon;
 
   if (need_copy)
-    retval = obstack_strdup (&objfile->per_bfd->storage_obstack, retval);
+    retval = objfile->intern (retval);
 
   return retval;
 }
@@ -10370,7 +10354,7 @@ 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)
@@ -10496,7 +10480,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
@@ -10774,7 +10758,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;
        }
     }
 
@@ -10868,9 +10852,9 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
         process_full_type_unit still needs to know if this is the first
         time.  */
 
-      tu_group->num_symtabs = line_header->file_names_size ();
-      tu_group->symtabs = XNEWVEC (struct symtab *,
-                                  line_header->file_names_size ());
+      tu_group->symtabs
+       = XOBNEWVEC (&COMPUNIT_OBJFILE (cust)->objfile_obstack,
+                    struct symtab *, line_header->file_names_size ());
 
       auto &file_names = line_header->file_names ();
       for (i = 0; i < file_names.size (); ++i)
@@ -10942,7 +10926,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;
        }
     }
 }
@@ -10984,7 +10968,7 @@ eq_dwo_file (const void *item_lhs, const void *item_rhs)
 /* Allocate a hash table for DWO files.  */
 
 static htab_up
-allocate_dwo_file_hash_table (struct objfile *objfile)
+allocate_dwo_file_hash_table ()
 {
   auto delete_dwo_file = [] (void *item)
     {
@@ -11011,8 +10995,7 @@ lookup_dwo_file_slot (struct dwarf2_per_objfile *dwarf2_per_objfile,
   void **slot;
 
   if (dwarf2_per_objfile->dwo_files == NULL)
-    dwarf2_per_objfile->dwo_files
-      = allocate_dwo_file_hash_table (dwarf2_per_objfile->objfile);
+    dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
 
   find_entry.dwo_name = dwo_name;
   find_entry.comp_dir = comp_dir;
@@ -11048,7 +11031,7 @@ eq_dwo_unit (const void *item_lhs, const void *item_rhs)
    There is one of these tables for each of CUs,TUs for each DWO file.  */
 
 static htab_up
-allocate_dwo_unit_table (struct objfile *objfile)
+allocate_dwo_unit_table ()
 {
   /* Start out with a pretty small number.
      Generally DWO files contain only one CU and maybe some TUs.  */
@@ -11142,7 +11125,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
        continue;
 
       if (cus_htab == NULL)
-       cus_htab = allocate_dwo_unit_table (objfile);
+       cus_htab = allocate_dwo_unit_table ();
 
       dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
       *dwo_unit = read_unit;
@@ -11649,8 +11632,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 = obstack_strdup (&objfile->objfile_obstack,
-                                          virtual_dwo_name);
+      dwo_file->dwo_name = objfile->intern (virtual_dwo_name);
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev = sections.abbrev;
       dwo_file->sections.line = sections.line;
@@ -11845,8 +11827,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 = obstack_strdup (&objfile->objfile_obstack,
-                                          virtual_dwo_name);
+      dwo_file->dwo_name = 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,
@@ -12110,6 +12091,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;
@@ -12299,7 +12285,7 @@ eq_dwp_loaded_cutus (const void *a, const void *b)
 /* Allocate a hash table for dwp_file loaded CUs/TUs.  */
 
 static htab_up
-allocate_dwp_loaded_cutus_table (struct objfile *objfile)
+allocate_dwp_loaded_cutus_table ()
 {
   return htab_up (htab_create_alloc (3,
                                     hash_dwp_loaded_cutus,
@@ -12432,8 +12418,8 @@ open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
                           dwarf2_locate_v2_dwp_sections,
                           dwp_file.get ());
 
-  dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table (objfile);
-  dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table (objfile);
+  dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table ();
+  dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table ();
 
   if (dwarf_read_debug)
     {
@@ -12718,7 +12704,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;
@@ -12795,7 +12781,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;
 
@@ -12864,7 +12850,7 @@ 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)
@@ -12917,7 +12903,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;
        }
     }
 
@@ -12939,7 +12925,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
@@ -13028,7 +13014,7 @@ 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))
+          child_die = child_die->sibling)
        process_die (child_die, cu);
       return;
     case PC_BOUNDS_INVALID:
@@ -13044,7 +13030,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);
@@ -13125,7 +13111,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)
@@ -13270,7 +13256,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;
@@ -13301,8 +13287,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
@@ -13466,13 +13451,11 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
   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);
@@ -13511,7 +13494,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:
@@ -13569,7 +13551,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.  */
@@ -13588,8 +13570,8 @@ 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.  */
@@ -13633,8 +13615,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
   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;
@@ -13642,7 +13623,6 @@ 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);
@@ -13679,11 +13659,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.  */
@@ -13702,8 +13681,8 @@ 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.  */
@@ -13903,7 +13882,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;
     }
 }
 
@@ -13959,7 +13938,7 @@ get_scope_pc_bounds (struct die_info *die,
            break;
          }
 
-         child = sibling_die (child);
+         child = child->sibling;
        }
     }
 
@@ -14142,7 +14121,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 ())
@@ -14180,8 +14159,6 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       new_field = &fip->fields.back ();
     }
 
-  fip->nfields++;
-
   attr = dwarf2_attr (die, DW_AT_accessibility, cu);
   if (attr != nullptr)
     new_field->accessibility = DW_UNSND (attr);
@@ -14271,7 +14248,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);
@@ -14441,7 +14418,7 @@ static void
 dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
                              struct dwarf2_cu *cu)
 {
-  int nfields = fip->nfields;
+  int nfields = fip->nfields ();
 
   /* Record the field count, allocate space for the array of fields,
      and create blank accessibility bitfields if necessary.  */
@@ -15020,7 +14997,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);
@@ -15199,7 +15176,7 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 
       for (die_info *variant_child = child_die->child;
           variant_child != NULL;
-          variant_child = sibling_die (variant_child))
+          variant_child = variant_child->sibling)
        {
          if (variant_child->tag == DW_TAG_member)
            {
@@ -15289,7 +15266,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *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.  */
@@ -15309,7 +15286,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
        }
 
       /* Attach fields and member functions to the type.  */
-      if (fi.nfields)
+      if (fi.nfields () > 0)
        dwarf2_attach_fields_to_type (&fi, type, cu);
       if (!fi.fnfieldlists.empty ())
        {
@@ -15437,7 +15414,7 @@ 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,
@@ -15493,13 +15470,12 @@ update_enumeration_type_from_children (struct die_info *die,
   struct die_info *child_die;
   int unsigned_enum = 1;
   int flag_enum = 1;
-  ULONGEST mask = 0;
 
   auto_obstack obstack;
 
   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;
@@ -15525,10 +15501,11 @@ update_enumeration_type_from_children (struct die_info *die,
          unsigned_enum = 0;
          flag_enum = 0;
        }
-      else if ((mask & value) != 0)
-       flag_enum = 0;
       else
-       mask |= value;
+       {
+         if (count_one_bits_ll (value) >= 2)
+           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.  */
@@ -15556,7 +15533,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);
@@ -15615,12 +15592,14 @@ 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);
@@ -15674,7 +15653,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
                }
            }
 
-         child_die = sibling_die (child_die);
+         child_die = child_die->sibling;
        }
 
       if (!fields.empty ())
@@ -15785,7 +15764,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
@@ -15945,7 +15924,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
@@ -16022,7 +16001,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)
@@ -16035,7 +16014,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.  */
@@ -16157,7 +16136,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;
        }
     }
 }
@@ -16193,7 +16172,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;
     }
 }
 
@@ -16537,7 +16516,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
@@ -16559,12 +16538,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
     {
@@ -16692,7 +16671,7 @@ 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.  */
@@ -16763,7 +16742,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;
        }
     }
 
@@ -16793,6 +16772,16 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
                 sect_offset_str (die->sect_off), objfile_name (objfile));
       TYPE_TARGET_TYPE (this_type) = NULL;
     }
+  if (name == NULL)
+    {
+      /* Gcc-7 and before supports -feliminate-dwarf2-dups, which generates
+        anonymous typedefs, which is, strictly speaking, invalid DWARF.
+        Handle these by just returning the target type, rather than
+        constructing an anonymous typedef type and trying to handle this
+        elsewhere.  */
+      set_die_type (die, target_type, cu);
+      return target_type;
+    }
   return this_type;
 }
 
@@ -16960,7 +16949,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) == TYPE_CODE_ERROR)
+         {
+           if (name == nullptr)
+             {
+               struct obstack *obstack
+                 = &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
+               name = obconcat (obstack, "_Complex ", TYPE_NAME (type),
+                                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);
@@ -17133,7 +17134,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
@@ -17311,7 +17312,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   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.
@@ -17572,11 +17573,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)
@@ -17931,18 +17936,17 @@ partial_die_info::read (const struct die_reader_specs *reader,
   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)
@@ -17966,8 +17970,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
                struct objfile *objfile = dwarf2_per_objfile->objfile;
 
                name
-                 = dwarf2_canonicalize_name (DW_STRING (&attr), cu,
-                                             &objfile->per_bfd->storage_obstack);
+                 = dwarf2_canonicalize_name (DW_STRING (&attr), cu, objfile);
              }
              break;
            }
@@ -18018,7 +18021,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;
@@ -18030,13 +18033,13 @@ 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)
                complaint (_("DW_AT_sibling points backwards"));
              else if (sibling_ptr > reader->buffer_end)
-               dwarf2_section_buffer_overflow_complaint (reader->die_section);
+               reader->die_section->overflow_complaint ();
              else
                sibling = sibling_ptr;
            }
@@ -18075,7 +18078,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);
            }
@@ -18292,15 +18295,32 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
          if (actual_class_name != NULL)
            {
              struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-             struct_pdi->name
-               = obstack_strdup (&objfile->per_bfd->storage_obstack,
-                                 actual_class_name.get ());
+             struct_pdi->name = objfile->intern (actual_class_name.get ());
            }
          break;
        }
     }
 }
 
+/* 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)
 {
@@ -18333,6 +18353,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)
@@ -18374,19 +18412,98 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
            base = demangled.get ();
 
          struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-         name = obstack_strdup (&objfile->per_bfd->storage_obstack, base);
+         name = objfile->intern (base);
        }
     }
 
   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_cu->dwarf2_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)
@@ -18395,6 +18512,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:
@@ -18499,6 +18619,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;
@@ -18518,9 +18645,9 @@ read_attribute_value (const struct die_reader_specs *reader,
     case DW_FORM_line_strp:
       if (!cu->per_cu->is_dwz)
        {
-         DW_STRING (attr) = read_indirect_line_string (dwarf2_per_objfile,
-                                                       abfd, info_ptr,
-                                                       cu_header, &bytes_read);
+         DW_STRING (attr)
+           = dwarf2_per_objfile->read_line_string (info_ptr, cu_header,
+                                                   &bytes_read);
          DW_STRING_IS_CANONICAL (attr) = 0;
          info_ptr += bytes_read;
          break;
@@ -18532,8 +18659,7 @@ read_attribute_value (const struct die_reader_specs *reader,
        LONGEST str_offset = cu_header->read_offset (abfd, info_ptr,
                                                     &bytes_read);
 
-       DW_STRING (attr) = read_indirect_string_from_dwz (objfile,
-                                                         dwz, str_offset);
+       DW_STRING (attr) = dwz->read_string (objfile, str_offset);
        DW_STRING_IS_CANONICAL (attr) = 0;
        info_ptr += bytes_read;
       }
@@ -18703,104 +18829,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 section SECT offset STR_OFFSET with error
-   reporting strings FORM_NAME and SECT_NAME.  */
-
-static const char *
-read_indirect_string_at_offset_from (struct objfile *objfile,
-                                    bfd *abfd, LONGEST str_offset,
-                                    struct dwarf2_section_info *sect,
-                                    const char *form_name,
-                                    const char *sect_name)
-{
-  sect->read (objfile);
-  if (sect->buffer == NULL)
-    error (_("%s used without %s section [in module %s]"),
-          form_name, sect_name, bfd_get_filename (abfd));
-  if (str_offset >= sect->size)
-    error (_("%s pointing outside of %s section [in module %s]"),
-          form_name, sect_name, bfd_get_filename (abfd));
-  gdb_assert (HOST_CHAR_BIT == 8);
-  if (sect->buffer[str_offset] == '\0')
-    return NULL;
-  return (const char *) (sect->buffer + str_offset);
-}
-
 /* 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,
-                               bfd *abfd, LONGEST str_offset)
-{
-  return read_indirect_string_at_offset_from (dwarf2_per_objfile->objfile,
-                                             abfd, str_offset,
-                                             &dwarf2_per_objfile->str,
-                                             "DW_FORM_strp", ".debug_str");
-}
-
-/* Return pointer to string at .debug_line_str offset STR_OFFSET.  */
-
-static const char *
-read_indirect_line_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
-                                    bfd *abfd, LONGEST str_offset)
+                               LONGEST str_offset)
 {
-  return read_indirect_string_at_offset_from (dwarf2_per_objfile->objfile,
-                                             abfd, str_offset,
-                                             &dwarf2_per_objfile->line_str,
-                                             "DW_FORM_line_strp",
-                                             ".debug_line_str");
-}
-
-/* Read a string at offset STR_OFFSET in the .debug_str section from
-   the .dwz file DWZ.  Throw an error if the offset is too large.  If
-   the string consists of a single NUL byte, return NULL; otherwise
-   return a pointer to the string.  */
-
-static const char *
-read_indirect_string_from_dwz (struct objfile *objfile, struct dwz_file *dwz,
-                              LONGEST str_offset)
-{
-  dwz->str.read (objfile);
-
-  if (dwz->str.buffer == NULL)
-    error (_("DW_FORM_GNU_strp_alt used without .debug_str "
-            "section [in module %s]"),
-          bfd_get_filename (dwz->dwz_bfd.get ()));
-  if (str_offset >= dwz->str.size)
-    error (_("DW_FORM_GNU_strp_alt pointing outside of "
-            ".debug_str section [in module %s]"),
-          bfd_get_filename (dwz->dwz_bfd.get ()));
-  gdb_assert (HOST_CHAR_BIT == 8);
-  if (dwz->str.buffer[str_offset] == '\0')
-    return NULL;
-  return (const char *) (dwz->str.buffer + str_offset);
+  return dwarf2_per_objfile->str.read_string (dwarf2_per_objfile->objfile,
+                                             str_offset, "DW_FORM_strp");
 }
 
 /* Return pointer to string at .debug_str offset as read from BUF.
@@ -18815,23 +18851,20 @@ read_indirect_string (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
 {
   LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr);
 
-  return read_indirect_string_at_offset (dwarf2_per_objfile, abfd, str_offset);
+  return read_indirect_string_at_offset (dwarf2_per_objfile, str_offset);
 }
 
-/* Return pointer to string at .debug_line_str offset as read from BUF.
-   BUF is assumed to be in a compilation unit described by CU_HEADER.
-   Return *BYTES_READ_PTR count of bytes read from BUF.  */
+/* See read.h.  */
 
-static const char *
-read_indirect_line_string (struct dwarf2_per_objfile *dwarf2_per_objfile,
-                          bfd *abfd, const gdb_byte *buf,
+const char *
+dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
                           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 read_indirect_line_string_at_offset (dwarf2_per_objfile, abfd,
-                                             str_offset);
+  return line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
 }
 
 /* Given index ADDR_INDEX in .debug_addr, fetch the value.
@@ -18886,14 +18919,10 @@ read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
   return read_addr_index (cu, addr_index);
 }
 
-/* Given an index in .debug_addr, fetch the value.
-   NOTE: This can be called during dwarf expression evaluation,
-   long after the debug information has been read, and thus per_cu->cu
-   may no longer exist.  */
+/* See read.h.  */
 
 CORE_ADDR
-dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
-                       unsigned int addr_index)
+dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu, unsigned int addr_index)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
   struct dwarf2_cu *cu = per_cu->cu;
@@ -19116,24 +19145,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.  */
 
@@ -19260,140 +19271,6 @@ get_debug_line_section (struct dwarf2_cu *cu)
   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 (read_indirect_line_string (dwarf2_per_objfile,
-                                                        abfd, 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.
@@ -19407,12 +19284,7 @@ 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;
 
@@ -19427,159 +19299,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.
@@ -19811,16 +19533,16 @@ void
 lnp_state_machine::handle_special_opcode (unsigned char op_code)
 {
   unsigned char adj_opcode = op_code - m_line_header->opcode_base;
-  CORE_ADDR addr_adj = (((m_op_index
-                         + (adj_opcode / m_line_header->line_range))
+  unsigned char adj_opcode_d = adj_opcode / m_line_header->line_range;
+  unsigned char adj_opcode_r = adj_opcode % m_line_header->line_range;
+  CORE_ADDR addr_adj = (((m_op_index + adj_opcode_d)
                         / m_line_header->maximum_ops_per_instruction)
                        * m_line_header->minimum_instruction_length);
   m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
-  m_op_index = ((m_op_index + (adj_opcode / m_line_header->line_range))
+  m_op_index = ((m_op_index + adj_opcode_d)
                % m_line_header->maximum_ops_per_instruction);
 
-  int line_delta = (m_line_header->line_base
-                   + (adj_opcode % m_line_header->line_range));
+  int line_delta = m_line_header->line_base + adj_opcode_r;
   advance_line (line_delta);
   record_line (false);
   m_discriminator = 0;
@@ -19913,7 +19635,7 @@ dwarf_record_line_p (struct dwarf2_cu *cu,
 
 static void
 dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
-                    unsigned int line, CORE_ADDR address,
+                    unsigned int line, CORE_ADDR address, bool is_stmt,
                     struct dwarf2_cu *cu)
 {
   CORE_ADDR addr = gdbarch_addr_bits_remove (gdbarch, address);
@@ -19927,7 +19649,7 @@ dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
     }
 
   if (cu != nullptr)
-    cu->get_builder ()->record_line (subfile, line, addr);
+    cu->get_builder ()->record_line (subfile, line, addr, is_stmt);
 }
 
 /* Subroutine of dwarf_decode_lines_1 to simplify it.
@@ -19950,7 +19672,7 @@ dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
                          paddress (gdbarch, address));
     }
 
-  dwarf_record_line_1 (gdbarch, subfile, 0, address, cu);
+  dwarf_record_line_1 (gdbarch, subfile, 0, address, true, cu);
 }
 
 void
@@ -19977,8 +19699,7 @@ lnp_state_machine::record_line (bool end_sequence)
   else if (m_op_index == 0 || end_sequence)
     {
       fe->included_p = 1;
-      if (m_record_lines_p
-         && (producer_is_codewarrior (m_cu) || m_is_stmt || end_sequence))
+      if (m_record_lines_p)
        {
          if (m_last_subfile != m_cu->get_builder ()->get_current_subfile ()
              || end_sequence)
@@ -19989,6 +19710,8 @@ lnp_state_machine::record_line (bool end_sequence)
 
          if (!end_sequence)
            {
+             bool is_stmt = producer_is_codewarrior (m_cu) || m_is_stmt;
+
              if (dwarf_record_line_p (m_cu, m_line, m_last_line,
                                       m_line_has_non_zero_discriminator,
                                       m_last_subfile))
@@ -19996,7 +19719,7 @@ lnp_state_machine::record_line (bool end_sequence)
                  buildsym_compunit *builder = m_cu->get_builder ();
                  dwarf_record_line_1 (m_gdbarch,
                                       builder->get_current_subfile (),
-                                      m_line, m_address,
+                                      m_line, m_address, is_stmt,
                                       m_currently_recording_lines ? m_cu : nullptr);
                }
              m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
@@ -21183,7 +20906,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);
@@ -21191,7 +20914,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);
     }
@@ -21679,19 +21402,11 @@ 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 *
 dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
-                         struct obstack *obstack)
+                         struct objfile *objfile)
 {
   if (name && cu->language == language_cplus)
     {
@@ -21700,7 +21415,7 @@ dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
       if (!canon_name.empty ())
        {
          if (canon_name != name)
-           name = obstack_strdup (obstack, canon_name);
+           name = objfile->intern (canon_name);
        }
     }
 
@@ -21769,23 +21484,20 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
            {
              gdb::unique_xmalloc_ptr<char> demangled
                (gdb_demangle (DW_STRING (attr), DMGL_TYPES));
+             if (demangled == nullptr)
+               return nullptr;
 
-             const char *base;
-
-             /* FIXME: we already did this for the partial symbol... */
-             DW_STRING (attr)
-               = obstack_strdup (&objfile->per_bfd->storage_obstack,
-                                 demangled.get ());
+             DW_STRING (attr) = objfile->intern (demangled.get ());
              DW_STRING_IS_CANONICAL (attr) = 1;
-
-             /* Strip any leading namespaces/classes, keep only the base name.
-                DW_AT_name for named DIEs does not contain the prefixes.  */
-             base = strrchr (DW_STRING (attr), ':');
-             if (base && base > DW_STRING (attr) && base[-1] == ':')
-               return &base[1];
-             else
-               return DW_STRING (attr);
            }
+
+         /* Strip any leading namespaces/classes, keep only the base name.
+            DW_AT_name for named DIEs does not contain the prefixes.  */
+         const char *base = strrchr (DW_STRING (attr), ':');
+         if (base && base > DW_STRING (attr) && base[-1] == ':')
+           return &base[1];
+         else
+           return DW_STRING (attr);
        }
       break;
 
@@ -21795,9 +21507,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 
   if (!DW_STRING_IS_CANONICAL (attr))
     {
-      DW_STRING (attr)
-       = dwarf2_canonicalize_name (DW_STRING (attr), cu,
-                                   &objfile->per_bfd->storage_obstack);
+      DW_STRING (attr) = dwarf2_canonicalize_name (DW_STRING (attr), cu,
+                                                  objfile);
       DW_STRING_IS_CANONICAL (attr) = 1;
     }
   return DW_STRING (attr);
@@ -21819,89 +21530,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)
 {
@@ -22088,43 +21716,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.  */
@@ -22215,7 +21806,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;
 
@@ -22232,14 +21823,11 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
   return die;
 }
 
-/* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU.
-   Returned value is intended for DW_OP_call*.  Returned
-   dwarf2_locexpr_baton->data has lifetime of
-   PER_CU->DWARF2_PER_OBJFILE->OBJFILE.  */
+/* See read.h.  */
 
 struct dwarf2_locexpr_baton
 dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
-                              struct dwarf2_per_cu_data *per_cu,
+                              dwarf2_per_cu_data *per_cu,
                               CORE_ADDR (*get_frame_pc) (void *baton),
                               void *baton, bool resolve_abstract_p)
 {
@@ -22338,12 +21926,11 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
   return retval;
 }
 
-/* Like dwarf2_fetch_die_loc_sect_off, but take a CU
-   offset.  */
+/* See read.h.  */
 
 struct dwarf2_locexpr_baton
 dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu,
-                            struct dwarf2_per_cu_data *per_cu,
+                            dwarf2_per_cu_data *per_cu,
                             CORE_ADDR (*get_frame_pc) (void *baton),
                             void *baton)
 {
@@ -22371,15 +21958,12 @@ write_constant_as_bytes (struct obstack *obstack,
   return result;
 }
 
-/* If the DIE at OFFSET in PER_CU has a DW_AT_const_value, return a
-   pointer to the constant bytes and set LEN to the length of the
-   data.  If memory is needed, allocate it on OBSTACK.  If the DIE
-   does not have a DW_AT_const_value, return NULL.  */
+/* See read.h.  */
 
 const gdb_byte *
 dwarf2_fetch_constant_bytes (sect_offset sect_off,
-                            struct dwarf2_per_cu_data *per_cu,
-                            struct obstack *obstack,
+                            dwarf2_per_cu_data *per_cu,
+                            obstack *obstack,
                             LONGEST *len)
 {
   struct dwarf2_cu *cu;
@@ -22504,12 +22088,11 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
   return result;
 }
 
-/* Return the type of the die at OFFSET in PER_CU.  Return NULL if no
-   valid type for this die is found.  */
+/* See read.h.  */
 
 struct type *
 dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
-                               struct dwarf2_per_cu_data *per_cu)
+                               dwarf2_per_cu_data *per_cu)
 {
   struct dwarf2_cu *cu;
   struct die_info *die;
@@ -22527,8 +22110,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
   return die_type (die, cu);
 }
 
-/* Return the type of the DIE at DIE_OFFSET in the CU named by
-   PER_CU.  */
+/* See read.h.  */
 
 struct type *
 dwarf2_get_die_type (cu_offset die_offset,
@@ -22729,7 +22311,7 @@ load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
   struct signatured_type *sig_type;
 
   /* Caller is responsible for ensuring type_unit_groups don't get here.  */
-  gdb_assert (! IS_TYPE_UNIT_GROUP (per_cu));
+  gdb_assert (! per_cu->type_unit_group_p ());
 
   /* We have the per_cu, but we need the signatured_type.
      Fortunately this is an easy translation.  */
@@ -23079,886 +22661,84 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
 }
 
 \f
+
 /* Macro support.  */
 
-static struct macro_source_file *
-macro_start_file (struct dwarf2_cu *cu,
-                 int file, int line,
-                  struct macro_source_file *current_file,
-                  struct line_header *lh)
+/* An overload of dwarf_decode_macros that finds the correct section
+   and ensures it is read in before calling the other overload.  */
+
+static void
+dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
+                    int section_is_gnu)
 {
-  /* File name relative to the compilation directory of this source file.  */
-  gdb::unique_xmalloc_ptr<char> file_name = lh->file_file_name (file);
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_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;
+  struct dwarf2_section_info *section;
+  const char *section_name;
 
-  if (! current_file)
+  if (cu->dwo_unit != nullptr)
     {
-      /* Note: We don't create a macro table for this compilation unit
-        at all until we actually get a filename.  */
-      struct macro_table *macro_table = cu->get_builder ()->get_macro_table ();
-
-      /* If we have no current file, then this must be the start_file
-        directive for the compilation unit's main source file.  */
-      current_file = macro_set_main (macro_table, file_name.get ());
-      macro_define_special (macro_table);
+      if (section_is_gnu)
+       {
+         section = &cu->dwo_unit->dwo_file->sections.macro;
+         section_name = ".debug_macro.dwo";
+       }
+      else
+       {
+         section = &cu->dwo_unit->dwo_file->sections.macinfo;
+         section_name = ".debug_macinfo.dwo";
+       }
     }
   else
-    current_file = macro_include (current_file, line, file_name.get ());
+    {
+      if (section_is_gnu)
+       {
+         section = &dwarf2_per_objfile->macro;
+         section_name = ".debug_macro";
+       }
+      else
+       {
+         section = &dwarf2_per_objfile->macinfo;
+         section_name = ".debug_macinfo";
+       }
+    }
+
+  section->read (objfile);
+  if (section->buffer == nullptr)
+    {
+      complaint (_("missing %s section"), section_name);
+      return;
+    }
+
+  buildsym_compunit *builder = cu->get_builder ();
 
-  return current_file;
+  dwarf_decode_macros (dwarf2_per_objfile, builder, section, lh,
+                      offset_size, offset, section_is_gnu);
 }
 
-static const char *
-consume_improper_spaces (const char *p, const char *body)
+/* Return the .debug_loc section to use for CU.
+   For DWO files use .debug_loc.dwo.  */
+
+static struct dwarf2_section_info *
+cu_debug_loc_section (struct dwarf2_cu *cu)
 {
-  if (*p == ' ')
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+
+  if (cu->dwo_unit)
     {
-      complaint (_("macro definition contains spaces "
-                  "in formal argument list:\n`%s'"),
-                body);
+      struct dwo_sections *sections = &cu->dwo_unit->dwo_file->sections;
 
-      while (*p == ' ')
-        p++;
+      return cu->header.version >= 5 ? &sections->loclists : &sections->loc;
     }
-
-  return p;
+  return (cu->header.version >= 5 ? &dwarf2_per_objfile->loclists
+                                 : &dwarf2_per_objfile->loc);
 }
 
-
-static void
-parse_macro_definition (struct macro_source_file *file, int line,
-                        const char *body)
-{
-  const char *p;
-
-  /* The body string takes one of two forms.  For object-like macro
-     definitions, it should be:
-
-        <macro name> " " <definition>
-
-     For function-like macro definitions, it should be:
-
-        <macro name> "() " <definition>
-     or
-        <macro name> "(" <arg name> ( "," <arg name> ) * ") " <definition>
-
-     Spaces may appear only where explicitly indicated, and in the
-     <definition>.
-
-     The Dwarf 2 spec says that an object-like macro's name is always
-     followed by a space, but versions of GCC around March 2002 omit
-     the space when the macro's definition is the empty string.
-
-     The Dwarf 2 spec says that there should be no spaces between the
-     formal arguments in a function-like macro's formal argument list,
-     but versions of GCC around March 2002 include spaces after the
-     commas.  */
-
-
-  /* Find the extent of the macro name.  The macro name is terminated
-     by either a space or null character (for an object-like macro) or
-     an opening paren (for a function-like macro).  */
-  for (p = body; *p; p++)
-    if (*p == ' ' || *p == '(')
-      break;
-
-  if (*p == ' ' || *p == '\0')
-    {
-      /* It's an object-like macro.  */
-      int name_len = p - body;
-      std::string name (body, name_len);
-      const char *replacement;
-
-      if (*p == ' ')
-        replacement = body + name_len + 1;
-      else
-        {
-         dwarf2_macro_malformed_definition_complaint (body);
-          replacement = body + name_len;
-        }
-
-      macro_define_object (file, line, name.c_str (), replacement);
-    }
-  else if (*p == '(')
-    {
-      /* It's a function-like macro.  */
-      std::string name (body, p - body);
-      int argc = 0;
-      int argv_size = 1;
-      char **argv = XNEWVEC (char *, argv_size);
-
-      p++;
-
-      p = consume_improper_spaces (p, body);
-
-      /* Parse the formal argument list.  */
-      while (*p && *p != ')')
-        {
-          /* Find the extent of the current argument name.  */
-          const char *arg_start = p;
-
-          while (*p && *p != ',' && *p != ')' && *p != ' ')
-            p++;
-
-          if (! *p || p == arg_start)
-           dwarf2_macro_malformed_definition_complaint (body);
-          else
-            {
-              /* Make sure argv has room for the new argument.  */
-              if (argc >= argv_size)
-                {
-                  argv_size *= 2;
-                  argv = XRESIZEVEC (char *, argv, argv_size);
-                }
-
-              argv[argc++] = savestring (arg_start, p - arg_start);
-            }
-
-          p = consume_improper_spaces (p, body);
-
-          /* Consume the comma, if present.  */
-          if (*p == ',')
-            {
-              p++;
-
-              p = consume_improper_spaces (p, body);
-            }
-        }
-
-      if (*p == ')')
-        {
-          p++;
-
-          if (*p == ' ')
-            /* Perfectly formed definition, no complaints.  */
-            macro_define_function (file, line, name.c_str (),
-                                   argc, (const char **) argv,
-                                   p + 1);
-          else if (*p == '\0')
-            {
-              /* Complain, but do define it.  */
-             dwarf2_macro_malformed_definition_complaint (body);
-              macro_define_function (file, line, name.c_str (),
-                                     argc, (const char **) argv,
-                                     p);
-            }
-          else
-            /* Just complain.  */
-           dwarf2_macro_malformed_definition_complaint (body);
-        }
-      else
-        /* Just complain.  */
-       dwarf2_macro_malformed_definition_complaint (body);
-
-      {
-        int i;
-
-        for (i = 0; i < argc; i++)
-          xfree (argv[i]);
-      }
-      xfree (argv);
-    }
-  else
-    dwarf2_macro_malformed_definition_complaint (body);
-}
-
-/* Skip some bytes from BYTES according to the form given in FORM.
-   Returns the new pointer.  */
-
-static const gdb_byte *
-skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
-                enum dwarf_form form,
-                unsigned int offset_size,
-                struct dwarf2_section_info *section)
-{
-  unsigned int bytes_read;
-
-  switch (form)
-    {
-    case DW_FORM_data1:
-    case DW_FORM_flag:
-      ++bytes;
-      break;
-
-    case DW_FORM_data2:
-      bytes += 2;
-      break;
-
-    case DW_FORM_data4:
-      bytes += 4;
-      break;
-
-    case DW_FORM_data8:
-      bytes += 8;
-      break;
-
-    case DW_FORM_data16:
-      bytes += 16;
-      break;
-
-    case DW_FORM_string:
-      read_direct_string (abfd, bytes, &bytes_read);
-      bytes += bytes_read;
-      break;
-
-    case DW_FORM_sec_offset:
-    case DW_FORM_strp:
-    case DW_FORM_GNU_strp_alt:
-      bytes += offset_size;
-      break;
-
-    case DW_FORM_block:
-      bytes += read_unsigned_leb128 (abfd, bytes, &bytes_read);
-      bytes += bytes_read;
-      break;
-
-    case DW_FORM_block1:
-      bytes += 1 + read_1_byte (abfd, bytes);
-      break;
-    case DW_FORM_block2:
-      bytes += 2 + read_2_bytes (abfd, bytes);
-      break;
-    case DW_FORM_block4:
-      bytes += 4 + read_4_bytes (abfd, bytes);
-      break;
-
-    case DW_FORM_addrx:
-    case DW_FORM_sdata:
-    case DW_FORM_strx:
-    case DW_FORM_udata:
-    case DW_FORM_GNU_addr_index:
-    case DW_FORM_GNU_str_index:
-      bytes = gdb_skip_leb128 (bytes, buffer_end);
-      if (bytes == NULL)
-       {
-         dwarf2_section_buffer_overflow_complaint (section);
-         return NULL;
-       }
-      break;
-
-    case DW_FORM_implicit_const:
-      break;
-
-    default:
-      {
-       complaint (_("invalid form 0x%x in `%s'"),
-                  form, section->get_name ());
-       return NULL;
-      }
-    }
-
-  return bytes;
-}
-
-/* A helper for dwarf_decode_macros that handles skipping an unknown
-   opcode.  Returns an updated pointer to the macro data buffer; or,
-   on error, issues a complaint and returns NULL.  */
-
-static const gdb_byte *
-skip_unknown_opcode (unsigned int opcode,
-                    const gdb_byte **opcode_definitions,
-                    const gdb_byte *mac_ptr, const gdb_byte *mac_end,
-                    bfd *abfd,
-                    unsigned int offset_size,
-                    struct dwarf2_section_info *section)
-{
-  unsigned int bytes_read, i;
-  unsigned long arg;
-  const gdb_byte *defn;
-
-  if (opcode_definitions[opcode] == NULL)
-    {
-      complaint (_("unrecognized DW_MACFINO opcode 0x%x"),
-                opcode);
-      return NULL;
-    }
-
-  defn = opcode_definitions[opcode];
-  arg = read_unsigned_leb128 (abfd, defn, &bytes_read);
-  defn += bytes_read;
-
-  for (i = 0; i < arg; ++i)
-    {
-      mac_ptr = skip_form_bytes (abfd, mac_ptr, mac_end,
-                                (enum dwarf_form) defn[i], offset_size,
-                                section);
-      if (mac_ptr == NULL)
-       {
-         /* skip_form_bytes already issued the complaint.  */
-         return NULL;
-       }
-    }
-
-  return mac_ptr;
-}
-
-/* A helper function which parses the header of a macro section.
-   If the macro section is the extended (for now called "GNU") type,
-   then this updates *OFFSET_SIZE.  Returns a pointer to just after
-   the header, or issues a complaint and returns NULL on error.  */
-
-static const gdb_byte *
-dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
-                         bfd *abfd,
-                         const gdb_byte *mac_ptr,
-                         unsigned int *offset_size,
-                         int section_is_gnu)
-{
-  memset (opcode_definitions, 0, 256 * sizeof (gdb_byte *));
-
-  if (section_is_gnu)
-    {
-      unsigned int version, flags;
-
-      version = read_2_bytes (abfd, mac_ptr);
-      if (version != 4 && version != 5)
-       {
-         complaint (_("unrecognized version `%d' in .debug_macro section"),
-                    version);
-         return NULL;
-       }
-      mac_ptr += 2;
-
-      flags = read_1_byte (abfd, mac_ptr);
-      ++mac_ptr;
-      *offset_size = (flags & 1) ? 8 : 4;
-
-      if ((flags & 2) != 0)
-       /* We don't need the line table offset.  */
-       mac_ptr += *offset_size;
-
-      /* Vendor opcode descriptions.  */
-      if ((flags & 4) != 0)
-       {
-         unsigned int i, count;
-
-         count = read_1_byte (abfd, mac_ptr);
-         ++mac_ptr;
-         for (i = 0; i < count; ++i)
-           {
-             unsigned int opcode, bytes_read;
-             unsigned long arg;
-
-             opcode = read_1_byte (abfd, mac_ptr);
-             ++mac_ptr;
-             opcode_definitions[opcode] = mac_ptr;
-             arg = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-             mac_ptr += bytes_read;
-             mac_ptr += arg;
-           }
-       }
-    }
-
-  return mac_ptr;
-}
-
-/* A helper for dwarf_decode_macros that handles the GNU extensions,
-   including DW_MACRO_import.  */
-
-static void
-dwarf_decode_macro_bytes (struct dwarf2_cu *cu,
-                         bfd *abfd,
-                         const gdb_byte *mac_ptr, const gdb_byte *mac_end,
-                         struct macro_source_file *current_file,
-                         struct line_header *lh,
-                         struct dwarf2_section_info *section,
-                         int section_is_gnu, int section_is_dwz,
-                         unsigned int offset_size,
-                         htab_t include_hash)
-{
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-  enum dwarf_macro_record_type macinfo_type;
-  int at_commandline;
-  const gdb_byte *opcode_definitions[256];
-
-  mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
-                                     &offset_size, section_is_gnu);
-  if (mac_ptr == NULL)
-    {
-      /* We already issued a complaint.  */
-      return;
-    }
-
-  /* Determines if GDB is still before first DW_MACINFO_start_file.  If true
-     GDB is still reading the definitions from command line.  First
-     DW_MACINFO_start_file will need to be ignored as it was already executed
-     to create CURRENT_FILE for the main source holding also the command line
-     definitions.  On first met DW_MACINFO_start_file this flag is reset to
-     normally execute all the remaining DW_MACINFO_start_file macinfos.  */
-
-  at_commandline = 1;
-
-  do
-    {
-      /* Do we at least have room for a macinfo type byte?  */
-      if (mac_ptr >= mac_end)
-       {
-         dwarf2_section_buffer_overflow_complaint (section);
-         break;
-       }
-
-      macinfo_type = (enum dwarf_macro_record_type) read_1_byte (abfd, mac_ptr);
-      mac_ptr++;
-
-      /* Note that we rely on the fact that the corresponding GNU and
-        DWARF constants are the same.  */
-      DIAGNOSTIC_PUSH
-      DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
-      switch (macinfo_type)
-       {
-         /* A zero macinfo type indicates the end of the macro
-            information.  */
-       case 0:
-         break;
-
-        case DW_MACRO_define:
-        case DW_MACRO_undef:
-       case DW_MACRO_define_strp:
-       case DW_MACRO_undef_strp:
-       case DW_MACRO_define_sup:
-       case DW_MACRO_undef_sup:
-          {
-            unsigned int bytes_read;
-            int line;
-            const char *body;
-           int is_define;
-
-           line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-           mac_ptr += bytes_read;
-
-           if (macinfo_type == DW_MACRO_define
-               || macinfo_type == DW_MACRO_undef)
-             {
-               body = read_direct_string (abfd, mac_ptr, &bytes_read);
-               mac_ptr += bytes_read;
-             }
-           else
-             {
-               LONGEST str_offset;
-
-               str_offset = read_offset (abfd, mac_ptr, offset_size);
-               mac_ptr += offset_size;
-
-               if (macinfo_type == DW_MACRO_define_sup
-                   || macinfo_type == DW_MACRO_undef_sup
-                   || section_is_dwz)
-                 {
-                   struct dwz_file *dwz
-                     = dwarf2_get_dwz_file (dwarf2_per_objfile);
-
-                   body = read_indirect_string_from_dwz (objfile,
-                                                         dwz, str_offset);
-                 }
-               else
-                 body = read_indirect_string_at_offset (dwarf2_per_objfile,
-                                                        abfd, str_offset);
-             }
-
-           is_define = (macinfo_type == DW_MACRO_define
-                        || macinfo_type == DW_MACRO_define_strp
-                        || macinfo_type == DW_MACRO_define_sup);
-            if (! current_file)
-             {
-               /* DWARF violation as no main source is present.  */
-               complaint (_("debug info with no main source gives macro %s "
-                            "on line %d: %s"),
-                          is_define ? _("definition") : _("undefinition"),
-                          line, body);
-               break;
-             }
-           if ((line == 0 && !at_commandline)
-               || (line != 0 && at_commandline))
-             complaint (_("debug info gives %s macro %s with %s line %d: %s"),
-                        at_commandline ? _("command-line") : _("in-file"),
-                        is_define ? _("definition") : _("undefinition"),
-                        line == 0 ? _("zero") : _("non-zero"), line, body);
-
-           if (body == NULL)
-             {
-               /* Fedora's rpm-build's "debugedit" binary
-                  corrupted .debug_macro sections.
-
-                  For more info, see
-                  https://bugzilla.redhat.com/show_bug.cgi?id=1708786 */
-               complaint (_("debug info gives %s invalid macro %s "
-                            "without body (corrupted?) at line %d "
-                            "on file %s"),
-                          at_commandline ? _("command-line") : _("in-file"),
-                          is_define ? _("definition") : _("undefinition"),
-                          line, current_file->filename);
-             }
-           else if (is_define)
-             parse_macro_definition (current_file, line, body);
-           else
-             {
-               gdb_assert (macinfo_type == DW_MACRO_undef
-                           || macinfo_type == DW_MACRO_undef_strp
-                           || macinfo_type == DW_MACRO_undef_sup);
-               macro_undef (current_file, line, body);
-             }
-          }
-          break;
-
-        case DW_MACRO_start_file:
-          {
-            unsigned int bytes_read;
-            int line, file;
-
-            line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-            mac_ptr += bytes_read;
-            file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-            mac_ptr += bytes_read;
-
-           if ((line == 0 && !at_commandline)
-               || (line != 0 && at_commandline))
-             complaint (_("debug info gives source %d included "
-                          "from %s at %s line %d"),
-                        file, at_commandline ? _("command-line") : _("file"),
-                        line == 0 ? _("zero") : _("non-zero"), line);
-
-           if (at_commandline)
-             {
-               /* This DW_MACRO_start_file was executed in the
-                  pass one.  */
-               at_commandline = 0;
-             }
-           else
-             current_file = macro_start_file (cu, file, line, current_file,
-                                              lh);
-          }
-          break;
-
-        case DW_MACRO_end_file:
-          if (! current_file)
-           complaint (_("macro debug info has an unmatched "
-                        "`close_file' directive"));
-          else
-            {
-              current_file = current_file->included_by;
-              if (! current_file)
-                {
-                  enum dwarf_macro_record_type next_type;
-
-                  /* GCC circa March 2002 doesn't produce the zero
-                     type byte marking the end of the compilation
-                     unit.  Complain if it's not there, but exit no
-                     matter what.  */
-
-                  /* Do we at least have room for a macinfo type byte?  */
-                  if (mac_ptr >= mac_end)
-                    {
-                     dwarf2_section_buffer_overflow_complaint (section);
-                      return;
-                    }
-
-                  /* We don't increment mac_ptr here, so this is just
-                     a look-ahead.  */
-                  next_type
-                   = (enum dwarf_macro_record_type) read_1_byte (abfd,
-                                                                 mac_ptr);
-                  if (next_type != 0)
-                   complaint (_("no terminating 0-type entry for "
-                                "macros in `.debug_macinfo' section"));
-
-                  return;
-                }
-            }
-          break;
-
-       case DW_MACRO_import:
-       case DW_MACRO_import_sup:
-         {
-           LONGEST offset;
-           void **slot;
-           bfd *include_bfd = abfd;
-           struct dwarf2_section_info *include_section = section;
-           const gdb_byte *include_mac_end = mac_end;
-           int is_dwz = section_is_dwz;
-           const gdb_byte *new_mac_ptr;
-
-           offset = read_offset (abfd, mac_ptr, offset_size);
-           mac_ptr += offset_size;
-
-           if (macinfo_type == DW_MACRO_import_sup)
-             {
-               struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
-
-               dwz->macro.read (objfile);
-
-               include_section = &dwz->macro;
-               include_bfd = include_section->get_bfd_owner ();
-               include_mac_end = dwz->macro.buffer + dwz->macro.size;
-               is_dwz = 1;
-             }
-
-           new_mac_ptr = include_section->buffer + offset;
-           slot = htab_find_slot (include_hash, new_mac_ptr, INSERT);
-
-           if (*slot != NULL)
-             {
-               /* This has actually happened; see
-                  http://sourceware.org/bugzilla/show_bug.cgi?id=13568.  */
-               complaint (_("recursive DW_MACRO_import in "
-                            ".debug_macro section"));
-             }
-           else
-             {
-               *slot = (void *) new_mac_ptr;
-
-               dwarf_decode_macro_bytes (cu, include_bfd, new_mac_ptr,
-                                         include_mac_end, current_file, lh,
-                                         section, section_is_gnu, is_dwz,
-                                         offset_size, include_hash);
-
-               htab_remove_elt (include_hash, (void *) new_mac_ptr);
-             }
-         }
-         break;
-
-        case DW_MACINFO_vendor_ext:
-         if (!section_is_gnu)
-           {
-             unsigned int bytes_read;
-
-             /* This reads the constant, but since we don't recognize
-                any vendor extensions, we ignore it.  */
-             read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-             mac_ptr += bytes_read;
-             read_direct_string (abfd, mac_ptr, &bytes_read);
-             mac_ptr += bytes_read;
-
-             /* We don't recognize any vendor extensions.  */
-             break;
-           }
-         /* FALLTHROUGH */
-
-       default:
-         mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
-                                        mac_ptr, mac_end, abfd, offset_size,
-                                        section);
-         if (mac_ptr == NULL)
-           return;
-         break;
-        }
-      DIAGNOSTIC_POP
-    } while (macinfo_type != 0);
-}
-
-static void
-dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
-                     int section_is_gnu)
-{
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct line_header *lh = cu->line_header;
-  bfd *abfd;
-  const gdb_byte *mac_ptr, *mac_end;
-  struct macro_source_file *current_file = 0;
-  enum dwarf_macro_record_type macinfo_type;
-  unsigned int offset_size = cu->header.offset_size;
-  const gdb_byte *opcode_definitions[256];
-  void **slot;
-  struct dwarf2_section_info *section;
-  const char *section_name;
-
-  if (cu->dwo_unit != NULL)
-    {
-      if (section_is_gnu)
-       {
-         section = &cu->dwo_unit->dwo_file->sections.macro;
-         section_name = ".debug_macro.dwo";
-       }
-      else
-       {
-         section = &cu->dwo_unit->dwo_file->sections.macinfo;
-         section_name = ".debug_macinfo.dwo";
-       }
-    }
-  else
-    {
-      if (section_is_gnu)
-       {
-         section = &dwarf2_per_objfile->macro;
-         section_name = ".debug_macro";
-       }
-      else
-       {
-         section = &dwarf2_per_objfile->macinfo;
-         section_name = ".debug_macinfo";
-       }
-    }
-
-  section->read (objfile);
-  if (section->buffer == NULL)
-    {
-      complaint (_("missing %s section"), section_name);
-      return;
-    }
-  abfd = section->get_bfd_owner ();
-
-  /* First pass: Find the name of the base filename.
-     This filename is needed in order to process all macros whose definition
-     (or undefinition) comes from the command line.  These macros are defined
-     before the first DW_MACINFO_start_file entry, and yet still need to be
-     associated to the base file.
-
-     To determine the base file name, we scan the macro definitions until we
-     reach the first DW_MACINFO_start_file entry.  We then initialize
-     CURRENT_FILE accordingly so that any macro definition found before the
-     first DW_MACINFO_start_file can still be associated to the base file.  */
-
-  mac_ptr = section->buffer + offset;
-  mac_end = section->buffer + section->size;
-
-  mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
-                                     &offset_size, section_is_gnu);
-  if (mac_ptr == NULL)
-    {
-      /* We already issued a complaint.  */
-      return;
-    }
-
-  do
-    {
-      /* Do we at least have room for a macinfo type byte?  */
-      if (mac_ptr >= mac_end)
-        {
-         /* Complaint is printed during the second pass as GDB will probably
-            stop the first pass earlier upon finding
-            DW_MACINFO_start_file.  */
-         break;
-        }
-
-      macinfo_type = (enum dwarf_macro_record_type) read_1_byte (abfd, mac_ptr);
-      mac_ptr++;
-
-      /* Note that we rely on the fact that the corresponding GNU and
-        DWARF constants are the same.  */
-      DIAGNOSTIC_PUSH
-      DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
-      switch (macinfo_type)
-        {
-          /* A zero macinfo type indicates the end of the macro
-             information.  */
-        case 0:
-         break;
-
-       case DW_MACRO_define:
-       case DW_MACRO_undef:
-         /* Only skip the data by MAC_PTR.  */
-         {
-           unsigned int bytes_read;
-
-           read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-           mac_ptr += bytes_read;
-           read_direct_string (abfd, mac_ptr, &bytes_read);
-           mac_ptr += bytes_read;
-         }
-         break;
-
-       case DW_MACRO_start_file:
-         {
-           unsigned int bytes_read;
-           int line, file;
-
-           line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-           mac_ptr += bytes_read;
-           file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-           mac_ptr += bytes_read;
-
-           current_file = macro_start_file (cu, file, line, current_file, lh);
-         }
-         break;
-
-       case DW_MACRO_end_file:
-         /* No data to skip by MAC_PTR.  */
-         break;
-
-       case DW_MACRO_define_strp:
-       case DW_MACRO_undef_strp:
-       case DW_MACRO_define_sup:
-       case DW_MACRO_undef_sup:
-         {
-           unsigned int bytes_read;
-
-           read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-           mac_ptr += bytes_read;
-           mac_ptr += offset_size;
-         }
-         break;
-
-       case DW_MACRO_import:
-       case DW_MACRO_import_sup:
-         /* Note that, according to the spec, a transparent include
-            chain cannot call DW_MACRO_start_file.  So, we can just
-            skip this opcode.  */
-         mac_ptr += offset_size;
-         break;
-
-       case DW_MACINFO_vendor_ext:
-         /* Only skip the data by MAC_PTR.  */
-         if (!section_is_gnu)
-           {
-             unsigned int bytes_read;
-
-             read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-             mac_ptr += bytes_read;
-             read_direct_string (abfd, mac_ptr, &bytes_read);
-             mac_ptr += bytes_read;
-           }
-         /* FALLTHROUGH */
-
-       default:
-         mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
-                                        mac_ptr, mac_end, abfd, offset_size,
-                                        section);
-         if (mac_ptr == NULL)
-           return;
-         break;
-       }
-      DIAGNOSTIC_POP
-    } while (macinfo_type != 0 && current_file == NULL);
-
-  /* Second pass: Process all entries.
-
-     Use the AT_COMMAND_LINE flag to determine whether we are still processing
-     command-line macro definitions/undefinitions.  This flag is unset when we
-     reach the first DW_MACINFO_start_file entry.  */
-
-  htab_up include_hash (htab_create_alloc (1, htab_hash_pointer,
-                                          htab_eq_pointer,
-                                          NULL, xcalloc, xfree));
-  mac_ptr = section->buffer + offset;
-  slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
-  *slot = (void *) mac_ptr;
-  dwarf_decode_macro_bytes (cu, abfd, mac_ptr, mac_end,
-                           current_file, lh, section,
-                           section_is_gnu, 0, offset_size,
-                           include_hash.get ());
-}
-
-/* Return the .debug_loc section to use for CU.
-   For DWO files use .debug_loc.dwo.  */
-
-static struct dwarf2_section_info *
-cu_debug_loc_section (struct dwarf2_cu *cu)
-{
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
-
-  if (cu->dwo_unit)
-    {
-      struct dwo_sections *sections = &cu->dwo_unit->dwo_file->sections;
-
-      return cu->header.version >= 5 ? &sections->loclists : &sections->loc;
-    }
-  return (cu->header.version >= 5 ? &dwarf2_per_objfile->loclists
-                                 : &dwarf2_per_objfile->loc);
-}
-
-/* A helper function that fills in a dwarf2_loclist_baton.  */
+/* A helper function that fills in a dwarf2_loclist_baton.  */
 
 static void
 fill_in_loclist_baton (struct dwarf2_cu *cu,
@@ -23977,7 +22757,10 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
      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;
 }
 
@@ -24002,7 +22785,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."));
 
@@ -24149,34 +22932,53 @@ dwarf2_per_cu_data::addr_type () const
   return addr_type;
 }
 
-/* Locate the .debug_info compilation unit from CU's objfile which contains
-   the DIE at OFFSET.  Raises an error on failure.  */
+/* A helper function for dwarf2_find_containing_comp_unit that returns
+   the index of the result, and that searches a vector.  It will
+   return a result even if the offset in question does not actually
+   occur in any CU.  This is separate so that it can be unit
+   tested.  */
 
-static struct dwarf2_per_cu_data *
-dwarf2_find_containing_comp_unit (sect_offset sect_off,
-                                 unsigned int offset_in_dwz,
-                                 struct dwarf2_per_objfile *dwarf2_per_objfile)
+static int
+dwarf2_find_containing_comp_unit
+  (sect_offset sect_off,
+   unsigned int offset_in_dwz,
+   const std::vector<dwarf2_per_cu_data *> &all_comp_units)
 {
-  struct dwarf2_per_cu_data *this_cu;
   int low, high;
 
   low = 0;
-  high = dwarf2_per_objfile->all_comp_units.size () - 1;
+  high = all_comp_units.size () - 1;
   while (high > low)
     {
       struct dwarf2_per_cu_data *mid_cu;
       int mid = low + (high - low) / 2;
 
-      mid_cu = dwarf2_per_objfile->all_comp_units[mid];
+      mid_cu = all_comp_units[mid];
       if (mid_cu->is_dwz > offset_in_dwz
          || (mid_cu->is_dwz == offset_in_dwz
-             && mid_cu->sect_off + mid_cu->length >= sect_off))
+             && mid_cu->sect_off + mid_cu->length > sect_off))
        high = mid;
       else
        low = mid + 1;
     }
   gdb_assert (low == high);
-  this_cu = dwarf2_per_objfile->all_comp_units[low];
+  return low;
+}
+
+/* Locate the .debug_info compilation unit from CU's objfile which contains
+   the DIE at OFFSET.  Raises an error on failure.  */
+
+static struct dwarf2_per_cu_data *
+dwarf2_find_containing_comp_unit (sect_offset sect_off,
+                                 unsigned int offset_in_dwz,
+                                 struct dwarf2_per_objfile *dwarf2_per_objfile)
+{
+  int low
+    = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
+                                       dwarf2_per_objfile->all_comp_units);
+  struct dwarf2_per_cu_data *this_cu
+    = dwarf2_per_objfile->all_comp_units[low];
+
   if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
     {
       if (low == 0 || this_cu->is_dwz != offset_in_dwz)
@@ -24199,6 +23001,57 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
     }
 }
 
+#if GDB_SELF_TEST
+
+namespace selftests {
+namespace find_containing_comp_unit {
+
+static void
+run_test ()
+{
+  struct dwarf2_per_cu_data one {};
+  struct dwarf2_per_cu_data two {};
+  struct dwarf2_per_cu_data three {};
+  struct dwarf2_per_cu_data four {};
+
+  one.length = 5;
+  two.sect_off = sect_offset (one.length);
+  two.length = 7;
+
+  three.length = 5;
+  three.is_dwz = 1;
+  four.sect_off = sect_offset (three.length);
+  four.length = 7;
+  four.is_dwz = 1;
+
+  std::vector<dwarf2_per_cu_data *> units;
+  units.push_back (&one);
+  units.push_back (&two);
+  units.push_back (&three);
+  units.push_back (&four);
+
+  int result;
+
+  result = dwarf2_find_containing_comp_unit (sect_offset (0), 0, units);
+  SELF_CHECK (units[result] == &one);
+  result = dwarf2_find_containing_comp_unit (sect_offset (3), 0, units);
+  SELF_CHECK (units[result] == &one);
+  result = dwarf2_find_containing_comp_unit (sect_offset (5), 0, units);
+  SELF_CHECK (units[result] == &two);
+
+  result = dwarf2_find_containing_comp_unit (sect_offset (0), 1, units);
+  SELF_CHECK (units[result] == &three);
+  result = dwarf2_find_containing_comp_unit (sect_offset (3), 1, units);
+  SELF_CHECK (units[result] == &three);
+  result = dwarf2_find_containing_comp_unit (sect_offset (5), 1, units);
+  SELF_CHECK (units[result] == &four);
+}
+
+}
+}
+
+#endif /* GDB_SELF_TEST */
+
 /* Initialize dwarf2_cu CU, owned by PER_CU.  */
 
 dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
@@ -24703,5 +23556,7 @@ Warning: This option must be enabled before gdb reads the file."),
 #if GDB_SELF_TEST
   selftests::register_test ("dw2_expand_symtabs_matching",
                            selftests::dw2_expand_symtabs_matching::run_test);
+  selftests::register_test ("dwarf2_find_containing_comp_unit",
+                           selftests::find_containing_comp_unit::run_test);
 #endif
 }
This page took 0.079527 seconds and 4 git commands to generate.