/* DWARF index writing support for GDB.

   Copyright (C) 1994-2018 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"

#include "addrmap.h"
#include "cli/cli-decode.h"
#include "common/byte-vector.h"
#include "common/filestuff.h"
#include "common/gdb_unlinker.h"
#include "common/scoped_fd.h"
#include "complaints.h"
#include "dwarf-index-common.h"
#include "dwarf2.h"
#include "dwarf2read.h"
#include "gdb/gdb-index.h"
#include "gdbcmd.h"
#include "objfiles.h"
#include "psympriv.h"

#include <algorithm>
#include <cmath>
#include <set>
#include <unordered_map>
#include <unordered_set>

/* Ensure only legit values are used.  */
#define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \
  do { \
    gdb_assert ((unsigned int) (value) <= 1); \
    GDB_INDEX_SYMBOL_STATIC_SET_VALUE((cu_index), (value)); \
  } while (0)

/* Ensure only legit values are used.  */
#define DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE(cu_index, value) \
  do { \
    gdb_assert ((value) >= GDB_INDEX_SYMBOL_KIND_TYPE \
                && (value) <= GDB_INDEX_SYMBOL_KIND_OTHER); \
    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.  */
#define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value) \
  do { \
    gdb_assert (((value) & ~GDB_INDEX_CU_MASK) == 0); \
    GDB_INDEX_CU_SET_VALUE((cu_index), (value)); \
  } while (0)

/* The "save gdb-index" command.  */

/* Write SIZE bytes from the buffer pointed to by DATA to FILE, with
   error checking.  */

static void
file_write (FILE *file, const void *data, size_t size)
{
  if (fwrite (data, 1, size, file) != size)
    error (_("couldn't data write to file"));
}

/* Write the contents of VEC to FILE, with error checking.  */

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]));
}

/* In-memory buffer to prepare data to be written later to a file.  */
class data_buf
{
public:
  /* Copy DATA to the end of the buffer.  */
  template<typename T>
  void append_data (const T &data)
  {
    std::copy (reinterpret_cast<const gdb_byte *> (&data),
	       reinterpret_cast<const gdb_byte *> (&data + 1),
	       grow (sizeof (data)));
  }

  /* Copy CSTR (a zero-terminated string) to the end of buffer.  The
     terminating zero is appended too.  */
  void append_cstr0 (const char *cstr)
  {
    const size_t size = strlen (cstr) + 1;
    std::copy (cstr, cstr + size, grow (size));
  }

  /* Store INPUT as ULEB128 to the end of buffer.  */
  void append_unsigned_leb128 (ULONGEST input)
  {
    for (;;)
      {
	gdb_byte output = input & 0x7f;
	input >>= 7;
	if (input)
	  output |= 0x80;
	append_data (output);
	if (input == 0)
	  break;
      }
  }

  /* Accept a host-format integer in VAL and append it to the buffer
     as a target-format integer which is LEN bytes long.  */
  void append_uint (size_t len, bfd_endian byte_order, ULONGEST val)
  {
    ::store_unsigned_integer (grow (len), len, byte_order, val);
  }

  /* Return the size of the buffer.  */
  size_t size () const
  {
    return m_vec.size ();
  }

  /* Return true iff the buffer is empty.  */
  bool empty () const
  {
    return m_vec.empty ();
  }

  /* Write the buffer to FILE.  */
  void file_write (FILE *file) const
  {
    ::file_write (file, m_vec);
  }

private:
  /* Grow SIZE bytes at the end of the buffer.  Returns a pointer to
     the start of the new block.  */
  gdb_byte *grow (size_t size)
  {
    m_vec.resize (m_vec.size () + size);
    return &*(m_vec.end () - size);
  }

  gdb::byte_vector m_vec;
};

/* An entry in the symbol table.  */
struct symtab_index_entry
{
  /* The name of the symbol.  */
  const char *name;
  /* The offset of the name in the constant pool.  */
  offset_type index_offset;
  /* A sorted vector of the indices of all the CUs that hold an object
     of this name.  */
  std::vector<offset_type> cu_indices;
};

/* The symbol table.  This is a power-of-2-sized hash table.  */
struct mapped_symtab
{
  mapped_symtab ()
  {
    data.resize (1024);
  }

  offset_type n_elements = 0;
  std::vector<symtab_index_entry> data;
};

/* Find a slot in SYMTAB for the symbol NAME.  Returns a reference to
   the slot.

   Function is used only during write_hash_table so no index format backward
   compatibility is needed.  */

static symtab_index_entry &
find_slot (struct mapped_symtab *symtab, const char *name)
{
  offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name);

  index = hash & (symtab->data.size () - 1);
  step = ((hash * 17) & (symtab->data.size () - 1)) | 1;

  for (;;)
    {
      if (symtab->data[index].name == NULL
	  || strcmp (name, symtab->data[index].name) == 0)
	return symtab->data[index];
      index = (index + step) & (symtab->data.size () - 1);
    }
}

/* Expand SYMTAB's hash table.  */

static void
hash_expand (struct mapped_symtab *symtab)
{
  auto old_entries = std::move (symtab->data);

  symtab->data.clear ();
  symtab->data.resize (old_entries.size () * 2);

  for (auto &it : old_entries)
    if (it.name != NULL)
      {
	auto &ref = find_slot (symtab, it.name);
	ref = std::move (it);
      }
}

/* Add an entry to SYMTAB.  NAME is the name of the symbol.
   CU_INDEX is the index of the CU in which the symbol appears.
   IS_STATIC is one if the symbol is static, otherwise zero (global).  */

static void
add_index_entry (struct mapped_symtab *symtab, const char *name,
		 int is_static, gdb_index_symbol_kind kind,
		 offset_type cu_index)
{
  offset_type cu_index_and_attrs;

  ++symtab->n_elements;
  if (4 * symtab->n_elements / 3 >= symtab->data.size ())
    hash_expand (symtab);

  symtab_index_entry &slot = find_slot (symtab, name);
  if (slot.name == NULL)
    {
      slot.name = name;
      /* index_offset is set later.  */
    }

  cu_index_and_attrs = 0;
  DW2_GDB_INDEX_CU_SET_VALUE (cu_index_and_attrs, cu_index);
  DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE (cu_index_and_attrs, is_static);
  DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE (cu_index_and_attrs, kind);

  /* We don't want to record an index value twice as we want to avoid the
     duplication.
     We process all global symbols and then all static symbols
     (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.  */
  slot.cu_indices.push_back (cu_index_and_attrs);
}

/* Sort and remove duplicates of all symbols' cu_indices lists.  */

static void
uniquify_cu_indices (struct mapped_symtab *symtab)
{
  for (auto &entry : symtab->data)
    {
      if (entry.name != NULL && !entry.cu_indices.empty ())
	{
	  auto &cu_indices = entry.cu_indices;
	  std::sort (cu_indices.begin (), cu_indices.end ());
	  auto from = std::unique (cu_indices.begin (), cu_indices.end ());
	  cu_indices.erase (from, cu_indices.end ());
	}
    }
}

/* A form of 'const char *' suitable for container keys.  Only the
   pointer is stored.  The strings themselves are compared, not the
   pointers.  */
class c_str_view
{
public:
  c_str_view (const char *cstr)
    : m_cstr (cstr)
  {}

  bool operator== (const c_str_view &other) const
  {
    return strcmp (m_cstr, other.m_cstr) == 0;
  }

  /* Return the underlying C string.  Note, the returned string is
     only a reference with lifetime of this object.  */
  const char *c_str () const
  {
    return m_cstr;
  }

private:
  friend class c_str_view_hasher;
  const char *const m_cstr;
};

/* A std::unordered_map::hasher for c_str_view that uses the right
   hash function for strings in a mapped index.  */
class c_str_view_hasher
{
public:
  size_t operator () (const c_str_view &x) const
  {
    return mapped_index_string_hash (INT_MAX, x.m_cstr);
  }
};

/* A std::unordered_map::hasher for std::vector<>.  */
template<typename T>
class vector_hasher
{
public:
  size_t operator () (const std::vector<T> &key) const
  {
    return iterative_hash (key.data (),
			   sizeof (key.front ()) * key.size (), 0);
  }
};

/* Write the mapped hash table SYMTAB to the data buffer OUTPUT, with
   constant pool entries going into the data buffer CPOOL.  */

static void
write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
{
  {
    /* Elements are sorted vectors of the indices of all the CUs that
       hold an object of this name.  */
    std::unordered_map<std::vector<offset_type>, offset_type,
		       vector_hasher<offset_type>>
      symbol_hash_table;

    /* We add all the index vectors to the constant pool first, to
       ensure alignment is ok.  */
    for (symtab_index_entry &entry : symtab->data)
      {
	if (entry.name == NULL)
	  continue;
	gdb_assert (entry.index_offset == 0);

	/* Finding before inserting is faster than always trying to
	   insert, because inserting always allocates a node, does the
	   lookup, and then destroys the new node if another node
	   already had the same key.  C++17 try_emplace will avoid
	   this.  */
	const auto found
	  = symbol_hash_table.find (entry.cu_indices);
	if (found != symbol_hash_table.end ())
	  {
	    entry.index_offset = found->second;
	    continue;
	  }

	symbol_hash_table.emplace (entry.cu_indices, cpool.size ());
	entry.index_offset = cpool.size ();
	cpool.append_data (MAYBE_SWAP (entry.cu_indices.size ()));
	for (const auto index : entry.cu_indices)
	  cpool.append_data (MAYBE_SWAP (index));
      }
  }

  /* Now write out the hash table.  */
  std::unordered_map<c_str_view, offset_type, c_str_view_hasher> str_table;
  for (const auto &entry : symtab->data)
    {
      offset_type str_off, vec_off;

      if (entry.name != NULL)
	{
	  const auto insertpair = str_table.emplace (entry.name, cpool.size ());
	  if (insertpair.second)
	    cpool.append_cstr0 (entry.name);
	  str_off = insertpair.first->second;
	  vec_off = entry.index_offset;
	}
      else
	{
	  /* While 0 is a valid constant pool index, it is not valid
	     to have 0 for both offsets.  */
	  str_off = 0;
	  vec_off = 0;
	}

      output.append_data (MAYBE_SWAP (str_off));
      output.append_data (MAYBE_SWAP (vec_off));
    }
}

typedef std::unordered_map<partial_symtab *, unsigned int> psym_index_map;

/* Helper struct for building the address table.  */
struct addrmap_index_data
{
  addrmap_index_data (data_buf &addr_vec_, psym_index_map &cu_index_htab_)
    : addr_vec (addr_vec_), cu_index_htab (cu_index_htab_)
  {}

  struct objfile *objfile;
  data_buf &addr_vec;
  psym_index_map &cu_index_htab;

  /* Non-zero if the previous_* fields are valid.
     We can't write an entry until we see the next entry (since it is only then
     that we know the end of the entry).  */
  int previous_valid;
  /* Index of the CU in the table of all CUs in the index file.  */
  unsigned int previous_cu_index;
  /* Start address of the CU.  */
  CORE_ADDR previous_cu_start;
};

/* Write an address entry to ADDR_VEC.  */

static void
add_address_entry (struct objfile *objfile, data_buf &addr_vec,
		   CORE_ADDR start, CORE_ADDR end, unsigned int cu_index)
{
  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));
}

/* Worker function for traversing an addrmap to build the address table.  */

static int
add_address_entry_worker (void *datap, CORE_ADDR start_addr, void *obj)
{
  struct addrmap_index_data *data = (struct addrmap_index_data *) datap;
  struct partial_symtab *pst = (struct partial_symtab *) obj;

  if (data->previous_valid)
    add_address_entry (data->objfile, data->addr_vec,
		       data->previous_cu_start, start_addr,
		       data->previous_cu_index);

  data->previous_cu_start = start_addr;
  if (pst != NULL)
    {
      const auto it = data->cu_index_htab.find (pst);
      gdb_assert (it != data->cu_index_htab.cend ());
      data->previous_cu_index = it->second;
      data->previous_valid = 1;
    }
  else
    data->previous_valid = 0;

  return 0;
}

/* Write OBJFILE's address map to ADDR_VEC.
   CU_INDEX_HTAB is used to map addrmap entries to their CU indices
   in the index file.  */

static void
write_address_map (struct objfile *objfile, data_buf &addr_vec,
		   psym_index_map &cu_index_htab)
{
  struct addrmap_index_data addrmap_index_data (addr_vec, cu_index_htab);

  /* When writing the address table, we have to cope with the fact that
     the addrmap iterator only provides the start of a region; we have to
     wait until the next invocation to get the start of the next region.  */

  addrmap_index_data.objfile = objfile;
  addrmap_index_data.previous_valid = 0;

  addrmap_foreach (objfile->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.
     The end address is recorded as the start of the next region, but that
     doesn't work here.  To cope we pass 0xff...ff, this is a rare situation
     anyway.  */
  if (addrmap_index_data.previous_valid)
    add_address_entry (objfile, addr_vec,
		       addrmap_index_data.previous_cu_start, (CORE_ADDR) -1,
		       addrmap_index_data.previous_cu_index);
}

/* Return the symbol kind of PSYM.  */

static gdb_index_symbol_kind
symbol_kind (struct partial_symbol *psym)
{
  domain_enum domain = psym->domain;
  enum address_class aclass = psym->aclass;

  switch (domain)
    {
    case VAR_DOMAIN:
      switch (aclass)
	{
	case LOC_BLOCK:
	  return GDB_INDEX_SYMBOL_KIND_FUNCTION;
	case LOC_TYPEDEF:
	  return GDB_INDEX_SYMBOL_KIND_TYPE;
	case LOC_COMPUTED:
	case LOC_CONST_BYTES:
	case LOC_OPTIMIZED_OUT:
	case LOC_STATIC:
	  return GDB_INDEX_SYMBOL_KIND_VARIABLE;
	case LOC_CONST:
	  /* Note: It's currently impossible to recognize psyms as enum values
	     short of reading the type info.  For now punt.  */
	  return GDB_INDEX_SYMBOL_KIND_VARIABLE;
	default:
	  /* There are other LOC_FOO values that one might want to classify
	     as variables, but dwarf2read.c doesn't currently use them.  */
	  return GDB_INDEX_SYMBOL_KIND_OTHER;
	}
    case STRUCT_DOMAIN:
      return GDB_INDEX_SYMBOL_KIND_TYPE;
    default:
      return GDB_INDEX_SYMBOL_KIND_OTHER;
    }
}

/* Add a list of partial symbols to SYMTAB.  */

static void
write_psymbols (struct mapped_symtab *symtab,
		std::unordered_set<partial_symbol *> &psyms_seen,
		struct partial_symbol **psymp,
		int count,
		offset_type cu_index,
		int is_static)
{
  for (; count-- > 0; ++psymp)
    {
      struct partial_symbol *psym = *psymp;

      if (psym->language == language_ada)
	error (_("Ada is not currently supported by the index"));

      /* 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),
			   is_static, kind, cu_index);
	}
    }
}

/* A helper struct used when iterating over debug_types.  */
struct signatured_type_index_data
{
  signatured_type_index_data (data_buf &types_list_,
                              std::unordered_set<partial_symbol *> &psyms_seen_)
    : types_list (types_list_), psyms_seen (psyms_seen_)
  {}

  struct objfile *objfile;
  struct mapped_symtab *symtab;
  data_buf &types_list;
  std::unordered_set<partial_symbol *> &psyms_seen;
  int cu_index;
};

/* A helper function that writes a single signatured_type to an
   obstack.  */

static int
write_one_signatured_type (void **slot, void *d)
{
  struct signatured_type_index_data *info
    = (struct signatured_type_index_data *) d;
  struct signatured_type *entry = (struct signatured_type *) *slot;
  struct partial_symtab *psymtab = entry->per_cu.v.psymtab;

  write_psymbols (info->symtab,
		  info->psyms_seen,
		  (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.data ()
		   + psymtab->statics_offset),
		  psymtab->n_static_syms, info->cu_index,
		  1);

  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE,
				to_underlying (entry->per_cu.sect_off));
  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE,
				to_underlying (entry->type_offset_in_tu));
  info->types_list.append_uint (8, BFD_ENDIAN_LITTLE, entry->signature);

  ++info->cu_index;

  return 1;
}

/* Recurse into all "included" dependencies and count their symbols as
   if they appeared in this psymtab.  */

static void
recursively_count_psymbols (struct partial_symtab *psymtab,
			    size_t &psyms_seen)
{
  for (int i = 0; i < psymtab->number_of_dependencies; ++i)
    if (psymtab->dependencies[i]->user != NULL)
      recursively_count_psymbols (psymtab->dependencies[i],
				  psyms_seen);

  psyms_seen += psymtab->n_global_syms;
  psyms_seen += psymtab->n_static_syms;
}

/* Recurse into all "included" dependencies and write their symbols as
   if they appeared in this psymtab.  */

static void
recursively_write_psymbols (struct objfile *objfile,
			    struct partial_symtab *psymtab,
			    struct mapped_symtab *symtab,
			    std::unordered_set<partial_symbol *> &psyms_seen,
			    offset_type cu_index)
{
  int i;

  for (i = 0; i < psymtab->number_of_dependencies; ++i)
    if (psymtab->dependencies[i]->user != NULL)
      recursively_write_psymbols (objfile, psymtab->dependencies[i],
				  symtab, psyms_seen, cu_index);

  write_psymbols (symtab,
		  psyms_seen,
		  objfile->global_psymbols.data () + psymtab->globals_offset,
		  psymtab->n_global_syms, cu_index,
		  0);
  write_psymbols (symtab,
		  psyms_seen,
		  objfile->static_psymbols.data () + psymtab->statics_offset,
		  psymtab->n_static_syms, cu_index,
		  1);
}

/* DWARF-5 .debug_names builder.  */
class debug_names
{
public:
  debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile, bool is_dwarf64,
	       bfd_endian dwarf5_byte_order)
    : m_dwarf5_byte_order (dwarf5_byte_order),
      m_dwarf32 (dwarf5_byte_order),
      m_dwarf64 (dwarf5_byte_order),
      m_dwarf (is_dwarf64
	       ? static_cast<dwarf &> (m_dwarf64)
	       : static_cast<dwarf &> (m_dwarf32)),
      m_name_table_string_offs (m_dwarf.name_table_string_offs),
      m_name_table_entry_offs (m_dwarf.name_table_entry_offs),
      m_debugstrlookup (dwarf2_per_objfile)
  {}

  int dwarf5_offset_size () const
  {
    const bool dwarf5_is_dwarf64 = &m_dwarf == &m_dwarf64;
    return dwarf5_is_dwarf64 ? 8 : 4;
  }

  /* Is this symbol from DW_TAG_compile_unit or DW_TAG_type_unit?  */
  enum class unit_kind { cu, tu };

  /* Insert one symbol.  */
  void insert (const partial_symbol *psym, int cu_index, bool is_static,
	       unit_kind kind)
  {
    const int dwarf_tag = psymbol_tag (psym);
    if (dwarf_tag == 0)
      return;
    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> ());
    std::set<symbol_value> &value_set = insertpair.first->second;
    value_set.emplace (symbol_value (dwarf_tag, cu_index, is_static, kind));
  }

  /* Build all the tables.  All symbols must be already inserted.
     This function does not call file_write, caller has to do it
     afterwards.  */
  void build ()
  {
    /* Verify the build method has not be called twice.  */
    gdb_assert (m_abbrev_table.empty ());
    const size_t name_count = m_name_to_value_set.size ();
    m_bucket_table.resize
      (std::pow (2, std::ceil (std::log2 (name_count * 4 / 3))));
    m_hash_table.reserve (name_count);
    m_name_table_string_offs.reserve (name_count);
    m_name_table_entry_offs.reserve (name_count);

    /* Map each hash of symbol to its name and value.  */
    struct hash_it_pair
    {
      uint32_t hash;
      decltype (m_name_to_value_set)::const_iterator it;
    };
    std::vector<std::forward_list<hash_it_pair>> bucket_hash;
    bucket_hash.resize (m_bucket_table.size ());
    for (decltype (m_name_to_value_set)::const_iterator it
	   = m_name_to_value_set.cbegin ();
	 it != m_name_to_value_set.cend ();
	 ++it)
      {
	const char *const name = it->first.c_str ();
	const uint32_t hash = dwarf5_djb_hash (name);
	hash_it_pair hashitpair;
	hashitpair.hash = hash;
	hashitpair.it = it;
	auto &slot = bucket_hash[hash % bucket_hash.size()];
	slot.push_front (std::move (hashitpair));
      }
    for (size_t bucket_ix = 0; bucket_ix < bucket_hash.size (); ++bucket_ix)
      {
	const std::forward_list<hash_it_pair> &hashitlist
	  = bucket_hash[bucket_ix];
	if (hashitlist.empty ())
	  continue;
	uint32_t &bucket_slot = m_bucket_table[bucket_ix];
	/* The hashes array is indexed starting at 1.  */
	store_unsigned_integer (reinterpret_cast<gdb_byte *> (&bucket_slot),
				sizeof (bucket_slot), m_dwarf5_byte_order,
				m_hash_table.size () + 1);
	for (const hash_it_pair &hashitpair : hashitlist)
	  {
	    m_hash_table.push_back (0);
	    store_unsigned_integer (reinterpret_cast<gdb_byte *>
							(&m_hash_table.back ()),
				    sizeof (m_hash_table.back ()),
				    m_dwarf5_byte_order, hashitpair.hash);
	    const c_str_view &name = hashitpair.it->first;
	    const std::set<symbol_value> &value_set = hashitpair.it->second;
	    m_name_table_string_offs.push_back_reorder
	      (m_debugstrlookup.lookup (name.c_str ()));
	    m_name_table_entry_offs.push_back_reorder (m_entry_pool.size ());
	    gdb_assert (!value_set.empty ());
	    for (const symbol_value &value : value_set)
	      {
		int &idx = m_indexkey_to_idx[index_key (value.dwarf_tag,
							value.is_static,
							value.kind)];
		if (idx == 0)
		  {
		    idx = m_idx_next++;
		    m_abbrev_table.append_unsigned_leb128 (idx);
		    m_abbrev_table.append_unsigned_leb128 (value.dwarf_tag);
		    m_abbrev_table.append_unsigned_leb128
			      (value.kind == unit_kind::cu ? DW_IDX_compile_unit
							   : DW_IDX_type_unit);
		    m_abbrev_table.append_unsigned_leb128 (DW_FORM_udata);
		    m_abbrev_table.append_unsigned_leb128 (value.is_static
							   ? DW_IDX_GNU_internal
							   : DW_IDX_GNU_external);
		    m_abbrev_table.append_unsigned_leb128 (DW_FORM_flag_present);

		    /* Terminate attributes list.  */
		    m_abbrev_table.append_unsigned_leb128 (0);
		    m_abbrev_table.append_unsigned_leb128 (0);
		  }

		m_entry_pool.append_unsigned_leb128 (idx);
		m_entry_pool.append_unsigned_leb128 (value.cu_index);
	      }

	    /* Terminate the list of CUs.  */
	    m_entry_pool.append_unsigned_leb128 (0);
	  }
      }
    gdb_assert (m_hash_table.size () == name_count);

    /* Terminate tags list.  */
    m_abbrev_table.append_unsigned_leb128 (0);
  }

  /* Return .debug_names bucket count.  This must be called only after
     calling the build method.  */
  uint32_t bucket_count () const
  {
    /* Verify the build method has been already called.  */
    gdb_assert (!m_abbrev_table.empty ());
    const uint32_t retval = m_bucket_table.size ();

    /* Check for overflow.  */
    gdb_assert (retval == m_bucket_table.size ());
    return retval;
  }

  /* Return .debug_names names count.  This must be called only after
     calling the build method.  */
  uint32_t name_count () const
  {
    /* Verify the build method has been already called.  */
    gdb_assert (!m_abbrev_table.empty ());
    const uint32_t retval = m_hash_table.size ();

    /* Check for overflow.  */
    gdb_assert (retval == m_hash_table.size ());
    return retval;
  }

  /* Return number of bytes of .debug_names abbreviation table.  This
     must be called only after calling the build method.  */
  uint32_t abbrev_table_bytes () const
  {
    gdb_assert (!m_abbrev_table.empty ());
    return m_abbrev_table.size ();
  }

  /* Recurse into all "included" dependencies and store their symbols
     as if they appeared in this psymtab.  */
  void recursively_write_psymbols
    (struct objfile *objfile,
     struct partial_symtab *psymtab,
     std::unordered_set<partial_symbol *> &psyms_seen,
     int cu_index)
  {
    for (int i = 0; i < psymtab->number_of_dependencies; ++i)
      if (psymtab->dependencies[i]->user != NULL)
	recursively_write_psymbols (objfile, psymtab->dependencies[i],
				    psyms_seen, cu_index);

    write_psymbols (psyms_seen,
		    objfile->global_psymbols.data () + psymtab->globals_offset,
		    psymtab->n_global_syms, cu_index, false, unit_kind::cu);
    write_psymbols (psyms_seen,
		    objfile->static_psymbols.data () + psymtab->statics_offset,
		    psymtab->n_static_syms, cu_index, true, unit_kind::cu);
  }

  /* Return number of bytes the .debug_names section will have.  This
     must be called only after calling the build method.  */
  size_t bytes () const
  {
    /* Verify the build method has been already called.  */
    gdb_assert (!m_abbrev_table.empty ());
    size_t expected_bytes = 0;
    expected_bytes += m_bucket_table.size () * sizeof (m_bucket_table[0]);
    expected_bytes += m_hash_table.size () * sizeof (m_hash_table[0]);
    expected_bytes += m_name_table_string_offs.bytes ();
    expected_bytes += m_name_table_entry_offs.bytes ();
    expected_bytes += m_abbrev_table.size ();
    expected_bytes += m_entry_pool.size ();
    return expected_bytes;
  }

  /* Write .debug_names to FILE_NAMES and .debug_str addition to
     FILE_STR.  This must be called only after calling the build
     method.  */
  void file_write (FILE *file_names, FILE *file_str) const
  {
    /* Verify the build method has been already called.  */
    gdb_assert (!m_abbrev_table.empty ());
    ::file_write (file_names, m_bucket_table);
    ::file_write (file_names, m_hash_table);
    m_name_table_string_offs.file_write (file_names);
    m_name_table_entry_offs.file_write (file_names);
    m_abbrev_table.file_write (file_names);
    m_entry_pool.file_write (file_names);
    m_debugstrlookup.file_write (file_str);
  }

  /* A helper user data for write_one_signatured_type.  */
  class write_one_signatured_type_data
  {
  public:
    write_one_signatured_type_data (debug_names &nametable_,
                                    signatured_type_index_data &&info_)
    : nametable (nametable_), info (std::move (info_))
    {}
    debug_names &nametable;
    struct signatured_type_index_data info;
  };

  /* A helper function to pass write_one_signatured_type to
     htab_traverse_noresize.  */
  static int
  write_one_signatured_type (void **slot, void *d)
  {
    write_one_signatured_type_data *data = (write_one_signatured_type_data *) d;
    struct signatured_type_index_data *info = &data->info;
    struct signatured_type *entry = (struct signatured_type *) *slot;

    data->nametable.write_one_signatured_type (entry, info);

    return 1;
  }

private:

  /* Storage for symbol names mapping them to their .debug_str section
     offsets.  */
  class debug_str_lookup
  {
  public:

    /* Object costructor 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),
	m_dwarf2_per_objfile (dwarf2_per_objfile)
    {
      dwarf2_read_section (dwarf2_per_objfile->objfile,
			   &dwarf2_per_objfile->str);
      if (dwarf2_per_objfile->str.buffer == NULL)
	return;
      for (const gdb_byte *data = dwarf2_per_objfile->str.buffer;
	   data < (dwarf2_per_objfile->str.buffer
		   + dwarf2_per_objfile->str.size);)
	{
	  const char *const s = reinterpret_cast<const char *> (data);
	  const auto insertpair
	    = m_str_table.emplace (c_str_view (s),
				   data - dwarf2_per_objfile->str.buffer);
	  if (!insertpair.second)
	    complaint (_("Duplicate string \"%s\" in "
			 ".debug_str section [in module %s]"),
		       s, bfd_get_filename (m_abfd));
	  data += strlen (s) + 1;
	}
    }

    /* Return offset of symbol name S in the .debug_str section.  Add
       such symbol to the section's end if it does not exist there
       yet.  */
    size_t lookup (const char *s)
    {
      const auto it = m_str_table.find (c_str_view (s));
      if (it != m_str_table.end ())
	return it->second;
      const size_t offset = (m_dwarf2_per_objfile->str.size
			     + m_str_add_buf.size ());
      m_str_table.emplace (c_str_view (s), offset);
      m_str_add_buf.append_cstr0 (s);
      return offset;
    }

    /* Append the end of the .debug_str section to FILE.  */
    void file_write (FILE *file) const
    {
      m_str_add_buf.file_write (file);
    }

  private:
    std::unordered_map<c_str_view, size_t, c_str_view_hasher> m_str_table;
    bfd *const m_abfd;
    struct dwarf2_per_objfile *m_dwarf2_per_objfile;

    /* Data to add at the end of .debug_str for new needed symbol names.  */
    data_buf m_str_add_buf;
  };

  /* Container to map used DWARF tags to their .debug_names abbreviation
     tags.  */
  class index_key
  {
  public:
    index_key (int dwarf_tag_, bool is_static_, unit_kind kind_)
      : dwarf_tag (dwarf_tag_), is_static (is_static_), kind (kind_)
    {
    }

    bool
    operator== (const index_key &other) const
    {
      return (dwarf_tag == other.dwarf_tag && is_static == other.is_static
	      && kind == other.kind);
    }

    const int dwarf_tag;
    const bool is_static;
    const unit_kind kind;
  };

  /* Provide std::unordered_map::hasher for index_key.  */
  class index_key_hasher
  {
  public:
    size_t
    operator () (const index_key &key) const
    {
      return (std::hash<int>() (key.dwarf_tag) << 1) | key.is_static;
    }
  };

  /* Parameters of one symbol entry.  */
  class symbol_value
  {
  public:
    const int dwarf_tag, cu_index;
    const bool is_static;
    const unit_kind kind;

    symbol_value (int dwarf_tag_, int cu_index_, bool is_static_,
		  unit_kind kind_)
      : dwarf_tag (dwarf_tag_), cu_index (cu_index_), is_static (is_static_),
        kind (kind_)
    {}

    bool
    operator< (const symbol_value &other) const
    {
#define X(n) \
  do \
    { \
      if (n < other.n) \
	return true; \
      if (n > other.n) \
	return false; \
    } \
  while (0)
      X (dwarf_tag);
      X (is_static);
      X (kind);
      X (cu_index);
#undef X
      return false;
    }
  };

  /* Abstract base class to unify DWARF-32 and DWARF-64 name table
     output.  */
  class offset_vec
  {
  protected:
    const bfd_endian dwarf5_byte_order;
  public:
    explicit offset_vec (bfd_endian dwarf5_byte_order_)
      : dwarf5_byte_order (dwarf5_byte_order_)
    {}

    /* Call std::vector::reserve for NELEM elements.  */
    virtual void reserve (size_t nelem) = 0;

    /* Call std::vector::push_back with store_unsigned_integer byte
       reordering for ELEM.  */
    virtual void push_back_reorder (size_t elem) = 0;

    /* Return expected output size in bytes.  */
    virtual size_t bytes () const = 0;

    /* Write name table to FILE.  */
    virtual void file_write (FILE *file) const = 0;
  };

  /* Template to unify DWARF-32 and DWARF-64 output.  */
  template<typename OffsetSize>
  class offset_vec_tmpl : public offset_vec
  {
  public:
    explicit offset_vec_tmpl (bfd_endian dwarf5_byte_order_)
      : offset_vec (dwarf5_byte_order_)
    {}

    /* Implement offset_vec::reserve.  */
    void reserve (size_t nelem) override
    {
      m_vec.reserve (nelem);
    }

    /* Implement offset_vec::push_back_reorder.  */
    void push_back_reorder (size_t elem) override
    {
      m_vec.push_back (elem);
      /* Check for overflow.  */
      gdb_assert (m_vec.back () == elem);
      store_unsigned_integer (reinterpret_cast<gdb_byte *> (&m_vec.back ()),
			      sizeof (m_vec.back ()), dwarf5_byte_order, elem);
    }

    /* Implement offset_vec::bytes.  */
    size_t bytes () const override
    {
      return m_vec.size () * sizeof (m_vec[0]);
    }

    /* Implement offset_vec::file_write.  */
    void file_write (FILE *file) const override
    {
      ::file_write (file, m_vec);
    }

  private:
    std::vector<OffsetSize> m_vec;
  };

  /* Base class to unify DWARF-32 and DWARF-64 .debug_names output
     respecting name table width.  */
  class dwarf
  {
  public:
    offset_vec &name_table_string_offs, &name_table_entry_offs;

    dwarf (offset_vec &name_table_string_offs_,
	   offset_vec &name_table_entry_offs_)
      : name_table_string_offs (name_table_string_offs_),
	name_table_entry_offs (name_table_entry_offs_)
    {
    }
  };

  /* Template to unify DWARF-32 and DWARF-64 .debug_names output
     respecting name table width.  */
  template<typename OffsetSize>
  class dwarf_tmpl : public dwarf
  {
  public:
    explicit dwarf_tmpl (bfd_endian dwarf5_byte_order_)
      : dwarf (m_name_table_string_offs, m_name_table_entry_offs),
	m_name_table_string_offs (dwarf5_byte_order_),
	m_name_table_entry_offs (dwarf5_byte_order_)
    {}

  private:
    offset_vec_tmpl<OffsetSize> m_name_table_string_offs;
    offset_vec_tmpl<OffsetSize> m_name_table_entry_offs;
  };

  /* Try to reconstruct original DWARF tag for given partial_symbol.
     This function is not DWARF-5 compliant but it is sufficient for
     GDB as a DWARF-5 index consumer.  */
  static int psymbol_tag (const struct partial_symbol *psym)
  {
    domain_enum domain = psym->domain;
    enum address_class aclass = psym->aclass;

    switch (domain)
      {
      case VAR_DOMAIN:
	switch (aclass)
	  {
	  case LOC_BLOCK:
	    return DW_TAG_subprogram;
	  case LOC_TYPEDEF:
	    return DW_TAG_typedef;
	  case LOC_COMPUTED:
	  case LOC_CONST_BYTES:
	  case LOC_OPTIMIZED_OUT:
	  case LOC_STATIC:
	    return DW_TAG_variable;
	  case LOC_CONST:
	    /* Note: It's currently impossible to recognize psyms as enum values
	       short of reading the type info.  For now punt.  */
	    return DW_TAG_variable;
	  default:
	    /* There are other LOC_FOO values that one might want to classify
	       as variables, but dwarf2read.c doesn't currently use them.  */
	    return DW_TAG_variable;
	  }
      case STRUCT_DOMAIN:
	return DW_TAG_structure_type;
      default:
	return 0;
      }
  }

  /* Call insert for all partial symbols and mark them in PSYMS_SEEN.  */
  void write_psymbols (std::unordered_set<partial_symbol *> &psyms_seen,
		       struct partial_symbol **psymp, int count, int cu_index,
		       bool is_static, unit_kind kind)
  {
    for (; count-- > 0; ++psymp)
      {
	struct partial_symbol *psym = *psymp;

	if (psym->language == 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);
      }
  }

  /* A helper function that writes a single signatured_type
     to a debug_names.  */
  void
  write_one_signatured_type (struct signatured_type *entry,
			     struct signatured_type_index_data *info)
  {
    struct partial_symtab *psymtab = entry->per_cu.v.psymtab;

    write_psymbols (info->psyms_seen,
		    (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.data ()
		     + psymtab->statics_offset),
		    psymtab->n_static_syms, info->cu_index, true,
		    unit_kind::tu);

    info->types_list.append_uint (dwarf5_offset_size (), m_dwarf5_byte_order,
				  to_underlying (entry->per_cu.sect_off));

    ++info->cu_index;
  }

  /* Store value of each symbol.  */
  std::unordered_map<c_str_view, std::set<symbol_value>, c_str_view_hasher>
    m_name_to_value_set;

  /* Tables of DWARF-5 .debug_names.  They are in object file byte
     order.  */
  std::vector<uint32_t> m_bucket_table;
  std::vector<uint32_t> m_hash_table;

  const bfd_endian m_dwarf5_byte_order;
  dwarf_tmpl<uint32_t> m_dwarf32;
  dwarf_tmpl<uint64_t> m_dwarf64;
  dwarf &m_dwarf;
  offset_vec &m_name_table_string_offs, &m_name_table_entry_offs;
  debug_str_lookup m_debugstrlookup;

  /* Map each used .debug_names abbreviation tag parameter to its
     index value.  */
  std::unordered_map<index_key, int, index_key_hasher> m_indexkey_to_idx;

  /* Next unused .debug_names abbreviation tag for
     m_indexkey_to_idx.  */
  int m_idx_next = 1;

  /* .debug_names abbreviation table.  */
  data_buf m_abbrev_table;

  /* .debug_names entry pool.  */
  data_buf m_entry_pool;
};

/* Return iff any of the needed offsets does not fit into 32-bit
   .debug_names section.  */

static bool
check_dwarf64_offsets (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
    {
      if (to_underlying (per_cu->sect_off) >= (static_cast<uint64_t> (1) << 32))
	return true;
    }
  for (const signatured_type *sigtype : dwarf2_per_objfile->all_type_units)
    {
      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;
    }
  return false;
}

/* The psyms_seen set is potentially going to be largish (~40k
   elements when indexing a -g3 build of GDB itself).  Estimate the
   number of elements in order to avoid too many rehashes, which
   require rebuilding buckets and thus many trips to
   malloc/free.  */

static size_t
psyms_seen_size (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
  size_t psyms_count = 0;
  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
    {
      struct partial_symtab *psymtab = per_cu->v.psymtab;

      if (psymtab != NULL && psymtab->user == NULL)
	recursively_count_psymbols (psymtab, psyms_count);
    }
  /* Generating an index for gdb itself shows a ratio of
     TOTAL_SEEN_SYMS/UNIQUE_SYMS or ~5.  4 seems like a good bet.  */
  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.  */

static size_t
write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file)
{
  struct objfile *objfile = dwarf2_per_objfile->objfile;
  mapped_symtab symtab;
  data_buf 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;
  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
     all_comp_units, but only in their own hash table.  */

  std::unordered_set<partial_symbol *> psyms_seen
    (psyms_seen_size (dwarf2_per_objfile));
  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 partial_symtab *psymtab = per_cu->v.psymtab;

      /* CU of a shared file from 'dwz -m' may be unused by this main file.
	 It may be referenced from a local scope but in such case it does not
	 need to be present in .gdb_index.  */
      if (psymtab == NULL)
	continue;

      if (psymtab->user == NULL)
	recursively_write_psymbols (objfile, psymtab, &symtab,
				    psyms_seen, i);

      const auto insertpair = cu_index_htab.emplace (psymtab, i);
      gdb_assert (insertpair.second);

      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);
    }

  /* Dump the address map.  */
  data_buf addr_vec;
  write_address_map (objfile, addr_vec, cu_index_htab);

  /* Write out the .debug_type entries, if any.  */
  data_buf types_cu_list;
  if (dwarf2_per_objfile->signatured_types)
    {
      signatured_type_index_data sig_data (types_cu_list,
					   psyms_seen);

      sig_data.objfile = objfile;
      sig_data.symtab = &symtab;
      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);
    }

  /* Now that we've processed all symbols we can shrink their cu_indices
     lists.  */
  uniquify_cu_indices (&symtab);

  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;

  /* 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;
}

/* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension.  */
static const gdb_byte dwarf5_gdb_augmentation[] = { 'G', 'D', 'B', 0 };

/* Write a new .debug_names section for OBJFILE into OUT_FILE, write
   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
write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
		   FILE *out_file, FILE *out_file_str)
{
  const bool dwarf5_is_dwarf64 = check_dwarf64_offsets (dwarf2_per_objfile);
  struct objfile *objfile = dwarf2_per_objfile->objfile;
  const enum bfd_endian dwarf5_byte_order
    = gdbarch_byte_order (get_objfile_arch (objfile));

  /* 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
     all_comp_units, but only in their own hash table.  */
  data_buf cu_list;
  debug_names nametable (dwarf2_per_objfile, dwarf5_is_dwarf64,
			 dwarf5_byte_order);
  std::unordered_set<partial_symbol *>
    psyms_seen (psyms_seen_size (dwarf2_per_objfile));
  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;

      /* CU of a shared file from 'dwz -m' may be unused by this main
	 file.  It may be referenced from a local scope but in such
	 case it does not need to be present in .debug_names.  */
      if (psymtab == NULL)
	continue;

      if (psymtab->user == NULL)
	nametable.recursively_write_psymbols (objfile, psymtab, psyms_seen, i);

      cu_list.append_uint (nametable.dwarf5_offset_size (), dwarf5_byte_order,
			   to_underlying (per_cu->sect_off));
    }

  /* Write out the .debug_type entries, if any.  */
  data_buf types_cu_list;
  if (dwarf2_per_objfile->signatured_types)
    {
      debug_names::write_one_signatured_type_data sig_data (nametable,
			signatured_type_index_data (types_cu_list, psyms_seen));

      sig_data.info.objfile = objfile;
      /* It is used only for gdb_index.  */
      sig_data.info.symtab = nullptr;
      sig_data.info.cu_index = 0;
      htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
			      debug_names::write_one_signatured_type,
			      &sig_data);
    }

  nametable.build ();

  /* No addr_vec - DWARF-5 uses .debug_aranges generated by GCC.  */

  const offset_type bytes_of_header
    = ((dwarf5_is_dwarf64 ? 12 : 4)
       + 2 + 2 + 7 * 4
       + sizeof (dwarf5_gdb_augmentation));
  size_t expected_bytes = 0;
  expected_bytes += bytes_of_header;
  expected_bytes += cu_list.size ();
  expected_bytes += types_cu_list.size ();
  expected_bytes += nametable.bytes ();
  data_buf header;

  if (!dwarf5_is_dwarf64)
    {
      const uint64_t size64 = expected_bytes - 4;
      gdb_assert (size64 < 0xfffffff0);
      header.append_uint (4, dwarf5_byte_order, size64);
    }
  else
    {
      header.append_uint (4, dwarf5_byte_order, 0xffffffff);
      header.append_uint (8, dwarf5_byte_order, expected_bytes - 12);
    }

  /* The version number.  */
  header.append_uint (2, dwarf5_byte_order, 5);

  /* Padding.  */
  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->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->all_type_units.size ());

  /* foreign_type_unit_count - The number of TUs in the foreign TU
     list.  */
  header.append_uint (4, dwarf5_byte_order, 0);

  /* bucket_count - The number of hash buckets in the hash lookup
     table.  */
  header.append_uint (4, dwarf5_byte_order, nametable.bucket_count ());

  /* name_count - The number of unique names in the index.  */
  header.append_uint (4, dwarf5_byte_order, nametable.name_count ());

  /* abbrev_table_size - The size in bytes of the abbreviations
     table.  */
  header.append_uint (4, dwarf5_byte_order, nametable.abbrev_table_bytes ());

  /* augmentation_string_size - The size in bytes of the augmentation
     string.  This value is rounded up to a multiple of 4.  */
  static_assert (sizeof (dwarf5_gdb_augmentation) % 4 == 0, "");
  header.append_uint (4, dwarf5_byte_order, sizeof (dwarf5_gdb_augmentation));
  header.append_data (dwarf5_gdb_augmentation);

  gdb_assert (header.size () == bytes_of_header);

  header.file_write (out_file);
  cu_list.file_write (out_file);
  types_cu_list.file_write (out_file);
  nametable.file_write (out_file, out_file_str);

  return expected_bytes;
}

/* Assert that FILE's size is EXPECTED_SIZE.  Assumes file's seek
   position is at the end of the file.  */

static void
assert_file_size (FILE *file, const char *filename, size_t expected_size)
{
  const auto file_size = ftell (file);
  if (file_size == -1)
    error (_("Can't get `%s' size"), filename);
  gdb_assert (file_size == expected_size);
}

/* See dwarf-index-write.h.  */

void
write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
			 const char *dir, const char *basename,
			 dw_index_kind index_kind)
{
  struct objfile *objfile = dwarf2_per_objfile->objfile;

  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)
    error (_("Cannot make an index when the file has multiple .debug_types sections"));

  if (!objfile->psymtabs || !objfile->psymtabs_addrmap)
    return;

  struct stat st;
  if (stat (objfile_name (objfile), &st) < 0)
    perror_with_name (objfile_name (objfile));

  /* Make a filename suitable to pass to mkstemp based on F (e.g.
     /tmp/foo -> /tmp/foo-XXXXXX).  */
  auto make_temp_filename = [] (const std::string &f) -> gdb::char_vector
    {
      gdb::char_vector filename_temp (f.length () + 8);
      strcpy (filename_temp.data (), f.c_str ());
      strcat (filename_temp.data () + f.size (), "-XXXXXX");
      return filename_temp;
    };

  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);

  gdb::optional<scoped_fd> out_file_fd
    (gdb::in_place, mkstemp (filename_temp.data ()));
  if (out_file_fd->get () == -1)
    perror_with_name (("mkstemp"));

  FILE *out_file = gdb_fopen_cloexec (filename_temp.data (), "wb").release ();
  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_TEMP 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.)  We don't need OUT_FILE_FD anymore, so we might
     as well close it now.  */
  out_file_fd.reset ();
  gdb::unlinker unlink_file (filename_temp.data ());
  gdb_file_up close_out_file (out_file);

  if (index_kind == dw_index_kind::DEBUG_NAMES)
    {
      std::string filename_str (std::string (dir) + SLASH_STRING
				+ basename + DEBUG_STR_SUFFIX);
      gdb::char_vector filename_str_temp = make_temp_filename (filename_str);

      gdb::optional<scoped_fd> out_file_str_fd
	(gdb::in_place, mkstemp (filename_str_temp.data ()));
      if (out_file_str_fd->get () == -1)
        perror_with_name (("mkstemp"));

      FILE *out_file_str
	= gdb_fopen_cloexec (filename_str_temp.data (), "wb").release ();
      if (out_file_str == nullptr)
	error (_("Can't open `%s' for writing"), filename_str_temp.data ());

      out_file_str_fd.reset ();
      gdb::unlinker unlink_file_str (filename_str_temp.data ());
      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_temp.data (), total_len);

      /* We want to keep the file .debug_str file too.  */
      unlink_file_str.keep ();

      /* Close and move the str file in place.  */
      close_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_temp.data (), total_len);
    }

  /* We want to keep the file.  */
  unlink_file.keep ();

  /* Close and move the file in place.  */
  close_out_file.reset ();
  if (rename (filename_temp.data (), filename.c_str ()) != 0)
	perror_with_name (("rename"));
}

/* Implementation of the `save gdb-index' command.

   Note that the .gdb_index file format used by this command is
   documented in the GDB manual.  Any changes here must be documented
   there.  */

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;

  if (!arg)
    arg = "";

  arg = skip_spaces (arg);
  if (strncmp (arg, dwarf5space, strlen (dwarf5space)) == 0)
    {
      index_kind = dw_index_kind::DEBUG_NAMES;
      arg += strlen (dwarf5space);
      arg = skip_spaces (arg);
    }

  if (!*arg)
    error (_("usage: save gdb-index [-dwarf-5] DIRECTORY"));

  ALL_OBJFILES (objfile)
  {
    struct stat st;

    /* 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);

    if (dwarf2_per_objfile != NULL)
      {
	TRY
	  {
	    const char *basename = lbasename (objfile_name (objfile));
	    write_psymtabs_to_index (dwarf2_per_objfile, arg, basename,
				     index_kind);
	  }
	CATCH (except, RETURN_MASK_ERROR)
	  {
	    exception_fprintf (gdb_stderr, except,
			       _("Error while writing index for `%s': "),
			       objfile_name (objfile));
	  }
	END_CATCH
      }

  }
}

void
_initialize_dwarf_index_write ()
{
  cmd_list_element *c = add_cmd ("gdb-index", class_files,
				 save_gdb_index_command, _("\
Save a gdb-index file.\n\
Usage: save gdb-index [-dwarf-5] DIRECTORY\n\
\n\
No options create one file with .gdb-index extension for pre-DWARF-5\n\
compatible .gdb_index section.  With -dwarf-5 creates two files with\n\
extension .debug_names and .debug_str for DWARF-5 .debug_names section."),
	       &save_cmdlist);
  set_cmd_completer (c, filename_completer);
}
