-Wwrite-strings: The Rest
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index a987e0eeff5edbc744790fe2ba044f2df769a122..966e1ee81ba99a17f96b095c19a5d14485f84af9 100644 (file)
@@ -70,6 +70,9 @@
 #include "build-id.h"
 #include "namespace.h"
 #include "common/gdb_unlinker.h"
+#include "common/function-view.h"
+#include "common/gdb_optional.h"
+#include "common/underlying.h"
 
 #include <fcntl.h>
 #include <sys/types.h>
@@ -222,10 +225,13 @@ struct dwarf2_per_objfile
   struct dwarf2_section_info abbrev;
   struct dwarf2_section_info line;
   struct dwarf2_section_info loc;
+  struct dwarf2_section_info loclists;
   struct dwarf2_section_info macinfo;
   struct dwarf2_section_info macro;
   struct dwarf2_section_info str;
+  struct dwarf2_section_info line_str;
   struct dwarf2_section_info ranges;
+  struct dwarf2_section_info rnglists;
   struct dwarf2_section_info addr;
   struct dwarf2_section_info frame;
   struct dwarf2_section_info eh_frame;
@@ -333,10 +339,13 @@ static const struct dwarf2_debug_sections dwarf2_elf_names =
   { ".debug_abbrev", ".zdebug_abbrev" },
   { ".debug_line", ".zdebug_line" },
   { ".debug_loc", ".zdebug_loc" },
+  { ".debug_loclists", ".zdebug_loclists" },
   { ".debug_macinfo", ".zdebug_macinfo" },
   { ".debug_macro", ".zdebug_macro" },
   { ".debug_str", ".zdebug_str" },
+  { ".debug_line_str", ".zdebug_line_str" },
   { ".debug_ranges", ".zdebug_ranges" },
+  { ".debug_rnglists", ".zdebug_rnglists" },
   { ".debug_types", ".zdebug_types" },
   { ".debug_addr", ".zdebug_addr" },
   { ".debug_frame", ".zdebug_frame" },
@@ -353,6 +362,7 @@ static const struct dwop_section_names
   struct dwarf2_section_names info_dwo;
   struct dwarf2_section_names line_dwo;
   struct dwarf2_section_names loc_dwo;
+  struct dwarf2_section_names loclists_dwo;
   struct dwarf2_section_names macinfo_dwo;
   struct dwarf2_section_names macro_dwo;
   struct dwarf2_section_names str_dwo;
@@ -367,6 +377,7 @@ dwop_section_names =
   { ".debug_info.dwo", ".zdebug_info.dwo" },
   { ".debug_line.dwo", ".zdebug_line.dwo" },
   { ".debug_loc.dwo", ".zdebug_loc.dwo" },
+  { ".debug_loclists.dwo", ".zdebug_loclists.dwo" },
   { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo" },
   { ".debug_macro.dwo", ".zdebug_macro.dwo" },
   { ".debug_str.dwo", ".zdebug_str.dwo" },
@@ -386,7 +397,7 @@ struct comp_unit_head
   short version;
   unsigned char addr_size;
   unsigned char signed_addr_p;
-  sect_offset abbrev_offset;
+  sect_offset abbrev_sect_off;
 
   /* Size of file offsets; either 4 or 8.  */
   unsigned int offset_size;
@@ -394,13 +405,22 @@ struct comp_unit_head
   /* Size of the length field; either 4 or 12.  */
   unsigned int initial_length_size;
 
+  enum dwarf_unit_type unit_type;
+
   /* Offset to the first byte of this compilation unit header in the
      .debug_info section, for resolving relative reference dies.  */
-  sect_offset offset;
+  sect_offset sect_off;
 
   /* Offset to first die in this cu from the start of the cu.
      This will be the first byte following the compilation unit header.  */
-  cu_offset first_die_offset;
+  cu_offset first_die_cu_offset;
+
+  /* 64-bit signature of this type unit - it is valid only for
+     UNIT_TYPE DW_UT_type.  */
+  ULONGEST signature;
+
+  /* For types, offset in the type's DIE of the type defined by this TU.  */
+  cu_offset type_cu_offset_in_tu;
 };
 
 /* Type used for delaying computation of method physnames.
@@ -569,9 +589,12 @@ struct dwarf2_per_cu_data
      initial_length_size.
      If the DIE refers to a DWO file, this is always of the original die,
      not the DWO file.  */
-  sect_offset offset;
+  sect_offset sect_off;
   unsigned int length;
 
+  /* DWARF standard version this data has been read from (such as 4 or 5).  */
+  short dwarf_version;
+
   /* Flag indicating this compilation unit will be read in before
      any of the current compilation units are processed.  */
   unsigned int queued : 1;
@@ -705,7 +728,7 @@ struct stmt_list_hash
   struct dwo_unit *dwo_unit;
 
   /* Offset in .debug_line or .debug_line.dwo.  */
-  sect_offset line_offset;
+  sect_offset line_sect_off;
 };
 
 /* Each element of dwarf2_per_objfile->type_unit_groups is a pointer to
@@ -756,6 +779,7 @@ struct dwo_sections
   struct dwarf2_section_info abbrev;
   struct dwarf2_section_info line;
   struct dwarf2_section_info loc;
+  struct dwarf2_section_info loclists;
   struct dwarf2_section_info macinfo;
   struct dwarf2_section_info macro;
   struct dwarf2_section_info str;
@@ -780,8 +804,8 @@ struct dwo_unit
   /* The section this CU/TU lives in, in the DWO file.  */
   struct dwarf2_section_info *section;
 
-  /* Same as dwarf2_per_cu_data:{offset,length} but in the DWO section.  */
-  sect_offset offset;
+  /* Same as dwarf2_per_cu_data:{sect_off,length} but in the DWO section.  */
+  sect_offset sect_off;
   unsigned int length;
 
   /* For types, offset in the type's DIE of the type defined by this TU.  */
@@ -1030,16 +1054,46 @@ typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader,
                                      int has_children,
                                      void *data);
 
+/* A 1-based directory index.  This is a strong typedef to prevent
+   accidentally using a directory index as a 0-based index into an
+   array/vector.  */
+enum class dir_index : unsigned int {};
+
+/* Likewise, a 1-based file name index.  */
+enum class file_name_index : unsigned int {};
+
 struct file_entry
 {
-  const char *name;
-  unsigned int dir_index;
-  unsigned int mod_time;
-  unsigned int length;
-  /* Non-zero if referenced by the Line Number Program.  */
-  int included_p;
+  file_entry () = default;
+
+  file_entry (const char *name_, dir_index d_index_,
+             unsigned int mod_time_, unsigned int length_)
+    : name (name_),
+      d_index (d_index_),
+      mod_time (mod_time_),
+      length (length_)
+  {}
+
+  /* Return the include directory at D_INDEX stored in LH.  Returns
+     NULL if D_INDEX is out of bounds.  */
+  const char *include_dir (const line_header *lh) const;
+
+  /* The file name.  Note this is an observing pointer.  The memory is
+     owned by debug_line_buffer.  */
+  const char *name {};
+
+  /* The directory index (1-based).  */
+  dir_index d_index {};
+
+  unsigned int mod_time {};
+
+  unsigned int length {};
+
+  /* True if referenced by the Line Number Program.  */
+  bool included_p {};
+
   /* The associated symbol table, if any.  */
-  struct symtab *symtab;
+  struct symtab *symtab {};
 };
 
 /* The line number information for a compilation unit (found in the
@@ -1047,52 +1101,99 @@ struct file_entry
    which contains the following information.  */
 struct line_header
 {
+  line_header ()
+    : offset_in_dwz {}
+  {}
+
+  /* Add an entry to the include directory table.  */
+  void add_include_dir (const char *include_dir);
+
+  /* Add an entry to the file name table.  */
+  void add_file_name (const char *name, dir_index d_index,
+                     unsigned int mod_time, unsigned int length);
+
+  /* Return the include dir at INDEX (1-based).  Returns NULL if INDEX
+     is out of bounds.  */
+  const char *include_dir_at (dir_index index) const
+  {
+    /* Convert directory index number (1-based) to vector index
+       (0-based).  */
+    size_t vec_index = to_underlying (index) - 1;
+
+    if (vec_index >= include_dirs.size ())
+      return NULL;
+    return include_dirs[vec_index];
+  }
+
+  /* Return the file name at INDEX (1-based).  Returns NULL if INDEX
+     is out of bounds.  */
+  file_entry *file_name_at (file_name_index index)
+  {
+    /* Convert file name index number (1-based) to vector index
+       (0-based).  */
+    size_t vec_index = to_underlying (index) - 1;
+
+    if (vec_index >= file_names.size ())
+      return NULL;
+    return &file_names[vec_index];
+  }
+
+  /* Const version of the above.  */
+  const file_entry *file_name_at (unsigned int index) const
+  {
+    if (index >= file_names.size ())
+      return NULL;
+    return &file_names[index];
+  }
+
   /* Offset of line number information in .debug_line section.  */
-  sect_offset offset;
+  sect_offset sect_off {};
 
   /* OFFSET is for struct dwz_file associated with dwarf2_per_objfile.  */
-  unsigned offset_in_dwz : 1;
-
-  unsigned int total_length;
-  unsigned short version;
-  unsigned int header_length;
-  unsigned char minimum_instruction_length;
-  unsigned char maximum_ops_per_instruction;
-  unsigned char default_is_stmt;
-  int line_base;
-  unsigned char line_range;
-  unsigned char opcode_base;
+  unsigned offset_in_dwz : 1; /* Can't initialize bitfields in-class.  */
+
+  unsigned int total_length {};
+  unsigned short version {};
+  unsigned int header_length {};
+  unsigned char minimum_instruction_length {};
+  unsigned char maximum_ops_per_instruction {};
+  unsigned char default_is_stmt {};
+  int line_base {};
+  unsigned char line_range {};
+  unsigned char opcode_base {};
 
   /* standard_opcode_lengths[i] is the number of operands for the
      standard opcode whose value is i.  This means that
      standard_opcode_lengths[0] is unused, and the last meaningful
      element is standard_opcode_lengths[opcode_base - 1].  */
-  unsigned char *standard_opcode_lengths;
+  std::unique_ptr<unsigned char[]> standard_opcode_lengths;
 
-  /* The include_directories table.  NOTE!  These strings are not
-     allocated with xmalloc; instead, they are pointers into
-     debug_line_buffer.  If you try to free them, `free' will get
-     indigestion.  */
-  unsigned int num_include_dirs, include_dirs_size;
-  const char **include_dirs;
+  /* The include_directories table.  Note these are observing
+     pointers.  The memory is owned by debug_line_buffer.  */
+  std::vector<const char *> include_dirs;
 
-  /* The file_names table.  NOTE!  These strings are not allocated
-     with xmalloc; instead, they are pointers into debug_line_buffer.
-     Don't try to free them directly.  */
-  unsigned int num_file_names, file_names_size;
-  struct file_entry *file_names;
+  /* The file_names table.  */
+  std::vector<file_entry> file_names;
 
   /* The start and end of the statement program following this
      header.  These point into dwarf2_per_objfile->line_buffer.  */
-  const gdb_byte *statement_program_start, *statement_program_end;
+  const gdb_byte *statement_program_start {}, *statement_program_end {};
 };
 
+typedef std::unique_ptr<line_header> line_header_up;
+
+const char *
+file_entry::include_dir (const line_header *lh) const
+{
+  return lh->include_dir_at (d_index);
+}
+
 /* When we construct a partial symbol table entry we only
    need this much information.  */
 struct partial_die_info
   {
     /* Offset of this DIE.  */
-    sect_offset offset;
+    sect_offset sect_off;
 
     /* DWARF-2 tag for this DIE.  */
     ENUM_BITFIELD(dwarf_tag) tag : 16;
@@ -1150,7 +1251,7 @@ struct partial_die_info
       /* The location description associated with this DIE, if any.  */
       struct dwarf_block *locdesc;
       /* The offset of an import, for DW_TAG_imported_unit.  */
-      sect_offset offset;
+      sect_offset sect_off;
     } d;
 
     /* If HAS_PC_INFO, the PC range associated with this DIE.  */
@@ -1188,6 +1289,9 @@ struct attr_abbrev
   {
     ENUM_BITFIELD(dwarf_attribute) name : 16;
     ENUM_BITFIELD(dwarf_form) form : 16;
+
+    /* It is valid only if FORM is DW_FORM_implicit_const.  */
+    LONGEST implicit_const;
   };
 
 /* Size of abbrev_table.abbrev_hash_table.  */
@@ -1199,7 +1303,7 @@ struct abbrev_table
 {
   /* Where the abbrev table came from.
      This is used as a sanity check when the table is used.  */
-  sect_offset offset;
+  sect_offset sect_off;
 
   /* Storage for the abbrev table.  */
   struct obstack abbrev_obstack;
@@ -1254,7 +1358,7 @@ struct die_info
     unsigned int abbrev;
 
     /* Offset in .debug_info or .debug_types section.  */
-    sect_offset offset;
+    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
@@ -1507,9 +1611,11 @@ static const char *read_indirect_string (bfd *, const gdb_byte *,
                                         const struct comp_unit_head *,
                                         unsigned int *);
 
-static const char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST);
+static const char *read_indirect_line_string (bfd *, const gdb_byte *,
+                                             const struct comp_unit_head *,
+                                             unsigned int *);
 
-static ULONGEST read_unsigned_leb128 (bfd *, const gdb_byte *, unsigned int *);
+static const char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST);
 
 static LONGEST read_signed_leb128 (bfd *, const gdb_byte *, unsigned int *);
 
@@ -1539,10 +1645,8 @@ static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu);
 static struct die_info *die_specification (struct die_info *die,
                                           struct dwarf2_cu **);
 
-static void free_line_header (struct line_header *lh);
-
-static struct line_header *dwarf_decode_line_header (unsigned int offset,
-                                                    struct dwarf2_cu *cu);
+static line_header_up dwarf_decode_line_header (sect_offset sect_off,
+                                               struct dwarf2_cu *cu);
 
 static void dwarf_decode_lines (struct line_header *, const char *,
                                struct dwarf2_cu *, struct partial_symtab *,
@@ -1721,7 +1825,7 @@ static const char *dwarf_attr_name (unsigned int);
 
 static const char *dwarf_form_name (unsigned int);
 
-static char *dwarf_bool_name (unsigned int);
+static const char *dwarf_bool_name (unsigned int);
 
 static const char *dwarf_type_encoding_name (unsigned int);
 
@@ -1806,7 +1910,7 @@ static hashval_t partial_die_hash (const void *item);
 static int partial_die_eq (const void *item_lhs, const void *item_rhs);
 
 static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
-  (sect_offset offset, unsigned int offset_in_dwz, struct objfile *objfile);
+  (sect_offset sect_off, unsigned int offset_in_dwz, struct objfile *objfile);
 
 static void init_one_comp_unit (struct dwarf2_cu *cu,
                                struct dwarf2_per_cu_data *per_cu);
@@ -1858,18 +1962,39 @@ static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
 
 static void process_queue (void);
 
-static void find_file_and_directory (struct die_info *die,
-                                    struct dwarf2_cu *cu,
-                                    const char **name, const char **comp_dir);
+/* The return type of find_file_and_directory.  Note, the enclosed
+   string pointers are only valid while this object is valid.  */
+
+struct file_and_directory
+{
+  /* The filename.  This is never NULL.  */
+  const char *name;
+
+  /* The compilation directory.  NULL if not known.  If we needed to
+     compute a new string, this points to COMP_DIR_STORAGE, otherwise,
+     points directly to the DW_AT_comp_dir string attribute owned by
+     the obstack that owns the DIE.  */
+  const char *comp_dir;
+
+  /* If we needed to build a new string for comp_dir, this is what
+     owns the storage.  */
+  std::string comp_dir_storage;
+};
+
+static file_and_directory find_file_and_directory (struct die_info *die,
+                                                  struct dwarf2_cu *cu);
 
 static char *file_full_name (int file, struct line_header *lh,
                             const char *comp_dir);
 
+/* Expected enum dwarf_unit_type for read_comp_unit_head.  */
+enum class rcuh_kind { COMPILE, TYPE };
+
 static const gdb_byte *read_and_check_comp_unit_head
   (struct comp_unit_head *header,
    struct dwarf2_section_info *section,
    struct dwarf2_section_info *abbrev_section, const gdb_byte *info_ptr,
-   int is_debug_types_section);
+   rcuh_kind section_kind);
 
 static void init_cutu_and_read_dies
   (struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table,
@@ -1977,7 +2102,7 @@ dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
 static hashval_t
 line_header_hash (const struct line_header *ofs)
 {
-  return ofs->offset.sect_off ^ ofs->offset_in_dwz;
+  return to_underlying (ofs->sect_off) ^ ofs->offset_in_dwz;
 }
 
 /* Hash function for htab_create_alloc_ex for line_header_hash.  */
@@ -1998,7 +2123,7 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
   const struct line_header *ofs_lhs = (const struct line_header *) item_lhs;
   const struct line_header *ofs_rhs = (const struct line_header *) item_rhs;
 
-  return (ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off
+  return (ofs_lhs->sect_off == ofs_rhs->sect_off
          && ofs_lhs->offset_in_dwz == ofs_rhs->offset_in_dwz);
 }
 
@@ -2224,6 +2349,11 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
       dwarf2_per_objfile->loc.s.section = sectp;
       dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp);
     }
+  else if (section_is_p (sectp->name, &names->loclists))
+    {
+      dwarf2_per_objfile->loclists.s.section = sectp;
+      dwarf2_per_objfile->loclists.size = bfd_get_section_size (sectp);
+    }
   else if (section_is_p (sectp->name, &names->macinfo))
     {
       dwarf2_per_objfile->macinfo.s.section = sectp;
@@ -2239,6 +2369,11 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
       dwarf2_per_objfile->str.s.section = sectp;
       dwarf2_per_objfile->str.size = bfd_get_section_size (sectp);
     }
+  else if (section_is_p (sectp->name, &names->line_str))
+    {
+      dwarf2_per_objfile->line_str.s.section = sectp;
+      dwarf2_per_objfile->line_str.size = bfd_get_section_size (sectp);
+    }
   else if (section_is_p (sectp->name, &names->addr))
     {
       dwarf2_per_objfile->addr.s.section = sectp;
@@ -2259,6 +2394,11 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
       dwarf2_per_objfile->ranges.s.section = sectp;
       dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp);
     }
+  else if (section_is_p (sectp->name, &names->rnglists))
+    {
+      dwarf2_per_objfile->rnglists.s.section = sectp;
+      dwarf2_per_objfile->rnglists.size = bfd_get_section_size (sectp);
+    }
   else if (section_is_p (sectp->name, &names->types))
     {
       struct dwarf2_section_info type_section;
@@ -2507,18 +2647,15 @@ dwarf2_get_dwz_file (void)
   buildid_len = (size_t) buildid_len_arg;
 
   filename = (const char *) data;
+
+  std::string abs_storage;
   if (!IS_ABSOLUTE_PATH (filename))
     {
       char *abs = gdb_realpath (objfile_name (dwarf2_per_objfile->objfile));
-      char *rel;
 
       make_cleanup (xfree, abs);
-      abs = ldirname (abs);
-      make_cleanup (xfree, abs);
-
-      rel = concat (abs, SLASH_STRING, filename, (char *) NULL);
-      make_cleanup (xfree, rel);
-      filename = rel;
+      abs_storage = ldirname (abs) + SLASH_STRING + filename;
+      filename = abs_storage.c_str ();
     }
 
   /* First try the file name given in the section.  If that doesn't
@@ -2606,7 +2743,7 @@ hash_stmt_list_entry (const struct stmt_list_hash *stmt_list_hash)
 
   if (stmt_list_hash->dwo_unit != NULL)
     v += (uintptr_t) stmt_list_hash->dwo_unit->dwo_file;
-  v += stmt_list_hash->line_offset.sect_off;
+  v += to_underlying (stmt_list_hash->line_sect_off);
   return v;
 }
 
@@ -2622,7 +2759,7 @@ eq_stmt_list_entry (const struct stmt_list_hash *lhs,
       && lhs->dwo_unit->dwo_file != rhs->dwo_unit->dwo_file)
     return 0;
 
-  return lhs->line_offset.sect_off == rhs->line_offset.sect_off;
+  return lhs->line_sect_off == rhs->line_sect_off;
 }
 
 /* Hash function for a quick_file_names.  */
@@ -2809,17 +2946,17 @@ create_cus_from_index_list (struct objfile *objfile,
 
   for (i = 0; i < n_elements; i += 2)
     {
-      struct dwarf2_per_cu_data *the_cu;
-      ULONGEST offset, length;
-
       gdb_static_assert (sizeof (ULONGEST) >= 8);
-      offset = extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE);
-      length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
+
+      sect_offset sect_off
+       = (sect_offset) extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE);
+      ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
       cu_list += 2 * 8;
 
-      the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                              struct dwarf2_per_cu_data);
-      the_cu->offset.sect_off = offset;
+      dwarf2_per_cu_data *the_cu
+       = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                         struct dwarf2_per_cu_data);
+      the_cu->sect_off = sect_off;
       the_cu->length = length;
       the_cu->objfile = objfile;
       the_cu->section = section;
@@ -2878,23 +3015,26 @@ create_signatured_type_table_from_index (struct objfile *objfile,
   for (i = 0; i < elements; i += 3)
     {
       struct signatured_type *sig_type;
-      ULONGEST offset, type_offset_in_tu, signature;
+      ULONGEST signature;
       void **slot;
+      cu_offset type_offset_in_tu;
 
       gdb_static_assert (sizeof (ULONGEST) >= 8);
-      offset = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE);
-      type_offset_in_tu = extract_unsigned_integer (bytes + 8, 8,
-                                                   BFD_ENDIAN_LITTLE);
+      sect_offset sect_off
+       = (sect_offset) extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE);
+      type_offset_in_tu
+       = (cu_offset) extract_unsigned_integer (bytes + 8, 8,
+                                               BFD_ENDIAN_LITTLE);
       signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
       bytes += 3 * 8;
 
       sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
                                 struct signatured_type);
       sig_type->signature = signature;
-      sig_type->type_offset_in_tu.cu_off = type_offset_in_tu;
+      sig_type->type_offset_in_tu = type_offset_in_tu;
       sig_type->per_cu.is_debug_types = 1;
       sig_type->per_cu.section = section;
-      sig_type->per_cu.offset.sect_off = offset;
+      sig_type->per_cu.sect_off = sect_off;
       sig_type->per_cu.objfile = objfile;
       sig_type->per_cu.v.quick
        = OBSTACK_ZALLOC (&objfile->objfile_obstack,
@@ -3284,13 +3424,10 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
   struct dwarf2_per_cu_data *this_cu = cu->per_cu;  
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *lh_cu;
-  struct line_header *lh;
   struct attribute *attr;
   int i;
-  const char *name, *comp_dir;
   void **slot;
   struct quick_file_names *qfn;
-  unsigned int line_offset;
 
   gdb_assert (! this_cu->is_debug_types);
 
@@ -3303,21 +3440,22 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
     }
 
   lh_cu = this_cu;
-  lh = NULL;
   slot = NULL;
-  line_offset = 0;
+
+  line_header_up lh;
+  sect_offset line_offset {};
 
   attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
   if (attr)
     {
       struct quick_file_names find_entry;
 
-      line_offset = DW_UNSND (attr);
+      line_offset = (sect_offset) DW_UNSND (attr);
 
       /* We may have already read in this line header (TU line header sharing).
         If we have we're done.  */
       find_entry.hash.dwo_unit = cu->dwo_unit;
-      find_entry.hash.line_offset.sect_off = line_offset;
+      find_entry.hash.line_sect_off = line_offset;
       slot = htab_find_slot (dwarf2_per_objfile->quick_file_names_table,
                             &find_entry, INSERT);
       if (*slot != NULL)
@@ -3336,21 +3474,19 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 
   qfn = XOBNEW (&objfile->objfile_obstack, struct quick_file_names);
   qfn->hash.dwo_unit = cu->dwo_unit;
-  qfn->hash.line_offset.sect_off = line_offset;
+  qfn->hash.line_sect_off = line_offset;
   gdb_assert (slot != NULL);
   *slot = qfn;
 
-  find_file_and_directory (comp_unit_die, cu, &name, &comp_dir);
+  file_and_directory fnd = find_file_and_directory (comp_unit_die, cu);
 
-  qfn->num_file_names = lh->num_file_names;
+  qfn->num_file_names = lh->file_names.size ();
   qfn->file_names =
-    XOBNEWVEC (&objfile->objfile_obstack, const char *, lh->num_file_names);
-  for (i = 0; i < lh->num_file_names; ++i)
-    qfn->file_names[i] = file_full_name (i + 1, lhcomp_dir);
+    XOBNEWVEC (&objfile->objfile_obstack, const char *, lh->file_names.size ());
+  for (i = 0; i < lh->file_names.size (); ++i)
+    qfn->file_names[i] = file_full_name (i + 1, lh.get (), fnd.comp_dir);
   qfn->real_names = NULL;
 
-  free_line_header (lh);
-
   lh_cu->v.quick->file_names = qfn;
 }
 
@@ -3446,8 +3582,7 @@ static int
 dw2_map_expand_apply (struct objfile *objfile,
                      struct dwarf2_per_cu_data *per_cu,
                      const char *name, const char *real_path,
-                     int (*callback) (struct symtab *, void *),
-                     void *data)
+                     gdb::function_view<bool (symtab *)> callback)
 {
   struct compunit_symtab *last_made = objfile->compunit_symtabs;
 
@@ -3459,17 +3594,16 @@ dw2_map_expand_apply (struct objfile *objfile,
      all of them.  */
   dw2_instantiate_symtab (per_cu);
 
-  return iterate_over_some_symtabs (name, real_path, callback, data,
-                                   objfile->compunit_symtabs, last_made);
+  return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
+                                   last_made, callback);
 }
 
 /* Implementation of the map_symtabs_matching_filename method.  */
 
-static int
-dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
-                                  const char *real_path,
-                                  int (*callback) (struct symtab *, void *),
-                                  void *data)
+static bool
+dw2_map_symtabs_matching_filename
+  (struct objfile *objfile, const char *name, const char *real_path,
+   gdb::function_view<bool (symtab *)> callback)
 {
   int i;
   const char *name_basename = lbasename (name);
@@ -3501,8 +3635,8 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
          if (compare_filenames_for_search (this_name, name))
            {
              if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-                                       callback, data))
-               return 1;
+                                       callback))
+               return true;
              continue;
            }
 
@@ -3516,8 +3650,8 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
          if (compare_filenames_for_search (this_real_name, name))
            {
              if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-                                       callback, data))
-               return 1;
+                                       callback))
+               return true;
              continue;
            }
 
@@ -3529,15 +3663,15 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
                  && FILENAME_CMP (real_path, this_real_name) == 0)
                {
                  if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
-                                           callback, data))
-                   return 1;
+                                           callback))
+                   return true;
                  continue;
                }
            }
        }
     }
 
-  return 0;
+  return false;
 }
 
 /* Struct used to manage iterating over all CUs looking for a symbol.  */
@@ -3875,11 +4009,10 @@ dw2_map_matching_symbols (struct objfile *objfile,
 static void
 dw2_expand_symtabs_matching
   (struct objfile *objfile,
-   expand_symtabs_file_matcher_ftype *file_matcher,
-   expand_symtabs_symbol_matcher_ftype *symbol_matcher,
-   expand_symtabs_exp_notify_ftype *expansion_notify,
-   enum search_domain kind,
-   void *data)
+   gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+   enum search_domain kind)
 {
   int i;
   offset_type iter;
@@ -3935,7 +4068,7 @@ dw2_expand_symtabs_matching
            {
              const char *this_real_name;
 
-             if (file_matcher (file_data->file_names[j], data, 0))
+             if (file_matcher (file_data->file_names[j], false))
                {
                  per_cu->v.quick->mark = 1;
                  break;
@@ -3945,11 +4078,11 @@ dw2_expand_symtabs_matching
                 files are involved, do a quick comparison of the basenames.  */
              if (!basenames_may_differ
                  && !file_matcher (lbasename (file_data->file_names[j]),
-                                   data, 1))
+                                   true))
                continue;
 
              this_real_name = dw2_get_real_path (objfile, file_data, j);
-             if (file_matcher (this_real_name, data, 0))
+             if (file_matcher (this_real_name, false))
                {
                  per_cu->v.quick->mark = 1;
                  break;
@@ -3978,7 +4111,7 @@ dw2_expand_symtabs_matching
 
       name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
 
-      if (! (*symbol_matcher) (name, data))
+      if (!symbol_matcher (name))
        continue;
 
       /* The name was matched, now expand corresponding CUs that were
@@ -4056,8 +4189,7 @@ dw2_expand_symtabs_matching
                  && symtab_was_null
                  && per_cu->v.quick->compunit_symtab != NULL)
                {
-                 expansion_notify (per_cu->v.quick->compunit_symtab,
-                                   data);
+                 expansion_notify (per_cu->v.quick->compunit_symtab);
                }
            }
        }
@@ -4290,15 +4422,15 @@ get_cu_length (const struct comp_unit_head *header)
   return header->initial_length_size + header->length;
 }
 
-/* Return TRUE if OFFSET is within CU_HEADER.  */
+/* Return TRUE if SECT_OFF is within CU_HEADER.  */
 
-static inline int
-offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset)
+static inline bool
+offset_in_cu_p (const comp_unit_head *cu_header, sect_offset sect_off)
 {
-  sect_offset bottom = { cu_header->offset.sect_off };
-  sect_offset top = { cu_header->offset.sect_off + get_cu_length (cu_header) };
+  sect_offset bottom = cu_header->sect_off;
+  sect_offset top = cu_header->sect_off + get_cu_length (cu_header);
 
-  return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off);
+  return sect_off >= bottom && sect_off < top;
 }
 
 /* Find the base address of the compilation unit for range lists and
@@ -4333,15 +4465,20 @@ dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
 }
 
 /* Read in the comp unit header information from the debug_info at info_ptr.
+   Use rcuh_kind::COMPILE as the default type if not known by the caller.
    NOTE: This leaves members offset, first_die_offset to be filled in
    by the caller.  */
 
 static const gdb_byte *
 read_comp_unit_head (struct comp_unit_head *cu_header,
-                    const gdb_byte *info_ptr, bfd *abfd)
+                    const gdb_byte *info_ptr,
+                    struct dwarf2_section_info *section,
+                    rcuh_kind section_kind)
 {
   int signed_addr;
   unsigned int bytes_read;
+  const char *filename = get_section_file_name (section);
+  bfd *abfd = get_section_bfd_owner (section);
 
   cu_header->length = read_initial_length (abfd, info_ptr, &bytes_read);
   cu_header->initial_length_size = bytes_read;
@@ -4349,17 +4486,75 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
   info_ptr += bytes_read;
   cu_header->version = read_2_bytes (abfd, info_ptr);
   info_ptr += 2;
-  cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header,
-                                            &bytes_read);
+  if (cu_header->version < 5)
+    switch (section_kind)
+      {
+      case rcuh_kind::COMPILE:
+       cu_header->unit_type = DW_UT_compile;
+       break;
+      case rcuh_kind::TYPE:
+       cu_header->unit_type = DW_UT_type;
+       break;
+      default:
+       internal_error (__FILE__, __LINE__,
+                       _("read_comp_unit_head: invalid section_kind"));
+      }
+  else
+    {
+      cu_header->unit_type = static_cast<enum dwarf_unit_type>
+                                                (read_1_byte (abfd, info_ptr));
+      info_ptr += 1;
+      switch (cu_header->unit_type)
+       {
+       case DW_UT_compile:
+         if (section_kind != rcuh_kind::COMPILE)
+           error (_("Dwarf Error: wrong unit_type in compilation unit header "
+                  "(is DW_UT_compile, should be DW_UT_type) [in module %s]"),
+                  filename);
+         break;
+       case DW_UT_type:
+         section_kind = rcuh_kind::TYPE;
+         break;
+       default:
+         error (_("Dwarf Error: wrong unit_type in compilation unit header "
+                "(is %d, should be %d or %d) [in module %s]"),
+                cu_header->unit_type, DW_UT_compile, DW_UT_type, filename);
+       }
+
+      cu_header->addr_size = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+    }
+  cu_header->abbrev_sect_off = (sect_offset) read_offset (abfd, info_ptr,
+                                                         cu_header,
+                                                         &bytes_read);
   info_ptr += bytes_read;
-  cu_header->addr_size = read_1_byte (abfd, info_ptr);
-  info_ptr += 1;
+  if (cu_header->version < 5)
+    {
+      cu_header->addr_size = read_1_byte (abfd, info_ptr);
+      info_ptr += 1;
+    }
   signed_addr = bfd_get_sign_extend_vma (abfd);
   if (signed_addr < 0)
     internal_error (__FILE__, __LINE__,
                    _("read_comp_unit_head: dwarf from non elf file"));
   cu_header->signed_addr_p = signed_addr;
 
+  if (section_kind == rcuh_kind::TYPE)
+    {
+      LONGEST type_offset;
+
+      cu_header->signature = read_8_bytes (abfd, info_ptr);
+      info_ptr += 8;
+
+      type_offset = read_offset (abfd, info_ptr, cu_header, &bytes_read);
+      info_ptr += bytes_read;
+      cu_header->type_cu_offset_in_tu = (cu_offset) type_offset;
+      if (to_underlying (cu_header->type_cu_offset_in_tu) != type_offset)
+       error (_("Dwarf Error: Too big type_offset in compilation unit "
+              "header (is %s) [in module %s]"), plongest (type_offset),
+              filename);
+    }
+
   return info_ptr;
 }
 
@@ -4390,25 +4585,26 @@ error_check_comp_unit_head (struct comp_unit_head *header,
 {
   const char *filename = get_section_file_name (section);
 
-  if (header->version != 2 && header->version != 3 && header->version != 4)
+  if (header->version < 2 || header->version > 5)
     error (_("Dwarf Error: wrong version in compilation unit header "
-          "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
+          "(is %d, should be 2, 3, 4 or 5) [in module %s]"), header->version,
           filename);
 
-  if (header->abbrev_offset.sect_off
+  if (to_underlying (header->abbrev_sect_off)
       >= dwarf2_section_size (dwarf2_per_objfile->objfile, abbrev_section))
-    error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
-          "(offset 0x%lx + 6) [in module %s]"),
-          (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off,
+    error (_("Dwarf Error: bad offset (0x%x) in compilation unit header "
+          "(offset 0x%x + 6) [in module %s]"),
+          to_underlying (header->abbrev_sect_off),
+          to_underlying (header->sect_off),
           filename);
 
-  /* Cast to unsigned long to use 64-bit arithmetic when possible to
+  /* Cast to ULONGEST to use 64-bit arithmetic when possible to
      avoid potential 32-bit overflow.  */
-  if (((unsigned long) header->offset.sect_off + get_cu_length (header))
+  if (((ULONGEST) header->sect_off + get_cu_length (header))
       > section->size)
-    error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
-          "(offset 0x%lx + 0) [in module %s]"),
-          (long) header->length, (long) header->offset.sect_off,
+    error (_("Dwarf Error: bad length (0x%x) in compilation unit header "
+          "(offset 0x%x + 0) [in module %s]"),
+          header->length, to_underlying (header->sect_off),
           filename);
 }
 
@@ -4421,56 +4617,16 @@ read_and_check_comp_unit_head (struct comp_unit_head *header,
                               struct dwarf2_section_info *section,
                               struct dwarf2_section_info *abbrev_section,
                               const gdb_byte *info_ptr,
-                              int is_debug_types_section)
-{
-  const gdb_byte *beg_of_comp_unit = info_ptr;
-  bfd *abfd = get_section_bfd_owner (section);
-
-  header->offset.sect_off = beg_of_comp_unit - section->buffer;
-
-  info_ptr = read_comp_unit_head (header, info_ptr, abfd);
-
-  /* If we're reading a type unit, skip over the signature and
-     type_offset fields.  */
-  if (is_debug_types_section)
-    info_ptr += 8 /*signature*/ + header->offset_size;
-
-  header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
-
-  error_check_comp_unit_head (header, section, abbrev_section);
-
-  return info_ptr;
-}
-
-/* Read in the types comp unit header information from .debug_types entry at
-   types_ptr.  The result is a pointer to one past the end of the header.  */
-
-static const gdb_byte *
-read_and_check_type_unit_head (struct comp_unit_head *header,
-                              struct dwarf2_section_info *section,
-                              struct dwarf2_section_info *abbrev_section,
-                              const gdb_byte *info_ptr,
-                              ULONGEST *signature,
-                              cu_offset *type_offset_in_tu)
+                              rcuh_kind section_kind)
 {
   const gdb_byte *beg_of_comp_unit = info_ptr;
   bfd *abfd = get_section_bfd_owner (section);
 
-  header->offset.sect_off = beg_of_comp_unit - section->buffer;
-
-  info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+  header->sect_off = (sect_offset) (beg_of_comp_unit - section->buffer);
 
-  /* If we're reading a type unit, skip over the signature and
-     type_offset fields.  */
-  if (signature != NULL)
-    *signature = read_8_bytes (abfd, info_ptr);
-  info_ptr += 8;
-  if (type_offset_in_tu != NULL)
-    type_offset_in_tu->cu_off = read_offset_1 (abfd, info_ptr,
-                                              header->offset_size);
-  info_ptr += header->offset_size;
+  info_ptr = read_comp_unit_head (header, info_ptr, section, section_kind);
 
-  header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
+  header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit);
 
   error_check_comp_unit_head (header, section, abbrev_section);
 
@@ -4481,20 +4637,28 @@ read_and_check_type_unit_head (struct comp_unit_head *header,
 
 static sect_offset
 read_abbrev_offset (struct dwarf2_section_info *section,
-                   sect_offset offset)
+                   sect_offset sect_off)
 {
   bfd *abfd = get_section_bfd_owner (section);
   const gdb_byte *info_ptr;
   unsigned int initial_length_size, offset_size;
-  sect_offset abbrev_offset;
+  uint16_t version;
 
   dwarf2_read_section (dwarf2_per_objfile->objfile, section);
-  info_ptr = section->buffer + offset.sect_off;
+  info_ptr = section->buffer + to_underlying (sect_off);
   read_initial_length (abfd, info_ptr, &initial_length_size);
   offset_size = initial_length_size == 4 ? 4 : 8;
-  info_ptr += initial_length_size + 2 /*version*/;
-  abbrev_offset.sect_off = read_offset_1 (abfd, info_ptr, offset_size);
-  return abbrev_offset;
+  info_ptr += initial_length_size;
+
+  version = read_2_bytes (abfd, info_ptr);
+  info_ptr += 2;
+  if (version >= 5)
+    {
+      /* Skip unit type and address size.  */
+      info_ptr += 2;
+    }
+
+  return (sect_offset) read_offset_1 (abfd, info_ptr, offset_size);
 }
 
 /* Allocate a new partial symtab for file named NAME and mark this new
@@ -4543,19 +4707,17 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu,
                               struct die_info *die,
                               struct partial_symtab *pst)
 {
-  struct line_header *lh = NULL;
+  line_header_up lh;
   struct attribute *attr;
 
   attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
   if (attr)
-    lh = dwarf_decode_line_header (DW_UNSND (attr), cu);
+    lh = dwarf_decode_line_header ((sect_offset) DW_UNSND (attr), cu);
   if (lh == NULL)
     return;  /* No linetable, so no includes.  */
 
   /* NOTE: pst->dirname is DW_AT_comp_dir (if present).  */
-  dwarf_decode_lines (lh, pst->dirname, cu, pst, pst->textlow, 1);
-
-  free_line_header (lh);
+  dwarf_decode_lines (lh.get (), pst->dirname, cu, pst, pst->textlow, 1);
 }
 
 static hashval_t
@@ -4606,11 +4768,13 @@ add_signatured_type_cu_to_table (void **slot, void *datum)
 }
 
 /* A helper for create_debug_types_hash_table.  Read types from SECTION
-   and fill them into TYPES_HTAB.  */
+   and fill them into TYPES_HTAB.  It will process only type units,
+   therefore DW_UT_type.  */
 
 static void
 create_debug_type_hash_table (struct dwo_file *dwo_file,
-                             dwarf2_section_info *section, htab_t &types_htab)
+                             dwarf2_section_info *section, htab_t &types_htab,
+                             rcuh_kind section_kind)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *abbrev_section;
@@ -4622,8 +4786,8 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
                    : &dwarf2_per_objfile->abbrev);
 
   if (dwarf_read_debug)
-    fprintf_unfiltered (gdb_stdlog, "Reading .debug_types%s for %s:\n",
-                       dwo_file ? ".dwo" : "",
+    fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
+                       get_section_name (section),
                        get_section_file_name (abbrev_section));
 
   dwarf2_read_section (objfile, section);
@@ -4643,9 +4807,6 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
   end_ptr = info_ptr + section->size;
   while (info_ptr < end_ptr)
     {
-      sect_offset offset;
-      cu_offset type_offset_in_tu;
-      ULONGEST signature;
       struct signatured_type *sig_type;
       struct dwo_unit *dwo_tu;
       void **slot;
@@ -4653,20 +4814,24 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
       struct comp_unit_head header;
       unsigned int length;
 
-      offset.sect_off = ptr - section->buffer;
+      sect_offset sect_off = (sect_offset) (ptr - section->buffer);
+
+      /* Initialize it due to a false compiler warning.  */
+      header.signature = -1;
+      header.type_cu_offset_in_tu = (cu_offset) -1;
 
       /* We need to read the type's signature in order to build the hash
         table, but we don't need anything else just yet.  */
 
-      ptr = read_and_check_type_unit_head (&header, section,
-                                          abbrev_section, ptr,
-                                          &signature, &type_offset_in_tu);
+      ptr = read_and_check_comp_unit_head (&header, section,
+                                          abbrev_section, ptr, section_kind);
 
       length = get_cu_length (&header);
 
       /* Skip dummy type units.  */
       if (ptr >= info_ptr + length
-         || peek_abbrev_code (abfd, ptr) == 0)
+         || peek_abbrev_code (abfd, ptr) == 0
+         || header.unit_type != DW_UT_type)
        {
          info_ptr += length;
          continue;
@@ -4686,10 +4851,10 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
          dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
                                   struct dwo_unit);
          dwo_tu->dwo_file = dwo_file;
-         dwo_tu->signature = signature;
-         dwo_tu->type_offset_in_tu = type_offset_in_tu;
+         dwo_tu->signature = header.signature;
+         dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu;
          dwo_tu->section = section;
-         dwo_tu->offset = offset;
+         dwo_tu->sect_off = sect_off;
          dwo_tu->length = length;
        }
       else
@@ -4699,12 +4864,12 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
          dwo_tu = NULL;
          sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
                                     struct signatured_type);
-         sig_type->signature = signature;
-         sig_type->type_offset_in_tu = type_offset_in_tu;
+         sig_type->signature = header.signature;
+         sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
          sig_type->per_cu.objfile = objfile;
          sig_type->per_cu.is_debug_types = 1;
          sig_type->per_cu.section = section;
-         sig_type->per_cu.offset = offset;
+         sig_type->per_cu.sect_off = sect_off;
          sig_type->per_cu.length = length;
        }
 
@@ -4714,35 +4879,35 @@ create_debug_type_hash_table (struct dwo_file *dwo_file,
       gdb_assert (slot != NULL);
       if (*slot != NULL)
        {
-         sect_offset dup_offset;
+         sect_offset dup_sect_off;
 
          if (dwo_file)
            {
              const struct dwo_unit *dup_tu
                = (const struct dwo_unit *) *slot;
 
-             dup_offset = dup_tu->offset;
+             dup_sect_off = dup_tu->sect_off;
            }
          else
            {
              const struct signatured_type *dup_tu
                = (const struct signatured_type *) *slot;
 
-             dup_offset = dup_tu->per_cu.offset;
+             dup_sect_off = dup_tu->per_cu.sect_off;
            }
 
          complaint (&symfile_complaints,
                     _("debug type entry at offset 0x%x is duplicate to"
                       " the entry at offset 0x%x, signature %s"),
-                    offset.sect_off, dup_offset.sect_off,
-                    hex_string (signature));
+                    to_underlying (sect_off), to_underlying (dup_sect_off),
+                    hex_string (header.signature));
        }
       *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
 
       if (dwarf_read_debug > 1)
        fprintf_unfiltered (gdb_stdlog, "  offset 0x%x, signature %s\n",
-                           offset.sect_off,
-                           hex_string (signature));
+                           to_underlying (sect_off),
+                           hex_string (header.signature));
 
       info_ptr += length;
     }
@@ -4771,7 +4936,8 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
   for (ix = 0;
        VEC_iterate (dwarf2_section_info_def, types, ix, section);
        ++ix)
-    create_debug_type_hash_table (dwo_file, section, types_htab);
+    create_debug_type_hash_table (dwo_file, section, types_htab,
+                                 rcuh_kind::TYPE);
 }
 
 /* Create the hash table of all entries in the .debug_types section,
@@ -4785,6 +4951,8 @@ create_all_type_units (struct objfile *objfile)
   htab_t types_htab = NULL;
   struct signatured_type **iter;
 
+  create_debug_type_hash_table (NULL, &dwarf2_per_objfile->info, types_htab,
+                               rcuh_kind::COMPILE);
   create_debug_types_hash_table (NULL, dwarf2_per_objfile->types, types_htab);
   if (types_htab == NULL)
     {
@@ -4875,12 +5043,12 @@ fill_in_sig_entry_from_dwo_entry (struct objfile *objfile,
   else
       gdb_assert (sig_entry->per_cu.v.psymtab == NULL);
   gdb_assert (sig_entry->signature == dwo_entry->signature);
-  gdb_assert (sig_entry->type_offset_in_section.sect_off == 0);
+  gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0);
   gdb_assert (sig_entry->type_unit_group == NULL);
   gdb_assert (sig_entry->dwo_unit == NULL);
 
   sig_entry->per_cu.section = dwo_entry->section;
-  sig_entry->per_cu.offset = dwo_entry->offset;
+  sig_entry->per_cu.sect_off = dwo_entry->sect_off;
   sig_entry->per_cu.length = dwo_entry->length;
   sig_entry->per_cu.reading_dwo_directly = 1;
   sig_entry->per_cu.objfile = objfile;
@@ -5159,48 +5327,45 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
   section = dwo_unit->section;
   dwarf2_read_section (objfile, section);
   abfd = get_section_bfd_owner (section);
-  begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off;
+  begin_info_ptr = info_ptr = (section->buffer
+                              + to_underlying (dwo_unit->sect_off));
   dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
   init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file);
 
   if (this_cu->is_debug_types)
     {
-      ULONGEST header_signature;
-      cu_offset type_offset_in_tu;
       struct signatured_type *sig_type = (struct signatured_type *) this_cu;
 
-      info_ptr = read_and_check_type_unit_head (&cu->header, section,
+      info_ptr = read_and_check_comp_unit_head (&cu->header, section,
                                                dwo_abbrev_section,
-                                               info_ptr,
-                                               &header_signature,
-                                               &type_offset_in_tu);
+                                               info_ptr, rcuh_kind::TYPE);
       /* This is not an assert because it can be caused by bad debug info.  */
-      if (sig_type->signature != header_signature)
+      if (sig_type->signature != cu->header.signature)
        {
          error (_("Dwarf Error: signature mismatch %s vs %s while reading"
                   " TU at offset 0x%x [in module %s]"),
                 hex_string (sig_type->signature),
-                hex_string (header_signature),
-                dwo_unit->offset.sect_off,
+                hex_string (cu->header.signature),
+                to_underlying (dwo_unit->sect_off),
                 bfd_get_filename (abfd));
        }
-      gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+      gdb_assert (dwo_unit->sect_off == cu->header.sect_off);
       /* For DWOs coming from DWP files, we don't know the CU length
         nor the type's offset in the TU until now.  */
       dwo_unit->length = get_cu_length (&cu->header);
-      dwo_unit->type_offset_in_tu = type_offset_in_tu;
+      dwo_unit->type_offset_in_tu = cu->header.type_cu_offset_in_tu;
 
       /* Establish the type offset that can be used to lookup the type.
         For DWO files, we don't know it until now.  */
-      sig_type->type_offset_in_section.sect_off =
-       dwo_unit->offset.sect_off + dwo_unit->type_offset_in_tu.cu_off;
+      sig_type->type_offset_in_section
+       = dwo_unit->sect_off + to_underlying (dwo_unit->type_offset_in_tu);
     }
   else
     {
       info_ptr = read_and_check_comp_unit_head (&cu->header, section,
                                                dwo_abbrev_section,
-                                               info_ptr, 0);
-      gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+                                               info_ptr, rcuh_kind::COMPILE);
+      gdb_assert (dwo_unit->sect_off == cu->header.sect_off);
       /* For DWOs coming from DWP files, we don't know the CU length
         until now.  */
       dwo_unit->length = get_cu_length (&cu->header);
@@ -5460,7 +5625,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   if (dwarf_die_debug)
     fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n",
                        this_cu->is_debug_types ? "type" : "comp",
-                       this_cu->offset.sect_off);
+                       to_underlying (this_cu->sect_off));
 
   if (use_existing_cu)
     gdb_assert (keep);
@@ -5482,7 +5647,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   /* This is cheap if the section is already read in.  */
   dwarf2_read_section (objfile, section);
 
-  begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+  begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
 
   abbrev_section = get_abbrev_section_for_cu (this_cu);
 
@@ -5509,47 +5674,47 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
     }
 
   /* Get the header.  */
-  if (cu->header.first_die_offset.cu_off != 0 && ! rereading_dwo_cu)
+  if (to_underlying (cu->header.first_die_cu_offset) != 0 && !rereading_dwo_cu)
     {
       /* We already have the header, there's no need to read it in again.  */
-      info_ptr += cu->header.first_die_offset.cu_off;
+      info_ptr += to_underlying (cu->header.first_die_cu_offset);
     }
   else
     {
       if (this_cu->is_debug_types)
        {
-         ULONGEST signature;
-         cu_offset type_offset_in_tu;
-
-         info_ptr = read_and_check_type_unit_head (&cu->header, section,
+         info_ptr = read_and_check_comp_unit_head (&cu->header, section,
                                                    abbrev_section, info_ptr,
-                                                   &signature,
-                                                   &type_offset_in_tu);
+                                                   rcuh_kind::TYPE);
 
          /* Since per_cu is the first member of struct signatured_type,
             we can go from a pointer to one to a pointer to the other.  */
          sig_type = (struct signatured_type *) this_cu;
-         gdb_assert (sig_type->signature == signature);
-         gdb_assert (sig_type->type_offset_in_tu.cu_off
-                     == type_offset_in_tu.cu_off);
-         gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+         gdb_assert (sig_type->signature == cu->header.signature);
+         gdb_assert (sig_type->type_offset_in_tu
+                     == cu->header.type_cu_offset_in_tu);
+         gdb_assert (this_cu->sect_off == cu->header.sect_off);
 
          /* LENGTH has not been set yet for type units if we're
             using .gdb_index.  */
          this_cu->length = get_cu_length (&cu->header);
 
          /* Establish the type offset that can be used to lookup the type.  */
-         sig_type->type_offset_in_section.sect_off =
-           this_cu->offset.sect_off + sig_type->type_offset_in_tu.cu_off;
+         sig_type->type_offset_in_section =
+           this_cu->sect_off + to_underlying (sig_type->type_offset_in_tu);
+
+         this_cu->dwarf_version = cu->header.version;
        }
       else
        {
          info_ptr = read_and_check_comp_unit_head (&cu->header, section,
                                                    abbrev_section,
-                                                   info_ptr, 0);
+                                                   info_ptr,
+                                                   rcuh_kind::COMPILE);
 
-         gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+         gdb_assert (this_cu->sect_off == cu->header.sect_off);
          gdb_assert (this_cu->length == get_cu_length (&cu->header));
+         this_cu->dwarf_version = cu->header.version;
        }
     }
 
@@ -5569,8 +5734,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   if (abbrev_table != NULL)
     {
       gdb_assert (cu->abbrev_table == NULL);
-      gdb_assert (cu->header.abbrev_offset.sect_off
-                 == abbrev_table->offset.sect_off);
+      gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
       cu->abbrev_table = abbrev_table;
     }
   else if (cu->abbrev_table == NULL)
@@ -5603,7 +5767,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
          complaint (&symfile_complaints,
                     _("compilation unit with DW_AT_GNU_dwo_name"
                       " has children (offset 0x%x) [in module %s]"),
-                    this_cu->offset.sect_off, bfd_get_filename (abfd));
+                    to_underlying (this_cu->sect_off), bfd_get_filename (abfd));
        }
       dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die);
       if (dwo_unit != NULL)
@@ -5693,7 +5857,7 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
   if (dwarf_die_debug)
     fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n",
                        this_cu->is_debug_types ? "type" : "comp",
-                       this_cu->offset.sect_off);
+                       to_underlying (this_cu->sect_off));
 
   gdb_assert (this_cu->cu == NULL);
 
@@ -5708,10 +5872,12 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
 
   cleanups = make_cleanup (free_stack_comp_unit, &cu);
 
-  begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+  begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
   info_ptr = read_and_check_comp_unit_head (&cu.header, section,
                                            abbrev_section, info_ptr,
-                                           this_cu->is_debug_types);
+                                           (this_cu->is_debug_types
+                                            ? rcuh_kind::TYPE
+                                            : rcuh_kind::COMPILE));
 
   this_cu->length = get_cu_length (&cu.header);
 
@@ -5819,7 +5985,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
     }
   else
     {
-      unsigned int line_offset = line_offset_struct.sect_off;
+      unsigned int line_offset = to_underlying (line_offset_struct);
       struct partial_symtab *pst;
       char *name;
 
@@ -5837,7 +6003,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
     }
 
   tu_group->hash.dwo_unit = cu->dwo_unit;
-  tu_group->hash.line_offset = line_offset_struct;
+  tu_group->hash.line_sect_off = line_offset_struct;
 
   return tu_group;
 }
@@ -5881,7 +6047,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
     }
 
   type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit;
-  type_unit_group_for_lookup.hash.line_offset.sect_off = line_offset;
+  type_unit_group_for_lookup.hash.line_sect_off = (sect_offset) line_offset;
   slot = htab_find_slot (dwarf2_per_objfile->type_unit_groups,
                         &type_unit_group_for_lookup, INSERT);
   if (*slot != NULL)
@@ -5891,9 +6057,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
     }
   else
     {
-      sect_offset line_offset_struct;
-
-      line_offset_struct.sect_off = line_offset;
+      sect_offset line_offset_struct = (sect_offset) line_offset;
       tu_group = create_type_unit_group (cu, line_offset_struct);
       *slot = tu_group;
       ++tu_stats->nr_symtabs;
@@ -6068,7 +6232,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
                          "Psymtab for %s unit @0x%x: %s - %s"
                          ", %d global, %d static syms\n",
                          per_cu->is_debug_types ? "type" : "comp",
-                         per_cu->offset.sect_off,
+                         to_underlying (per_cu->sect_off),
                          paddress (gdbarch, pst->textlow),
                          paddress (gdbarch, pst->texthigh),
                          pst->n_global_syms, pst->n_static_syms);
@@ -6166,8 +6330,8 @@ sort_tu_by_abbrev_offset (const void *ap, const void *bp)
     = (const struct tu_abbrev_offset * const*) ap;
   const struct tu_abbrev_offset * const *b
     = (const struct tu_abbrev_offset * const*) bp;
-  unsigned int aoff = (*a)->abbrev_offset.sect_off;
-  unsigned int boff = (*b)->abbrev_offset.sect_off;
+  sect_offset aoff = (*a)->abbrev_offset;
+  sect_offset boff = (*b)->abbrev_offset;
 
   return (aoff > boff) - (aoff < boff);
 }
@@ -6239,13 +6403,13 @@ build_type_psymtabs_1 (void)
       sorted_by_abbrev[i].sig_type = sig_type;
       sorted_by_abbrev[i].abbrev_offset =
        read_abbrev_offset (sig_type->per_cu.section,
-                           sig_type->per_cu.offset);
+                           sig_type->per_cu.sect_off);
     }
   cleanups = make_cleanup (xfree, sorted_by_abbrev);
   qsort (sorted_by_abbrev, dwarf2_per_objfile->n_type_units,
         sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset);
 
-  abbrev_offset.sect_off = ~(unsigned) 0;
+  abbrev_offset = (sect_offset) ~(unsigned) 0;
   abbrev_table = NULL;
   make_cleanup (abbrev_table_free_cleanup, &abbrev_table);
 
@@ -6255,7 +6419,7 @@ build_type_psymtabs_1 (void)
 
       /* Switch to the next abbrev table if necessary.  */
       if (abbrev_table == NULL
-         || tu->abbrev_offset.sect_off != abbrev_offset.sect_off)
+         || tu->abbrev_offset != abbrev_offset)
        {
          if (abbrev_table != NULL)
            {
@@ -6574,9 +6738,8 @@ read_comp_units_from_section (struct objfile *objfile,
     {
       unsigned int length, initial_length_size;
       struct dwarf2_per_cu_data *this_cu;
-      sect_offset offset;
 
-      offset.sect_off = info_ptr - section->buffer;
+      sect_offset sect_off = (sect_offset) (info_ptr - section->buffer);
 
       /* Read just enough information to find out where the next
         compilation unit is.  */
@@ -6585,7 +6748,7 @@ read_comp_units_from_section (struct objfile *objfile,
       /* Save the compilation unit for later lookup.  */
       this_cu = XOBNEW (&objfile->objfile_obstack, struct dwarf2_per_cu_data);
       memset (this_cu, 0, sizeof (*this_cu));
-      this_cu->offset = offset;
+      this_cu->sect_off = sect_off;
       this_cu->length = length + initial_length_size;
       this_cu->is_dwz = is_dwz;
       this_cu->objfile = objfile;
@@ -6721,7 +6884,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
                           objfile_name (cu->objfile));
                  }
 
-               per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset,
+               per_cu = dwarf2_find_containing_comp_unit (pdi->d.sect_off,
                                                           pdi->is_dwz,
                                                           cu->objfile);
 
@@ -6834,7 +6997,7 @@ partial_die_parent_scope (struct partial_die_info *pdi,
         ignoring them.  */
       complaint (&symfile_complaints,
                 _("unhandled containing DIE tag %d for DIE at %d"),
-                parent->tag, pdi->offset.sect_off);
+                parent->tag, to_underlying (pdi->sect_off));
       parent->scope = grandparent_scope;
     }
 
@@ -6868,7 +7031,7 @@ partial_die_full_name (struct partial_die_info *pdi,
          /* DW_FORM_ref_addr is using section offset.  */
          attr.name = (enum dwarf_attribute) 0;
          attr.form = DW_FORM_ref_addr;
-         attr.u.unsnd = pdi->offset.sect_off;
+         attr.u.unsnd = to_underlying (pdi->sect_off);
          die = follow_die_ref (NULL, &attr, &ref_cu);
 
          return xstrdup (dwarf2_full_name (NULL, die, ref_cu));
@@ -7228,7 +7391,7 @@ peek_die_abbrev (const gdb_byte *info_ptr, unsigned int *bytes_read,
       error (_("Dwarf Error: Could not find abbrev number %d in %s"
               " at offset 0x%x [in module %s]"),
             abbrev_number, cu->per_cu->is_debug_types ? "TU" : "CU",
-            cu->header.offset.sect_off, bfd_get_filename (abfd));
+            to_underlying (cu->header.sect_off), bfd_get_filename (abfd));
     }
 
   return abbrev;
@@ -7284,8 +7447,8 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
                       _("ignoring absolute DW_AT_sibling"));
          else
            {
-             unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off;
-             const gdb_byte *sibling_ptr = buffer + off;
+             sect_offset off = dwarf2_get_ref_die_offset (&attr);
+             const gdb_byte *sibling_ptr = buffer + to_underlying (off);
 
              if (sibling_ptr < info_ptr)
                complaint (&symfile_complaints,
@@ -7322,6 +7485,7 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
          info_ptr += 1;
          break;
        case DW_FORM_flag_present:
+       case DW_FORM_implicit_const:
          break;
        case DW_FORM_data2:
        case DW_FORM_ref2:
@@ -7336,6 +7500,9 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
        case DW_FORM_ref_sig8:
          info_ptr += 8;
          break;
+       case DW_FORM_data16:
+         info_ptr += 16;
+         break;
        case DW_FORM_string:
          read_direct_string (abfd, info_ptr, &bytes_read);
          info_ptr += bytes_read;
@@ -7569,14 +7736,15 @@ process_queue (void)
 
              sprintf (buf, "TU %s at offset 0x%x",
                       hex_string (sig_type->signature),
-                      per_cu->offset.sect_off);
+                      to_underlying (per_cu->sect_off));
              /* There can be 100s of TUs.
                 Only print them in verbose mode.  */
              debug_print_threshold = 2;
            }
          else
            {
-             sprintf (buf, "CU at offset 0x%x", per_cu->offset.sect_off);
+             sprintf (buf, "CU at offset 0x%x",
+                      to_underlying (per_cu->sect_off));
              debug_print_threshold = 1;
            }
 
@@ -7686,7 +7854,7 @@ die_hash (const void *item)
 {
   const struct die_info *die = (const struct die_info *) item;
 
-  return die->offset.sect_off;
+  return to_underlying (die->sect_off);
 }
 
 /* Trivial comparison function for die_info structures: two DIEs
@@ -7698,7 +7866,7 @@ die_eq (const void *item_lhs, const void *item_rhs)
   const struct die_info *die_lhs = (const struct die_info *) item_lhs;
   const struct die_info *die_rhs = (const struct die_info *) item_rhs;
 
-  return die_lhs->offset.sect_off == die_rhs->offset.sect_off;
+  return die_lhs->sect_off == die_rhs->sect_off;
 }
 
 /* die_reader_func for load_full_comp_unit.
@@ -8223,13 +8391,10 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_import, cu);
   if (attr != NULL)
     {
-      struct dwarf2_per_cu_data *per_cu;
-      sect_offset offset;
-      int is_dwz;
-
-      offset = dwarf2_get_ref_die_offset (attr);
-      is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
-      per_cu = dwarf2_find_containing_comp_unit (offset, is_dwz, cu->objfile);
+      sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+      bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+      dwarf2_per_cu_data *per_cu
+       = dwarf2_find_containing_comp_unit (sect_off, is_dwz, cu->objfile);
 
       /* If necessary, add it to the queue and load its DIEs.  */
       if (maybe_queue_comp_unit (cu, per_cu, cu->language))
@@ -8283,6 +8448,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_catch_block:
       read_lexical_block_scope (die, cu);
       break;
+    case DW_TAG_call_site:
     case DW_TAG_GNU_call_site:
       read_call_site_scope (die, cu);
       break;
@@ -8305,6 +8471,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_pointer_type:
     case DW_TAG_ptr_to_member_type:
     case DW_TAG_reference_type:
+    case DW_TAG_rvalue_reference_type:
     case DW_TAG_string_type:
       break;
 
@@ -8761,7 +8928,7 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
          complaint (&symfile_complaints,
                     _("Computed physname <%s> does not match demangled <%s> "
                       "(from linkage <%s>) - DIE at 0x%x [in module %s]"),
-                    physname, canon, mangled, die->offset.sect_off,
+                    physname, canon, mangled, to_underlying (die->sect_off),
                     objfile_name (objfile));
 
          /* Prefer DW_AT_linkage_name (in the CANON form) - when it
@@ -8825,16 +8992,16 @@ read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu)
        {
          complaint (&symfile_complaints,
                     _("DIE at 0x%x has too many recursively imported "
-                      "declarations"), d->offset.sect_off);
+                      "declarations"), to_underlying (d->sect_off));
          return 0;
        }
 
       if (attr != NULL)
        {
          struct type *type;
-         sect_offset offset = dwarf2_get_ref_die_offset (attr);
+         sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
 
-         type = get_die_type_at_offset (offset, cu->per_cu);
+         type = get_die_type_at_offset (sect_off, cu->per_cu);
          if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
            {
              /* This declaration is a global namespace alias.  Add
@@ -8972,7 +9139,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
            complaint (&symfile_complaints,
                       _("child DW_TAG_imported_declaration expected "
                         "- DIE at 0x%x [in module %s]"),
-                      child_die->offset.sect_off, objfile_name (objfile));
+                      to_underlying (child_die->sect_off), objfile_name (objfile));
            continue;
          }
 
@@ -8993,7 +9160,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
            complaint (&symfile_complaints,
                       _("child DW_TAG_imported_declaration has unknown "
                         "imported name - DIE at 0x%x [in module %s]"),
-                      child_die->offset.sect_off, objfile_name (objfile));
+                      to_underlying (child_die->sect_off), objfile_name (objfile));
            continue;
          }
 
@@ -9014,17 +9181,6 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   do_cleanups (cleanups);
 }
 
-/* Cleanup function for handle_DW_AT_stmt_list.  */
-
-static void
-free_cu_line_header (void *arg)
-{
-  struct dwarf2_cu *cu = (struct dwarf2_cu *) arg;
-
-  free_line_header (cu->line_header);
-  cu->line_header = NULL;
-}
-
 /* Check for possibly missing DW_AT_comp_dir with relative .debug_line
    directory paths.  GCC SVN r127613 (new option -fdebug-prefix-map) fixed
    this, it was first present in GCC release 4.3.0.  */
@@ -9038,37 +9194,38 @@ producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu)
   return cu->producer_is_gcc_lt_4_3;
 }
 
-static void
-find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
-                        const char **name, const char **comp_dir)
+static file_and_directory
+find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
 {
+  file_and_directory res;
+
   /* Find the filename.  Do not use dwarf2_name here, since the filename
      is not a source language identifier.  */
-  *name = dwarf2_string_attr (die, DW_AT_name, cu);
-  *comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
+  res.name = dwarf2_string_attr (die, DW_AT_name, cu);
+  res.comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
 
-  if (*comp_dir == NULL
-      && producer_is_gcc_lt_4_3 (cu) && *name != NULL
-      && IS_ABSOLUTE_PATH (*name))
+  if (res.comp_dir == NULL
+      && producer_is_gcc_lt_4_3 (cu) && res.name != NULL
+      && IS_ABSOLUTE_PATH (res.name))
     {
-      char *d = ldirname (*name);
-
-      *comp_dir = d;
-      if (d != NULL)
-       make_cleanup (xfree, d);
+      res.comp_dir_storage = ldirname (res.name);
+      if (!res.comp_dir_storage.empty ())
+       res.comp_dir = res.comp_dir_storage.c_str ();
     }
-  if (*comp_dir != NULL)
+  if (res.comp_dir != NULL)
     {
       /* Irix 6.2 native cc prepends <machine>.: to the compilation
         directory, get rid of it.  */
-      const char *cp = strchr (*comp_dir, ':');
+      const char *cp = strchr (res.comp_dir, ':');
 
-      if (cp && cp != *comp_dir && cp[-1] == '.' && cp[1] == '/')
-       *comp_dir = cp + 1;
+      if (cp && cp != res.comp_dir && cp[-1] == '.' && cp[1] == '/')
+       res.comp_dir = cp + 1;
     }
 
-  if (*name == NULL)
-    *name = "<unknown>";
+  if (res.name == NULL)
+    res.name = "<unknown>";
+
+  return res;
 }
 
 /* Handle DW_AT_stmt_list for a compilation unit.
@@ -9082,7 +9239,6 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct attribute *attr;
-  unsigned int line_offset;
   struct line_header line_header_local;
   hashval_t line_header_local_hash;
   unsigned u;
@@ -9095,7 +9251,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
   if (attr == NULL)
     return;
 
-  line_offset = DW_UNSND (attr);
+  sect_offset line_offset = (sect_offset) DW_UNSND (attr);
 
   /* The line header hash table is only created if needed (it exists to
      prevent redundant reading of the line table for partial_units).
@@ -9115,7 +9271,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
                                dummy_obstack_deallocate);
     }
 
-  line_header_local.offset.sect_off = line_offset;
+  line_header_local.sect_off = line_offset;
   line_header_local.offset_in_dwz = cu->per_cu->is_dwz;
   line_header_local_hash = line_header_hash (&line_header_local);
   if (dwarf2_per_objfile->line_header_hash != NULL)
@@ -9137,9 +9293,10 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
 
   /* dwarf_decode_line_header does not yet provide sufficient information.
      We always have to call also dwarf_decode_lines for it.  */
-  cu->line_header = dwarf_decode_line_header (line_offset, cu);
-  if (cu->line_header == NULL)
+  line_header_up lh = dwarf_decode_line_header (line_offset, cu);
+  if (lh == NULL)
     return;
+  cu->line_header = lh.get ();
 
   if (dwarf2_per_objfile->line_header_hash == NULL)
     slot = NULL;
@@ -9164,11 +9321,12 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
         number information unit.  And if we're not using line_header_hash
         then this is what we want as well.  */
       gdb_assert (die->tag != DW_TAG_partial_unit);
-      make_cleanup (free_cu_line_header, cu);
     }
   decode_mapping = (die->tag != DW_TAG_partial_unit);
   dwarf_decode_lines (cu->line_header, comp_dir, cu, NULL, lowpc,
                      decode_mapping);
+
+  lh.release ();
 }
 
 /* Process DW_TAG_compile_unit or DW_TAG_partial_unit.  */
@@ -9178,12 +9336,9 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
-  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct attribute *attr;
-  const char *name = NULL;
-  const char *comp_dir = NULL;
   struct die_info *child_die;
   CORE_ADDR baseaddr;
 
@@ -9197,7 +9352,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
     lowpc = highpc;
   lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
 
-  find_file_and_directory (die, cu, &name, &comp_dir);
+  file_and_directory fnd = find_file_and_directory (die, cu);
 
   prepare_one_comp_unit (cu, die, cu->language);
 
@@ -9211,12 +9366,12 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL)
     set_cu_language (DW_LANG_Go, cu);
 
-  dwarf2_start_symtab (cu, name, comp_dir, lowpc);
+  dwarf2_start_symtab (cu, fnd.name, fnd.comp_dir, lowpc);
 
   /* Decode line number information if present.  We do this before
      processing child DIEs, so that the line header table is available
      for DW_AT_decl_file.  */
-  handle_DW_AT_stmt_list (die, cu, comp_dir, lowpc);
+  handle_DW_AT_stmt_list (die, cu, fnd.comp_dir, lowpc);
 
   /* Process all dies in compilation unit.  */
   if (die->child != NULL)
@@ -9233,12 +9388,14 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
      refers to information in the line number info statement program
      header, so we can only read it if we've read the header
      successfully.  */
-  attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
+  attr = dwarf2_attr (die, DW_AT_macros, cu);
+  if (attr == NULL)
+    attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
   if (attr && cu->line_header)
     {
       if (dwarf2_attr (die, DW_AT_macro_info, cu))
        complaint (&symfile_complaints,
-                  _("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info"));
+                  _("CU refers to both DW_AT_macros and DW_AT_macro_info"));
 
       dwarf_decode_macros (cu, DW_UNSND (attr), 1);
     }
@@ -9252,8 +9409,6 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
          dwarf_decode_macros (cu, macro_offset, 0);
        }
     }
-
-  do_cleanups (back_to);
 }
 
 /* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
@@ -9268,9 +9423,8 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
   struct type_unit_group *tu_group;
   int first_time;
-  struct line_header *lh;
   struct attribute *attr;
-  unsigned int i, line_offset;
+  unsigned int i;
   struct signatured_type *sig_type;
 
   gdb_assert (per_cu->is_debug_types);
@@ -9292,10 +9446,10 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
 
   /* We have to handle the case of both a missing DW_AT_stmt_list or bad
      debug info.  */
-  lh = NULL;
+  line_header_up lh;
   if (attr != NULL)
     {
-      line_offset = DW_UNSND (attr);
+      sect_offset line_offset = (sect_offset) DW_UNSND (attr);
       lh = dwarf_decode_line_header (line_offset, cu);
     }
   if (lh == NULL)
@@ -9310,8 +9464,7 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
       return;
     }
 
-  cu->line_header = lh;
-  make_cleanup (free_cu_line_header, cu);
+  cu->line_header = lh.get ();
 
   if (first_time)
     {
@@ -9322,17 +9475,14 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
         process_full_type_unit still needs to know if this is the first
         time.  */
 
-      tu_group->num_symtabs = lh->num_file_names;
-      tu_group->symtabs = XNEWVEC (struct symtab *, lh->num_file_names);
+      tu_group->num_symtabs = lh->file_names.size ();
+      tu_group->symtabs = XNEWVEC (struct symtab *, lh->file_names.size ());
 
-      for (i = 0; i < lh->num_file_names; ++i)
+      for (i = 0; i < lh->file_names.size (); ++i)
        {
-         const char *dir = NULL;
-         struct file_entry *fe = &lh->file_names[i];
+         file_entry &fe = lh->file_names[i];
 
-         if (fe->dir_index && lh->include_dirs != NULL)
-           dir = lh->include_dirs[fe->dir_index - 1];
-         dwarf2_start_subfile (fe->name, dir);
+         dwarf2_start_subfile (fe.name, fe.include_dir (lh.get ()));
 
          if (current_subfile->symtab == NULL)
            {
@@ -9344,15 +9494,15 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
                = allocate_symtab (cust, current_subfile->name);
            }
 
-         fe->symtab = current_subfile->symtab;
-         tu_group->symtabs[i] = fe->symtab;
+         fe.symtab = current_subfile->symtab;
+         tu_group->symtabs[i] = fe.symtab;
        }
     }
   else
     {
       restart_symtab (tu_group->compunit_symtab, "", 0);
 
-      for (i = 0; i < lh->num_file_names; ++i)
+      for (i = 0; i < lh->file_names.size (); ++i)
        {
          struct file_entry *fe = &lh->file_names[i];
 
@@ -9360,6 +9510,8 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
        }
     }
 
+  lh.release ();
+
   /* The main symtab is allocated last.  Type units don't have DW_AT_name
      so they don't have a "real" (so to speak) symtab anyway.
      There is later code that will assign the main symtab to all symbols
@@ -9521,7 +9673,7 @@ create_dwo_cu_reader (const struct die_reader_specs *reader,
                      void *datap)
 {
   struct dwarf2_cu *cu = reader->cu;
-  sect_offset offset = cu->per_cu->offset;
+  sect_offset sect_off = cu->per_cu->sect_off;
   struct dwarf2_section_info *section = cu->per_cu->section;
   struct create_dwo_cu_data *data = (struct create_dwo_cu_data *) datap;
   struct dwo_file *dwo_file = data->dwo_file;
@@ -9534,19 +9686,20 @@ create_dwo_cu_reader (const struct die_reader_specs *reader,
       complaint (&symfile_complaints,
                 _("Dwarf Error: debug entry at offset 0x%x is missing"
                   " its dwo_id [in module %s]"),
-                offset.sect_off, dwo_file->dwo_name);
+                to_underlying (sect_off), dwo_file->dwo_name);
       return;
     }
 
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = DW_UNSND (attr);
   dwo_unit->section = section;
-  dwo_unit->offset = offset;
+  dwo_unit->sect_off = sect_off;
   dwo_unit->length = cu->per_cu->length;
 
   if (dwarf_read_debug)
     fprintf_unfiltered (gdb_stdlog, "  offset 0x%x, dwo_id %s\n",
-                       offset.sect_off, hex_string (dwo_unit->signature));
+                       to_underlying (sect_off),
+                       hex_string (dwo_unit->signature));
 }
 
 /* Create the dwo_unit for the lone CU in DWO_FILE.
@@ -9587,7 +9740,7 @@ create_dwo_cu (struct dwo_file *dwo_file)
       memset (&per_cu, 0, sizeof (per_cu));
       per_cu.objfile = objfile;
       per_cu.is_debug_types = 0;
-      per_cu.offset.sect_off = info_ptr - section->buffer;
+      per_cu.sect_off = sect_offset (info_ptr - section->buffer);
       per_cu.section = section;
 
       init_cutu_and_read_dies_no_follow (&per_cu, dwo_file,
@@ -10806,49 +10959,44 @@ open_and_init_dwp_file (void)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwp_file *dwp_file;
-  char *dwp_name;
-  struct cleanup *cleanups = make_cleanup (null_cleanup, 0);
 
   /* Try to find first .dwp for the binary file before any symbolic links
      resolving.  */
 
   /* If the objfile is a debug file, find the name of the real binary
      file and get the name of dwp file from there.  */
+  std::string dwp_name;
   if (objfile->separate_debug_objfile_backlink != NULL)
     {
       struct objfile *backlink = objfile->separate_debug_objfile_backlink;
       const char *backlink_basename = lbasename (backlink->original_name);
-      char *debug_dirname = ldirname (objfile->original_name);
 
-      make_cleanup (xfree, debug_dirname);
-      dwp_name = xstrprintf ("%s%s%s.dwp", debug_dirname,
-                            SLASH_STRING, backlink_basename);
+      dwp_name = ldirname (objfile->original_name) + SLASH_STRING + backlink_basename;
     }
   else
-    dwp_name = xstrprintf ("%s.dwp", objfile->original_name);
-  make_cleanup (xfree, dwp_name);
+    dwp_name = objfile->original_name;
 
-  gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name));
+  dwp_name += ".dwp";
+
+  gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name.c_str ()));
   if (dbfd == NULL
       && strcmp (objfile->original_name, objfile_name (objfile)) != 0)
     {
       /* Try to find .dwp for the binary file after gdb_realpath resolving.  */
-      dwp_name = xstrprintf ("%s.dwp", objfile_name (objfile));
-      make_cleanup (xfree, dwp_name);
-      dbfd = open_dwp_file (dwp_name);
+      dwp_name = objfile_name (objfile);
+      dwp_name += ".dwp";
+      dbfd = open_dwp_file (dwp_name.c_str ());
     }
 
   if (dbfd == NULL)
     {
       if (dwarf_read_debug)
-       fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name);
-      do_cleanups (cleanups);
+       fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name.c_str ());
       return NULL;
     }
   dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file);
   dwp_file->name = bfd_get_filename (dbfd.get ());
   dwp_file->dbfd = dbfd.release ();
-  do_cleanups (cleanups);
 
   /* +1: section 0 is unused */
   dwp_file->num_sections = bfd_count_sections (dwp_file->dbfd) + 1;
@@ -10872,7 +11020,7 @@ open_and_init_dwp_file (void)
       error (_("Dwarf Error: DWP file CU version %s doesn't match"
               " TU version %s [in DWP file %s]"),
             pulongest (dwp_file->cus->version),
-            pulongest (dwp_file->tus->version), dwp_name);
+            pulongest (dwp_file->tus->version), dwp_name.c_str ());
     }
   dwp_file->version = dwp_file->cus->version;
 
@@ -11037,7 +11185,7 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
             kind, dwo_name, hex_string (signature),
             dwp_text != NULL ? dwp_text : "",
             this_unit->is_debug_types ? "TU" : "CU",
-            this_unit->offset.sect_off, objfile_name (objfile));
+            to_underlying (this_unit->sect_off), objfile_name (objfile));
 
     do_cleanups (cleanups);
   }
@@ -11215,7 +11363,8 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
           && origin_die->tag == DW_TAG_subprogram))
     complaint (&symfile_complaints,
               _("DIE 0x%x and its abstract origin 0x%x have different tags"),
-              die->offset.sect_off, origin_die->offset.sect_off);
+              to_underlying (die->sect_off),
+              to_underlying (origin_die->sect_off));
 
   child_die = die->child;
   die_children_count = 0;
@@ -11236,11 +11385,12 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
       struct dwarf2_cu *child_origin_cu;
 
       /* We are trying to process concrete instance entries:
-        DW_TAG_GNU_call_site DIEs indeed have a DW_AT_abstract_origin tag, but
+        DW_TAG_call_site DIEs indeed have a DW_AT_abstract_origin tag, but
         it's not relevant to our analysis here. i.e. detecting DIEs that are
         present in the abstract instance but not referenced in the concrete
         one.  */
-      if (child_die->tag == DW_TAG_GNU_call_site)
+      if (child_die->tag == DW_TAG_call_site
+          || child_die->tag == DW_TAG_GNU_call_site)
        continue;
 
       /* For each CHILD_DIE, find the corresponding child of
@@ -11269,25 +11419,27 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
                   && child_origin_die->tag == DW_TAG_subprogram))
            complaint (&symfile_complaints,
                       _("Child DIE 0x%x and its abstract origin 0x%x have "
-                        "different tags"), child_die->offset.sect_off,
-                      child_origin_die->offset.sect_off);
+                        "different tags"),
+                      to_underlying (child_die->sect_off),
+                      to_underlying (child_origin_die->sect_off));
          if (child_origin_die->parent != origin_die)
            complaint (&symfile_complaints,
                       _("Child DIE 0x%x and its abstract origin 0x%x have "
-                        "different parents"), child_die->offset.sect_off,
-                      child_origin_die->offset.sect_off);
+                        "different parents"),
+                      to_underlying (child_die->sect_off),
+                      to_underlying (child_origin_die->sect_off));
          else
-           *offsets_end++ = child_origin_die->offset;
+           *offsets_end++ = child_origin_die->sect_off;
        }
     }
   qsort (offsets, offsets_end - offsets, sizeof (*offsets),
         unsigned_int_compar);
   for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
-    if (offsetp[-1].sect_off == offsetp->sect_off)
+    if (offsetp[-1] == *offsetp)
       complaint (&symfile_complaints,
                 _("Multiple children of DIE 0x%x refer "
                   "to DIE 0x%x as their abstract origin"),
-                die->offset.sect_off, offsetp->sect_off);
+                to_underlying (die->sect_off), to_underlying (*offsetp));
 
   offsetp = offsets;
   origin_child_die = origin_die->child;
@@ -11295,10 +11447,10 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
     {
       /* Is ORIGIN_CHILD_DIE referenced by any of the DIE children?  */
       while (offsetp < offsets_end
-            && offsetp->sect_off < origin_child_die->offset.sect_off)
+            && *offsetp < origin_child_die->sect_off)
        offsetp++;
       if (offsetp >= offsets_end
-         || offsetp->sect_off > origin_child_die->offset.sect_off)
+         || *offsetp > origin_child_die->sect_off)
        {
          /* Found that ORIGIN_CHILD_DIE is really not referenced.
             Check whether we're already processing ORIGIN_CHILD_DIE.
@@ -11355,7 +11507,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
     {
       complaint (&symfile_complaints,
                 _("missing name for subprogram DIE at %d"),
-                die->offset.sect_off);
+                to_underlying (die->sect_off));
       return;
     }
 
@@ -11368,7 +11520,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
        complaint (&symfile_complaints,
                   _("cannot get low and high bounds "
                     "for subprogram DIE at %d"),
-                  die->offset.sect_off);
+                  to_underlying (die->sect_off));
       return;
     }
 
@@ -11575,7 +11727,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
   local_using_directives = newobj->local_using_directives;
 }
 
-/* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab.  */
+/* Read in DW_TAG_call_site and insert it to CU->call_site_htab.  */
 
 static void
 read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -11591,13 +11743,19 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+  attr = dwarf2_attr (die, DW_AT_call_return_pc, cu);
+  if (attr == NULL)
+    {
+      /* This was a pre-DWARF-5 GNU extension alias
+        for DW_AT_call_return_pc.  */
+      attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+    }
   if (!attr)
     {
       complaint (&symfile_complaints,
-                _("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
+                _("missing DW_AT_call_return_pc for DW_TAG_call_site "
                   "DIE 0x%x [in module %s]"),
-                die->offset.sect_off, objfile_name (objfile));
+                to_underlying (die->sect_off), objfile_name (objfile));
       return;
     }
   pc = attr_value_as_address (attr) + baseaddr;
@@ -11612,9 +11770,9 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (*slot != NULL)
     {
       complaint (&symfile_complaints,
-                _("Duplicate PC %s for DW_TAG_GNU_call_site "
+                _("Duplicate PC %s for DW_TAG_call_site "
                   "DIE 0x%x [in module %s]"),
-                paddress (gdbarch, pc), die->offset.sect_off,
+                paddress (gdbarch, pc), to_underlying (die->sect_off),
                 objfile_name (objfile));
       return;
     }
@@ -11625,12 +11783,13 @@ 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))
     {
-      if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+      if (child_die->tag != DW_TAG_call_site_parameter
+          && child_die->tag != DW_TAG_GNU_call_site_parameter)
        {
          complaint (&symfile_complaints,
-                    _("Tag %d is not DW_TAG_GNU_call_site_parameter in "
-                      "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-                    child_die->tag, child_die->offset.sect_off,
+                    _("Tag %d is not DW_TAG_call_site_parameter in "
+                      "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+                    child_die->tag, to_underlying (child_die->sect_off),
                     objfile_name (objfile));
          continue;
        }
@@ -11647,7 +11806,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
   memset (call_site, 0, sizeof (*call_site) - sizeof (*call_site->parameter));
   call_site->pc = pc;
 
-  if (dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
+  if (dwarf2_flag_true_p (die, DW_AT_call_tail_call, cu)
+      || dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
     {
       struct die_info *func_die;
 
@@ -11657,10 +11817,12 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
           && func_die->tag != DW_TAG_subroutine_type;
           func_die = func_die->parent);
 
-      /* DW_AT_GNU_all_call_sites is a superset
-        of DW_AT_GNU_all_tail_call_sites.  */
+      /* DW_AT_call_all_calls is a superset
+        of DW_AT_call_all_tail_calls.  */
       if (func_die
+          && !dwarf2_flag_true_p (func_die, DW_AT_call_all_calls, cu)
           && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_call_sites, cu)
+         && !dwarf2_flag_true_p (func_die, DW_AT_call_all_tail_calls, cu)
          && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_tail_call_sites, cu))
        {
          /* TYPE_TAIL_CALL_LIST is not interesting in functions where it is
@@ -11688,15 +11850,22 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
            }
          else
            complaint (&symfile_complaints,
-                      _("Cannot find function owning DW_TAG_GNU_call_site "
+                      _("Cannot find function owning DW_TAG_call_site "
                         "DIE 0x%x [in module %s]"),
-                      die->offset.sect_off, objfile_name (objfile));
+                      to_underlying (die->sect_off), objfile_name (objfile));
        }
     }
 
-  attr = dwarf2_attr (die, DW_AT_GNU_call_site_target, cu);
+  attr = dwarf2_attr (die, DW_AT_call_target, cu);
+  if (attr == NULL)
+    attr = dwarf2_attr (die, DW_AT_GNU_call_site_target, cu);
   if (attr == NULL)
-    attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+    attr = dwarf2_attr (die, DW_AT_call_origin, cu);
+  if (attr == NULL)
+    {
+      /* This was a pre-DWARF-5 GNU extension alias for DW_AT_call_origin.  */
+      attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+    }
   SET_FIELD_DWARF_BLOCK (call_site->target, NULL);
   if (!attr || (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0))
     /* Keep NULL DWARF_BLOCK.  */;
@@ -11734,9 +11903,9 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
            target_physname = dwarf2_physname (NULL, target_die, target_cu);
          if (target_physname == NULL)
            complaint (&symfile_complaints,
-                      _("DW_AT_GNU_call_site_target target DIE has invalid "
+                      _("DW_AT_call_target target DIE has invalid "
                         "physname, for referencing DIE 0x%x [in module %s]"),
-                      die->offset.sect_off, objfile_name (objfile));
+                      to_underlying (die->sect_off), objfile_name (objfile));
          else
            SET_FIELD_PHYSNAME (call_site->target, target_physname);
        }
@@ -11748,9 +11917,9 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
          if (dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL)
              <= PC_BOUNDS_INVALID)
            complaint (&symfile_complaints,
-                      _("DW_AT_GNU_call_site_target target DIE has invalid "
+                      _("DW_AT_call_target target DIE has invalid "
                         "low pc, for referencing DIE 0x%x [in module %s]"),
-                      die->offset.sect_off, objfile_name (objfile));
+                      to_underlying (die->sect_off), objfile_name (objfile));
          else
            {
              lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
@@ -11760,9 +11929,9 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
   else
     complaint (&symfile_complaints,
-              _("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither "
+              _("DW_TAG_call_site DW_AT_call_target is neither "
                 "block nor reference, for DIE 0x%x [in module %s]"),
-              die->offset.sect_off, objfile_name (objfile));
+              to_underlying (die->sect_off), objfile_name (objfile));
 
   call_site->per_cu = cu->per_cu;
 
@@ -11773,7 +11942,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       struct call_site_parameter *parameter;
       struct attribute *loc, *origin;
 
-      if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+      if (child_die->tag != DW_TAG_call_site_parameter
+          && child_die->tag != DW_TAG_GNU_call_site_parameter)
        {
          /* Already printed the complaint above.  */
          continue;
@@ -11784,37 +11954,43 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 
       /* DW_AT_location specifies the register number or DW_AT_abstract_origin
         specifies DW_TAG_formal_parameter.  Value of the data assumed for the
-        register is contained in DW_AT_GNU_call_site_value.  */
+        register is contained in DW_AT_call_value.  */
 
       loc = dwarf2_attr (child_die, DW_AT_location, cu);
-      origin = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
+      origin = dwarf2_attr (child_die, DW_AT_call_parameter, cu);
+      if (origin == NULL)
+       {
+         /* This was a pre-DWARF-5 GNU extension alias
+            for DW_AT_call_parameter.  */
+         origin = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
+       }
       if (loc == NULL && origin != NULL && attr_form_is_ref (origin))
        {
-         sect_offset offset;
-
          parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
-         offset = dwarf2_get_ref_die_offset (origin);
-         if (!offset_in_cu_p (&cu->header, offset))
+
+         sect_offset sect_off
+           = (sect_offset) dwarf2_get_ref_die_offset (origin);
+         if (!offset_in_cu_p (&cu->header, sect_off))
            {
              /* As DW_OP_GNU_parameter_ref uses CU-relative offset this
                 binding can be done only inside one CU.  Such referenced DIE
                 therefore cannot be even moved to DW_TAG_partial_unit.  */
              complaint (&symfile_complaints,
-                        _("DW_AT_abstract_origin offset is not in CU for "
-                          "DW_TAG_GNU_call_site child DIE 0x%x "
-                          "[in module %s]"),
-                        child_die->offset.sect_off, objfile_name (objfile));
+                        _("DW_AT_call_parameter offset is not in CU for "
+                          "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+                        to_underlying (child_die->sect_off),
+                        objfile_name (objfile));
              continue;
            }
-         parameter->u.param_offset.cu_off = (offset.sect_off
-                                             - cu->header.offset.sect_off);
+         parameter->u.param_cu_off
+           = (cu_offset) (sect_off - cu->header.sect_off);
        }
       else if (loc == NULL || origin != NULL || !attr_form_is_block (loc))
        {
          complaint (&symfile_complaints,
                     _("No DW_FORM_block* DW_AT_location for "
-                      "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-                    child_die->offset.sect_off, objfile_name (objfile));
+                      "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+                    to_underlying (child_die->sect_off), objfile_name (objfile));
          continue;
        }
       else
@@ -11832,20 +12008,24 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
              complaint (&symfile_complaints,
                         _("Only single DW_OP_reg or DW_OP_fbreg is supported "
                           "for DW_FORM_block* DW_AT_location is supported for "
-                          "DW_TAG_GNU_call_site child DIE 0x%x "
+                          "DW_TAG_call_site child DIE 0x%x "
                           "[in module %s]"),
-                        child_die->offset.sect_off, objfile_name (objfile));
+                        to_underlying (child_die->sect_off),
+                        objfile_name (objfile));
              continue;
            }
        }
 
-      attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
+      attr = dwarf2_attr (child_die, DW_AT_call_value, cu);
+      if (attr == NULL)
+       attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
       if (!attr_form_is_block (attr))
        {
          complaint (&symfile_complaints,
-                    _("No DW_FORM_block* DW_AT_GNU_call_site_value for "
-                      "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-                    child_die->offset.sect_off, objfile_name (objfile));
+                    _("No DW_FORM_block* DW_AT_call_value for "
+                      "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+                    to_underlying (child_die->sect_off),
+                    objfile_name (objfile));
          continue;
        }
       parameter->value = DW_BLOCK (attr)->data;
@@ -11856,14 +12036,17 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       parameter->data_value_size = 0;
       call_site->parameter_count++;
 
-      attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_data_value, cu);
+      attr = dwarf2_attr (child_die, DW_AT_call_data_value, cu);
+      if (attr == NULL)
+       attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_data_value, cu);
       if (attr)
        {
          if (!attr_form_is_block (attr))
            complaint (&symfile_complaints,
-                      _("No DW_FORM_block* DW_AT_GNU_call_site_data_value for "
-                        "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-                      child_die->offset.sect_off, objfile_name (objfile));
+                      _("No DW_FORM_block* DW_AT_call_data_value for "
+                        "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+                      to_underlying (child_die->sect_off),
+                      objfile_name (objfile));
          else
            {
              parameter->data_value = DW_BLOCK (attr)->data;
@@ -11873,13 +12056,17 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
-/* Call CALLBACK from DW_AT_ranges attribute value OFFSET.
-   Return 1 if the attributes are present and valid, otherwise, return 0.  */
+/* Call CALLBACK from DW_AT_ranges attribute value OFFSET
+   reading .debug_rnglists.
+   Callback's type should be:
+    void (CORE_ADDR range_beginning, CORE_ADDR range_end)
+   Return true if the attributes are present and valid, otherwise,
+   return false.  */
 
-static int
-dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
-                      std::function<void (CORE_ADDR range_beginning,
-                                          CORE_ADDR range_end)> callback)
+template <typename Callback>
+static bool
+dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
+                        Callback &&callback)
 {
   struct objfile *objfile = cu->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
@@ -11892,65 +12079,123 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
   int found_base;
   unsigned int dummy;
   const gdb_byte *buffer;
+  CORE_ADDR low = 0;
+  CORE_ADDR high = 0;
   CORE_ADDR baseaddr;
+  bool overflow = false;
 
   found_base = cu->base_known;
   base = cu->base_address;
 
-  dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
-  if (offset >= dwarf2_per_objfile->ranges.size)
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->rnglists);
+  if (offset >= dwarf2_per_objfile->rnglists.size)
     {
       complaint (&symfile_complaints,
                 _("Offset %d out of bounds for DW_AT_ranges attribute"),
                 offset);
-      return 0;
+      return false;
     }
-  buffer = dwarf2_per_objfile->ranges.buffer + offset;
+  buffer = dwarf2_per_objfile->rnglists.buffer + offset;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   while (1)
     {
-      CORE_ADDR range_beginning, range_end;
-
-      range_beginning = read_address (obfd, buffer, cu, &dummy);
-      buffer += addr_size;
-      range_end = read_address (obfd, buffer, cu, &dummy);
-      buffer += addr_size;
-      offset += 2 * addr_size;
-
-      /* An end of list marker is a pair of zero addresses.  */
-      if (range_beginning == 0 && range_end == 0)
-       /* Found the end of list entry.  */
-       break;
+      /* Initialize it due to a false compiler warning.  */
+      CORE_ADDR range_beginning = 0, range_end = 0;
+      const gdb_byte *buf_end = (dwarf2_per_objfile->rnglists.buffer
+                                + dwarf2_per_objfile->rnglists.size);
+      unsigned int bytes_read;
 
-      /* Each base address selection entry is a pair of 2 values.
-        The first is the largest possible address, the second is
-        the base address.  Check for a base address here.  */
-      if ((range_beginning & mask) == mask)
+      if (buffer == buf_end)
        {
-         /* If we found the largest possible address, then we already
-            have the base address in range_end.  */
-         base = range_end;
+         overflow = true;
+         break;
+       }
+      const auto rlet = static_cast<enum dwarf_range_list_entry>(*buffer++);
+      switch (rlet)
+       {
+       case DW_RLE_end_of_list:
+         break;
+       case DW_RLE_base_address:
+         if (buffer + cu->header.addr_size > buf_end)
+           {
+             overflow = true;
+             break;
+           }
+         base = read_address (obfd, buffer, cu, &bytes_read);
          found_base = 1;
-         continue;
+         buffer += bytes_read;
+         break;
+       case DW_RLE_start_length:
+         if (buffer + cu->header.addr_size > buf_end)
+           {
+             overflow = true;
+             break;
+           }
+         range_beginning = read_address (obfd, buffer, cu, &bytes_read);
+         buffer += bytes_read;
+         range_end = (range_beginning
+                      + read_unsigned_leb128 (obfd, buffer, &bytes_read));
+         buffer += bytes_read;
+         if (buffer > buf_end)
+           {
+             overflow = true;
+             break;
+           }
+         break;
+       case DW_RLE_offset_pair:
+         range_beginning = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+         buffer += bytes_read;
+         if (buffer > buf_end)
+           {
+             overflow = true;
+             break;
+           }
+         range_end = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+         buffer += bytes_read;
+         if (buffer > buf_end)
+           {
+             overflow = true;
+             break;
+           }
+         break;
+       case DW_RLE_start_end:
+         if (buffer + 2 * cu->header.addr_size > buf_end)
+           {
+             overflow = true;
+             break;
+           }
+         range_beginning = read_address (obfd, buffer, cu, &bytes_read);
+         buffer += bytes_read;
+         range_end = read_address (obfd, buffer, cu, &bytes_read);
+         buffer += bytes_read;
+         break;
+       default:
+         complaint (&symfile_complaints,
+                    _("Invalid .debug_rnglists data (no base address)"));
+         return false;
        }
+      if (rlet == DW_RLE_end_of_list || overflow)
+       break;
+      if (rlet == DW_RLE_base_address)
+       continue;
 
       if (!found_base)
        {
          /* We have no valid base address for the ranges
             data.  */
          complaint (&symfile_complaints,
-                    _("Invalid .debug_ranges data (no base address)"));
-         return 0;
+                    _("Invalid .debug_rnglists data (no base address)"));
+         return false;
        }
 
       if (range_beginning > range_end)
        {
          /* Inverted range entries are invalid.  */
          complaint (&symfile_complaints,
-                    _("Invalid .debug_ranges data (inverted range)"));
-         return 0;
+                    _("Invalid .debug_rnglists data (inverted range)"));
+         return false;
        }
 
       /* Empty range entries have no effect.  */
@@ -11966,7 +12211,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
          && !dwarf2_per_objfile->has_section_at_zero)
        {
          complaint (&symfile_complaints,
-                    _(".debug_ranges entry has start address of zero"
+                    _(".debug_rnglists entry has start address of zero"
                       " [in module %s]"), objfile_name (objfile));
          continue;
        }
@@ -11974,12 +12219,130 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
       callback (range_beginning, range_end);
     }
 
-  return 1;
+  if (overflow)
+    {
+      complaint (&symfile_complaints,
+                _("Offset %d is not terminated "
+                  "for DW_AT_ranges attribute"),
+                offset);
+      return false;
+    }
+
+  return true;
 }
 
-/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
-   Return 1 if the attributes are present and valid, otherwise, return 0.
-   If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'.  */
+/* Call CALLBACK from DW_AT_ranges attribute value OFFSET reading .debug_ranges.
+   Callback's type should be:
+    void (CORE_ADDR range_beginning, CORE_ADDR range_end)
+   Return 1 if the attributes are present and valid, otherwise, return 0.  */
+
+template <typename Callback>
+static int
+dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
+                      Callback &&callback)
+{
+  struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct comp_unit_head *cu_header = &cu->header;
+  bfd *obfd = objfile->obfd;
+  unsigned int addr_size = cu_header->addr_size;
+  CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
+  /* Base address selection entry.  */
+  CORE_ADDR base;
+  int found_base;
+  unsigned int dummy;
+  const gdb_byte *buffer;
+  CORE_ADDR baseaddr;
+
+  if (cu_header->version >= 5)
+    return dwarf2_rnglists_process (offset, cu, callback);
+
+  found_base = cu->base_known;
+  base = cu->base_address;
+
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
+  if (offset >= dwarf2_per_objfile->ranges.size)
+    {
+      complaint (&symfile_complaints,
+                _("Offset %d out of bounds for DW_AT_ranges attribute"),
+                offset);
+      return 0;
+    }
+  buffer = dwarf2_per_objfile->ranges.buffer + offset;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  while (1)
+    {
+      CORE_ADDR range_beginning, range_end;
+
+      range_beginning = read_address (obfd, buffer, cu, &dummy);
+      buffer += addr_size;
+      range_end = read_address (obfd, buffer, cu, &dummy);
+      buffer += addr_size;
+      offset += 2 * addr_size;
+
+      /* An end of list marker is a pair of zero addresses.  */
+      if (range_beginning == 0 && range_end == 0)
+       /* Found the end of list entry.  */
+       break;
+
+      /* Each base address selection entry is a pair of 2 values.
+        The first is the largest possible address, the second is
+        the base address.  Check for a base address here.  */
+      if ((range_beginning & mask) == mask)
+       {
+         /* 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)
+       {
+         /* We have no valid base address for the ranges
+            data.  */
+         complaint (&symfile_complaints,
+                    _("Invalid .debug_ranges data (no base address)"));
+         return 0;
+       }
+
+      if (range_beginning > range_end)
+       {
+         /* Inverted range entries are invalid.  */
+         complaint (&symfile_complaints,
+                    _("Invalid .debug_ranges data (inverted range)"));
+         return 0;
+       }
+
+      /* Empty range entries have no effect.  */
+      if (range_beginning == range_end)
+       continue;
+
+      range_beginning += base;
+      range_end += base;
+
+      /* A not-uncommon case of bad debug info.
+        Don't pollute the addrmap with bad data.  */
+      if (range_beginning + baseaddr == 0
+         && !dwarf2_per_objfile->has_section_at_zero)
+       {
+         complaint (&symfile_complaints,
+                    _(".debug_ranges entry has start address of zero"
+                      " [in module %s]"), objfile_name (objfile));
+         continue;
+       }
+
+      callback (range_beginning, range_end);
+    }
+
+  return 1;
+}
+
+/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
+   Return 1 if the attributes are present and valid, otherwise, return 0.
+   If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'.  */
 
 static int
 dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
@@ -12285,6 +12648,8 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
       dwarf2_ranges_process (offset, cu,
        [&] (CORE_ADDR start, CORE_ADDR end)
        {
+         start += baseaddr;
+         end += baseaddr;
          start = gdbarch_adjust_dwarf2_addr (gdbarch, start);
          end = gdbarch_adjust_dwarf2_addr (gdbarch, end);
          record_block_range (block, start, end - 1);
@@ -12930,7 +13295,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
                  complaint (&symfile_complaints,
                             _("cannot determine context for virtual member "
                               "function \"%s\" (offset %d)"),
-                            fieldname, die->offset.sect_off);
+                            fieldname, to_underlying (die->sect_off));
                }
              else
                {
@@ -12958,7 +13323,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
          complaint (&symfile_complaints,
                     _("Member function \"%s\" (offset %d) is virtual "
                       "but the vtable offset is not specified"),
-                    fieldname, die->offset.sect_off);
+                    fieldname, to_underlying (die->sect_off));
          ALLOCATE_CPLUS_STRUCT_TYPE (type);
          TYPE_CPLUS_DYNAMIC (type) = 1;
        }
@@ -13648,8 +14013,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
       struct signatured_type *sig_type;
 
       sig_type = (struct signatured_type *) cu->per_cu;
-      gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
-      if (sig_type->type_offset_in_section.sect_off != die->offset.sect_off)
+      gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
+      if (sig_type->type_offset_in_section != die->sect_off)
        return;
     }
 
@@ -13889,7 +14254,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
   baton->data = ptr;
 
   *ptr++ = DW_OP_call4;
-  cu_off = common_die->offset.sect_off - cu->per_cu->offset.sect_off;
+  cu_off = common_die->sect_off - cu->per_cu->sect_off;
   store_unsigned_integer (ptr, 4, byte_order, cu_off);
   ptr += 4;
 
@@ -13992,7 +14357,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
                             _("Variable in common block has "
                               "DW_AT_data_member_location "
                               "- DIE at 0x%x [in module %s]"),
-                            child_die->offset.sect_off,
+                            to_underlying (child_die->sect_off),
                             objfile_name (cu->objfile));
 
                  if (attr_form_is_section_offset (member_loc))
@@ -14112,7 +14477,7 @@ read_module_type (struct die_info *die, struct dwarf2_cu *cu)
   if (!module_name)
     complaint (&symfile_complaints,
               _("DW_TAG_module has no name, offset 0x%x"),
-               die->offset.sect_off);
+               to_underlying (die->sect_off));
   type = init_type (objfile, TYPE_CODE_MODULE, 0, module_name);
 
   /* determine_prefix uses TYPE_TAG_NAME.  */
@@ -14272,16 +14637,19 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
-/* Extract all information from a DW_TAG_reference_type DIE and add to
+/* Extract all information from a DW_TAG_{rvalue_,}reference_type DIE and add to
    the user defined type vector.  */
 
 static struct type *
-read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
+read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
+                          enum type_code refcode)
 {
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type, *target_type;
   struct attribute *attr;
 
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
   target_type = die_type (die, cu);
 
   /* The die_type call above may have already set the type for this DIE.  */
@@ -14289,7 +14657,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_reference_type (target_type);
+  type = lookup_reference_type (target_type, refcode);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
@@ -14652,7 +15020,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
       complaint (&symfile_complaints,
                 _("Self-referential DW_TAG_typedef "
                   "- DIE at 0x%x [in module %s]"),
-                die->offset.sect_off, objfile_name (objfile));
+                to_underlying (die->sect_off), objfile_name (objfile));
       TYPE_TARGET_TYPE (this_type) = NULL;
     }
   return this_type;
@@ -14946,7 +15314,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   else if (!low_default_is_valid)
     complaint (&symfile_complaints, _("Missing DW_AT_lower_bound "
                                      "- DIE at 0x%x [in module %s]"),
-              die->offset.sect_off, objfile_name (cu->objfile));
+              to_underlying (die->sect_off), objfile_name (cu->objfile));
 
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
   if (!attr_to_dynamic_prop (attr, die, cu, &high))
@@ -15168,13 +15536,12 @@ read_full_die_1 (const struct die_reader_specs *reader,
                 int *has_children, int num_extra_attrs)
 {
   unsigned int abbrev_number, bytes_read, i;
-  sect_offset offset;
   struct abbrev_info *abbrev;
   struct die_info *die;
   struct dwarf2_cu *cu = reader->cu;
   bfd *abfd = reader->abfd;
 
-  offset.sect_off = info_ptr - reader->buffer;
+  sect_offset sect_off = (sect_offset) (info_ptr - reader->buffer);
   abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
   info_ptr += bytes_read;
   if (!abbrev_number)
@@ -15191,7 +15558,7 @@ read_full_die_1 (const struct die_reader_specs *reader,
           bfd_get_filename (abfd));
 
   die = dwarf_alloc_die (cu, abbrev->num_attrs + num_extra_attrs);
-  die->offset = offset;
+  die->sect_off = sect_off;
   die->tag = abbrev->tag;
   die->abbrev = abbrev_number;
 
@@ -15296,7 +15663,7 @@ abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table,
 
 static struct abbrev_table *
 abbrev_table_read_table (struct dwarf2_section_info *section,
-                        sect_offset offset)
+                        sect_offset sect_off)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *abfd = get_section_bfd_owner (section);
@@ -15309,7 +15676,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
   unsigned int allocated_attrs;
 
   abbrev_table = XNEW (struct abbrev_table);
-  abbrev_table->offset = offset;
+  abbrev_table->sect_off = sect_off;
   obstack_init (&abbrev_table->abbrev_obstack);
   abbrev_table->abbrevs =
     XOBNEWVEC (&abbrev_table->abbrev_obstack, struct abbrev_info *,
@@ -15318,7 +15685,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
          ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
 
   dwarf2_read_section (objfile, section);
-  abbrev_ptr = section->buffer + offset.sect_off;
+  abbrev_ptr = section->buffer + to_underlying (sect_off);
   abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
   abbrev_ptr += bytes_read;
 
@@ -15341,10 +15708,23 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
       /* now read in declarations */
       for (;;)
        {
+         LONGEST implicit_const;
+
          abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
          abbrev_ptr += bytes_read;
          abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
          abbrev_ptr += bytes_read;
+         if (abbrev_form == DW_FORM_implicit_const)
+           {
+             implicit_const = read_signed_leb128 (abfd, abbrev_ptr,
+                                                  &bytes_read);
+             abbrev_ptr += bytes_read;
+           }
+         else
+           {
+             /* Initialize it due to a false compiler warning.  */
+             implicit_const = -1;
+           }
 
          if (abbrev_name == 0)
            break;
@@ -15360,6 +15740,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
            = (enum dwarf_attribute) abbrev_name;
          cur_attrs[cur_abbrev->num_attrs].form
            = (enum dwarf_form) abbrev_form;
+         cur_attrs[cur_abbrev->num_attrs].implicit_const = implicit_const;
          ++cur_abbrev->num_attrs;
        }
 
@@ -15421,7 +15802,7 @@ dwarf2_read_abbrevs (struct dwarf2_cu *cu,
                     struct dwarf2_section_info *abbrev_section)
 {
   cu->abbrev_table =
-    abbrev_table_read_table (abbrev_section, cu->header.abbrev_offset);
+    abbrev_table_read_table (abbrev_section, cu->header.abbrev_sect_off);
 }
 
 /* Release the memory used by the abbrev table for a compilation unit.  */
@@ -15623,7 +16004,7 @@ load_partial_dies (const struct die_reader_specs *reader,
        complaint (&symfile_complaints,
                   _("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
                     "- DIE at 0x%x [in module %s]"),
-                  part_die->offset.sect_off, objfile_name (objfile));
+                  to_underlying (part_die->sect_off), objfile_name (objfile));
 
       /* If we're at the second level, and we're an enumerator, and
         our parent has no specification (meaning possibly lives in a
@@ -15696,7 +16077,8 @@ load_partial_dies (const struct die_reader_specs *reader,
          void **slot;
 
          slot = htab_find_slot_with_hash (cu->partial_dies, part_die,
-                                          part_die->offset.sect_off, INSERT);
+                                          to_underlying (part_die->sect_off),
+                                          INSERT);
          *slot = part_die;
        }
 
@@ -15763,7 +16145,7 @@ read_partial_die (const struct die_reader_specs *reader,
 
   memset (part_die, 0, sizeof (struct partial_die_info));
 
-  part_die->offset.sect_off = info_ptr - buffer;
+  part_die->sect_off = (sect_offset) (info_ptr - buffer);
 
   info_ptr += abbrev_len;
 
@@ -15862,8 +16244,8 @@ read_partial_die (const struct die_reader_specs *reader,
                       _("ignoring absolute DW_AT_sibling"));
          else
            {
-             unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off;
-             const gdb_byte *sibling_ptr = buffer + off;
+             sect_offset off = dwarf2_get_ref_die_offset (&attr);
+             const gdb_byte *sibling_ptr = buffer + to_underlying (off);
 
              if (sibling_ptr < info_ptr)
                complaint (&symfile_complaints,
@@ -15908,7 +16290,7 @@ read_partial_die (const struct die_reader_specs *reader,
        case DW_AT_import:
          if (part_die->tag == DW_TAG_imported_unit)
            {
-             part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
+             part_die->d.sect_off = dwarf2_get_ref_die_offset (&attr);
              part_die->is_dwz = (attr.form == DW_FORM_GNU_ref_alt
                                  || cu->per_cu->is_dwz);
            }
@@ -15944,7 +16326,7 @@ read_partial_die (const struct die_reader_specs *reader,
                     _("DW_AT_low_pc %s is zero "
                       "for DIE at 0x%x [in module %s]"),
                     paddress (gdbarch, part_die->lowpc),
-                    part_die->offset.sect_off, objfile_name (objfile));
+                    to_underlying (part_die->sect_off), objfile_name (objfile));
        }
       /* dwarf2_get_pc_bounds has also the strict low < high requirement.  */
       else if (part_die->lowpc >= part_die->highpc)
@@ -15956,7 +16338,8 @@ read_partial_die (const struct die_reader_specs *reader,
                       "for DIE at 0x%x [in module %s]"),
                     paddress (gdbarch, part_die->lowpc),
                     paddress (gdbarch, part_die->highpc),
-                    part_die->offset.sect_off, objfile_name (objfile));
+                    to_underlying (part_die->sect_off),
+                    objfile_name (objfile));
        }
       else
        part_die->has_pc_info = 1;
@@ -15968,15 +16351,15 @@ read_partial_die (const struct die_reader_specs *reader,
 /* Find a cached partial DIE at OFFSET in CU.  */
 
 static struct partial_die_info *
-find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
+find_partial_die_in_comp_unit (sect_offset sect_off, struct dwarf2_cu *cu)
 {
   struct partial_die_info *lookup_die = NULL;
   struct partial_die_info part_die;
 
-  part_die.offset = offset;
+  part_die.sect_off = sect_off;
   lookup_die = ((struct partial_die_info *)
                htab_find_with_hash (cu->partial_dies, &part_die,
-                                    offset.sect_off));
+                                    to_underlying (sect_off)));
 
   return lookup_die;
 }
@@ -15987,16 +16370,16 @@ find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
    DW_FORM_ref_sig8).  */
 
 static struct partial_die_info *
-find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu)
+find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   struct dwarf2_per_cu_data *per_cu = NULL;
   struct partial_die_info *pd = NULL;
 
   if (offset_in_dwz == cu->per_cu->is_dwz
-      && offset_in_cu_p (&cu->header, offset))
+      && offset_in_cu_p (&cu->header, sect_off))
     {
-      pd = find_partial_die_in_comp_unit (offset, cu);
+      pd = find_partial_die_in_comp_unit (sect_off, cu);
       if (pd != NULL)
        return pd;
       /* We missed recording what we needed.
@@ -16008,19 +16391,19 @@ find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu)
       /* TUs don't reference other CUs/TUs (except via type signatures).  */
       if (cu->per_cu->is_debug_types)
        {
-         error (_("Dwarf Error: Type Unit at offset 0x%lx contains"
-                  " external reference to offset 0x%lx [in module %s].\n"),
-                (long) cu->header.offset.sect_off, (long) offset.sect_off,
+         error (_("Dwarf Error: Type Unit at offset 0x%x contains"
+                  " external reference to offset 0x%x [in module %s].\n"),
+                to_underlying (cu->header.sect_off), to_underlying (sect_off),
                 bfd_get_filename (objfile->obfd));
        }
-      per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
+      per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
                                                 objfile);
 
       if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
        load_partial_comp_unit (per_cu);
 
       per_cu->cu->last_used = 0;
-      pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+      pd = find_partial_die_in_comp_unit (sect_off, per_cu->cu);
     }
 
   /* If we didn't find it, and not all dies have been loaded,
@@ -16038,14 +16421,14 @@ find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu)
         set.  */
       load_partial_comp_unit (per_cu);
 
-      pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+      pd = find_partial_die_in_comp_unit (sect_off, per_cu->cu);
     }
 
   if (pd == NULL)
     internal_error (__FILE__, __LINE__,
                    _("could not find partial DIE 0x%x "
                      "in cache [from module %s]\n"),
-                   offset.sect_off, bfd_get_filename (objfile->obfd));
+                   to_underlying (sect_off), bfd_get_filename (objfile->obfd));
   return pd;
 }
 
@@ -16194,7 +16577,7 @@ fixup_partial_die (struct partial_die_info *part_die,
 static const gdb_byte *
 read_attribute_value (const struct die_reader_specs *reader,
                      struct attribute *attr, unsigned form,
-                     const gdb_byte *info_ptr)
+                     LONGEST implicit_const, const gdb_byte *info_ptr)
 {
   struct dwarf2_cu *cu = reader->cu;
   struct objfile *objfile = cu->objfile;
@@ -16252,6 +16635,13 @@ read_attribute_value (const struct die_reader_specs *reader,
       DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
       info_ptr += 8;
       break;
+    case DW_FORM_data16:
+      blk = dwarf_alloc_block (cu);
+      blk->size = 16;
+      blk->data = read_n_bytes (abfd, info_ptr, 16);
+      info_ptr += 16;
+      DW_BLOCK (attr) = blk;
+      break;
     case DW_FORM_sec_offset:
       DW_UNSND (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read);
       info_ptr += bytes_read;
@@ -16271,6 +16661,16 @@ read_attribute_value (const struct die_reader_specs *reader,
          break;
        }
       /* FALLTHROUGH */
+    case DW_FORM_line_strp:
+      if (!cu->per_cu->is_dwz)
+       {
+         DW_STRING (attr) = read_indirect_line_string (abfd, info_ptr,
+                                                       cu_header, &bytes_read);
+         DW_STRING_IS_CANONICAL (attr) = 0;
+         info_ptr += bytes_read;
+         break;
+       }
+      /* FALLTHROUGH */
     case DW_FORM_GNU_strp_alt:
       {
        struct dwz_file *dwz = dwarf2_get_dwz_file ();
@@ -16319,22 +16719,22 @@ read_attribute_value (const struct die_reader_specs *reader,
       info_ptr += bytes_read;
       break;
     case DW_FORM_ref1:
-      DW_UNSND (attr) = (cu->header.offset.sect_off
+      DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
                         + read_1_byte (abfd, info_ptr));
       info_ptr += 1;
       break;
     case DW_FORM_ref2:
-      DW_UNSND (attr) = (cu->header.offset.sect_off
+      DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
                         + read_2_bytes (abfd, info_ptr));
       info_ptr += 2;
       break;
     case DW_FORM_ref4:
-      DW_UNSND (attr) = (cu->header.offset.sect_off
+      DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
                         + read_4_bytes (abfd, info_ptr));
       info_ptr += 4;
       break;
     case DW_FORM_ref8:
-      DW_UNSND (attr) = (cu->header.offset.sect_off
+      DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
                         + read_8_bytes (abfd, info_ptr));
       info_ptr += 8;
       break;
@@ -16343,14 +16743,23 @@ read_attribute_value (const struct die_reader_specs *reader,
       info_ptr += 8;
       break;
     case DW_FORM_ref_udata:
-      DW_UNSND (attr) = (cu->header.offset.sect_off
+      DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
                         + read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
       info_ptr += bytes_read;
       break;
     case DW_FORM_indirect:
       form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
-      info_ptr = read_attribute_value (reader, attr, form, info_ptr);
+      if (form == DW_FORM_implicit_const)
+       {
+         implicit_const = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+         info_ptr += bytes_read;
+       }
+      info_ptr = read_attribute_value (reader, attr, form, implicit_const,
+                                      info_ptr);
+      break;
+    case DW_FORM_implicit_const:
+      DW_SND (attr) = implicit_const;
       break;
     case DW_FORM_GNU_addr_index:
       if (reader->dwo_file == NULL)
@@ -16420,7 +16829,8 @@ read_attribute (const struct die_reader_specs *reader,
                const gdb_byte *info_ptr)
 {
   attr->name = abbrev->name;
-  return read_attribute_value (reader, attr, abbrev->form, info_ptr);
+  return read_attribute_value (reader, attr, abbrev->form,
+                              abbrev->implicit_const, info_ptr);
 }
 
 /* Read dwarf information from a buffer.  */
@@ -16673,21 +17083,47 @@ read_direct_string (bfd *abfd, const gdb_byte *buf,
   return (const char *) buf;
 }
 
+/* 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 (bfd *abfd, LONGEST str_offset)
-{
-  dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->str);
-  if (dwarf2_per_objfile->str.buffer == NULL)
-    error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
-          bfd_get_filename (abfd));
-  if (str_offset >= dwarf2_per_objfile->str.size)
-    error (_("DW_FORM_strp pointing outside of "
-            ".debug_str section [in module %s]"),
-          bfd_get_filename (abfd));
+read_indirect_string_at_offset_from (bfd *abfd, LONGEST str_offset,
+                                    struct dwarf2_section_info *sect,
+                                    const char *form_name,
+                                    const char *sect_name)
+{
+  dwarf2_read_section (dwarf2_per_objfile->objfile, sect);
+  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 (dwarf2_per_objfile->str.buffer[str_offset] == '\0')
+  if (sect->buffer[str_offset] == '\0')
     return NULL;
-  return (const char *) (dwarf2_per_objfile->str.buffer + str_offset);
+  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 (bfd *abfd, LONGEST str_offset)
+{
+  return read_indirect_string_at_offset_from (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 (bfd *abfd, LONGEST str_offset)
+{
+  return read_indirect_string_at_offset_from (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
@@ -16714,6 +17150,10 @@ read_indirect_string_from_dwz (struct dwz_file *dwz, LONGEST str_offset)
   return (const char *) (dwz->str.buffer + str_offset);
 }
 
+/* Return pointer to string at .debug_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.  */
+
 static const char *
 read_indirect_string (bfd *abfd, const gdb_byte *buf,
                      const struct comp_unit_head *cu_header,
@@ -16724,9 +17164,23 @@ read_indirect_string (bfd *abfd, const gdb_byte *buf,
   return read_indirect_string_at_offset (abfd, str_offset);
 }
 
-static ULONGEST
+/* 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.  */
+
+static const char *
+read_indirect_line_string (bfd *abfd, const gdb_byte *buf,
+                          const struct comp_unit_head *cu_header,
+                          unsigned int *bytes_read_ptr)
+{
+  LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
+
+  return read_indirect_line_string_at_offset (abfd, str_offset);
+}
+
+ULONGEST
 read_unsigned_leb128 (bfd *abfd, const gdb_byte *buf,
-                     unsigned int *bytes_read_ptr)
+                         unsigned int *bytes_read_ptr)
 {
   ULONGEST result;
   unsigned int num_read;
@@ -16928,16 +17382,16 @@ read_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
   dwarf2_read_section (objfile, str_offsets_section);
   if (str_section->buffer == NULL)
     error (_("%s used without .debug_str.dwo section"
-            " in CU at offset 0x%lx [in module %s]"),
-          form_name, (long) cu->header.offset.sect_off, objf_name);
+            " in CU at offset 0x%x [in module %s]"),
+          form_name, to_underlying (cu->header.sect_off), objf_name);
   if (str_offsets_section->buffer == NULL)
     error (_("%s used without .debug_str_offsets.dwo section"
-            " in CU at offset 0x%lx [in module %s]"),
-          form_name, (long) cu->header.offset.sect_off, objf_name);
+            " in CU at offset 0x%x [in module %s]"),
+          form_name, to_underlying (cu->header.sect_off), objf_name);
   if (str_index * cu->header.offset_size >= str_offsets_section->size)
     error (_("%s pointing outside of .debug_str_offsets.dwo"
-            " section in CU at offset 0x%lx [in module %s]"),
-          form_name, (long) cu->header.offset.sect_off, objf_name);
+            " section in CU at offset 0x%x [in module %s]"),
+          form_name, to_underlying (cu->header.sect_off), objf_name);
   info_ptr = (str_offsets_section->buffer
              + str_index * cu->header.offset_size);
   if (cu->header.offset_size == 4)
@@ -16946,8 +17400,8 @@ read_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
     str_offset = bfd_get_64 (abfd, info_ptr);
   if (str_offset >= str_section->size)
     error (_("Offset from %s pointing outside of"
-            " .debug_str.dwo section in CU at offset 0x%lx [in module %s]"),
-          form_name, (long) cu->header.offset.sect_off, objf_name);
+            " .debug_str.dwo section in CU at offset 0x%x [in module %s]"),
+          form_name, to_underlying (cu->header.sect_off), objf_name);
   return (const char *) (str_section->buffer + str_offset);
 }
 
@@ -17086,14 +17540,14 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c
 
   if (attr != NULL)
     {
-      if (attr->form == DW_FORM_strp || attr->form == DW_FORM_string
-         || attr->form == DW_FORM_GNU_strp_alt)
+      if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp
+         || attr->form == DW_FORM_string || attr->form == DW_FORM_GNU_strp_alt)
        str = DW_STRING (attr);
       else
         complaint (&symfile_complaints,
                   _("string type expected for attribute %s for "
                     "DIE at 0x%x in module %s"),
-                  dwarf_attr_name (name), die->offset.sect_off,
+                  dwarf_attr_name (name), to_underlying (die->sect_off),
                   objfile_name (cu->objfile));
     }
 
@@ -17147,28 +17601,6 @@ die_specification (struct die_info *die, struct dwarf2_cu **spec_cu)
     return follow_die_ref (die, spec_attr, spec_cu);
 }
 
-/* Free the line_header structure *LH, and any arrays and strings it
-   refers to.
-   NOTE: This is also used as a "cleanup" function.  */
-
-static void
-free_line_header (struct line_header *lh)
-{
-  if (lh->standard_opcode_lengths)
-    xfree (lh->standard_opcode_lengths);
-
-  /* Remember that all the lh->file_names[i].name pointers are
-     pointers into debug_line_buffer, and don't need to be freed.  */
-  if (lh->file_names)
-    xfree (lh->file_names);
-
-  /* Similarly for the include directory names.  */
-  if (lh->include_dirs)
-    xfree (lh->include_dirs);
-
-  xfree (lh);
-}
-
 /* Stub for free_line_header to match void * callback types.  */
 
 static void
@@ -17176,69 +17608,30 @@ free_line_header_voidp (void *arg)
 {
   struct line_header *lh = (struct line_header *) arg;
 
-  free_line_header (lh);
+  delete lh;
 }
 
-/* Add an entry to LH's include directory table.  */
-
-static void
-add_include_dir (struct line_header *lh, const char *include_dir)
+void
+line_header::add_include_dir (const char *include_dir)
 {
   if (dwarf_line_debug >= 2)
-    fprintf_unfiltered (gdb_stdlog, "Adding dir %u: %s\n",
-                       lh->num_include_dirs + 1, include_dir);
+    fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n",
+                       include_dirs.size () + 1, include_dir);
 
-  /* Grow the array if necessary.  */
-  if (lh->include_dirs_size == 0)
-    {
-      lh->include_dirs_size = 1; /* for testing */
-      lh->include_dirs = XNEWVEC (const char *, lh->include_dirs_size);
-    }
-  else if (lh->num_include_dirs >= lh->include_dirs_size)
-    {
-      lh->include_dirs_size *= 2;
-      lh->include_dirs = XRESIZEVEC (const char *, lh->include_dirs,
-                                    lh->include_dirs_size);
-    }
-
-  lh->include_dirs[lh->num_include_dirs++] = include_dir;
+  include_dirs.push_back (include_dir);
 }
 
-/* Add an entry to LH's file name table.  */
-
-static void
-add_file_name (struct line_header *lh,
-               const char *name,
-               unsigned int dir_index,
-               unsigned int mod_time,
-               unsigned int length)
+void
+line_header::add_file_name (const char *name,
+                           dir_index d_index,
+                           unsigned int mod_time,
+                           unsigned int length)
 {
-  struct file_entry *fe;
-
   if (dwarf_line_debug >= 2)
     fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n",
-                       lh->num_file_names + 1, name);
-
-  /* Grow the array if necessary.  */
-  if (lh->file_names_size == 0)
-    {
-      lh->file_names_size = 1; /* for testing */
-      lh->file_names = XNEWVEC (struct file_entry, lh->file_names_size);
-    }
-  else if (lh->num_file_names >= lh->file_names_size)
-    {
-      lh->file_names_size *= 2;
-      lh->file_names
-       = XRESIZEVEC (struct file_entry, lh->file_names, lh->file_names_size);
-    }
+                       (unsigned) file_names.size () + 1, name);
 
-  fe = &lh->file_names[lh->num_file_names++];
-  fe->name = name;
-  fe->dir_index = dir_index;
-  fe->mod_time = mod_time;
-  fe->length = length;
-  fe->included_p = 0;
-  fe->symtab = NULL;
+  file_names.emplace_back (name, d_index, mod_time, length);
 }
 
 /* A convenience function to find the proper .debug_line section for a CU.  */
@@ -17264,6 +17657,135 @@ 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 (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;
+  int i;
+  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 (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_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 (&symfile_complaints,
+                        _("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.
@@ -17274,11 +17796,9 @@ get_debug_line_section (struct dwarf2_cu *cu)
    the returned object point into the dwarf line section buffer,
    and must not be freed.  */
 
-static struct line_header *
-dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
+static line_header_up
+dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
 {
-  struct cleanup *back_to;
-  struct line_header *lh;
   const gdb_byte *line_ptr;
   unsigned int bytes_read, offset_size;
   int i;
@@ -17303,21 +17823,18 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
 
   /* 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 (offset + 4 >= section->size)
+  if (to_underlying (sect_off) + 4 >= section->size)
     {
       dwarf2_statement_list_fits_in_line_number_section_complaint ();
       return 0;
     }
 
-  lh = XNEW (struct line_header);
-  memset (lh, 0, sizeof (*lh));
-  back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
-                          (void *) lh);
+  line_header_up lh (new line_header ());
 
-  lh->offset.sect_off = offset;
+  lh->sect_off = sect_off;
   lh->offset_in_dwz = cu->per_cu->is_dwz;
 
-  line_ptr = section->buffer + offset;
+  line_ptr = section->buffer + to_underlying (sect_off);
 
   /* Read in the header.  */
   lh->total_length =
@@ -17327,13 +17844,12 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
   if (line_ptr + lh->total_length > (section->buffer + section->size))
     {
       dwarf2_statement_list_fits_in_line_number_section_complaint ();
-      do_cleanups (back_to);
       return 0;
     }
   lh->statement_program_end = line_ptr + lh->total_length;
   lh->version = read_2_bytes (abfd, line_ptr);
   line_ptr += 2;
-  if (lh->version > 4)
+  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.  */
@@ -17341,6 +17857,25 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
                 _("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 (&symfile_complaints,
+                    _("unsupported segment selector size %u "
+                      "in .debug_line section"),
+                    segment_selector_size);
+         return NULL;
+       }
+    }
   lh->header_length = read_offset_1 (abfd, line_ptr, offset_size);
   line_ptr += offset_size;
   lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
@@ -17369,7 +17904,7 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
   line_ptr += 1;
   lh->opcode_base = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
-  lh->standard_opcode_lengths = XNEWVEC (unsigned char, lh->opcode_base);
+  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)
@@ -17378,30 +17913,54 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
       line_ptr += 1;
     }
 
-  /* Read directory table.  */
-  while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+  if (lh->version >= 5)
     {
-      line_ptr += bytes_read;
-      add_include_dir (lh, cur_dir);
-    }
-  line_ptr += bytes_read;
+      /* Read directory table.  */
+      read_formatted_entries (abfd, &line_ptr, lh.get (), &cu->header,
+                             [] (struct line_header *lh, const char *name,
+                                 dir_index d_index, unsigned int mod_time,
+                                 unsigned int length)
+       {
+         lh->add_include_dir (name);
+       });
 
-  /* Read file name table.  */
-  while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+      /* Read file name table.  */
+      read_formatted_entries (abfd, &line_ptr, lh.get (), &cu->header,
+                             [] (struct line_header *lh, const char *name,
+                                 dir_index d_index, unsigned int mod_time,
+                                 unsigned int length)
+       {
+         lh->add_file_name (name, d_index, mod_time, length);
+       });
+    }
+  else
     {
-      unsigned int dir_index, mod_time, length;
-
-      line_ptr += bytes_read;
-      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);
+      /* 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;
 
-      add_file_name (lh, cur_file, dir_index, mod_time, length);
+      /* 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;
     }
-  line_ptr += bytes_read;
   lh->statement_program_start = line_ptr;
 
   if (line_ptr > (section->buffer + section->size))
@@ -17409,7 +17968,6 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
               _("line number info header doesn't "
                 "fit in `.debug_line' section"));
 
-  discard_cleanups (back_to);
   return lh;
 }
 
@@ -17427,16 +17985,14 @@ psymtab_include_file_name (const struct line_header *lh, int file_index,
                           const struct partial_symtab *pst,
                           const char *comp_dir)
 {
-  const struct file_entry fe = lh->file_names [file_index];
+  const file_entry &fe = lh->file_names[file_index];
   const char *include_name = fe.name;
   const char *include_name_to_compare = include_name;
-  const char *dir_name = NULL;
   const char *pst_filename;
   char *copied_name = NULL;
   int file_is_pst;
 
-  if (fe.dir_index && lh->include_dirs != NULL)
-    dir_name = lh->include_dirs[fe.dir_index - 1];
+  const char *dir_name = fe.include_dir (lh);
 
   if (!IS_ABSOLUTE_PATH (include_name)
       && (dir_name != NULL || comp_dir != NULL))
@@ -17501,51 +18057,203 @@ psymtab_include_file_name (const struct line_header *lh, int file_index,
 
 /* State machine to track the state of the line number program.  */
 
-typedef struct
+class lnp_state_machine
 {
-  /* These are part of the standard DWARF line number state machine.  */
+public:
+  /* Initialize a machine state for the start of a line number
+     program.  */
+  lnp_state_machine (gdbarch *arch, line_header *lh, bool record_lines_p);
+
+  file_entry *current_file ()
+  {
+    /* lh->file_names is 0-based, but the file name numbers in the
+       statement program are 1-based.  */
+    return m_line_header->file_name_at (m_file);
+  }
+
+  /* Record the line in the state machine.  END_SEQUENCE is true if
+     we're processing the end of a sequence.  */
+  void record_line (bool end_sequence);
+
+  /* Check address and if invalid nop-out the rest of the lines in this
+     sequence.  */
+  void check_line_address (struct dwarf2_cu *cu,
+                          const gdb_byte *line_ptr,
+                          CORE_ADDR lowpc, CORE_ADDR address);
+
+  void handle_set_discriminator (unsigned int discriminator)
+  {
+    m_discriminator = discriminator;
+    m_line_has_non_zero_discriminator |= discriminator != 0;
+  }
+
+  /* Handle DW_LNE_set_address.  */
+  void handle_set_address (CORE_ADDR baseaddr, CORE_ADDR address)
+  {
+    m_op_index = 0;
+    address += baseaddr;
+    m_address = gdbarch_adjust_dwarf2_line (m_gdbarch, address, false);
+  }
+
+  /* Handle DW_LNS_advance_pc.  */
+  void handle_advance_pc (CORE_ADDR adjust);
+
+  /* Handle a special opcode.  */
+  void handle_special_opcode (unsigned char op_code);
+
+  /* Handle DW_LNS_advance_line.  */
+  void handle_advance_line (int line_delta)
+  {
+    advance_line (line_delta);
+  }
+
+  /* Handle DW_LNS_set_file.  */
+  void handle_set_file (file_name_index file);
+
+  /* Handle DW_LNS_negate_stmt.  */
+  void handle_negate_stmt ()
+  {
+    m_is_stmt = !m_is_stmt;
+  }
+
+  /* Handle DW_LNS_const_add_pc.  */
+  void handle_const_add_pc ();
 
-  unsigned char op_index;
-  unsigned int file;
-  unsigned int line;
-  CORE_ADDR address;
-  int is_stmt;
-  unsigned int discriminator;
+  /* Handle DW_LNS_fixed_advance_pc.  */
+  void handle_fixed_advance_pc (CORE_ADDR addr_adj)
+  {
+    m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+    m_op_index = 0;
+  }
+
+  /* Handle DW_LNS_copy.  */
+  void handle_copy ()
+  {
+    record_line (false);
+    m_discriminator = 0;
+  }
+
+  /* Handle DW_LNE_end_sequence.  */
+  void handle_end_sequence ()
+  {
+    m_record_line_callback = ::record_line;
+  }
+
+private:
+  /* Advance the line by LINE_DELTA.  */
+  void advance_line (int line_delta)
+  {
+    m_line += line_delta;
+
+    if (line_delta != 0)
+      m_line_has_non_zero_discriminator = m_discriminator != 0;
+  }
+
+  gdbarch *m_gdbarch;
+
+  /* True if we're recording lines.
+     Otherwise we're building partial symtabs and are just interested in
+     finding include files mentioned by the line number program.  */
+  bool m_record_lines_p;
+
+  /* The line number header.  */
+  line_header *m_line_header;
+
+  /* These are part of the standard DWARF line number state machine,
+     and initialized according to the DWARF spec.  */
+
+  unsigned char m_op_index = 0;
+  /* The line table index (1-based) of the current file.  */
+  file_name_index m_file = (file_name_index) 1;
+  unsigned int m_line = 1;
+
+  /* These are initialized in the constructor.  */
+
+  CORE_ADDR m_address;
+  bool m_is_stmt;
+  unsigned int m_discriminator;
 
   /* Additional bits of state we need to track.  */
 
   /* The last file that we called dwarf2_start_subfile for.
      This is only used for TLLs.  */
-  unsigned int last_file;
+  unsigned int m_last_file = 0;
   /* The last file a line number was recorded for.  */
-  struct subfile *last_subfile;
+  struct subfile *m_last_subfile = NULL;
 
   /* The function to call to record a line.  */
-  record_line_ftype *record_line;
+  record_line_ftype *m_record_line_callback = NULL;
 
   /* The last line number that was recorded, used to coalesce
      consecutive entries for the same line.  This can happen, for
      example, when discriminators are present.  PR 17276.  */
-  unsigned int last_line;
-  int line_has_non_zero_discriminator;
-} lnp_state_machine;
+  unsigned int m_last_line = 0;
+  bool m_line_has_non_zero_discriminator = false;
+};
+
+void
+lnp_state_machine::handle_advance_pc (CORE_ADDR adjust)
+{
+  CORE_ADDR addr_adj = (((m_op_index + adjust)
+                        / 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 + adjust)
+               % m_line_header->maximum_ops_per_instruction);
+}
 
-/* There's a lot of static state to pass to dwarf_record_line.
-   This keeps it all together.  */
+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))
+                        / 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_line_header->maximum_ops_per_instruction);
 
-typedef struct
+  int line_delta = (m_line_header->line_base
+                   + (adj_opcode % m_line_header->line_range));
+  advance_line (line_delta);
+  record_line (false);
+  m_discriminator = 0;
+}
+
+void
+lnp_state_machine::handle_set_file (file_name_index file)
 {
-  /* The gdbarch.  */
-  struct gdbarch *gdbarch;
+  m_file = file;
 
-  /* The line number header.  */
-  struct line_header *line_header;
+  const file_entry *fe = current_file ();
+  if (fe == NULL)
+    dwarf2_debug_line_missing_file_complaint ();
+  else if (m_record_lines_p)
+    {
+      const char *dir = fe->include_dir (m_line_header);
 
-  /* Non-zero if we're recording lines.
-     Otherwise we're building partial symtabs and are just interested in
-     finding include files mentioned by the line number program.  */
-  int record_lines_p;
-} lnp_reader_state;
+      m_last_subfile = current_subfile;
+      m_line_has_non_zero_discriminator = m_discriminator != 0;
+      dwarf2_start_subfile (fe->name, dir);
+    }
+}
+
+void
+lnp_state_machine::handle_const_add_pc ()
+{
+  CORE_ADDR adjust
+    = (255 - m_line_header->opcode_base) / m_line_header->line_range;
+
+  CORE_ADDR addr_adj
+    = (((m_op_index + adjust)
+       / 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 + adjust)
+               % m_line_header->maximum_ops_per_instruction);
+}
 
 /* Ignore this record_line request.  */
 
@@ -17646,102 +18354,76 @@ dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
   dwarf_record_line_1 (gdbarch, subfile, 0, address, p_record_line);
 }
 
-/* Record the line in STATE.
-   END_SEQUENCE is non-zero if we're processing the end of a sequence.  */
-
-static void
-dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state,
-                  int end_sequence)
+void
+lnp_state_machine::record_line (bool end_sequence)
 {
-  const struct line_header *lh = reader->line_header;
-  unsigned int file, line, discriminator;
-  int is_stmt;
-
-  file = state->file;
-  line = state->line;
-  is_stmt = state->is_stmt;
-  discriminator = state->discriminator;
-
   if (dwarf_line_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
                          "Processing actual line %u: file %u,"
                          " address %s, is_stmt %u, discrim %u\n",
-                         line, file,
-                         paddress (reader->gdbarch, state->address),
-                         is_stmt, discriminator);
+                         m_line, to_underlying (m_file),
+                         paddress (m_gdbarch, m_address),
+                         m_is_stmt, m_discriminator);
     }
 
-  if (file == 0 || file - 1 >= lh->num_file_names)
+  file_entry *fe = current_file ();
+
+  if (fe == NULL)
     dwarf2_debug_line_missing_file_complaint ();
   /* For now we ignore lines not starting on an instruction boundary.
      But not when processing end_sequence for compatibility with the
      previous version of the code.  */
-  else if (state->op_index == 0 || end_sequence)
+  else if (m_op_index == 0 || end_sequence)
     {
-      lh->file_names[file - 1].included_p = 1;
-      if (reader->record_lines_p && is_stmt)
+      fe->included_p = 1;
+      if (m_record_lines_p && m_is_stmt)
        {
-         if (state->last_subfile != current_subfile || end_sequence)
+         if (m_last_subfile != current_subfile || end_sequence)
            {
-             dwarf_finish_line (reader->gdbarch, state->last_subfile,
-                                state->address, state->record_line);
+             dwarf_finish_line (m_gdbarch, m_last_subfile,
+                                m_address, m_record_line_callback);
            }
 
          if (!end_sequence)
            {
-             if (dwarf_record_line_p (line, state->last_line,
-                                      state->line_has_non_zero_discriminator,
-                                      state->last_subfile))
+             if (dwarf_record_line_p (m_line, m_last_line,
+                                      m_line_has_non_zero_discriminator,
+                                      m_last_subfile))
                {
-                 dwarf_record_line_1 (reader->gdbarch, current_subfile,
-                                      line, state->address,
-                                      state->record_line);
+                 dwarf_record_line_1 (m_gdbarch, current_subfile,
+                                      m_line, m_address,
+                                      m_record_line_callback);
                }
-             state->last_subfile = current_subfile;
-             state->last_line = line;
+             m_last_subfile = current_subfile;
+             m_last_line = m_line;
            }
        }
     }
 }
 
-/* Initialize STATE for the start of a line number program.  */
-
-static void
-init_lnp_state_machine (lnp_state_machine *state,
-                       const lnp_reader_state *reader)
+lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,
+                                     bool record_lines_p)
 {
-  memset (state, 0, sizeof (*state));
-
-  /* Just starting, there is no "last file".  */
-  state->last_file = 0;
-  state->last_subfile = NULL;
+  m_gdbarch = arch;
+  m_record_lines_p = record_lines_p;
+  m_line_header = lh;
 
-  state->record_line = record_line;
+  m_record_line_callback = ::record_line;
 
-  state->last_line = 0;
-  state->line_has_non_zero_discriminator = 0;
-
-  /* Initialize these according to the DWARF spec.  */
-  state->op_index = 0;
-  state->file = 1;
-  state->line = 1;
   /* Call `gdbarch_adjust_dwarf2_line' on the initial 0 address as if there
      was a line entry for it so that the backend has a chance to adjust it
      and also record it in case it needs it.  This is currently used by MIPS
      code, cf. `mips_adjust_dwarf2_line'.  */
-  state->address = gdbarch_adjust_dwarf2_line (reader->gdbarch, 0, 0);
-  state->is_stmt = reader->line_header->default_is_stmt;
-  state->discriminator = 0;
+  m_address = gdbarch_adjust_dwarf2_line (arch, 0, 0);
+  m_is_stmt = lh->default_is_stmt;
+  m_discriminator = 0;
 }
 
-/* Check address and if invalid nop-out the rest of the lines in this
-   sequence.  */
-
-static void
-check_line_address (struct dwarf2_cu *cu, lnp_state_machine *state,
-                   const gdb_byte *line_ptr,
-                   CORE_ADDR lowpc, CORE_ADDR address)
+void
+lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
+                                      const gdb_byte *line_ptr,
+                                      CORE_ADDR lowpc, CORE_ADDR address)
 {
   /* If address < lowpc then it's not a usable value, it's outside the
      pc range of the CU.  However, we restrict the test to only address
@@ -17759,9 +18441,9 @@ check_line_address (struct dwarf2_cu *cu, lnp_state_machine *state,
       complaint (&symfile_complaints,
                 _(".debug_line address at offset 0x%lx is 0 [in module %s]"),
                 line_offset, objfile_name (objfile));
-      state->record_line = noop_record_line;
-      /* Note: sm.record_line is left as noop_record_line
-        until we see DW_LNE_end_sequence.  */
+      m_record_line_callback = noop_record_line;
+      /* Note: record_line_callback is left as noop_record_line until
+        we see DW_LNE_end_sequence.  */
     }
 }
 
@@ -17782,44 +18464,32 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
   struct objfile *objfile = cu->objfile;
   bfd *abfd = objfile->obfd;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
-  /* Non-zero if we're recording line info (as opposed to building partial
-     symtabs).  */
-  int record_lines_p = !decode_for_pst_p;
-  /* A collection of things we need to pass to dwarf_record_line.  */
-  lnp_reader_state reader_state;
+  /* True if we're recording line info (as opposed to building partial
+     symtabs and just interested in finding include files mentioned by
+     the line number program).  */
+  bool record_lines_p = !decode_for_pst_p;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   line_ptr = lh->statement_program_start;
   line_end = lh->statement_program_end;
 
-  reader_state.gdbarch = gdbarch;
-  reader_state.line_header = lh;
-  reader_state.record_lines_p = record_lines_p;
-
   /* Read the statement sequences until there's nothing left.  */
   while (line_ptr < line_end)
     {
-      /* The DWARF line number program state machine.  */
-      lnp_state_machine state_machine;
-      int end_sequence = 0;
-
-      /* Reset the state machine at the start of each sequence.  */
-      init_lnp_state_machine (&state_machine, &reader_state);
+      /* The DWARF line number program state machine.  Reset the state
+        machine at the start of each sequence.  */
+      lnp_state_machine state_machine (gdbarch, lh, record_lines_p);
+      bool end_sequence = false;
 
-      if (record_lines_p && lh->num_file_names >= state_machine.file)
+      if (record_lines_p)
        {
-          /* Start a subfile for the current file of the state machine.  */
-         /* lh->include_dirs and lh->file_names are 0-based, but the
-            directory and file name numbers in the statement program
-            are 1-based.  */
-          struct file_entry *fe = &lh->file_names[state_machine.file - 1];
-          const char *dir = NULL;
+         /* Start a subfile for the current file of the state
+            machine.  */
+         const file_entry *fe = state_machine.current_file ();
 
-          if (fe->dir_index && lh->include_dirs != NULL)
-            dir = lh->include_dirs[fe->dir_index - 1];
-
-         dwarf2_start_subfile (fe->name, dir);
+         if (fe != NULL)
+           dwarf2_start_subfile (fe->name, fe->include_dir (lh));
        }
 
       /* Decode the table.  */
@@ -17831,28 +18501,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
          if (op_code >= lh->opcode_base)
            {
              /* Special opcode.  */
-             unsigned char adj_opcode;
-             CORE_ADDR addr_adj;
-             int line_delta;
-
-             adj_opcode = op_code - lh->opcode_base;
-             addr_adj = (((state_machine.op_index
-                           + (adj_opcode / lh->line_range))
-                          / lh->maximum_ops_per_instruction)
-                         * lh->minimum_instruction_length);
-             state_machine.address
-               += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
-             state_machine.op_index = ((state_machine.op_index
-                                        + (adj_opcode / lh->line_range))
-                                       % lh->maximum_ops_per_instruction);
-             line_delta = lh->line_base + (adj_opcode % lh->line_range);
-             state_machine.line += line_delta;
-             if (line_delta != 0)
-               state_machine.line_has_non_zero_discriminator
-                 = state_machine.discriminator != 0;
-
-             dwarf_record_line (&reader_state, &state_machine, 0);
-             state_machine.discriminator = 0;
+             state_machine.handle_special_opcode (op_code);
            }
          else switch (op_code)
            {
@@ -17866,32 +18515,30 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
              switch (extended_op)
                {
                case DW_LNE_end_sequence:
-                 state_machine.record_line = record_line;
-                 end_sequence = 1;
+                 state_machine.handle_end_sequence ();
+                 end_sequence = true;
                  break;
                case DW_LNE_set_address:
                  {
                    CORE_ADDR address
                      = read_address (abfd, line_ptr, cu, &bytes_read);
-
                    line_ptr += bytes_read;
-                   check_line_address (cu, &state_machine, line_ptr,
-                                       lowpc, address);
-                   state_machine.op_index = 0;
-                   address += baseaddr;
-                   state_machine.address
-                     = gdbarch_adjust_dwarf2_line (gdbarch, address, 0);
+
+                   state_machine.check_line_address (cu, line_ptr,
+                                                     lowpc, address);
+                   state_machine.handle_set_address (baseaddr, address);
                  }
                  break;
                case DW_LNE_define_file:
                   {
                     const char *cur_file;
-                    unsigned int dir_index, mod_time, length;
+                   unsigned int mod_time, length;
+                   dir_index dindex;
 
                     cur_file = read_direct_string (abfd, line_ptr,
                                                   &bytes_read);
                     line_ptr += bytes_read;
-                    dir_index =
+                    dindex = (dir_index)
                       read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
                     line_ptr += bytes_read;
                     mod_time =
@@ -17900,20 +18547,23 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
                     length =
                       read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
                     line_ptr += bytes_read;
-                    add_file_name (lh, cur_file, dir_index, mod_time, length);
+                    lh->add_file_name (cur_file, dindex, mod_time, length);
                   }
                  break;
                case DW_LNE_set_discriminator:
-                 /* The discriminator is not interesting to the debugger;
-                    just ignore it.  We still need to check its value though:
-                    if there are consecutive entries for the same
-                    (non-prologue) line we want to coalesce them.
-                    PR 17276.  */
-                 state_machine.discriminator
-                   = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-                 state_machine.line_has_non_zero_discriminator
-                   |= state_machine.discriminator != 0;
-                 line_ptr += bytes_read;
+                 {
+                   /* The discriminator is not interesting to the
+                      debugger; just ignore it.  We still need to
+                      check its value though:
+                      if there are consecutive entries for the same
+                      (non-prologue) line we want to coalesce them.
+                      PR 17276.  */
+                   unsigned int discr
+                     = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                   line_ptr += bytes_read;
+
+                   state_machine.handle_set_discriminator (discr);
+                 }
                  break;
                default:
                  complaint (&symfile_complaints,
@@ -17931,64 +18581,34 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
                }
              break;
            case DW_LNS_copy:
-             dwarf_record_line (&reader_state, &state_machine, 0);
-             state_machine.discriminator = 0;
+             state_machine.handle_copy ();
              break;
            case DW_LNS_advance_pc:
              {
                CORE_ADDR adjust
                  = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-               CORE_ADDR addr_adj;
-
-               addr_adj = (((state_machine.op_index + adjust)
-                            / lh->maximum_ops_per_instruction)
-                           * lh->minimum_instruction_length);
-               state_machine.address
-                 += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
-               state_machine.op_index = ((state_machine.op_index + adjust)
-                                         % lh->maximum_ops_per_instruction);
                line_ptr += bytes_read;
+
+               state_machine.handle_advance_pc (adjust);
              }
              break;
            case DW_LNS_advance_line:
              {
                int line_delta
                  = read_signed_leb128 (abfd, line_ptr, &bytes_read);
-
-               state_machine.line += line_delta;
-               if (line_delta != 0)
-                 state_machine.line_has_non_zero_discriminator
-                   = state_machine.discriminator != 0;
                line_ptr += bytes_read;
+
+               state_machine.handle_advance_line (line_delta);
              }
              break;
            case DW_LNS_set_file:
              {
-               /* The arrays lh->include_dirs and lh->file_names are
-                  0-based, but the directory and file name numbers in
-                  the statement program are 1-based.  */
-               struct file_entry *fe;
-               const char *dir = NULL;
-
-               state_machine.file = read_unsigned_leb128 (abfd, line_ptr,
-                                                          &bytes_read);
+               file_name_index file
+                 = (file_name_index) read_unsigned_leb128 (abfd, line_ptr,
+                                                           &bytes_read);
                line_ptr += bytes_read;
-               if (state_machine.file == 0
-                   || state_machine.file - 1 >= lh->num_file_names)
-                 dwarf2_debug_line_missing_file_complaint ();
-               else
-                 {
-                   fe = &lh->file_names[state_machine.file - 1];
-                   if (fe->dir_index && lh->include_dirs != NULL)
-                     dir = lh->include_dirs[fe->dir_index - 1];
-                   if (record_lines_p)
-                     {
-                       state_machine.last_subfile = current_subfile;
-                       state_machine.line_has_non_zero_discriminator
-                         = state_machine.discriminator != 0;
-                       dwarf2_start_subfile (fe->name, dir);
-                     }
-                 }
+
+               state_machine.handle_set_file (file);
              }
              break;
            case DW_LNS_set_column:
@@ -17996,7 +18616,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
              line_ptr += bytes_read;
              break;
            case DW_LNS_negate_stmt:
-             state_machine.is_stmt = (!state_machine.is_stmt);
+             state_machine.handle_negate_stmt ();
              break;
            case DW_LNS_set_basic_block:
              break;
@@ -18006,28 +18626,14 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
               instruction length since special opcode 255 would have
               scaled the increment.  */
            case DW_LNS_const_add_pc:
-             {
-               CORE_ADDR adjust = (255 - lh->opcode_base) / lh->line_range;
-               CORE_ADDR addr_adj;
-
-               addr_adj = (((state_machine.op_index + adjust)
-                            / lh->maximum_ops_per_instruction)
-                           * lh->minimum_instruction_length);
-               state_machine.address
-                 += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
-               state_machine.op_index = ((state_machine.op_index + adjust)
-                                         % lh->maximum_ops_per_instruction);
-             }
+             state_machine.handle_const_add_pc ();
              break;
            case DW_LNS_fixed_advance_pc:
              {
-               CORE_ADDR addr_adj;
-
-               addr_adj = read_2_bytes (abfd, line_ptr);
-               state_machine.address
-                 += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
-               state_machine.op_index = 0;
+               CORE_ADDR addr_adj = read_2_bytes (abfd, line_ptr);
                line_ptr += 2;
+
+               state_machine.handle_fixed_advance_pc (addr_adj);
              }
              break;
            default:
@@ -18049,7 +18655,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 
       /* We got a DW_LNE_end_sequence (or we ran off the end of the buffer,
         in which case we still finish recording the last line).  */
-      dwarf_record_line (&reader_state, &state_machine, 1);
+      state_machine.record_line (true);
     }
 }
 
@@ -18098,7 +18704,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
 
       /* Now that we're done scanning the Line Header Program, we can
          create the psymtab of each included file.  */
-      for (file_index = 0; file_index < lh->num_file_names; file_index++)
+      for (file_index = 0; file_index < lh->file_names.size (); file_index++)
         if (lh->file_names[file_index].included_p == 1)
           {
            const char *include_name =
@@ -18115,22 +18721,18 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
       struct compunit_symtab *cust = buildsym_compunit_symtab ();
       int i;
 
-      for (i = 0; i < lh->num_file_names; i++)
+      for (i = 0; i < lh->file_names.size (); i++)
        {
-         const char *dir = NULL;
-         struct file_entry *fe;
+         file_entry &fe = lh->file_names[i];
 
-         fe = &lh->file_names[i];
-         if (fe->dir_index && lh->include_dirs != NULL)
-           dir = lh->include_dirs[fe->dir_index - 1];
-         dwarf2_start_subfile (fe->name, dir);
+         dwarf2_start_subfile (fe.name, fe.include_dir (lh));
 
          if (current_subfile->symtab == NULL)
            {
              current_subfile->symtab
                = allocate_symtab (cust, current_subfile->name);
            }
-         fe->symtab = current_subfile->symtab;
+         fe.symtab = current_subfile->symtab;
        }
     }
 }
@@ -18339,19 +18941,19 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
                          cu);
       if (attr)
        {
-         int file_index = DW_UNSND (attr);
+         file_name_index file_index = (file_name_index) DW_UNSND (attr);
+         struct file_entry *fe;
+
+         if (cu->line_header != NULL)
+           fe = cu->line_header->file_name_at (file_index);
+         else
+           fe = NULL;
 
-         if (cu->line_header == NULL
-             || file_index > cu->line_header->num_file_names)
+         if (fe == NULL)
            complaint (&symfile_complaints,
                       _("file index out of range"));
-         else if (file_index > 0)
-           {
-             struct file_entry *fe;
-
-             fe = &cu->line_header->file_names[file_index - 1];
-             symbol_set_symtab (sym, fe->symtab);
-           }
+         else
+           symbol_set_symtab (sym, fe->symtab);
        }
 
       switch (die->tag)
@@ -18765,6 +19367,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
     case DW_FORM_block4:
     case DW_FORM_block:
     case DW_FORM_exprloc:
+    case DW_FORM_data16:
       blk = DW_BLOCK (attr);
       if (TYPE_LENGTH (type) != blk->size)
        dwarf2_const_value_length_mismatch_complaint (name, blk->size,
@@ -18934,8 +19537,8 @@ build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die)
 
   message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
                        objfile_name (objfile),
-                       cu->header.offset.sect_off,
-                       die->offset.sect_off);
+                       to_underlying (cu->header.sect_off),
+                       to_underlying (die->sect_off));
   saved = (char *) obstack_copy0 (&objfile->objfile_obstack,
                                  message, strlen (message));
   xfree (message);
@@ -18964,16 +19567,16 @@ 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 offset = dwarf2_get_ref_die_offset (attr);
+      sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
 
-      per_cu = dwarf2_find_containing_comp_unit (offset, 1, cu->objfile);
-      this_type = get_die_type_at_offset (offset, per_cu);
+      per_cu = dwarf2_find_containing_comp_unit (sect_off, 1, cu->objfile);
+      this_type = get_die_type_at_offset (sect_off, per_cu);
     }
   else if (attr_form_is_ref (attr))
     {
-      sect_offset offset = dwarf2_get_ref_die_offset (attr);
+      sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
 
-      this_type = get_die_type_at_offset (offset, cu->per_cu);
+      this_type = get_die_type_at_offset (sect_off, cu->per_cu);
     }
   else if (attr->form == DW_FORM_ref_sig8)
     {
@@ -18986,7 +19589,7 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
       complaint (&symfile_complaints,
                 _("Dwarf Error: Bad type attribute %s in DIE"
                   " at 0x%x [in module %s]"),
-                dwarf_attr_name (attr->name), die->offset.sect_off,
+                dwarf_attr_name (attr->name), to_underlying (die->sect_off),
                 objfile_name (objfile));
       return build_error_marker_type (cu, die);
     }
@@ -19073,7 +19676,10 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
       this_type = read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
-      this_type = read_tag_reference_type (die, cu);
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_REF);
+      break;
+    case DW_TAG_rvalue_reference_type:
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_RVALUE_REF);
       break;
     case DW_TAG_const_type:
       this_type = read_tag_const_type (die, cu);
@@ -19194,7 +19800,7 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
    prefix part in such case.  See
    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510.  */
 
-static char *
+static const char *
 anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
@@ -19247,7 +19853,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *parent, *spec_die;
   struct dwarf2_cu *spec_cu;
   struct type *parent_type;
-  char *retval;
+  const char *retval;
 
   if (cu->language != language_cplus
       && cu->language != language_fortran && cu->language != language_d
@@ -19649,7 +20255,7 @@ dwarf_form_name (unsigned form)
   return name;
 }
 
-static char *
+static const char *
 dwarf_bool_name (unsigned mybool)
 {
   if (mybool)
@@ -19678,13 +20284,14 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
 
   print_spaces (indent, f);
   fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n",
-          dwarf_tag_name (die->tag), die->abbrev, die->offset.sect_off);
+                     dwarf_tag_name (die->tag), die->abbrev,
+                     to_underlying (die->sect_off));
 
   if (die->parent != NULL)
     {
       print_spaces (indent, f);
       fprintf_unfiltered (f, "  parent at offset: 0x%x\n",
-                         die->parent->offset.sect_off);
+                         to_underlying (die->parent->sect_off));
     }
 
   print_spaces (indent, f);
@@ -19719,6 +20326,9 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
          fprintf_unfiltered (f, "expression: size %s",
                              pulongest (DW_BLOCK (&die->attrs[i])->size));
          break;
+       case DW_FORM_data16:
+         fprintf_unfiltered (f, "constant of 16 bytes");
+         break;
        case DW_FORM_ref_addr:
          fprintf_unfiltered (f, "ref address: ");
          fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
@@ -19754,6 +20364,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
          break;
        case DW_FORM_string:
        case DW_FORM_strp:
+       case DW_FORM_line_strp:
        case DW_FORM_GNU_str_index:
        case DW_FORM_GNU_strp_alt:
          fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
@@ -19839,7 +20450,8 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
 {
   void **slot;
 
-  slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset.sect_off,
+  slot = htab_find_slot_with_hash (cu->die_hash, die,
+                                  to_underlying (die->sect_off),
                                   INSERT);
 
   *slot = die;
@@ -19851,16 +20463,13 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
 static sect_offset
 dwarf2_get_ref_die_offset (const struct attribute *attr)
 {
-  sect_offset retval = { DW_UNSND (attr) };
-
   if (attr_form_is_ref (attr))
-    return retval;
+    return (sect_offset) DW_UNSND (attr);
 
-  retval.sect_off = 0;
   complaint (&symfile_complaints,
             _("unsupported die ref attribute form: '%s'"),
             dwarf_form_name (attr->form));
-  return retval;
+  return {};
 }
 
 /* Return the constant value held by ATTR.  Return DEFAULT_VALUE if
@@ -19879,6 +20488,7 @@ dwarf2_get_attr_constant_value (const struct attribute *attr, int default_value)
     return DW_UNSND (attr);
   else
     {
+      /* For DW_FORM_data16 see attr_form_is_constant.  */
       complaint (&symfile_complaints,
                 _("Attribute value is not a constant (%s)"),
                  dwarf_form_name (attr->form));
@@ -19916,7 +20526,7 @@ follow_die_ref_or_sig (struct die_info *src_die, const struct attribute *attr,
    Returns NULL if OFFSET is invalid.  */
 
 static struct die_info *
-follow_die_offset (sect_offset offset, int offset_in_dwz,
+follow_die_offset (sect_offset sect_off, int offset_in_dwz,
                   struct dwarf2_cu **ref_cu)
 {
   struct die_info temp_die;
@@ -19931,15 +20541,15 @@ follow_die_offset (sect_offset offset, int offset_in_dwz,
       /* .debug_types CUs cannot reference anything outside their CU.
         If they need to, they have to reference a signatured type via
         DW_FORM_ref_sig8.  */
-      if (! offset_in_cu_p (&cu->header, offset))
+      if (!offset_in_cu_p (&cu->header, sect_off))
        return NULL;
     }
   else if (offset_in_dwz != cu->per_cu->is_dwz
-          || ! offset_in_cu_p (&cu->header, offset))
+          || !offset_in_cu_p (&cu->header, sect_off))
     {
       struct dwarf2_per_cu_data *per_cu;
 
-      per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
+      per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
                                                 cu->objfile);
 
       /* If necessary, add it to the queue and load its DIEs.  */
@@ -19956,9 +20566,10 @@ follow_die_offset (sect_offset offset, int offset_in_dwz,
     }
 
   *ref_cu = target_cu;
-  temp_die.offset = offset;
+  temp_die.sect_off = sect_off;
   return (struct die_info *) htab_find_with_hash (target_cu->die_hash,
-                                                 &temp_die, offset.sect_off);
+                                                 &temp_die,
+                                                 to_underlying (sect_off));
 }
 
 /* Follow reference attribute ATTR of SRC_DIE.
@@ -19969,29 +20580,29 @@ static struct die_info *
 follow_die_ref (struct die_info *src_die, const struct attribute *attr,
                struct dwarf2_cu **ref_cu)
 {
-  sect_offset offset = dwarf2_get_ref_die_offset (attr);
+  sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
   struct dwarf2_cu *cu = *ref_cu;
   struct die_info *die;
 
-  die = follow_die_offset (offset,
+  die = follow_die_offset (sect_off,
                           (attr->form == DW_FORM_GNU_ref_alt
                            || cu->per_cu->is_dwz),
                           ref_cu);
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
           "at 0x%x [in module %s]"),
-          offset.sect_off, src_die->offset.sect_off,
+          to_underlying (sect_off), to_underlying (src_die->sect_off),
           objfile_name (cu->objfile));
 
   return die;
 }
 
-/* Return DWARF block referenced by DW_AT_location of DIE at OFFSET at PER_CU.
+/* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU.
    Returned value is intended for DW_OP_call*.  Returned
    dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE.  */
 
 struct dwarf2_locexpr_baton
-dwarf2_fetch_die_loc_sect_off (sect_offset offset,
+dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
                               struct dwarf2_per_cu_data *per_cu,
                               CORE_ADDR (*get_frame_pc) (void *baton),
                               void *baton)
@@ -20011,13 +20622,13 @@ dwarf2_fetch_die_loc_sect_off (sect_offset offset,
       /* We shouldn't get here for a dummy CU, but don't crash on the user.
         Instead just throw an error, not much else we can do.  */
       error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"),
-            offset.sect_off, objfile_name (per_cu->objfile));
+            to_underlying (sect_off), objfile_name (per_cu->objfile));
     }
 
-  die = follow_die_offset (offset, per_cu->is_dwz, &cu);
+  die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
-          offset.sect_off, objfile_name (per_cu->objfile));
+          to_underlying (sect_off), objfile_name (per_cu->objfile));
 
   attr = dwarf2_attr (die, DW_AT_location, cu);
   if (!attr)
@@ -20045,7 +20656,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset offset,
       if (!attr_form_is_block (attr))
        error (_("Dwarf Error: DIE at 0x%x referenced in module %s "
                 "is neither DW_FORM_block* nor DW_FORM_exprloc"),
-              offset.sect_off, objfile_name (per_cu->objfile));
+              to_underlying (sect_off), objfile_name (per_cu->objfile));
 
       retval.data = DW_BLOCK (attr)->data;
       retval.size = DW_BLOCK (attr)->size;
@@ -20066,9 +20677,9 @@ dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu,
                             CORE_ADDR (*get_frame_pc) (void *baton),
                             void *baton)
 {
-  sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
+  sect_offset sect_off = per_cu->sect_off + to_underlying (offset_in_cu);
 
-  return dwarf2_fetch_die_loc_sect_off (offset, per_cu, get_frame_pc, baton);
+  return dwarf2_fetch_die_loc_sect_off (sect_off, per_cu, get_frame_pc, baton);
 }
 
 /* Write a constant of a given type as target-ordered bytes into
@@ -20096,7 +20707,7 @@ write_constant_as_bytes (struct obstack *obstack,
    does not have a DW_AT_const_value, return NULL.  */
 
 const gdb_byte *
-dwarf2_fetch_constant_bytes (sect_offset offset,
+dwarf2_fetch_constant_bytes (sect_offset sect_off,
                             struct dwarf2_per_cu_data *per_cu,
                             struct obstack *obstack,
                             LONGEST *len)
@@ -20119,13 +20730,13 @@ dwarf2_fetch_constant_bytes (sect_offset offset,
       /* We shouldn't get here for a dummy CU, but don't crash on the user.
         Instead just throw an error, not much else we can do.  */
       error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"),
-            offset.sect_off, objfile_name (per_cu->objfile));
+            to_underlying (sect_off), objfile_name (per_cu->objfile));
     }
 
-  die = follow_die_offset (offset, per_cu->is_dwz, &cu);
+  die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
-          offset.sect_off, objfile_name (per_cu->objfile));
+          to_underlying (sect_off), objfile_name (per_cu->objfile));
 
 
   attr = dwarf2_attr (die, DW_AT_const_value, cu);
@@ -20162,6 +20773,7 @@ dwarf2_fetch_constant_bytes (sect_offset offset,
     case DW_FORM_block4:
     case DW_FORM_block:
     case DW_FORM_exprloc:
+    case DW_FORM_data16:
       result = DW_BLOCK (attr)->data;
       *len = DW_BLOCK (attr)->size;
       break;
@@ -20222,6 +20834,31 @@ dwarf2_fetch_constant_bytes (sect_offset offset,
   return result;
 }
 
+/* Return the type of the die at OFFSET in PER_CU.  Return NULL if no
+   valid type for this die is found.  */
+
+struct type *
+dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
+                               struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf2_cu *cu;
+  struct die_info *die;
+
+  dw2_setup (per_cu->objfile);
+
+  if (per_cu->cu == NULL)
+    load_cu (per_cu);
+  cu = per_cu->cu;
+  if (!cu)
+    return NULL;
+
+  die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
+  if (!die)
+    return NULL;
+
+  return die_type (die, cu);
+}
+
 /* Return the type of the DIE at DIE_OFFSET in the CU named by
    PER_CU.  */
 
@@ -20229,11 +20866,9 @@ struct type *
 dwarf2_get_die_type (cu_offset die_offset,
                     struct dwarf2_per_cu_data *per_cu)
 {
-  sect_offset die_offset_sect;
-
   dw2_setup (per_cu->objfile);
 
-  die_offset_sect.sect_off = per_cu->offset.sect_off + die_offset.cu_off;
+  sect_offset die_offset_sect = per_cu->sect_off + to_underlying (die_offset);
   return get_die_type_at_offset (die_offset_sect, per_cu);
 }
 
@@ -20261,10 +20896,10 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
 
   sig_cu = sig_type->per_cu.cu;
   gdb_assert (sig_cu != NULL);
-  gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
-  temp_die.offset = sig_type->type_offset_in_section;
+  gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
+  temp_die.sect_off = sig_type->type_offset_in_section;
   die = (struct die_info *) htab_find_with_hash (sig_cu->die_hash, &temp_die,
-                                                temp_die.offset.sect_off);
+                                                to_underlying (temp_die.sect_off));
   if (die)
     {
       /* For .gdb_index version 7 keep track of included TUs.
@@ -20307,7 +20942,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr,
     {
       error (_("Dwarf Error: Cannot find signatured DIE %s referenced"
                " from DIE at 0x%x [in module %s]"),
-             hex_string (signature), src_die->offset.sect_off,
+             hex_string (signature), to_underlying (src_die->sect_off),
             objfile_name ((*ref_cu)->objfile));
     }
 
@@ -20317,7 +20952,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr,
       dump_die_for_error (src_die);
       error (_("Dwarf Error: Problem reading signatured DIE %s referenced"
               " from DIE at 0x%x [in module %s]"),
-            hex_string (signature), src_die->offset.sect_off,
+            hex_string (signature), to_underlying (src_die->sect_off),
             objfile_name ((*ref_cu)->objfile));
     }
 
@@ -20344,7 +20979,7 @@ get_signatured_type (struct die_info *die, ULONGEST signature,
       complaint (&symfile_complaints,
                 _("Dwarf Error: Cannot find signatured DIE %s referenced"
                   " from DIE at 0x%x [in module %s]"),
-                hex_string (signature), die->offset.sect_off,
+                hex_string (signature), to_underlying (die->sect_off),
                 objfile_name (dwarf2_per_objfile->objfile));
       return build_error_marker_type (cu, die);
     }
@@ -20366,7 +21001,7 @@ get_signatured_type (struct die_info *die, ULONGEST signature,
          complaint (&symfile_complaints,
                     _("Dwarf Error: Cannot build signatured type %s"
                       " referenced from DIE at 0x%x [in module %s]"),
-                    hex_string (signature), die->offset.sect_off,
+                    hex_string (signature), to_underlying (die->sect_off),
                     objfile_name (dwarf2_per_objfile->objfile));
          type = build_error_marker_type (cu, die);
        }
@@ -20376,7 +21011,7 @@ get_signatured_type (struct die_info *die, ULONGEST signature,
       complaint (&symfile_complaints,
                 _("Dwarf Error: Problem reading signatured DIE %s referenced"
                   " from DIE at 0x%x [in module %s]"),
-                hex_string (signature), die->offset.sect_off,
+                hex_string (signature), to_underlying (die->sect_off),
                 objfile_name (dwarf2_per_objfile->objfile));
       type = build_error_marker_type (cu, die);
     }
@@ -20409,7 +21044,7 @@ get_DW_AT_signature_type (struct die_info *die, const struct attribute *attr,
       complaint (&symfile_complaints,
                 _("Dwarf Error: DW_AT_signature has bad form %s in DIE"
                   " at 0x%x [in module %s]"),
-                dwarf_form_name (attr->form), die->offset.sect_off,
+                dwarf_form_name (attr->form), to_underlying (die->sect_off),
                 objfile_name (dwarf2_per_objfile->objfile));
       return build_error_marker_type (cu, die);
     }
@@ -20790,15 +21425,17 @@ file_file_name (int file, struct line_header *lh)
 {
   /* Is the file number a valid index into the line header's file name
      table?  Remember that file numbers start with one, not zero.  */
-  if (1 <= file && file <= lh->num_file_names)
+  if (1 <= file && file <= lh->file_names.size ())
     {
-      struct file_entry *fe = &lh->file_names[file - 1];
+      const file_entry &fe = lh->file_names[file - 1];
 
-      if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0
-         || lh->include_dirs == NULL)
-        return xstrdup (fe->name);
-      return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING,
-                    fe->name, (char *) NULL);
+      if (!IS_ABSOLUTE_PATH (fe.name))
+       {
+         const char *dir = fe.include_dir (lh);
+         if (dir != NULL)
+           return concat (dir, SLASH_STRING, fe.name, (char *) NULL);
+       }
+      return xstrdup (fe.name);
     }
   else
     {
@@ -20827,7 +21464,7 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir)
 {
   /* Is the file number a valid index into the line header's file name
      table?  Remember that file numbers start with one, not zero.  */
-  if (1 <= file && file <= lh->num_file_names)
+  if (1 <= file && file <= lh->file_names.size ())
     {
       char *relative = file_file_name (file, lh);
 
@@ -21070,6 +21707,10 @@ skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
       bytes += 8;
       break;
 
+    case DW_FORM_data16:
+      bytes += 16;
+      break;
+
     case DW_FORM_string:
       read_direct_string (abfd, bytes, &bytes_read);
       bytes += bytes_read;
@@ -21183,7 +21824,7 @@ dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
       unsigned int version, flags;
 
       version = read_2_bytes (abfd, mac_ptr);
-      if (version != 4)
+      if (version != 4 && version != 5)
        {
          complaint (&symfile_complaints,
                     _("unrecognized version `%d' in .debug_macro section"),
@@ -21226,7 +21867,7 @@ dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
 }
 
 /* A helper for dwarf_decode_macros that handles the GNU extensions,
-   including DW_MACRO_GNU_transparent_include.  */
+   including DW_MACRO_import.  */
 
 static void
 dwarf_decode_macro_bytes (bfd *abfd,
@@ -21281,12 +21922,12 @@ dwarf_decode_macro_bytes (bfd *abfd,
        case 0:
          break;
 
-        case DW_MACRO_GNU_define:
-        case DW_MACRO_GNU_undef:
-       case DW_MACRO_GNU_define_indirect:
-       case DW_MACRO_GNU_undef_indirect:
-       case DW_MACRO_GNU_define_indirect_alt:
-       case DW_MACRO_GNU_undef_indirect_alt:
+        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;
@@ -21296,8 +21937,8 @@ dwarf_decode_macro_bytes (bfd *abfd,
            line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
            mac_ptr += bytes_read;
 
-           if (macinfo_type == DW_MACRO_GNU_define
-               || macinfo_type == DW_MACRO_GNU_undef)
+           if (macinfo_type == DW_MACRO_define
+               || macinfo_type == DW_MACRO_undef)
              {
                body = read_direct_string (abfd, mac_ptr, &bytes_read);
                mac_ptr += bytes_read;
@@ -21309,8 +21950,8 @@ dwarf_decode_macro_bytes (bfd *abfd,
                str_offset = read_offset_1 (abfd, mac_ptr, offset_size);
                mac_ptr += offset_size;
 
-               if (macinfo_type == DW_MACRO_GNU_define_indirect_alt
-                   || macinfo_type == DW_MACRO_GNU_undef_indirect_alt
+               if (macinfo_type == DW_MACRO_define_sup
+                   || macinfo_type == DW_MACRO_undef_sup
                    || section_is_dwz)
                  {
                    struct dwz_file *dwz = dwarf2_get_dwz_file ();
@@ -21321,9 +21962,9 @@ dwarf_decode_macro_bytes (bfd *abfd,
                  body = read_indirect_string_at_offset (abfd, str_offset);
              }
 
-           is_define = (macinfo_type == DW_MACRO_GNU_define
-                        || macinfo_type == DW_MACRO_GNU_define_indirect
-                        || macinfo_type == DW_MACRO_GNU_define_indirect_alt);
+           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.  */
@@ -21346,15 +21987,15 @@ dwarf_decode_macro_bytes (bfd *abfd,
              parse_macro_definition (current_file, line, body);
            else
              {
-               gdb_assert (macinfo_type == DW_MACRO_GNU_undef
-                           || macinfo_type == DW_MACRO_GNU_undef_indirect
-                           || macinfo_type == DW_MACRO_GNU_undef_indirect_alt);
+               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_GNU_start_file:
+        case DW_MACRO_start_file:
           {
             unsigned int bytes_read;
             int line, file;
@@ -21374,7 +22015,7 @@ dwarf_decode_macro_bytes (bfd *abfd,
 
            if (at_commandline)
              {
-               /* This DW_MACRO_GNU_start_file was executed in the
+               /* This DW_MACRO_start_file was executed in the
                   pass one.  */
                at_commandline = 0;
              }
@@ -21383,7 +22024,7 @@ dwarf_decode_macro_bytes (bfd *abfd,
           }
           break;
 
-        case DW_MACRO_GNU_end_file:
+        case DW_MACRO_end_file:
           if (! current_file)
            complaint (&symfile_complaints,
                       _("macro debug info has an unmatched "
@@ -21422,8 +22063,8 @@ dwarf_decode_macro_bytes (bfd *abfd,
             }
           break;
 
-       case DW_MACRO_GNU_transparent_include:
-       case DW_MACRO_GNU_transparent_include_alt:
+       case DW_MACRO_import:
+       case DW_MACRO_import_sup:
          {
            LONGEST offset;
            void **slot;
@@ -21436,7 +22077,7 @@ dwarf_decode_macro_bytes (bfd *abfd,
            offset = read_offset_1 (abfd, mac_ptr, offset_size);
            mac_ptr += offset_size;
 
-           if (macinfo_type == DW_MACRO_GNU_transparent_include_alt)
+           if (macinfo_type == DW_MACRO_import_sup)
              {
                struct dwz_file *dwz = dwarf2_get_dwz_file ();
 
@@ -21456,7 +22097,7 @@ dwarf_decode_macro_bytes (bfd *abfd,
                /* This has actually happened; see
                   http://sourceware.org/bugzilla/show_bug.cgi?id=13568.  */
                complaint (&symfile_complaints,
-                          _("recursive DW_MACRO_GNU_transparent_include in "
+                          _("recursive DW_MACRO_import in "
                             ".debug_macro section"));
              }
            else
@@ -21598,8 +22239,8 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
         case 0:
          break;
 
-       case DW_MACRO_GNU_define:
-       case DW_MACRO_GNU_undef:
+       case DW_MACRO_define:
+       case DW_MACRO_undef:
          /* Only skip the data by MAC_PTR.  */
          {
            unsigned int bytes_read;
@@ -21611,7 +22252,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
          }
          break;
 
-       case DW_MACRO_GNU_start_file:
+       case DW_MACRO_start_file:
          {
            unsigned int bytes_read;
            int line, file;
@@ -21625,14 +22266,14 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
          }
          break;
 
-       case DW_MACRO_GNU_end_file:
+       case DW_MACRO_end_file:
          /* No data to skip by MAC_PTR.  */
          break;
 
-       case DW_MACRO_GNU_define_indirect:
-       case DW_MACRO_GNU_undef_indirect:
-       case DW_MACRO_GNU_define_indirect_alt:
-       case DW_MACRO_GNU_undef_indirect_alt:
+       case DW_MACRO_define_strp:
+       case DW_MACRO_undef_strp:
+       case DW_MACRO_define_sup:
+       case DW_MACRO_undef_sup:
          {
            unsigned int bytes_read;
 
@@ -21642,10 +22283,10 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
          }
          break;
 
-       case DW_MACRO_GNU_transparent_include:
-       case DW_MACRO_GNU_transparent_include_alt:
+       case DW_MACRO_import:
+       case DW_MACRO_import_sup:
          /* Note that, according to the spec, a transparent include
-            chain cannot call DW_MACRO_GNU_start_file.  So, we can just
+            chain cannot call DW_MACRO_start_file.  So, we can just
             skip this opcode.  */
          mac_ptr += offset_size;
          break;
@@ -21733,7 +22374,10 @@ attr_form_is_section_offset (const struct attribute *attr)
    (lineptr, loclistptr, macptr or rangelistptr).  The DWARF spec says
    that, if an attribute's can be either a constant or one of the
    section offset classes, DW_FORM_data4 and DW_FORM_data8 should be
-   taken as section offsets, not constants.  */
+   taken as section offsets, not constants.
+
+   DW_FORM_data16 is not considered as dwarf2_get_attr_constant_value
+   cannot handle that.  */
 
 static int
 attr_form_is_constant (const struct attribute *attr)
@@ -21781,8 +22425,13 @@ static struct dwarf2_section_info *
 cu_debug_loc_section (struct dwarf2_cu *cu)
 {
   if (cu->dwo_unit)
-    return &cu->dwo_unit->dwo_file->sections.loc;
-  return &dwarf2_per_objfile->loc;
+    {
+      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.  */
@@ -21897,10 +22546,11 @@ per_cu_header_read_in (struct comp_unit_head *cu_headerp,
   if (per_cu->cu)
     return &per_cu->cu->header;
 
-  info_ptr = per_cu->section->buffer + per_cu->offset.sect_off;
+  info_ptr = per_cu->section->buffer + to_underlying (per_cu->sect_off);
 
   memset (cu_headerp, 0, sizeof (*cu_headerp));
-  read_comp_unit_head (cu_headerp, info_ptr, per_cu->objfile->obfd);
+  read_comp_unit_head (cu_headerp, info_ptr, per_cu->section,
+                      rcuh_kind::COMPILE);
 
   return cu_headerp;
 }
@@ -21960,11 +22610,19 @@ dwarf2_per_cu_text_offset (struct dwarf2_per_cu_data *per_cu)
   return ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 }
 
+/* Return DWARF version number of PER_CU.  */
+
+short
+dwarf2_version (struct dwarf2_per_cu_data *per_cu)
+{
+  return per_cu->dwarf_version;
+}
+
 /* 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 offset,
+dwarf2_find_containing_comp_unit (sect_offset sect_off,
                                  unsigned int offset_in_dwz,
                                  struct objfile *objfile)
 {
@@ -21980,35 +22638,34 @@ dwarf2_find_containing_comp_unit (sect_offset offset,
       int mid = low + (high - low) / 2;
 
       mid_cu = dwarf2_per_objfile->all_comp_units[mid];
-      cu_off = &mid_cu->offset;
+      cu_off = &mid_cu->sect_off;
       if (mid_cu->is_dwz > offset_in_dwz
-         || (mid_cu->is_dwz == offset_in_dwz
-             && cu_off->sect_off >= offset.sect_off))
+         || (mid_cu->is_dwz == offset_in_dwz && *cu_off >= sect_off))
        high = mid;
       else
        low = mid + 1;
     }
   gdb_assert (low == high);
   this_cu = dwarf2_per_objfile->all_comp_units[low];
-  cu_off = &this_cu->offset;
-  if (this_cu->is_dwz != offset_in_dwz || cu_off->sect_off > offset.sect_off)
+  cu_off = &this_cu->sect_off;
+  if (this_cu->is_dwz != offset_in_dwz || *cu_off > sect_off)
     {
       if (low == 0 || this_cu->is_dwz != offset_in_dwz)
        error (_("Dwarf Error: could not find partial DIE containing "
-              "offset 0x%lx [in module %s]"),
-              (long) offset.sect_off, bfd_get_filename (objfile->obfd));
+              "offset 0x%x [in module %s]"),
+              to_underlying (sect_off), bfd_get_filename (objfile->obfd));
 
-      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.sect_off
-                 <= offset.sect_off);
+      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->sect_off
+                 <= sect_off);
       return dwarf2_per_objfile->all_comp_units[low-1];
     }
   else
     {
       this_cu = dwarf2_per_objfile->all_comp_units[low];
       if (low == dwarf2_per_objfile->n_comp_units - 1
-         && offset.sect_off >= this_cu->offset.sect_off + this_cu->length)
-       error (_("invalid dwarf2 offset %u"), offset.sect_off);
-      gdb_assert (offset.sect_off < this_cu->offset.sect_off + this_cu->length);
+         && sect_off >= this_cu->sect_off + this_cu->length)
+       error (_("invalid dwarf2 offset %u"), to_underlying (sect_off));
+      gdb_assert (sect_off < this_cu->sect_off + this_cu->length);
       return this_cu;
     }
 }
@@ -22213,7 +22870,7 @@ dwarf2_free_objfile (struct objfile *objfile)
 struct dwarf2_per_cu_offset_and_type
 {
   const struct dwarf2_per_cu_data *per_cu;
-  sect_offset offset;
+  sect_offset sect_off;
   struct type *type;
 };
 
@@ -22225,7 +22882,7 @@ per_cu_offset_and_type_hash (const void *item)
   const struct dwarf2_per_cu_offset_and_type *ofs
     = (const struct dwarf2_per_cu_offset_and_type *) item;
 
-  return (uintptr_t) ofs->per_cu + ofs->offset.sect_off;
+  return (uintptr_t) ofs->per_cu + to_underlying (ofs->sect_off);
 }
 
 /* Equality function for a dwarf2_per_cu_offset_and_type.  */
@@ -22239,7 +22896,7 @@ per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs)
     = (const struct dwarf2_per_cu_offset_and_type *) item_rhs;
 
   return (ofs_lhs->per_cu == ofs_rhs->per_cu
-         && ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off);
+         && ofs_lhs->sect_off == ofs_rhs->sect_off);
 }
 
 /* Set the type associated with DIE to TYPE.  Save it in CU's hash
@@ -22294,9 +22951,9 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   else if (attr != NULL)
     {
       complaint (&symfile_complaints,
-                _("DW_AT_allocated has the wrong form (%s) at DIE 0x%x"),
-                (attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
-                die->offset.sect_off);
+                _("DW_AT_allocated has the wrong form (%s) at DIE 0x%x"),
+                (attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
+                to_underlying (die->sect_off));
     }
 
   /* Read DW_AT_associated and set in type.  */
@@ -22309,9 +22966,9 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   else if (attr != NULL)
     {
       complaint (&symfile_complaints,
-                _("DW_AT_associated has the wrong form (%s) at DIE 0x%x"),
-                (attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
-                die->offset.sect_off);
+                _("DW_AT_associated has the wrong form (%s) at DIE 0x%x"),
+                (attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
+                to_underlying (die->sect_off));
     }
 
   /* Read DW_AT_data_location and set in type.  */
@@ -22332,25 +22989,25 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
     }
 
   ofs.per_cu = cu->per_cu;
-  ofs.offset = die->offset;
+  ofs.sect_off = die->sect_off;
   ofs.type = type;
   slot = (struct dwarf2_per_cu_offset_and_type **)
     htab_find_slot (dwarf2_per_objfile->die_type_hash, &ofs, INSERT);
   if (*slot)
     complaint (&symfile_complaints,
               _("A problem internal to GDB: DIE 0x%x has type already set"),
-              die->offset.sect_off);
+              to_underlying (die->sect_off));
   *slot = XOBNEW (&objfile->objfile_obstack,
                  struct dwarf2_per_cu_offset_and_type);
   **slot = ofs;
   return type;
 }
 
-/* Look up the type for the die at OFFSET in PER_CU in die_type_hash,
+/* Look up the type for the die at SECT_OFF in PER_CU in die_type_hash,
    or return NULL if the die does not have a saved type.  */
 
 static struct type *
-get_die_type_at_offset (sect_offset offset,
+get_die_type_at_offset (sect_offset sect_off,
                        struct dwarf2_per_cu_data *per_cu)
 {
   struct dwarf2_per_cu_offset_and_type *slot, ofs;
@@ -22359,7 +23016,7 @@ get_die_type_at_offset (sect_offset offset,
     return NULL;
 
   ofs.per_cu = per_cu;
-  ofs.offset = offset;
+  ofs.sect_off = sect_off;
   slot = ((struct dwarf2_per_cu_offset_and_type *)
          htab_find (dwarf2_per_objfile->die_type_hash, &ofs));
   if (slot)
@@ -22374,7 +23031,7 @@ get_die_type_at_offset (sect_offset offset,
 static struct type *
 get_die_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  return get_die_type_at_offset (die->offset, cu->per_cu);
+  return get_die_type_at_offset (die->sect_off, cu->per_cu);
 }
 
 /* Add a dependence relationship from CU to REF_PER_CU.  */
@@ -22456,7 +23113,7 @@ partial_die_hash (const void *item)
   const struct partial_die_info *part_die
     = (const struct partial_die_info *) item;
 
-  return part_die->offset.sect_off;
+  return to_underlying (part_die->sect_off);
 }
 
 /* Trivial comparison function for partial_die_info structures: two DIEs
@@ -22470,7 +23127,7 @@ partial_die_eq (const void *item_lhs, const void *item_rhs)
   const struct partial_die_info *part_die_rhs
     = (const struct partial_die_info *) item_rhs;
 
-  return part_die_lhs->offset.sect_off == part_die_rhs->offset.sect_off;
+  return part_die_lhs->sect_off == part_die_rhs->sect_off;
 }
 
 static struct cmd_list_element *set_dwarf_cmdlist;
@@ -23151,10 +23808,10 @@ write_one_signatured_type (void **slot, void *d)
                  1);
 
   store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
-                         entry->per_cu.offset.sect_off);
+                         to_underlying (entry->per_cu.sect_off));
   obstack_grow (info->types_list, val, 8);
   store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
-                         entry->type_offset_in_tu.cu_off);
+                         to_underlying (entry->type_offset_in_tu));
   obstack_grow (info->types_list, val, 8);
   store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature);
   obstack_grow (info->types_list, val, 8);
@@ -23290,7 +23947,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
       *slot = map;
 
       store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
-                             per_cu->offset.sect_off);
+                             to_underlying (per_cu->sect_off));
       obstack_grow (&cu_list, val, 8);
       store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->length);
       obstack_grow (&cu_list, val, 8);
This page took 0.11271 seconds and 4 git commands to generate.