Remove ALL_PSPACE_OBJFILES
[deliverable/binutils-gdb.git] / gdb / dwarf-index-write.c
index 3059e0b776a311223b777a9331be91c7f1ba4c2a..c12ef1269d47bd29448b6b49d3422cbc0b1afcd9 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
 
@@ -24,6 +24,8 @@
 #include "common/byte-vector.h"
 #include "common/filestuff.h"
 #include "common/gdb_unlinker.h"
+#include "common/pathstuff.h"
+#include "common/scoped_fd.h"
 #include "complaints.h"
 #include "dwarf-index-common.h"
 #include "dwarf2.h"
 #include "psympriv.h"
 
 #include <algorithm>
+#include <cmath>
 #include <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 { \
@@ -83,7 +81,8 @@ template<typename Elem, typename Alloc>
 static void
 file_write (FILE *file, const std::vector<Elem, Alloc> &vec)
 {
-  file_write (file, vec.data (), vec.size () * sizeof (vec[0]));
+  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.  */
@@ -153,7 +152,7 @@ private:
   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;
@@ -426,12 +425,8 @@ static void
 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));
 }
 
@@ -498,8 +493,8 @@ write_address_map (struct objfile *objfile, data_buf &addr_vec,
 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)
     {
@@ -545,7 +540,7 @@ write_psymbols (struct mapped_symtab *symtab,
     {
       struct partial_symbol *psym = *psymp;
 
-      if (SYMBOL_LANGUAGE (psym) == language_ada)
+      if (psym->language == language_ada)
        error (_("Ada is not currently supported by the index"));
 
       /* Only add a given psymbol once.  */
@@ -553,7 +548,7 @@ write_psymbols (struct mapped_symtab *symtab,
        {
          gdb_index_symbol_kind kind = symbol_kind (psym);
 
-         add_index_entry (symtab, SYMBOL_SEARCH_NAME (psym),
+         add_index_entry (symtab, symbol_search_name (psym),
                           is_static, kind, cu_index);
        }
     }
@@ -587,12 +582,14 @@ write_one_signatured_type (void **slot, void *d)
 
   write_psymbols (info->symtab,
                  info->psyms_seen,
-                 &info->objfile->global_psymbols[psymtab->globals_offset],
+                 (info->objfile->global_psymbols.data ()
+                  + psymtab->globals_offset),
                  psymtab->n_global_syms, info->cu_index,
                  0);
   write_psymbols (info->symtab,
                  info->psyms_seen,
-                 &info->objfile->static_psymbols[psymtab->statics_offset],
+                 (info->objfile->static_psymbols.data ()
+                  + psymtab->statics_offset),
                  psymtab->n_static_syms, info->cu_index,
                  1);
 
@@ -642,12 +639,12 @@ recursively_write_psymbols (struct objfile *objfile,
 
   write_psymbols (symtab,
                  psyms_seen,
-                 &objfile->global_psymbols[psymtab->globals_offset],
+                 objfile->global_psymbols.data () + psymtab->globals_offset,
                  psymtab->n_global_syms, cu_index,
                  0);
   write_psymbols (symtab,
                  psyms_seen,
-                 &objfile->static_psymbols[psymtab->statics_offset],
+                 objfile->static_psymbols.data () + psymtab->statics_offset,
                  psymtab->n_static_syms, cu_index,
                  1);
 }
@@ -685,7 +682,7 @@ public:
     const int dwarf_tag = psymbol_tag (psym);
     if (dwarf_tag == 0)
       return;
-    const char *const name = SYMBOL_SEARCH_NAME (psym);
+    const char *const name = symbol_search_name (psym);
     const auto insertpair
       = m_name_to_value_set.emplace (c_str_view (name),
                                     std::set<symbol_value> ());
@@ -838,10 +835,10 @@ public:
                                    psyms_seen, cu_index);
 
     write_psymbols (psyms_seen,
-                   &objfile->global_psymbols[psymtab->globals_offset],
+                   objfile->global_psymbols.data () + psymtab->globals_offset,
                    psymtab->n_global_syms, cu_index, false, unit_kind::cu);
     write_psymbols (psyms_seen,
-                   &objfile->static_psymbols[psymtab->statics_offset],
+                   objfile->static_psymbols.data () + psymtab->statics_offset,
                    psymtab->n_static_syms, cu_index, true, unit_kind::cu);
   }
 
@@ -930,8 +927,7 @@ private:
            = 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;
@@ -1139,8 +1135,8 @@ private:
      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)
       {
@@ -1181,7 +1177,7 @@ private:
       {
        struct partial_symbol *psym = *psymp;
 
-       if (SYMBOL_LANGUAGE (psym) == language_ada)
+       if (psym->language == language_ada)
          error (_("Ada is not currently supported by the index"));
 
        /* Only add a given psymbol once.  */
@@ -1199,11 +1195,13 @@ private:
     struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
 
     write_psymbols (info->psyms_seen,
-                   &info->objfile->global_psymbols[psymtab->globals_offset],
+                   (info->objfile->global_psymbols.data ()
+                    + psymtab->globals_offset),
                    psymtab->n_global_syms, info->cu_index, false,
                    unit_kind::tu);
     write_psymbols (info->psyms_seen,
-                   &info->objfile->static_psymbols[psymtab->statics_offset],
+                   (info->objfile->static_psymbols.data ()
+                    + psymtab->statics_offset),
                    psymtab->n_static_syms, info->cu_index, true,
                    unit_kind::tu);
 
@@ -1250,17 +1248,14 @@ private:
 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;
     }
-  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;
@@ -1278,10 +1273,8 @@ static size_t
 psyms_seen_size (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   size_t psyms_count = 0;
-  for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  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)
@@ -1307,7 +1300,7 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
      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
@@ -1315,7 +1308,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));
-  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];
@@ -1352,7 +1345,7 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
 
       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);
     }
@@ -1427,7 +1420,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));
-  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;
@@ -1495,11 +1488,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 (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.  */
-  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.  */
@@ -1544,11 +1539,11 @@ assert_file_size (FILE *file, const char *filename, size_t expected_size)
   gdb_assert (file_size == expected_size);
 }
 
-/* Create an index file for OBJFILE in the directory DIR.  */
+/* See dwarf-index-write.h.  */
 
-static void
+void
 write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
-                        const char *dir,
+                        const char *dir, const char *basename,
                         dw_index_kind index_kind)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
@@ -1566,50 +1561,74 @@ write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
   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))
+  std::string filename (std::string (dir) + SLASH_STRING + basename
                        + (index_kind == dw_index_kind::DEBUG_NAMES
                           ? INDEX5_SUFFIX : INDEX4_SUFFIX));
+  gdb::char_vector filename_temp = make_temp_filename (filename);
+
+  /* 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;
+  scoped_fd out_file_fd (gdb_mkostemp_cloexec (filename_temp.data (),
+                                              O_BINARY));
+  if (out_file_fd.get () == -1)
+    perror_with_name (("mkstemp"));
 
-  FILE *out_file = gdb_fopen_cloexec (filename.c_str (), "wb").release ();
-  if (!out_file)
-    error (_("Can't open `%s' for writing"), filename.c_str ());
+  gdb_file_up out_file = out_file_fd.to_file ("wb");
+  if (out_file == nullptr)
+    error (_("Can't open `%s' for writing"), filename_temp.data ());
 
-  /* 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);
+  unlink_file.emplace (filename_temp.data ());
 
   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);
+                               + basename + DEBUG_STR_SUFFIX);
+      gdb::char_vector filename_str_temp = make_temp_filename (filename_str);
+
+      /* As above, arrange to unlink the file only after the file
+        descriptor has been closed.  */
+      gdb::optional<gdb::unlinker> unlink_file_str;
+      scoped_fd out_file_str_fd
+       (gdb_mkostemp_cloexec (filename_str_temp.data (), O_BINARY));
+      if (out_file_str_fd.get () == -1)
+        perror_with_name (("mkstemp"));
+
+      gdb_file_up out_file_str = out_file_str_fd.to_file ("wb");
+      if (out_file_str == nullptr)
+       error (_("Can't open `%s' for writing"), filename_str_temp.data ());
+
+      unlink_file_str.emplace (filename_str_temp.data ());
 
       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);
+       = write_debug_names (dwarf2_per_objfile, out_file.get (),
+                            out_file_str.get ());
+      assert_file_size (out_file.get (), filename_temp.data (), total_len);
 
       /* We want to keep the file .debug_str file too.  */
-      unlink_file_str.keep ();
+      unlink_file_str->keep ();
+
+      /* Close and move the str file in place.  */
+      out_file_str.reset ();
+      if (rename (filename_str_temp.data (), filename_str.c_str ()) != 0)
+       perror_with_name (("rename"));
     }
   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, out_file.get ());
+      assert_file_size (out_file.get (), filename_temp.data (), total_len);
     }
 
   /* We want to keep the file.  */
-  unlink_file.keep ();
+  unlink_file->keep ();
+
+  /* Close and move the file in place.  */
+  out_file.reset ();
+  if (rename (filename_temp.data (), filename.c_str ()) != 0)
+       perror_with_name (("rename"));
 }
 
 /* Implementation of the `save gdb-index' command.
@@ -1654,7 +1673,9 @@ save_gdb_index_command (const char *arg, int from_tty)
       {
        TRY
          {
-           write_psymtabs_to_index (dwarf2_per_objfile, arg, index_kind);
+           const char *basename = lbasename (objfile_name (objfile));
+           write_psymtabs_to_index (dwarf2_per_objfile, arg, basename,
+                                    index_kind);
          }
        CATCH (except, RETURN_MASK_ERROR)
          {
This page took 0.029526 seconds and 4 git commands to generate.