Use an accessor function for general_symbol_info::language
[deliverable/binutils-gdb.git] / gdb / dwarf-index-write.c
index 058712d9e22d0b3fa44f583e3624128aeebfcd91..66c2368b9c14d244b600b18b578e3e40da0a247c 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF index writing support for GDB.
 
 /* DWARF index writing support for GDB.
 
-   Copyright (C) 1994-2018 Free Software Foundation, Inc.
+   Copyright (C) 1994-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
 
 #include "defs.h"
 
 
 #include "defs.h"
 
+#include "dwarf-index-write.h"
+
 #include "addrmap.h"
 #include "cli/cli-decode.h"
 #include "addrmap.h"
 #include "cli/cli-decode.h"
-#include "common/byte-vector.h"
-#include "common/filestuff.h"
-#include "common/gdb_unlinker.h"
+#include "gdbsupport/byte-vector.h"
+#include "gdbsupport/filestuff.h"
+#include "gdbsupport/gdb_unlinker.h"
+#include "gdbsupport/pathstuff.h"
+#include "gdbsupport/scoped_fd.h"
 #include "complaints.h"
 #include "dwarf-index-common.h"
 #include "dwarf2.h"
 #include "complaints.h"
 #include "dwarf-index-common.h"
 #include "dwarf2.h"
@@ -32,6 +36,7 @@
 #include "gdbcmd.h"
 #include "objfiles.h"
 #include "psympriv.h"
 #include "gdbcmd.h"
 #include "objfiles.h"
 #include "psympriv.h"
+#include "ada-lang.h"
 
 #include <algorithm>
 #include <cmath>
 
 #include <algorithm>
 #include <cmath>
 #include <unordered_map>
 #include <unordered_set>
 
 #include <unordered_map>
 #include <unordered_set>
 
-/* The suffix for an index file.  */
-#define INDEX4_SUFFIX ".gdb-index"
-#define INDEX5_SUFFIX ".debug_names"
-#define DEBUG_STR_SUFFIX ".debug_str"
-
 /* Ensure only legit values are used.  */
 #define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \
   do { \
 /* Ensure only legit values are used.  */
 #define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \
   do { \
@@ -59,7 +59,7 @@
     GDB_INDEX_SYMBOL_KIND_SET_VALUE((cu_index), (value)); \
   } while (0)
 
     GDB_INDEX_SYMBOL_KIND_SET_VALUE((cu_index), (value)); \
   } while (0)
 
-/* Ensure we don't use more than the alloted nuber of bits for the CU.  */
+/* Ensure we don't use more than the allotted number of bits for the CU.  */
 #define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value) \
   do { \
     gdb_assert (((value) & ~GDB_INDEX_CU_MASK) == 0); \
 #define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value) \
   do { \
     gdb_assert (((value) & ~GDB_INDEX_CU_MASK) == 0); \
@@ -84,7 +84,8 @@ template<typename Elem, typename Alloc>
 static void
 file_write (FILE *file, const std::vector<Elem, Alloc> &vec)
 {
 static void
 file_write (FILE *file, const std::vector<Elem, Alloc> &vec)
 {
-  file_write (file, vec.data (), vec.size () * sizeof (vec[0]));
+  if (!vec.empty ())
+    file_write (file, vec.data (), vec.size () * sizeof (vec[0]));
 }
 
 /* In-memory buffer to prepare data to be written later to a file.  */
 }
 
 /* In-memory buffer to prepare data to be written later to a file.  */
@@ -154,7 +155,7 @@ private:
   gdb_byte *grow (size_t size)
   {
     m_vec.resize (m_vec.size () + size);
   gdb_byte *grow (size_t size)
   {
     m_vec.resize (m_vec.size () + size);
-    return &*m_vec.end () - size;
+    return &*(m_vec.end () - size);
   }
 
   gdb::byte_vector m_vec;
   }
 
   gdb::byte_vector m_vec;
@@ -258,7 +259,7 @@ add_index_entry (struct mapped_symtab *symtab, const char *name,
      (which would allow us to avoid the duplication by only having to check
      the last entry pushed), but a symbol could have multiple kinds in one CU.
      To keep things simple we don't worry about the duplication here and
      (which would allow us to avoid the duplication by only having to check
      the last entry pushed), but a symbol could have multiple kinds in one CU.
      To keep things simple we don't worry about the duplication here and
-     sort and uniqufy the list after we've processed all symbols.  */
+     sort and uniquify the list after we've processed all symbols.  */
   slot.cu_indices.push_back (cu_index_and_attrs);
 }
 
   slot.cu_indices.push_back (cu_index_and_attrs);
 }
 
@@ -427,12 +428,8 @@ static void
 add_address_entry (struct objfile *objfile, data_buf &addr_vec,
                   CORE_ADDR start, CORE_ADDR end, unsigned int cu_index)
 {
 add_address_entry (struct objfile *objfile, data_buf &addr_vec,
                   CORE_ADDR start, CORE_ADDR end, unsigned int cu_index)
 {
-  CORE_ADDR baseaddr;
-
-  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-
-  addr_vec.append_uint (8, BFD_ENDIAN_LITTLE, start - baseaddr);
-  addr_vec.append_uint (8, BFD_ENDIAN_LITTLE, end - baseaddr);
+  addr_vec.append_uint (8, BFD_ENDIAN_LITTLE, start);
+  addr_vec.append_uint (8, BFD_ENDIAN_LITTLE, end);
   addr_vec.append_data (MAYBE_SWAP (cu_index));
 }
 
   addr_vec.append_data (MAYBE_SWAP (cu_index));
 }
 
@@ -480,8 +477,8 @@ write_address_map (struct objfile *objfile, data_buf &addr_vec,
   addrmap_index_data.objfile = objfile;
   addrmap_index_data.previous_valid = 0;
 
   addrmap_index_data.objfile = objfile;
   addrmap_index_data.previous_valid = 0;
 
-  addrmap_foreach (objfile->psymtabs_addrmap, add_address_entry_worker,
-                  &addrmap_index_data);
+  addrmap_foreach (objfile->partial_symtabs->psymtabs_addrmap,
+                  add_address_entry_worker, &addrmap_index_data);
 
   /* It's highly unlikely the last entry (end address = 0xff...ff)
      is valid, but we should still handle it.
 
   /* It's highly unlikely the last entry (end address = 0xff...ff)
      is valid, but we should still handle it.
@@ -499,8 +496,8 @@ write_address_map (struct objfile *objfile, data_buf &addr_vec,
 static gdb_index_symbol_kind
 symbol_kind (struct partial_symbol *psym)
 {
 static gdb_index_symbol_kind
 symbol_kind (struct partial_symbol *psym)
 {
-  domain_enum domain = PSYMBOL_DOMAIN (psym);
-  enum address_class aclass = PSYMBOL_CLASS (psym);
+  domain_enum domain = psym->domain;
+  enum address_class aclass = psym->aclass;
 
   switch (domain)
     {
 
   switch (domain)
     {
@@ -546,15 +543,16 @@ write_psymbols (struct mapped_symtab *symtab,
     {
       struct partial_symbol *psym = *psymp;
 
     {
       struct partial_symbol *psym = *psymp;
 
-      if (SYMBOL_LANGUAGE (psym) == language_ada)
-       error (_("Ada is not currently supported by the index"));
+      if (psym->ginfo.language () == language_ada)
+       error (_("Ada is not currently supported by the index; "
+                "use the DWARF 5 index instead"));
 
       /* Only add a given psymbol once.  */
       if (psyms_seen.insert (psym).second)
        {
          gdb_index_symbol_kind kind = symbol_kind (psym);
 
 
       /* Only add a given psymbol once.  */
       if (psyms_seen.insert (psym).second)
        {
          gdb_index_symbol_kind kind = symbol_kind (psym);
 
-         add_index_entry (symtab, SYMBOL_SEARCH_NAME (psym),
+         add_index_entry (symtab, psym->ginfo.search_name (),
                           is_static, kind, cu_index);
        }
     }
                           is_static, kind, cu_index);
        }
     }
@@ -588,12 +586,14 @@ write_one_signatured_type (void **slot, void *d)
 
   write_psymbols (info->symtab,
                  info->psyms_seen,
 
   write_psymbols (info->symtab,
                  info->psyms_seen,
-                 &info->objfile->global_psymbols[psymtab->globals_offset],
+                 (info->objfile->partial_symtabs->global_psymbols.data ()
+                  + psymtab->globals_offset),
                  psymtab->n_global_syms, info->cu_index,
                  0);
   write_psymbols (info->symtab,
                  info->psyms_seen,
                  psymtab->n_global_syms, info->cu_index,
                  0);
   write_psymbols (info->symtab,
                  info->psyms_seen,
-                 &info->objfile->static_psymbols[psymtab->statics_offset],
+                 (info->objfile->partial_symtabs->static_psymbols.data ()
+                  + psymtab->statics_offset),
                  psymtab->n_static_syms, info->cu_index,
                  1);
 
                  psymtab->n_static_syms, info->cu_index,
                  1);
 
@@ -643,12 +643,14 @@ recursively_write_psymbols (struct objfile *objfile,
 
   write_psymbols (symtab,
                  psyms_seen,
 
   write_psymbols (symtab,
                  psyms_seen,
-                 &objfile->global_psymbols[psymtab->globals_offset],
+                 (objfile->partial_symtabs->global_psymbols.data ()
+                  + psymtab->globals_offset),
                  psymtab->n_global_syms, cu_index,
                  0);
   write_psymbols (symtab,
                  psyms_seen,
                  psymtab->n_global_syms, cu_index,
                  0);
   write_psymbols (symtab,
                  psyms_seen,
-                 &objfile->static_psymbols[psymtab->statics_offset],
+                 (objfile->partial_symtabs->static_psymbols.data ()
+                  + psymtab->statics_offset),
                  psymtab->n_static_syms, cu_index,
                  1);
 }
                  psymtab->n_static_syms, cu_index,
                  1);
 }
@@ -686,7 +688,44 @@ public:
     const int dwarf_tag = psymbol_tag (psym);
     if (dwarf_tag == 0)
       return;
     const int dwarf_tag = psymbol_tag (psym);
     if (dwarf_tag == 0)
       return;
-    const char *const name = SYMBOL_SEARCH_NAME (psym);
+    const char *name = psym->ginfo.search_name ();
+
+    if (psym->ginfo.language () == language_ada)
+      {
+       /* We want to ensure that the Ada main function's name appears
+          verbatim in the index.  However, this name will be of the
+          form "_ada_mumble", and will be rewritten by ada_decode.
+          So, recognize it specially here and add it to the index by
+          hand.  */
+       if (strcmp (main_name (), name) == 0)
+         {
+           const auto insertpair
+             = m_name_to_value_set.emplace (c_str_view (name),
+                                            std::set<symbol_value> ());
+           std::set<symbol_value> &value_set = insertpair.first->second;
+           value_set.emplace (symbol_value (dwarf_tag, cu_index, is_static,
+                                            kind));
+         }
+
+       /* In order for the index to work when read back into gdb, it
+          has to supply a funny form of the name: it should be the
+          encoded name, with any suffixes stripped.  Using the
+          ordinary encoded name will not work properly with the
+          searching logic in find_name_components_bounds; nor will
+          using the decoded name.  Furthermore, an Ada "verbatim"
+          name (of the form "<MumBle>") must be entered without the
+          angle brackets.  Note that the current index is unusual,
+          see PR symtab/24820 for details.  */
+       std::string decoded = ada_decode (name);
+       if (decoded[0] == '<')
+         name = (char *) obstack_copy0 (&m_string_obstack,
+                                        decoded.c_str () + 1,
+                                        decoded.length () - 2);
+       else
+         name = obstack_strdup (&m_string_obstack,
+                                ada_encode (decoded.c_str ()));
+      }
+
     const auto insertpair
       = m_name_to_value_set.emplace (c_str_view (name),
                                     std::set<symbol_value> ());
     const auto insertpair
       = m_name_to_value_set.emplace (c_str_view (name),
                                     std::set<symbol_value> ());
@@ -839,10 +878,12 @@ public:
                                    psyms_seen, cu_index);
 
     write_psymbols (psyms_seen,
                                    psyms_seen, cu_index);
 
     write_psymbols (psyms_seen,
-                   &objfile->global_psymbols[psymtab->globals_offset],
+                   (objfile->partial_symtabs->global_psymbols.data ()
+                    + psymtab->globals_offset),
                    psymtab->n_global_syms, cu_index, false, unit_kind::cu);
     write_psymbols (psyms_seen,
                    psymtab->n_global_syms, cu_index, false, unit_kind::cu);
     write_psymbols (psyms_seen,
-                   &objfile->static_psymbols[psymtab->statics_offset],
+                   (objfile->partial_symtabs->static_psymbols.data ()
+                    + psymtab->statics_offset),
                    psymtab->n_static_syms, cu_index, true, unit_kind::cu);
   }
 
                    psymtab->n_static_syms, cu_index, true, unit_kind::cu);
   }
 
@@ -912,7 +953,7 @@ private:
   {
   public:
 
   {
   public:
 
-    /* Object costructor to be called for current DWARF2_PER_OBJFILE.
+    /* Object constructor to be called for current DWARF2_PER_OBJFILE.
        All .debug_str section strings are automatically stored.  */
     debug_str_lookup (struct dwarf2_per_objfile *dwarf2_per_objfile)
       : m_abfd (dwarf2_per_objfile->objfile->obfd),
        All .debug_str section strings are automatically stored.  */
     debug_str_lookup (struct dwarf2_per_objfile *dwarf2_per_objfile)
       : m_abfd (dwarf2_per_objfile->objfile->obfd),
@@ -931,8 +972,7 @@ private:
            = m_str_table.emplace (c_str_view (s),
                                   data - dwarf2_per_objfile->str.buffer);
          if (!insertpair.second)
            = m_str_table.emplace (c_str_view (s),
                                   data - dwarf2_per_objfile->str.buffer);
          if (!insertpair.second)
-           complaint (&symfile_complaints,
-                      _("Duplicate string \"%s\" in "
+           complaint (_("Duplicate string \"%s\" in "
                         ".debug_str section [in module %s]"),
                       s, bfd_get_filename (m_abfd));
          data += strlen (s) + 1;
                         ".debug_str section [in module %s]"),
                       s, bfd_get_filename (m_abfd));
          data += strlen (s) + 1;
@@ -1140,8 +1180,8 @@ private:
      GDB as a DWARF-5 index consumer.  */
   static int psymbol_tag (const struct partial_symbol *psym)
   {
      GDB as a DWARF-5 index consumer.  */
   static int psymbol_tag (const struct partial_symbol *psym)
   {
-    domain_enum domain = PSYMBOL_DOMAIN (psym);
-    enum address_class aclass = PSYMBOL_CLASS (psym);
+    domain_enum domain = psym->domain;
+    enum address_class aclass = psym->aclass;
 
     switch (domain)
       {
 
     switch (domain)
       {
@@ -1182,9 +1222,6 @@ private:
       {
        struct partial_symbol *psym = *psymp;
 
       {
        struct partial_symbol *psym = *psymp;
 
-       if (SYMBOL_LANGUAGE (psym) == language_ada)
-         error (_("Ada is not currently supported by the index"));
-
        /* Only add a given psymbol once.  */
        if (psyms_seen.insert (psym).second)
          insert (psym, cu_index, is_static, kind);
        /* Only add a given psymbol once.  */
        if (psyms_seen.insert (psym).second)
          insert (psym, cu_index, is_static, kind);
@@ -1200,11 +1237,13 @@ private:
     struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
 
     write_psymbols (info->psyms_seen,
     struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
 
     write_psymbols (info->psyms_seen,
-                   &info->objfile->global_psymbols[psymtab->globals_offset],
+                   (info->objfile->partial_symtabs->global_psymbols.data ()
+                    + psymtab->globals_offset),
                    psymtab->n_global_syms, info->cu_index, false,
                    unit_kind::tu);
     write_psymbols (info->psyms_seen,
                    psymtab->n_global_syms, info->cu_index, false,
                    unit_kind::tu);
     write_psymbols (info->psyms_seen,
-                   &info->objfile->static_psymbols[psymtab->statics_offset],
+                   (info->objfile->partial_symtabs->static_psymbols.data ()
+                    + psymtab->statics_offset),
                    psymtab->n_static_syms, info->cu_index, true,
                    unit_kind::tu);
 
                    psymtab->n_static_syms, info->cu_index, true,
                    unit_kind::tu);
 
@@ -1243,6 +1282,9 @@ private:
 
   /* .debug_names entry pool.  */
   data_buf m_entry_pool;
 
   /* .debug_names entry pool.  */
   data_buf m_entry_pool;
+
+  /* Temporary storage for Ada names.  */
+  auto_obstack m_string_obstack;
 };
 
 /* Return iff any of the needed offsets does not fit into 32-bit
 };
 
 /* Return iff any of the needed offsets does not fit into 32-bit
@@ -1251,17 +1293,14 @@ private:
 static bool
 check_dwarf64_offsets (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
 static bool
 check_dwarf64_offsets (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
     {
     {
-      const dwarf2_per_cu_data &per_cu = *dwarf2_per_objfile->all_comp_units[i];
-
-      if (to_underlying (per_cu.sect_off) >= (static_cast<uint64_t> (1) << 32))
+      if (to_underlying (per_cu->sect_off) >= (static_cast<uint64_t> (1) << 32))
        return true;
     }
        return true;
     }
-  for (int i = 0; i < dwarf2_per_objfile->n_type_units; ++i)
+  for (const signatured_type *sigtype : dwarf2_per_objfile->all_type_units)
     {
     {
-      const signatured_type &sigtype = *dwarf2_per_objfile->all_type_units[i];
-      const dwarf2_per_cu_data &per_cu = sigtype.per_cu;
+      const dwarf2_per_cu_data &per_cu = sigtype->per_cu;
 
       if (to_underlying (per_cu.sect_off) >= (static_cast<uint64_t> (1) << 32))
        return true;
 
       if (to_underlying (per_cu.sect_off) >= (static_cast<uint64_t> (1) << 32))
        return true;
@@ -1279,10 +1318,8 @@ static size_t
 psyms_seen_size (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   size_t psyms_count = 0;
 psyms_seen_size (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   size_t psyms_count = 0;
-  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
     {
     {
-      struct dwarf2_per_cu_data *per_cu
-       = dwarf2_per_objfile->all_comp_units[i];
       struct partial_symtab *psymtab = per_cu->v.psymtab;
 
       if (psymtab != NULL && psymtab->user == NULL)
       struct partial_symtab *psymtab = per_cu->v.psymtab;
 
       if (psymtab != NULL && psymtab->user == NULL)
@@ -1293,22 +1330,88 @@ psyms_seen_size (struct dwarf2_per_objfile *dwarf2_per_objfile)
   return psyms_count / 4;
 }
 
   return psyms_count / 4;
 }
 
-/* Write new .gdb_index section for OBJFILE into OUT_FILE.
-   Return how many bytes were expected to be written into OUT_FILE.  */
+/* Assert that FILE's size is EXPECTED_SIZE.  Assumes file's seek
+   position is at the end of the file.  */
 
 
-static size_t
-write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
+static void
+assert_file_size (FILE *file, size_t expected_size)
+{
+  const auto file_size = ftell (file);
+  if (file_size == -1)
+    perror_with_name (("ftell"));
+  gdb_assert (file_size == expected_size);
+}
+
+/* Write a gdb index file to OUT_FILE from all the sections passed as
+   arguments.  */
+
+static void
+write_gdbindex_1 (FILE *out_file,
+                 const data_buf &cu_list,
+                 const data_buf &types_cu_list,
+                 const data_buf &addr_vec,
+                 const data_buf &symtab_vec,
+                 const data_buf &constant_pool)
+{
+  data_buf contents;
+  const offset_type size_of_header = 6 * sizeof (offset_type);
+  offset_type total_len = size_of_header;
+
+  /* The version number.  */
+  contents.append_data (MAYBE_SWAP (8));
+
+  /* The offset of the CU list from the start of the file.  */
+  contents.append_data (MAYBE_SWAP (total_len));
+  total_len += cu_list.size ();
+
+  /* The offset of the types CU list from the start of the file.  */
+  contents.append_data (MAYBE_SWAP (total_len));
+  total_len += types_cu_list.size ();
+
+  /* The offset of the address table from the start of the file.  */
+  contents.append_data (MAYBE_SWAP (total_len));
+  total_len += addr_vec.size ();
+
+  /* The offset of the symbol table from the start of the file.  */
+  contents.append_data (MAYBE_SWAP (total_len));
+  total_len += symtab_vec.size ();
+
+  /* The offset of the constant pool from the start of the file.  */
+  contents.append_data (MAYBE_SWAP (total_len));
+  total_len += constant_pool.size ();
+
+  gdb_assert (contents.size () == size_of_header);
+
+  contents.file_write (out_file);
+  cu_list.file_write (out_file);
+  types_cu_list.file_write (out_file);
+  addr_vec.file_write (out_file);
+  symtab_vec.file_write (out_file);
+  constant_pool.file_write (out_file);
+
+  assert_file_size (out_file, total_len);
+}
+
+/* Write contents of a .gdb_index section for OBJFILE into OUT_FILE.
+   If OBJFILE has an associated dwz file, write contents of a .gdb_index
+   section for that dwz file into DWZ_OUT_FILE.  If OBJFILE does not have an
+   associated dwz file, DWZ_OUT_FILE must be NULL.  */
+
+static void
+write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file,
+               FILE *dwz_out_file)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   mapped_symtab symtab;
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   mapped_symtab symtab;
-  data_buf cu_list;
+  data_buf objfile_cu_list;
+  data_buf dwz_cu_list;
 
   /* While we're scanning CU's create a table that maps a psymtab pointer
      (which is what addrmap records) to its index (which is what is recorded
      in the index file).  This will later be needed to write the address
      table.  */
   psym_index_map cu_index_htab;
 
   /* While we're scanning CU's create a table that maps a psymtab pointer
      (which is what addrmap records) to its index (which is what is recorded
      in the index file).  This will later be needed to write the address
      table.  */
   psym_index_map cu_index_htab;
-  cu_index_htab.reserve (dwarf2_per_objfile->n_comp_units);
+  cu_index_htab.reserve (dwarf2_per_objfile->all_comp_units.size ());
 
   /* The CU list is already sorted, so we don't need to do additional
      work here.  Also, the debug_types entries do not appear in
 
   /* The CU list is already sorted, so we don't need to do additional
      work here.  Also, the debug_types entries do not appear in
@@ -1316,7 +1419,7 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
 
   std::unordered_set<partial_symbol *> psyms_seen
     (psyms_seen_size (dwarf2_per_objfile));
 
   std::unordered_set<partial_symbol *> psyms_seen
     (psyms_seen_size (dwarf2_per_objfile));
-  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (int i = 0; i < dwarf2_per_objfile->all_comp_units.size (); ++i)
     {
       struct dwarf2_per_cu_data *per_cu
        = dwarf2_per_objfile->all_comp_units[i];
     {
       struct dwarf2_per_cu_data *per_cu
        = dwarf2_per_objfile->all_comp_units[i];
@@ -1335,6 +1438,10 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
       const auto insertpair = cu_index_htab.emplace (psymtab, i);
       gdb_assert (insertpair.second);
 
       const auto insertpair = cu_index_htab.emplace (psymtab, i);
       gdb_assert (insertpair.second);
 
+      /* The all_comp_units list contains CUs read from the objfile as well as
+        from the eventual dwz file.  We need to place the entry in the
+        corresponding index.  */
+      data_buf &cu_list = per_cu->is_dwz ? dwz_cu_list : objfile_cu_list;
       cu_list.append_uint (8, BFD_ENDIAN_LITTLE,
                           to_underlying (per_cu->sect_off));
       cu_list.append_uint (8, BFD_ENDIAN_LITTLE, per_cu->length);
       cu_list.append_uint (8, BFD_ENDIAN_LITTLE,
                           to_underlying (per_cu->sect_off));
       cu_list.append_uint (8, BFD_ENDIAN_LITTLE, per_cu->length);
@@ -1353,7 +1460,7 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
 
       sig_data.objfile = objfile;
       sig_data.symtab = &symtab;
 
       sig_data.objfile = objfile;
       sig_data.symtab = &symtab;
-      sig_data.cu_index = dwarf2_per_objfile->n_comp_units;
+      sig_data.cu_index = dwarf2_per_objfile->all_comp_units.size ();
       htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
                              write_one_signatured_type, &sig_data);
     }
       htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
                              write_one_signatured_type, &sig_data);
     }
@@ -1365,43 +1472,13 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
   data_buf symtab_vec, constant_pool;
   write_hash_table (&symtab, symtab_vec, constant_pool);
 
   data_buf symtab_vec, constant_pool;
   write_hash_table (&symtab, symtab_vec, constant_pool);
 
-  data_buf contents;
-  const offset_type size_of_contents = 6 * sizeof (offset_type);
-  offset_type total_len = size_of_contents;
+  write_gdbindex_1(out_file, objfile_cu_list, types_cu_list, addr_vec,
+                  symtab_vec, constant_pool);
 
 
-  /* The version number.  */
-  contents.append_data (MAYBE_SWAP (8));
-
-  /* The offset of the CU list from the start of the file.  */
-  contents.append_data (MAYBE_SWAP (total_len));
-  total_len += cu_list.size ();
-
-  /* The offset of the types CU list from the start of the file.  */
-  contents.append_data (MAYBE_SWAP (total_len));
-  total_len += types_cu_list.size ();
-
-  /* The offset of the address table from the start of the file.  */
-  contents.append_data (MAYBE_SWAP (total_len));
-  total_len += addr_vec.size ();
-
-  /* The offset of the symbol table from the start of the file.  */
-  contents.append_data (MAYBE_SWAP (total_len));
-  total_len += symtab_vec.size ();
-
-  /* The offset of the constant pool from the start of the file.  */
-  contents.append_data (MAYBE_SWAP (total_len));
-  total_len += constant_pool.size ();
-
-  gdb_assert (contents.size () == size_of_contents);
-
-  contents.file_write (out_file);
-  cu_list.file_write (out_file);
-  types_cu_list.file_write (out_file);
-  addr_vec.file_write (out_file);
-  symtab_vec.file_write (out_file);
-  constant_pool.file_write (out_file);
-
-  return total_len;
+  if (dwz_out_file != NULL)
+    write_gdbindex_1 (dwz_out_file, dwz_cu_list, {}, {}, {}, {});
+  else
+    gdb_assert (dwz_cu_list.empty ());
 }
 
 /* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension.  */
 }
 
 /* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension.  */
@@ -1411,7 +1488,7 @@ static const gdb_byte dwarf5_gdb_augmentation[] = { 'G', 'D', 'B', 0 };
    needed addition to .debug_str section to OUT_FILE_STR.  Return how
    many bytes were expected to be written into OUT_FILE.  */
 
    needed addition to .debug_str section to OUT_FILE_STR.  Return how
    many bytes were expected to be written into OUT_FILE.  */
 
-static size_t
+static void
 write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
                   FILE *out_file, FILE *out_file_str)
 {
 write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
                   FILE *out_file, FILE *out_file_str)
 {
@@ -1428,7 +1505,7 @@ write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
                         dwarf5_byte_order);
   std::unordered_set<partial_symbol *>
     psyms_seen (psyms_seen_size (dwarf2_per_objfile));
                         dwarf5_byte_order);
   std::unordered_set<partial_symbol *>
     psyms_seen (psyms_seen_size (dwarf2_per_objfile));
-  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (int i = 0; i < dwarf2_per_objfile->all_comp_units.size (); ++i)
     {
       const dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->all_comp_units[i];
       partial_symtab *psymtab = per_cu->v.psymtab;
     {
       const dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->all_comp_units[i];
       partial_symtab *psymtab = per_cu->v.psymtab;
@@ -1496,11 +1573,13 @@ write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
   header.append_uint (2, dwarf5_byte_order, 0);
 
   /* comp_unit_count - The number of CUs in the CU list.  */
   header.append_uint (2, dwarf5_byte_order, 0);
 
   /* comp_unit_count - The number of CUs in the CU list.  */
-  header.append_uint (4, dwarf5_byte_order, dwarf2_per_objfile->n_comp_units);
+  header.append_uint (4, dwarf5_byte_order,
+                     dwarf2_per_objfile->all_comp_units.size ());
 
   /* local_type_unit_count - The number of TUs in the local TU
      list.  */
 
   /* local_type_unit_count - The number of TUs in the local TU
      list.  */
-  header.append_uint (4, dwarf5_byte_order, dwarf2_per_objfile->n_type_units);
+  header.append_uint (4, dwarf5_byte_order,
+                     dwarf2_per_objfile->all_type_units.size ());
 
   /* foreign_type_unit_count - The number of TUs in the foreign TU
      list.  */
 
   /* foreign_type_unit_count - The number of TUs in the foreign TU
      list.  */
@@ -1530,26 +1609,69 @@ write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
   types_cu_list.file_write (out_file);
   nametable.file_write (out_file, out_file_str);
 
   types_cu_list.file_write (out_file);
   nametable.file_write (out_file, out_file_str);
 
-  return expected_bytes;
+  assert_file_size (out_file, expected_bytes);
 }
 
 }
 
-/* Assert that FILE's size is EXPECTED_SIZE.  Assumes file's seek
-   position is at the end of the file.  */
+/* This represents an index file being written (work-in-progress).
 
 
-static void
-assert_file_size (FILE *file, const char *filename, size_t expected_size)
+   The data is initially written to a temporary file.  When the finalize method
+   is called, the file is closed and moved to its final location.
+
+   On failure (if this object is being destroyed with having called finalize),
+   the temporary file is closed and deleted.  */
+
+struct index_wip_file
 {
 {
-  const auto file_size = ftell (file);
-  if (file_size == -1)
-    error (_("Can't get `%s' size"), filename);
-  gdb_assert (file_size == expected_size);
-}
+  index_wip_file (const char *dir, const char *basename,
+                 const char *suffix)
+  {
+    filename = (std::string (dir) + SLASH_STRING + basename
+               + suffix);
 
 
-/* Create an index file for OBJFILE in the directory DIR.  */
+    filename_temp = make_temp_filename (filename);
 
 
-static void
+    scoped_fd out_file_fd (gdb_mkostemp_cloexec (filename_temp.data (),
+                                                O_BINARY));
+    if (out_file_fd.get () == -1)
+      perror_with_name (("mkstemp"));
+
+    out_file = out_file_fd.to_file ("wb");
+
+    if (out_file == nullptr)
+      error (_("Can't open `%s' for writing"), filename_temp.data ());
+
+    unlink_file.emplace (filename_temp.data ());
+  }
+
+  void finalize ()
+  {
+    /* We want to keep the file.  */
+    unlink_file->keep ();
+
+    /* Close and move the str file in place.  */
+    unlink_file.reset ();
+    if (rename (filename_temp.data (), filename.c_str ()) != 0)
+      perror_with_name (("rename"));
+  }
+
+  std::string filename;
+  gdb::char_vector filename_temp;
+
+  /* Order matters here; we want FILE to be closed before
+     FILENAME_TEMP is unlinked, because on MS-Windows one cannot
+     delete a file that is still open.  So, we wrap the unlinker in an
+     optional and emplace it once we know the file name.  */
+  gdb::optional<gdb::unlinker> unlink_file;
+
+  gdb_file_up out_file;
+};
+
+/* See dwarf-index-write.h.  */
+
+void
 write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
 write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
-                        const char *dir,
+                        const char *dir, const char *basename,
+                        const char *dwz_basename,
                         dw_index_kind index_kind)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
                         dw_index_kind index_kind)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
@@ -1557,60 +1679,44 @@ write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
   if (dwarf2_per_objfile->using_index)
     error (_("Cannot use an index to create the index"));
 
   if (dwarf2_per_objfile->using_index)
     error (_("Cannot use an index to create the index"));
 
-  if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) > 1)
+  if (dwarf2_per_objfile->types.size () > 1)
     error (_("Cannot make an index when the file has multiple .debug_types sections"));
 
     error (_("Cannot make an index when the file has multiple .debug_types sections"));
 
-  if (!objfile->psymtabs || !objfile->psymtabs_addrmap)
+  if (!objfile->partial_symtabs->psymtabs
+      || !objfile->partial_symtabs->psymtabs_addrmap)
     return;
 
   struct stat st;
   if (stat (objfile_name (objfile), &st) < 0)
     perror_with_name (objfile_name (objfile));
 
     return;
 
   struct stat st;
   if (stat (objfile_name (objfile), &st) < 0)
     perror_with_name (objfile_name (objfile));
 
-  std::string filename (std::string (dir) + SLASH_STRING
-                       + lbasename (objfile_name (objfile))
-                       + (index_kind == dw_index_kind::DEBUG_NAMES
-                          ? INDEX5_SUFFIX : INDEX4_SUFFIX));
+  const char *index_suffix = (index_kind == dw_index_kind::DEBUG_NAMES
+                             ? INDEX5_SUFFIX : INDEX4_SUFFIX);
 
 
-  FILE *out_file = gdb_fopen_cloexec (filename.c_str (), "wb").release ();
-  if (!out_file)
-    error (_("Can't open `%s' for writing"), filename.c_str ());
+  index_wip_file objfile_index_wip (dir, basename, index_suffix);
+  gdb::optional<index_wip_file> dwz_index_wip;
 
 
-  /* Order matters here; we want FILE to be closed before FILENAME is
-     unlinked, because on MS-Windows one cannot delete a file that is
-     still open.  (Don't call anything here that might throw until
-     file_closer is created.)  */
-  gdb::unlinker unlink_file (filename.c_str ());
-  gdb_file_up close_out_file (out_file);
+  if (dwz_basename != NULL)
+      dwz_index_wip.emplace (dir, dwz_basename, index_suffix);
 
   if (index_kind == dw_index_kind::DEBUG_NAMES)
     {
 
   if (index_kind == dw_index_kind::DEBUG_NAMES)
     {
-      std::string filename_str (std::string (dir) + SLASH_STRING
-                               + lbasename (objfile_name (objfile))
-                               + DEBUG_STR_SUFFIX);
-      FILE *out_file_str
-       = gdb_fopen_cloexec (filename_str.c_str (), "wb").release ();
-      if (!out_file_str)
-       error (_("Can't open `%s' for writing"), filename_str.c_str ());
-      gdb::unlinker unlink_file_str (filename_str.c_str ());
-      gdb_file_up close_out_file_str (out_file_str);
-
-      const size_t total_len
-       = write_debug_names (dwarf2_per_objfile, out_file, out_file_str);
-      assert_file_size (out_file, filename.c_str (), total_len);
-
-      /* We want to keep the file .debug_str file too.  */
-      unlink_file_str.keep ();
+      index_wip_file str_wip_file (dir, basename, DEBUG_STR_SUFFIX);
+
+      write_debug_names (dwarf2_per_objfile, objfile_index_wip.out_file.get (),
+                        str_wip_file.out_file.get ());
+
+      str_wip_file.finalize ();
     }
   else
     }
   else
-    {
-      const size_t total_len
-       = write_gdbindex (dwarf2_per_objfile, out_file);
-      assert_file_size (out_file, filename.c_str (), total_len);
-    }
+    write_gdbindex (dwarf2_per_objfile, objfile_index_wip.out_file.get (),
+                   (dwz_index_wip.has_value ()
+                    ? dwz_index_wip->out_file.get () : NULL));
+
+  objfile_index_wip.finalize ();
 
 
-  /* We want to keep the file.  */
-  unlink_file.keep ();
+  if (dwz_index_wip.has_value ())
+    dwz_index_wip->finalize ();
 }
 
 /* Implementation of the `save gdb-index' command.
 }
 
 /* Implementation of the `save gdb-index' command.
@@ -1622,7 +1728,6 @@ write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
 static void
 save_gdb_index_command (const char *arg, int from_tty)
 {
 static void
 save_gdb_index_command (const char *arg, int from_tty)
 {
-  struct objfile *objfile;
   const char dwarf5space[] = "-dwarf-5 ";
   dw_index_kind index_kind = dw_index_kind::GDB_INDEX;
 
   const char dwarf5space[] = "-dwarf-5 ";
   dw_index_kind index_kind = dw_index_kind::GDB_INDEX;
 
@@ -1640,33 +1745,40 @@ save_gdb_index_command (const char *arg, int from_tty)
   if (!*arg)
     error (_("usage: save gdb-index [-dwarf-5] DIRECTORY"));
 
   if (!*arg)
     error (_("usage: save gdb-index [-dwarf-5] DIRECTORY"));
 
-  ALL_OBJFILES (objfile)
-  {
-    struct stat st;
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      struct stat st;
 
 
-    /* If the objfile does not correspond to an actual file, skip it.  */
-    if (stat (objfile_name (objfile), &st) < 0)
-      continue;
+      /* If the objfile does not correspond to an actual file, skip it.  */
+      if (stat (objfile_name (objfile), &st) < 0)
+       continue;
 
 
-    struct dwarf2_per_objfile *dwarf2_per_objfile
-      = get_dwarf2_per_objfile (objfile);
+      struct dwarf2_per_objfile *dwarf2_per_objfile
+       = get_dwarf2_per_objfile (objfile);
 
 
-    if (dwarf2_per_objfile != NULL)
-      {
-       TRY
-         {
-           write_psymtabs_to_index (dwarf2_per_objfile, arg, index_kind);
-         }
-       CATCH (except, RETURN_MASK_ERROR)
-         {
-           exception_fprintf (gdb_stderr, except,
-                              _("Error while writing index for `%s': "),
-                              objfile_name (objfile));
-         }
-       END_CATCH
-      }
+      if (dwarf2_per_objfile != NULL)
+       {
+         try
+           {
+             const char *basename = lbasename (objfile_name (objfile));
+             const dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+             const char *dwz_basename = NULL;
+
+             if (dwz != NULL)
+               dwz_basename = lbasename (dwz->filename ());
+
+             write_psymtabs_to_index (dwarf2_per_objfile, arg, basename,
+                                      dwz_basename, index_kind);
+           }
+         catch (const gdb_exception_error &except)
+           {
+             exception_fprintf (gdb_stderr, except,
+                                _("Error while writing index for `%s': "),
+                                objfile_name (objfile));
+           }
+           }
 
 
-  }
+    }
 }
 
 void
 }
 
 void
This page took 0.034561 seconds and 4 git commands to generate.