xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/dwarf2/index-write.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17d62b00eSchristos /* DWARF index writing support for GDB.
27d62b00eSchristos 
3*6881a400Schristos    Copyright (C) 1994-2023 Free Software Foundation, Inc.
47d62b00eSchristos 
57d62b00eSchristos    This file is part of GDB.
67d62b00eSchristos 
77d62b00eSchristos    This program is free software; you can redistribute it and/or modify
87d62b00eSchristos    it under the terms of the GNU General Public License as published by
97d62b00eSchristos    the Free Software Foundation; either version 3 of the License, or
107d62b00eSchristos    (at your option) any later version.
117d62b00eSchristos 
127d62b00eSchristos    This program is distributed in the hope that it will be useful,
137d62b00eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
147d62b00eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
157d62b00eSchristos    GNU General Public License for more details.
167d62b00eSchristos 
177d62b00eSchristos    You should have received a copy of the GNU General Public License
187d62b00eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
197d62b00eSchristos 
207d62b00eSchristos #include "defs.h"
217d62b00eSchristos 
227d62b00eSchristos #include "dwarf2/index-write.h"
237d62b00eSchristos 
247d62b00eSchristos #include "addrmap.h"
257d62b00eSchristos #include "cli/cli-decode.h"
267d62b00eSchristos #include "gdbsupport/byte-vector.h"
277d62b00eSchristos #include "gdbsupport/filestuff.h"
287d62b00eSchristos #include "gdbsupport/gdb_unlinker.h"
297d62b00eSchristos #include "gdbsupport/pathstuff.h"
307d62b00eSchristos #include "gdbsupport/scoped_fd.h"
317d62b00eSchristos #include "complaints.h"
327d62b00eSchristos #include "dwarf2/index-common.h"
337d62b00eSchristos #include "dwarf2.h"
347d62b00eSchristos #include "dwarf2/read.h"
357d62b00eSchristos #include "dwarf2/dwz.h"
367d62b00eSchristos #include "gdb/gdb-index.h"
377d62b00eSchristos #include "gdbcmd.h"
387d62b00eSchristos #include "objfiles.h"
397d62b00eSchristos #include "ada-lang.h"
40*6881a400Schristos #include "dwarf2/tag.h"
417d62b00eSchristos 
427d62b00eSchristos #include <algorithm>
437d62b00eSchristos #include <cmath>
447d62b00eSchristos #include <forward_list>
457d62b00eSchristos #include <set>
467d62b00eSchristos #include <unordered_map>
477d62b00eSchristos #include <unordered_set>
487d62b00eSchristos 
497d62b00eSchristos /* Ensure only legit values are used.  */
507d62b00eSchristos #define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \
517d62b00eSchristos   do { \
527d62b00eSchristos     gdb_assert ((unsigned int) (value) <= 1); \
537d62b00eSchristos     GDB_INDEX_SYMBOL_STATIC_SET_VALUE((cu_index), (value)); \
547d62b00eSchristos   } while (0)
557d62b00eSchristos 
567d62b00eSchristos /* Ensure only legit values are used.  */
577d62b00eSchristos #define DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE(cu_index, value) \
587d62b00eSchristos   do { \
597d62b00eSchristos     gdb_assert ((value) >= GDB_INDEX_SYMBOL_KIND_TYPE \
607d62b00eSchristos 		&& (value) <= GDB_INDEX_SYMBOL_KIND_OTHER); \
617d62b00eSchristos     GDB_INDEX_SYMBOL_KIND_SET_VALUE((cu_index), (value)); \
627d62b00eSchristos   } while (0)
637d62b00eSchristos 
647d62b00eSchristos /* Ensure we don't use more than the allotted number of bits for the CU.  */
657d62b00eSchristos #define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value) \
667d62b00eSchristos   do { \
677d62b00eSchristos     gdb_assert (((value) & ~GDB_INDEX_CU_MASK) == 0); \
687d62b00eSchristos     GDB_INDEX_CU_SET_VALUE((cu_index), (value)); \
697d62b00eSchristos   } while (0)
707d62b00eSchristos 
717d62b00eSchristos /* The "save gdb-index" command.  */
727d62b00eSchristos 
737d62b00eSchristos /* Write SIZE bytes from the buffer pointed to by DATA to FILE, with
747d62b00eSchristos    error checking.  */
757d62b00eSchristos 
767d62b00eSchristos static void
777d62b00eSchristos file_write (FILE *file, const void *data, size_t size)
787d62b00eSchristos {
797d62b00eSchristos   if (fwrite (data, 1, size, file) != size)
807d62b00eSchristos     error (_("couldn't data write to file"));
817d62b00eSchristos }
827d62b00eSchristos 
837d62b00eSchristos /* Write the contents of VEC to FILE, with error checking.  */
847d62b00eSchristos 
857d62b00eSchristos template<typename Elem, typename Alloc>
867d62b00eSchristos static void
877d62b00eSchristos file_write (FILE *file, const std::vector<Elem, Alloc> &vec)
887d62b00eSchristos {
897d62b00eSchristos   if (!vec.empty ())
907d62b00eSchristos     file_write (file, vec.data (), vec.size () * sizeof (vec[0]));
917d62b00eSchristos }
927d62b00eSchristos 
937d62b00eSchristos /* In-memory buffer to prepare data to be written later to a file.  */
947d62b00eSchristos class data_buf
957d62b00eSchristos {
967d62b00eSchristos public:
97*6881a400Schristos   /* Copy ARRAY to the end of the buffer.  */
98*6881a400Schristos   void append_array (gdb::array_view<const gdb_byte> array)
997d62b00eSchristos   {
100*6881a400Schristos     std::copy (array.begin (), array.end (), grow (array.size ()));
1017d62b00eSchristos   }
1027d62b00eSchristos 
1037d62b00eSchristos   /* Copy CSTR (a zero-terminated string) to the end of buffer.  The
1047d62b00eSchristos      terminating zero is appended too.  */
1057d62b00eSchristos   void append_cstr0 (const char *cstr)
1067d62b00eSchristos   {
1077d62b00eSchristos     const size_t size = strlen (cstr) + 1;
1087d62b00eSchristos     std::copy (cstr, cstr + size, grow (size));
1097d62b00eSchristos   }
1107d62b00eSchristos 
1117d62b00eSchristos   /* Store INPUT as ULEB128 to the end of buffer.  */
1127d62b00eSchristos   void append_unsigned_leb128 (ULONGEST input)
1137d62b00eSchristos   {
1147d62b00eSchristos     for (;;)
1157d62b00eSchristos       {
1167d62b00eSchristos 	gdb_byte output = input & 0x7f;
1177d62b00eSchristos 	input >>= 7;
1187d62b00eSchristos 	if (input)
1197d62b00eSchristos 	  output |= 0x80;
120*6881a400Schristos 	m_vec.push_back (output);
1217d62b00eSchristos 	if (input == 0)
1227d62b00eSchristos 	  break;
1237d62b00eSchristos       }
1247d62b00eSchristos   }
1257d62b00eSchristos 
1267d62b00eSchristos   /* Accept a host-format integer in VAL and append it to the buffer
1277d62b00eSchristos      as a target-format integer which is LEN bytes long.  */
1287d62b00eSchristos   void append_uint (size_t len, bfd_endian byte_order, ULONGEST val)
1297d62b00eSchristos   {
1307d62b00eSchristos     ::store_unsigned_integer (grow (len), len, byte_order, val);
1317d62b00eSchristos   }
1327d62b00eSchristos 
133*6881a400Schristos   /* Copy VALUE to the end of the buffer, little-endian.  */
134*6881a400Schristos   void append_offset (offset_type value)
135*6881a400Schristos   {
136*6881a400Schristos     append_uint (sizeof (value), BFD_ENDIAN_LITTLE, value);
137*6881a400Schristos   }
138*6881a400Schristos 
1397d62b00eSchristos   /* Return the size of the buffer.  */
1407d62b00eSchristos   size_t size () const
1417d62b00eSchristos   {
1427d62b00eSchristos     return m_vec.size ();
1437d62b00eSchristos   }
1447d62b00eSchristos 
1457d62b00eSchristos   /* Return true iff the buffer is empty.  */
1467d62b00eSchristos   bool empty () const
1477d62b00eSchristos   {
1487d62b00eSchristos     return m_vec.empty ();
1497d62b00eSchristos   }
1507d62b00eSchristos 
1517d62b00eSchristos   /* Write the buffer to FILE.  */
1527d62b00eSchristos   void file_write (FILE *file) const
1537d62b00eSchristos   {
1547d62b00eSchristos     ::file_write (file, m_vec);
1557d62b00eSchristos   }
1567d62b00eSchristos 
1577d62b00eSchristos private:
1587d62b00eSchristos   /* Grow SIZE bytes at the end of the buffer.  Returns a pointer to
1597d62b00eSchristos      the start of the new block.  */
1607d62b00eSchristos   gdb_byte *grow (size_t size)
1617d62b00eSchristos   {
1627d62b00eSchristos     m_vec.resize (m_vec.size () + size);
1637d62b00eSchristos     return &*(m_vec.end () - size);
1647d62b00eSchristos   }
1657d62b00eSchristos 
1667d62b00eSchristos   gdb::byte_vector m_vec;
1677d62b00eSchristos };
1687d62b00eSchristos 
1697d62b00eSchristos /* An entry in the symbol table.  */
1707d62b00eSchristos struct symtab_index_entry
1717d62b00eSchristos {
1727d62b00eSchristos   /* The name of the symbol.  */
1737d62b00eSchristos   const char *name;
1747d62b00eSchristos   /* The offset of the name in the constant pool.  */
1757d62b00eSchristos   offset_type index_offset;
1767d62b00eSchristos   /* A sorted vector of the indices of all the CUs that hold an object
1777d62b00eSchristos      of this name.  */
1787d62b00eSchristos   std::vector<offset_type> cu_indices;
179*6881a400Schristos 
180*6881a400Schristos   /* Minimize CU_INDICES, sorting them and removing duplicates as
181*6881a400Schristos      appropriate.  */
182*6881a400Schristos   void minimize ();
1837d62b00eSchristos };
1847d62b00eSchristos 
1857d62b00eSchristos /* The symbol table.  This is a power-of-2-sized hash table.  */
1867d62b00eSchristos struct mapped_symtab
1877d62b00eSchristos {
1887d62b00eSchristos   mapped_symtab ()
1897d62b00eSchristos   {
1907d62b00eSchristos     data.resize (1024);
1917d62b00eSchristos   }
1927d62b00eSchristos 
193*6881a400Schristos   /* Minimize each entry in the symbol table, removing duplicates.  */
194*6881a400Schristos   void minimize ()
195*6881a400Schristos   {
196*6881a400Schristos     for (symtab_index_entry &item : data)
197*6881a400Schristos       item.minimize ();
198*6881a400Schristos   }
199*6881a400Schristos 
2007d62b00eSchristos   offset_type n_elements = 0;
2017d62b00eSchristos   std::vector<symtab_index_entry> data;
2027d62b00eSchristos 
203*6881a400Schristos   /* Temporary storage for names.  */
2047d62b00eSchristos   auto_obstack m_string_obstack;
2057d62b00eSchristos };
2067d62b00eSchristos 
2077d62b00eSchristos /* Find a slot in SYMTAB for the symbol NAME.  Returns a reference to
2087d62b00eSchristos    the slot.
2097d62b00eSchristos 
2107d62b00eSchristos    Function is used only during write_hash_table so no index format backward
2117d62b00eSchristos    compatibility is needed.  */
2127d62b00eSchristos 
2137d62b00eSchristos static symtab_index_entry &
2147d62b00eSchristos find_slot (struct mapped_symtab *symtab, const char *name)
2157d62b00eSchristos {
2167d62b00eSchristos   offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name);
2177d62b00eSchristos 
2187d62b00eSchristos   index = hash & (symtab->data.size () - 1);
2197d62b00eSchristos   step = ((hash * 17) & (symtab->data.size () - 1)) | 1;
2207d62b00eSchristos 
2217d62b00eSchristos   for (;;)
2227d62b00eSchristos     {
2237d62b00eSchristos       if (symtab->data[index].name == NULL
2247d62b00eSchristos 	  || strcmp (name, symtab->data[index].name) == 0)
2257d62b00eSchristos 	return symtab->data[index];
2267d62b00eSchristos       index = (index + step) & (symtab->data.size () - 1);
2277d62b00eSchristos     }
2287d62b00eSchristos }
2297d62b00eSchristos 
2307d62b00eSchristos /* Expand SYMTAB's hash table.  */
2317d62b00eSchristos 
2327d62b00eSchristos static void
2337d62b00eSchristos hash_expand (struct mapped_symtab *symtab)
2347d62b00eSchristos {
2357d62b00eSchristos   auto old_entries = std::move (symtab->data);
2367d62b00eSchristos 
2377d62b00eSchristos   symtab->data.clear ();
2387d62b00eSchristos   symtab->data.resize (old_entries.size () * 2);
2397d62b00eSchristos 
2407d62b00eSchristos   for (auto &it : old_entries)
2417d62b00eSchristos     if (it.name != NULL)
2427d62b00eSchristos       {
2437d62b00eSchristos 	auto &ref = find_slot (symtab, it.name);
2447d62b00eSchristos 	ref = std::move (it);
2457d62b00eSchristos       }
2467d62b00eSchristos }
2477d62b00eSchristos 
2487d62b00eSchristos /* Add an entry to SYMTAB.  NAME is the name of the symbol.
2497d62b00eSchristos    CU_INDEX is the index of the CU in which the symbol appears.
2507d62b00eSchristos    IS_STATIC is one if the symbol is static, otherwise zero (global).  */
2517d62b00eSchristos 
2527d62b00eSchristos static void
2537d62b00eSchristos add_index_entry (struct mapped_symtab *symtab, const char *name,
2547d62b00eSchristos 		 int is_static, gdb_index_symbol_kind kind,
2557d62b00eSchristos 		 offset_type cu_index)
2567d62b00eSchristos {
2577d62b00eSchristos   offset_type cu_index_and_attrs;
2587d62b00eSchristos 
2597d62b00eSchristos   ++symtab->n_elements;
2607d62b00eSchristos   if (4 * symtab->n_elements / 3 >= symtab->data.size ())
2617d62b00eSchristos     hash_expand (symtab);
2627d62b00eSchristos 
2637d62b00eSchristos   symtab_index_entry &slot = find_slot (symtab, name);
2647d62b00eSchristos   if (slot.name == NULL)
2657d62b00eSchristos     {
2667d62b00eSchristos       slot.name = name;
2677d62b00eSchristos       /* index_offset is set later.  */
2687d62b00eSchristos     }
2697d62b00eSchristos 
2707d62b00eSchristos   cu_index_and_attrs = 0;
2717d62b00eSchristos   DW2_GDB_INDEX_CU_SET_VALUE (cu_index_and_attrs, cu_index);
2727d62b00eSchristos   DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE (cu_index_and_attrs, is_static);
2737d62b00eSchristos   DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE (cu_index_and_attrs, kind);
2747d62b00eSchristos 
2757d62b00eSchristos   /* We don't want to record an index value twice as we want to avoid the
2767d62b00eSchristos      duplication.
2777d62b00eSchristos      We process all global symbols and then all static symbols
2787d62b00eSchristos      (which would allow us to avoid the duplication by only having to check
2797d62b00eSchristos      the last entry pushed), but a symbol could have multiple kinds in one CU.
2807d62b00eSchristos      To keep things simple we don't worry about the duplication here and
2817d62b00eSchristos      sort and uniquify the list after we've processed all symbols.  */
2827d62b00eSchristos   slot.cu_indices.push_back (cu_index_and_attrs);
2837d62b00eSchristos }
2847d62b00eSchristos 
285*6881a400Schristos /* See symtab_index_entry.  */
2867d62b00eSchristos 
287*6881a400Schristos void
288*6881a400Schristos symtab_index_entry::minimize ()
2897d62b00eSchristos {
290*6881a400Schristos   if (name == nullptr || cu_indices.empty ())
291*6881a400Schristos     return;
292*6881a400Schristos 
2937d62b00eSchristos   std::sort (cu_indices.begin (), cu_indices.end ());
2947d62b00eSchristos   auto from = std::unique (cu_indices.begin (), cu_indices.end ());
2957d62b00eSchristos   cu_indices.erase (from, cu_indices.end ());
296*6881a400Schristos 
297*6881a400Schristos   /* We don't want to enter a variable or type more than once, so
298*6881a400Schristos      remove any such duplicates from the list as well.  When doing
299*6881a400Schristos      this, we want to keep the entry from the first CU -- but this is
300*6881a400Schristos      implicit due to the sort.  This choice is done because it's
301*6881a400Schristos      similar to what gdb historically did for partial symbols.  */
302*6881a400Schristos   std::unordered_set<offset_type> seen;
303*6881a400Schristos   from = std::remove_if (cu_indices.begin (), cu_indices.end (),
304*6881a400Schristos 			 [&] (offset_type val)
305*6881a400Schristos     {
306*6881a400Schristos       gdb_index_symbol_kind kind = GDB_INDEX_SYMBOL_KIND_VALUE (val);
307*6881a400Schristos       if (kind != GDB_INDEX_SYMBOL_KIND_TYPE
308*6881a400Schristos 	  && kind != GDB_INDEX_SYMBOL_KIND_VARIABLE)
309*6881a400Schristos 	return false;
310*6881a400Schristos 
311*6881a400Schristos       val &= ~GDB_INDEX_CU_MASK;
312*6881a400Schristos       return !seen.insert (val).second;
313*6881a400Schristos     });
314*6881a400Schristos   cu_indices.erase (from, cu_indices.end ());
3157d62b00eSchristos }
3167d62b00eSchristos 
3177d62b00eSchristos /* A form of 'const char *' suitable for container keys.  Only the
3187d62b00eSchristos    pointer is stored.  The strings themselves are compared, not the
3197d62b00eSchristos    pointers.  */
3207d62b00eSchristos class c_str_view
3217d62b00eSchristos {
3227d62b00eSchristos public:
3237d62b00eSchristos   c_str_view (const char *cstr)
3247d62b00eSchristos     : m_cstr (cstr)
3257d62b00eSchristos   {}
3267d62b00eSchristos 
3277d62b00eSchristos   bool operator== (const c_str_view &other) const
3287d62b00eSchristos   {
3297d62b00eSchristos     return strcmp (m_cstr, other.m_cstr) == 0;
3307d62b00eSchristos   }
3317d62b00eSchristos 
3327d62b00eSchristos   /* Return the underlying C string.  Note, the returned string is
3337d62b00eSchristos      only a reference with lifetime of this object.  */
3347d62b00eSchristos   const char *c_str () const
3357d62b00eSchristos   {
3367d62b00eSchristos     return m_cstr;
3377d62b00eSchristos   }
3387d62b00eSchristos 
3397d62b00eSchristos private:
3407d62b00eSchristos   friend class c_str_view_hasher;
3417d62b00eSchristos   const char *const m_cstr;
3427d62b00eSchristos };
3437d62b00eSchristos 
3447d62b00eSchristos /* A std::unordered_map::hasher for c_str_view that uses the right
3457d62b00eSchristos    hash function for strings in a mapped index.  */
3467d62b00eSchristos class c_str_view_hasher
3477d62b00eSchristos {
3487d62b00eSchristos public:
3497d62b00eSchristos   size_t operator () (const c_str_view &x) const
3507d62b00eSchristos   {
3517d62b00eSchristos     return mapped_index_string_hash (INT_MAX, x.m_cstr);
3527d62b00eSchristos   }
3537d62b00eSchristos };
3547d62b00eSchristos 
3557d62b00eSchristos /* A std::unordered_map::hasher for std::vector<>.  */
3567d62b00eSchristos template<typename T>
3577d62b00eSchristos class vector_hasher
3587d62b00eSchristos {
3597d62b00eSchristos public:
3607d62b00eSchristos   size_t operator () (const std::vector<T> &key) const
3617d62b00eSchristos   {
3627d62b00eSchristos     return iterative_hash (key.data (),
3637d62b00eSchristos 			   sizeof (key.front ()) * key.size (), 0);
3647d62b00eSchristos   }
3657d62b00eSchristos };
3667d62b00eSchristos 
3677d62b00eSchristos /* Write the mapped hash table SYMTAB to the data buffer OUTPUT, with
3687d62b00eSchristos    constant pool entries going into the data buffer CPOOL.  */
3697d62b00eSchristos 
3707d62b00eSchristos static void
3717d62b00eSchristos write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
3727d62b00eSchristos {
3737d62b00eSchristos   {
3747d62b00eSchristos     /* Elements are sorted vectors of the indices of all the CUs that
3757d62b00eSchristos        hold an object of this name.  */
3767d62b00eSchristos     std::unordered_map<std::vector<offset_type>, offset_type,
3777d62b00eSchristos 		       vector_hasher<offset_type>>
3787d62b00eSchristos       symbol_hash_table;
3797d62b00eSchristos 
3807d62b00eSchristos     /* We add all the index vectors to the constant pool first, to
3817d62b00eSchristos        ensure alignment is ok.  */
3827d62b00eSchristos     for (symtab_index_entry &entry : symtab->data)
3837d62b00eSchristos       {
3847d62b00eSchristos 	if (entry.name == NULL)
3857d62b00eSchristos 	  continue;
3867d62b00eSchristos 	gdb_assert (entry.index_offset == 0);
3877d62b00eSchristos 
3887d62b00eSchristos 	/* Finding before inserting is faster than always trying to
3897d62b00eSchristos 	   insert, because inserting always allocates a node, does the
3907d62b00eSchristos 	   lookup, and then destroys the new node if another node
3917d62b00eSchristos 	   already had the same key.  C++17 try_emplace will avoid
3927d62b00eSchristos 	   this.  */
3937d62b00eSchristos 	const auto found
3947d62b00eSchristos 	  = symbol_hash_table.find (entry.cu_indices);
3957d62b00eSchristos 	if (found != symbol_hash_table.end ())
3967d62b00eSchristos 	  {
3977d62b00eSchristos 	    entry.index_offset = found->second;
3987d62b00eSchristos 	    continue;
3997d62b00eSchristos 	  }
4007d62b00eSchristos 
4017d62b00eSchristos 	symbol_hash_table.emplace (entry.cu_indices, cpool.size ());
4027d62b00eSchristos 	entry.index_offset = cpool.size ();
403*6881a400Schristos 	cpool.append_offset (entry.cu_indices.size ());
4047d62b00eSchristos 	for (const auto index : entry.cu_indices)
405*6881a400Schristos 	  cpool.append_offset (index);
4067d62b00eSchristos       }
4077d62b00eSchristos   }
4087d62b00eSchristos 
4097d62b00eSchristos   /* Now write out the hash table.  */
4107d62b00eSchristos   std::unordered_map<c_str_view, offset_type, c_str_view_hasher> str_table;
4117d62b00eSchristos   for (const auto &entry : symtab->data)
4127d62b00eSchristos     {
4137d62b00eSchristos       offset_type str_off, vec_off;
4147d62b00eSchristos 
4157d62b00eSchristos       if (entry.name != NULL)
4167d62b00eSchristos 	{
4177d62b00eSchristos 	  const auto insertpair = str_table.emplace (entry.name, cpool.size ());
4187d62b00eSchristos 	  if (insertpair.second)
4197d62b00eSchristos 	    cpool.append_cstr0 (entry.name);
4207d62b00eSchristos 	  str_off = insertpair.first->second;
4217d62b00eSchristos 	  vec_off = entry.index_offset;
4227d62b00eSchristos 	}
4237d62b00eSchristos       else
4247d62b00eSchristos 	{
4257d62b00eSchristos 	  /* While 0 is a valid constant pool index, it is not valid
4267d62b00eSchristos 	     to have 0 for both offsets.  */
4277d62b00eSchristos 	  str_off = 0;
4287d62b00eSchristos 	  vec_off = 0;
4297d62b00eSchristos 	}
4307d62b00eSchristos 
431*6881a400Schristos       output.append_offset (str_off);
432*6881a400Schristos       output.append_offset (vec_off);
4337d62b00eSchristos     }
4347d62b00eSchristos }
4357d62b00eSchristos 
436*6881a400Schristos typedef std::unordered_map<dwarf2_per_cu_data *, unsigned int> cu_index_map;
4377d62b00eSchristos 
4387d62b00eSchristos /* Helper struct for building the address table.  */
4397d62b00eSchristos struct addrmap_index_data
4407d62b00eSchristos {
441*6881a400Schristos   addrmap_index_data (data_buf &addr_vec_, cu_index_map &cu_index_htab_)
442*6881a400Schristos     : addr_vec (addr_vec_),
443*6881a400Schristos       cu_index_htab (cu_index_htab_)
4447d62b00eSchristos   {}
4457d62b00eSchristos 
4467d62b00eSchristos   data_buf &addr_vec;
447*6881a400Schristos   cu_index_map &cu_index_htab;
4487d62b00eSchristos 
449*6881a400Schristos   int operator() (CORE_ADDR start_addr, void *obj);
450*6881a400Schristos 
451*6881a400Schristos   /* True if the previous_* fields are valid.
4527d62b00eSchristos      We can't write an entry until we see the next entry (since it is only then
4537d62b00eSchristos      that we know the end of the entry).  */
454*6881a400Schristos   bool previous_valid = false;
4557d62b00eSchristos   /* Index of the CU in the table of all CUs in the index file.  */
456*6881a400Schristos   unsigned int previous_cu_index = 0;
4577d62b00eSchristos   /* Start address of the CU.  */
458*6881a400Schristos   CORE_ADDR previous_cu_start = 0;
4597d62b00eSchristos };
4607d62b00eSchristos 
4617d62b00eSchristos /* Write an address entry to ADDR_VEC.  */
4627d62b00eSchristos 
4637d62b00eSchristos static void
464*6881a400Schristos add_address_entry (data_buf &addr_vec,
4657d62b00eSchristos 		   CORE_ADDR start, CORE_ADDR end, unsigned int cu_index)
4667d62b00eSchristos {
4677d62b00eSchristos   addr_vec.append_uint (8, BFD_ENDIAN_LITTLE, start);
4687d62b00eSchristos   addr_vec.append_uint (8, BFD_ENDIAN_LITTLE, end);
469*6881a400Schristos   addr_vec.append_offset (cu_index);
4707d62b00eSchristos }
4717d62b00eSchristos 
4727d62b00eSchristos /* Worker function for traversing an addrmap to build the address table.  */
4737d62b00eSchristos 
474*6881a400Schristos int
475*6881a400Schristos addrmap_index_data::operator() (CORE_ADDR start_addr, void *obj)
4767d62b00eSchristos {
477*6881a400Schristos   dwarf2_per_cu_data *per_cu = (dwarf2_per_cu_data *) obj;
4787d62b00eSchristos 
479*6881a400Schristos   if (previous_valid)
480*6881a400Schristos     add_address_entry (addr_vec,
481*6881a400Schristos 		       previous_cu_start, start_addr,
482*6881a400Schristos 		       previous_cu_index);
4837d62b00eSchristos 
484*6881a400Schristos   previous_cu_start = start_addr;
485*6881a400Schristos   if (per_cu != NULL)
4867d62b00eSchristos     {
487*6881a400Schristos       const auto it = cu_index_htab.find (per_cu);
488*6881a400Schristos       gdb_assert (it != cu_index_htab.cend ());
489*6881a400Schristos       previous_cu_index = it->second;
490*6881a400Schristos       previous_valid = true;
4917d62b00eSchristos     }
4927d62b00eSchristos   else
493*6881a400Schristos     previous_valid = false;
4947d62b00eSchristos 
4957d62b00eSchristos   return 0;
4967d62b00eSchristos }
4977d62b00eSchristos 
498*6881a400Schristos /* Write PER_BFD's address map to ADDR_VEC.
4997d62b00eSchristos    CU_INDEX_HTAB is used to map addrmap entries to their CU indices
5007d62b00eSchristos    in the index file.  */
5017d62b00eSchristos 
5027d62b00eSchristos static void
503*6881a400Schristos write_address_map (struct addrmap *addrmap, data_buf &addr_vec,
504*6881a400Schristos 		   cu_index_map &cu_index_htab)
5057d62b00eSchristos {
5067d62b00eSchristos   struct addrmap_index_data addrmap_index_data (addr_vec, cu_index_htab);
5077d62b00eSchristos 
508*6881a400Schristos   addrmap->foreach (addrmap_index_data);
5097d62b00eSchristos 
5107d62b00eSchristos   /* It's highly unlikely the last entry (end address = 0xff...ff)
5117d62b00eSchristos      is valid, but we should still handle it.
5127d62b00eSchristos      The end address is recorded as the start of the next region, but that
5137d62b00eSchristos      doesn't work here.  To cope we pass 0xff...ff, this is a rare situation
5147d62b00eSchristos      anyway.  */
5157d62b00eSchristos   if (addrmap_index_data.previous_valid)
516*6881a400Schristos     add_address_entry (addr_vec,
5177d62b00eSchristos 		       addrmap_index_data.previous_cu_start, (CORE_ADDR) -1,
5187d62b00eSchristos 		       addrmap_index_data.previous_cu_index);
5197d62b00eSchristos }
5207d62b00eSchristos 
5217d62b00eSchristos /* DWARF-5 .debug_names builder.  */
5227d62b00eSchristos class debug_names
5237d62b00eSchristos {
5247d62b00eSchristos public:
5257d62b00eSchristos   debug_names (dwarf2_per_objfile *per_objfile, bool is_dwarf64,
5267d62b00eSchristos 	       bfd_endian dwarf5_byte_order)
5277d62b00eSchristos     : m_dwarf5_byte_order (dwarf5_byte_order),
5287d62b00eSchristos       m_dwarf32 (dwarf5_byte_order),
5297d62b00eSchristos       m_dwarf64 (dwarf5_byte_order),
5307d62b00eSchristos       m_dwarf (is_dwarf64
5317d62b00eSchristos 	       ? static_cast<dwarf &> (m_dwarf64)
5327d62b00eSchristos 	       : static_cast<dwarf &> (m_dwarf32)),
5337d62b00eSchristos       m_name_table_string_offs (m_dwarf.name_table_string_offs),
5347d62b00eSchristos       m_name_table_entry_offs (m_dwarf.name_table_entry_offs),
5357d62b00eSchristos       m_debugstrlookup (per_objfile)
5367d62b00eSchristos   {}
5377d62b00eSchristos 
5387d62b00eSchristos   int dwarf5_offset_size () const
5397d62b00eSchristos   {
5407d62b00eSchristos     const bool dwarf5_is_dwarf64 = &m_dwarf == &m_dwarf64;
5417d62b00eSchristos     return dwarf5_is_dwarf64 ? 8 : 4;
5427d62b00eSchristos   }
5437d62b00eSchristos 
5447d62b00eSchristos   /* Is this symbol from DW_TAG_compile_unit or DW_TAG_type_unit?  */
5457d62b00eSchristos   enum class unit_kind { cu, tu };
5467d62b00eSchristos 
5477d62b00eSchristos   /* Insert one symbol.  */
548*6881a400Schristos   void insert (const cooked_index_entry *entry)
5497d62b00eSchristos   {
550*6881a400Schristos     const auto it = m_cu_index_htab.find (entry->per_cu);
551*6881a400Schristos     gdb_assert (it != m_cu_index_htab.cend ());
552*6881a400Schristos     const char *name = entry->full_name (&m_string_obstack);
5537d62b00eSchristos 
554*6881a400Schristos     /* This is incorrect but it mirrors gdb's historical behavior; and
555*6881a400Schristos        because the current .debug_names generation is also incorrect,
556*6881a400Schristos        it seems better to follow what was done before, rather than
557*6881a400Schristos        introduce a mismatch between the newer and older gdb.  */
558*6881a400Schristos     dwarf_tag tag = entry->tag;
559*6881a400Schristos     if (tag != DW_TAG_typedef && tag_is_type (tag))
560*6881a400Schristos       tag = DW_TAG_structure_type;
561*6881a400Schristos     else if (tag == DW_TAG_enumerator || tag == DW_TAG_constant)
562*6881a400Schristos       tag = DW_TAG_variable;
563*6881a400Schristos 
564*6881a400Schristos     int cu_index = it->second;
565*6881a400Schristos     bool is_static = (entry->flags & IS_STATIC) != 0;
566*6881a400Schristos     unit_kind kind = (entry->per_cu->is_debug_types
567*6881a400Schristos 		      ? unit_kind::tu
568*6881a400Schristos 		      : unit_kind::cu);
569*6881a400Schristos 
570*6881a400Schristos     if (entry->per_cu->lang () == language_ada)
5717d62b00eSchristos       {
5727d62b00eSchristos 	/* We want to ensure that the Ada main function's name appears
5737d62b00eSchristos 	   verbatim in the index.  However, this name will be of the
5747d62b00eSchristos 	   form "_ada_mumble", and will be rewritten by ada_decode.
5757d62b00eSchristos 	   So, recognize it specially here and add it to the index by
5767d62b00eSchristos 	   hand.  */
5777d62b00eSchristos 	if (strcmp (main_name (), name) == 0)
5787d62b00eSchristos 	  {
5797d62b00eSchristos 	    const auto insertpair
5807d62b00eSchristos 	      = m_name_to_value_set.emplace (c_str_view (name),
5817d62b00eSchristos 					     std::set<symbol_value> ());
5827d62b00eSchristos 	    std::set<symbol_value> &value_set = insertpair.first->second;
583*6881a400Schristos 	    value_set.emplace (symbol_value (tag, cu_index, is_static, kind));
5847d62b00eSchristos 	  }
5857d62b00eSchristos 
5867d62b00eSchristos 	/* In order for the index to work when read back into gdb, it
5877d62b00eSchristos 	   has to supply a funny form of the name: it should be the
5887d62b00eSchristos 	   encoded name, with any suffixes stripped.  Using the
5897d62b00eSchristos 	   ordinary encoded name will not work properly with the
5907d62b00eSchristos 	   searching logic in find_name_components_bounds; nor will
5917d62b00eSchristos 	   using the decoded name.  Furthermore, an Ada "verbatim"
5927d62b00eSchristos 	   name (of the form "<MumBle>") must be entered without the
5937d62b00eSchristos 	   angle brackets.  Note that the current index is unusual,
5947d62b00eSchristos 	   see PR symtab/24820 for details.  */
5957d62b00eSchristos 	std::string decoded = ada_decode (name);
5967d62b00eSchristos 	if (decoded[0] == '<')
5977d62b00eSchristos 	  name = (char *) obstack_copy0 (&m_string_obstack,
5987d62b00eSchristos 					 decoded.c_str () + 1,
5997d62b00eSchristos 					 decoded.length () - 2);
6007d62b00eSchristos 	else
6017d62b00eSchristos 	  name = obstack_strdup (&m_string_obstack,
6027d62b00eSchristos 				 ada_encode (decoded.c_str ()));
6037d62b00eSchristos       }
6047d62b00eSchristos 
6057d62b00eSchristos     const auto insertpair
6067d62b00eSchristos       = m_name_to_value_set.emplace (c_str_view (name),
6077d62b00eSchristos 				     std::set<symbol_value> ());
6087d62b00eSchristos     std::set<symbol_value> &value_set = insertpair.first->second;
609*6881a400Schristos     value_set.emplace (symbol_value (tag, cu_index, is_static, kind));
6107d62b00eSchristos   }
6117d62b00eSchristos 
6127d62b00eSchristos   /* Build all the tables.  All symbols must be already inserted.
6137d62b00eSchristos      This function does not call file_write, caller has to do it
6147d62b00eSchristos      afterwards.  */
6157d62b00eSchristos   void build ()
6167d62b00eSchristos   {
6177d62b00eSchristos     /* Verify the build method has not be called twice.  */
6187d62b00eSchristos     gdb_assert (m_abbrev_table.empty ());
6197d62b00eSchristos     const size_t name_count = m_name_to_value_set.size ();
6207d62b00eSchristos     m_bucket_table.resize
6217d62b00eSchristos       (std::pow (2, std::ceil (std::log2 (name_count * 4 / 3))));
6227d62b00eSchristos     m_hash_table.reserve (name_count);
6237d62b00eSchristos     m_name_table_string_offs.reserve (name_count);
6247d62b00eSchristos     m_name_table_entry_offs.reserve (name_count);
6257d62b00eSchristos 
6267d62b00eSchristos     /* Map each hash of symbol to its name and value.  */
6277d62b00eSchristos     struct hash_it_pair
6287d62b00eSchristos     {
6297d62b00eSchristos       uint32_t hash;
6307d62b00eSchristos       decltype (m_name_to_value_set)::const_iterator it;
6317d62b00eSchristos     };
6327d62b00eSchristos     std::vector<std::forward_list<hash_it_pair>> bucket_hash;
6337d62b00eSchristos     bucket_hash.resize (m_bucket_table.size ());
6347d62b00eSchristos     for (decltype (m_name_to_value_set)::const_iterator it
6357d62b00eSchristos 	   = m_name_to_value_set.cbegin ();
6367d62b00eSchristos 	 it != m_name_to_value_set.cend ();
6377d62b00eSchristos 	 ++it)
6387d62b00eSchristos       {
6397d62b00eSchristos 	const char *const name = it->first.c_str ();
6407d62b00eSchristos 	const uint32_t hash = dwarf5_djb_hash (name);
6417d62b00eSchristos 	hash_it_pair hashitpair;
6427d62b00eSchristos 	hashitpair.hash = hash;
6437d62b00eSchristos 	hashitpair.it = it;
6447d62b00eSchristos 	auto &slot = bucket_hash[hash % bucket_hash.size()];
6457d62b00eSchristos 	slot.push_front (std::move (hashitpair));
6467d62b00eSchristos       }
6477d62b00eSchristos     for (size_t bucket_ix = 0; bucket_ix < bucket_hash.size (); ++bucket_ix)
6487d62b00eSchristos       {
6497d62b00eSchristos 	const std::forward_list<hash_it_pair> &hashitlist
6507d62b00eSchristos 	  = bucket_hash[bucket_ix];
6517d62b00eSchristos 	if (hashitlist.empty ())
6527d62b00eSchristos 	  continue;
6537d62b00eSchristos 	uint32_t &bucket_slot = m_bucket_table[bucket_ix];
6547d62b00eSchristos 	/* The hashes array is indexed starting at 1.  */
6557d62b00eSchristos 	store_unsigned_integer (reinterpret_cast<gdb_byte *> (&bucket_slot),
6567d62b00eSchristos 				sizeof (bucket_slot), m_dwarf5_byte_order,
6577d62b00eSchristos 				m_hash_table.size () + 1);
6587d62b00eSchristos 	for (const hash_it_pair &hashitpair : hashitlist)
6597d62b00eSchristos 	  {
6607d62b00eSchristos 	    m_hash_table.push_back (0);
6617d62b00eSchristos 	    store_unsigned_integer (reinterpret_cast<gdb_byte *>
6627d62b00eSchristos 							(&m_hash_table.back ()),
6637d62b00eSchristos 				    sizeof (m_hash_table.back ()),
6647d62b00eSchristos 				    m_dwarf5_byte_order, hashitpair.hash);
6657d62b00eSchristos 	    const c_str_view &name = hashitpair.it->first;
6667d62b00eSchristos 	    const std::set<symbol_value> &value_set = hashitpair.it->second;
6677d62b00eSchristos 	    m_name_table_string_offs.push_back_reorder
6687d62b00eSchristos 	      (m_debugstrlookup.lookup (name.c_str ()));
6697d62b00eSchristos 	    m_name_table_entry_offs.push_back_reorder (m_entry_pool.size ());
6707d62b00eSchristos 	    gdb_assert (!value_set.empty ());
6717d62b00eSchristos 	    for (const symbol_value &value : value_set)
6727d62b00eSchristos 	      {
6737d62b00eSchristos 		int &idx = m_indexkey_to_idx[index_key (value.dwarf_tag,
6747d62b00eSchristos 							value.is_static,
6757d62b00eSchristos 							value.kind)];
6767d62b00eSchristos 		if (idx == 0)
6777d62b00eSchristos 		  {
6787d62b00eSchristos 		    idx = m_idx_next++;
6797d62b00eSchristos 		    m_abbrev_table.append_unsigned_leb128 (idx);
6807d62b00eSchristos 		    m_abbrev_table.append_unsigned_leb128 (value.dwarf_tag);
6817d62b00eSchristos 		    m_abbrev_table.append_unsigned_leb128
6827d62b00eSchristos 			      (value.kind == unit_kind::cu ? DW_IDX_compile_unit
6837d62b00eSchristos 							   : DW_IDX_type_unit);
6847d62b00eSchristos 		    m_abbrev_table.append_unsigned_leb128 (DW_FORM_udata);
6857d62b00eSchristos 		    m_abbrev_table.append_unsigned_leb128 (value.is_static
6867d62b00eSchristos 							   ? DW_IDX_GNU_internal
6877d62b00eSchristos 							   : DW_IDX_GNU_external);
6887d62b00eSchristos 		    m_abbrev_table.append_unsigned_leb128 (DW_FORM_flag_present);
6897d62b00eSchristos 
6907d62b00eSchristos 		    /* Terminate attributes list.  */
6917d62b00eSchristos 		    m_abbrev_table.append_unsigned_leb128 (0);
6927d62b00eSchristos 		    m_abbrev_table.append_unsigned_leb128 (0);
6937d62b00eSchristos 		  }
6947d62b00eSchristos 
6957d62b00eSchristos 		m_entry_pool.append_unsigned_leb128 (idx);
6967d62b00eSchristos 		m_entry_pool.append_unsigned_leb128 (value.cu_index);
6977d62b00eSchristos 	      }
6987d62b00eSchristos 
6997d62b00eSchristos 	    /* Terminate the list of CUs.  */
7007d62b00eSchristos 	    m_entry_pool.append_unsigned_leb128 (0);
7017d62b00eSchristos 	  }
7027d62b00eSchristos       }
7037d62b00eSchristos     gdb_assert (m_hash_table.size () == name_count);
7047d62b00eSchristos 
7057d62b00eSchristos     /* Terminate tags list.  */
7067d62b00eSchristos     m_abbrev_table.append_unsigned_leb128 (0);
7077d62b00eSchristos   }
7087d62b00eSchristos 
7097d62b00eSchristos   /* Return .debug_names bucket count.  This must be called only after
7107d62b00eSchristos      calling the build method.  */
7117d62b00eSchristos   uint32_t bucket_count () const
7127d62b00eSchristos   {
7137d62b00eSchristos     /* Verify the build method has been already called.  */
7147d62b00eSchristos     gdb_assert (!m_abbrev_table.empty ());
7157d62b00eSchristos     const uint32_t retval = m_bucket_table.size ();
7167d62b00eSchristos 
7177d62b00eSchristos     /* Check for overflow.  */
7187d62b00eSchristos     gdb_assert (retval == m_bucket_table.size ());
7197d62b00eSchristos     return retval;
7207d62b00eSchristos   }
7217d62b00eSchristos 
7227d62b00eSchristos   /* Return .debug_names names count.  This must be called only after
7237d62b00eSchristos      calling the build method.  */
7247d62b00eSchristos   uint32_t name_count () const
7257d62b00eSchristos   {
7267d62b00eSchristos     /* Verify the build method has been already called.  */
7277d62b00eSchristos     gdb_assert (!m_abbrev_table.empty ());
7287d62b00eSchristos     const uint32_t retval = m_hash_table.size ();
7297d62b00eSchristos 
7307d62b00eSchristos     /* Check for overflow.  */
7317d62b00eSchristos     gdb_assert (retval == m_hash_table.size ());
7327d62b00eSchristos     return retval;
7337d62b00eSchristos   }
7347d62b00eSchristos 
7357d62b00eSchristos   /* Return number of bytes of .debug_names abbreviation table.  This
7367d62b00eSchristos      must be called only after calling the build method.  */
7377d62b00eSchristos   uint32_t abbrev_table_bytes () const
7387d62b00eSchristos   {
7397d62b00eSchristos     gdb_assert (!m_abbrev_table.empty ());
7407d62b00eSchristos     return m_abbrev_table.size ();
7417d62b00eSchristos   }
7427d62b00eSchristos 
7437d62b00eSchristos   /* Return number of bytes the .debug_names section will have.  This
7447d62b00eSchristos      must be called only after calling the build method.  */
7457d62b00eSchristos   size_t bytes () const
7467d62b00eSchristos   {
7477d62b00eSchristos     /* Verify the build method has been already called.  */
7487d62b00eSchristos     gdb_assert (!m_abbrev_table.empty ());
7497d62b00eSchristos     size_t expected_bytes = 0;
7507d62b00eSchristos     expected_bytes += m_bucket_table.size () * sizeof (m_bucket_table[0]);
7517d62b00eSchristos     expected_bytes += m_hash_table.size () * sizeof (m_hash_table[0]);
7527d62b00eSchristos     expected_bytes += m_name_table_string_offs.bytes ();
7537d62b00eSchristos     expected_bytes += m_name_table_entry_offs.bytes ();
7547d62b00eSchristos     expected_bytes += m_abbrev_table.size ();
7557d62b00eSchristos     expected_bytes += m_entry_pool.size ();
7567d62b00eSchristos     return expected_bytes;
7577d62b00eSchristos   }
7587d62b00eSchristos 
7597d62b00eSchristos   /* Write .debug_names to FILE_NAMES and .debug_str addition to
7607d62b00eSchristos      FILE_STR.  This must be called only after calling the build
7617d62b00eSchristos      method.  */
7627d62b00eSchristos   void file_write (FILE *file_names, FILE *file_str) const
7637d62b00eSchristos   {
7647d62b00eSchristos     /* Verify the build method has been already called.  */
7657d62b00eSchristos     gdb_assert (!m_abbrev_table.empty ());
7667d62b00eSchristos     ::file_write (file_names, m_bucket_table);
7677d62b00eSchristos     ::file_write (file_names, m_hash_table);
7687d62b00eSchristos     m_name_table_string_offs.file_write (file_names);
7697d62b00eSchristos     m_name_table_entry_offs.file_write (file_names);
7707d62b00eSchristos     m_abbrev_table.file_write (file_names);
7717d62b00eSchristos     m_entry_pool.file_write (file_names);
7727d62b00eSchristos     m_debugstrlookup.file_write (file_str);
7737d62b00eSchristos   }
7747d62b00eSchristos 
775*6881a400Schristos   void add_cu (dwarf2_per_cu_data *per_cu, offset_type index)
7767d62b00eSchristos   {
777*6881a400Schristos     m_cu_index_htab.emplace (per_cu, index);
7787d62b00eSchristos   }
7797d62b00eSchristos 
7807d62b00eSchristos private:
7817d62b00eSchristos 
7827d62b00eSchristos   /* Storage for symbol names mapping them to their .debug_str section
7837d62b00eSchristos      offsets.  */
7847d62b00eSchristos   class debug_str_lookup
7857d62b00eSchristos   {
7867d62b00eSchristos   public:
7877d62b00eSchristos 
7887d62b00eSchristos     /* Object constructor to be called for current DWARF2_PER_OBJFILE.
7897d62b00eSchristos        All .debug_str section strings are automatically stored.  */
7907d62b00eSchristos     debug_str_lookup (dwarf2_per_objfile *per_objfile)
791*6881a400Schristos       : m_abfd (per_objfile->objfile->obfd.get ()),
7927d62b00eSchristos 	m_per_objfile (per_objfile)
7937d62b00eSchristos     {
7947d62b00eSchristos       per_objfile->per_bfd->str.read (per_objfile->objfile);
7957d62b00eSchristos       if (per_objfile->per_bfd->str.buffer == NULL)
7967d62b00eSchristos 	return;
7977d62b00eSchristos       for (const gdb_byte *data = per_objfile->per_bfd->str.buffer;
7987d62b00eSchristos 	   data < (per_objfile->per_bfd->str.buffer
7997d62b00eSchristos 		   + per_objfile->per_bfd->str.size);)
8007d62b00eSchristos 	{
8017d62b00eSchristos 	  const char *const s = reinterpret_cast<const char *> (data);
8027d62b00eSchristos 	  const auto insertpair
8037d62b00eSchristos 	    = m_str_table.emplace (c_str_view (s),
8047d62b00eSchristos 				   data - per_objfile->per_bfd->str.buffer);
8057d62b00eSchristos 	  if (!insertpair.second)
8067d62b00eSchristos 	    complaint (_("Duplicate string \"%s\" in "
8077d62b00eSchristos 			 ".debug_str section [in module %s]"),
8087d62b00eSchristos 		       s, bfd_get_filename (m_abfd));
8097d62b00eSchristos 	  data += strlen (s) + 1;
8107d62b00eSchristos 	}
8117d62b00eSchristos     }
8127d62b00eSchristos 
8137d62b00eSchristos     /* Return offset of symbol name S in the .debug_str section.  Add
8147d62b00eSchristos        such symbol to the section's end if it does not exist there
8157d62b00eSchristos        yet.  */
8167d62b00eSchristos     size_t lookup (const char *s)
8177d62b00eSchristos     {
8187d62b00eSchristos       const auto it = m_str_table.find (c_str_view (s));
8197d62b00eSchristos       if (it != m_str_table.end ())
8207d62b00eSchristos 	return it->second;
8217d62b00eSchristos       const size_t offset = (m_per_objfile->per_bfd->str.size
8227d62b00eSchristos 			     + m_str_add_buf.size ());
8237d62b00eSchristos       m_str_table.emplace (c_str_view (s), offset);
8247d62b00eSchristos       m_str_add_buf.append_cstr0 (s);
8257d62b00eSchristos       return offset;
8267d62b00eSchristos     }
8277d62b00eSchristos 
8287d62b00eSchristos     /* Append the end of the .debug_str section to FILE.  */
8297d62b00eSchristos     void file_write (FILE *file) const
8307d62b00eSchristos     {
8317d62b00eSchristos       m_str_add_buf.file_write (file);
8327d62b00eSchristos     }
8337d62b00eSchristos 
8347d62b00eSchristos   private:
8357d62b00eSchristos     std::unordered_map<c_str_view, size_t, c_str_view_hasher> m_str_table;
8367d62b00eSchristos     bfd *const m_abfd;
8377d62b00eSchristos     dwarf2_per_objfile *m_per_objfile;
8387d62b00eSchristos 
8397d62b00eSchristos     /* Data to add at the end of .debug_str for new needed symbol names.  */
8407d62b00eSchristos     data_buf m_str_add_buf;
8417d62b00eSchristos   };
8427d62b00eSchristos 
8437d62b00eSchristos   /* Container to map used DWARF tags to their .debug_names abbreviation
8447d62b00eSchristos      tags.  */
8457d62b00eSchristos   class index_key
8467d62b00eSchristos   {
8477d62b00eSchristos   public:
8487d62b00eSchristos     index_key (int dwarf_tag_, bool is_static_, unit_kind kind_)
8497d62b00eSchristos       : dwarf_tag (dwarf_tag_), is_static (is_static_), kind (kind_)
8507d62b00eSchristos     {
8517d62b00eSchristos     }
8527d62b00eSchristos 
8537d62b00eSchristos     bool
8547d62b00eSchristos     operator== (const index_key &other) const
8557d62b00eSchristos     {
8567d62b00eSchristos       return (dwarf_tag == other.dwarf_tag && is_static == other.is_static
8577d62b00eSchristos 	      && kind == other.kind);
8587d62b00eSchristos     }
8597d62b00eSchristos 
8607d62b00eSchristos     const int dwarf_tag;
8617d62b00eSchristos     const bool is_static;
8627d62b00eSchristos     const unit_kind kind;
8637d62b00eSchristos   };
8647d62b00eSchristos 
8657d62b00eSchristos   /* Provide std::unordered_map::hasher for index_key.  */
8667d62b00eSchristos   class index_key_hasher
8677d62b00eSchristos   {
8687d62b00eSchristos   public:
8697d62b00eSchristos     size_t
8707d62b00eSchristos     operator () (const index_key &key) const
8717d62b00eSchristos     {
8727d62b00eSchristos       return (std::hash<int>() (key.dwarf_tag) << 1) | key.is_static;
8737d62b00eSchristos     }
8747d62b00eSchristos   };
8757d62b00eSchristos 
8767d62b00eSchristos   /* Parameters of one symbol entry.  */
8777d62b00eSchristos   class symbol_value
8787d62b00eSchristos   {
8797d62b00eSchristos   public:
8807d62b00eSchristos     const int dwarf_tag, cu_index;
8817d62b00eSchristos     const bool is_static;
8827d62b00eSchristos     const unit_kind kind;
8837d62b00eSchristos 
8847d62b00eSchristos     symbol_value (int dwarf_tag_, int cu_index_, bool is_static_,
8857d62b00eSchristos 		  unit_kind kind_)
8867d62b00eSchristos       : dwarf_tag (dwarf_tag_), cu_index (cu_index_), is_static (is_static_),
8877d62b00eSchristos 	kind (kind_)
8887d62b00eSchristos     {}
8897d62b00eSchristos 
8907d62b00eSchristos     bool
8917d62b00eSchristos     operator< (const symbol_value &other) const
8927d62b00eSchristos     {
8937d62b00eSchristos #define X(n) \
8947d62b00eSchristos   do \
8957d62b00eSchristos     { \
8967d62b00eSchristos       if (n < other.n) \
8977d62b00eSchristos 	return true; \
8987d62b00eSchristos       if (n > other.n) \
8997d62b00eSchristos 	return false; \
9007d62b00eSchristos     } \
9017d62b00eSchristos   while (0)
9027d62b00eSchristos       X (dwarf_tag);
9037d62b00eSchristos       X (is_static);
9047d62b00eSchristos       X (kind);
9057d62b00eSchristos       X (cu_index);
9067d62b00eSchristos #undef X
9077d62b00eSchristos       return false;
9087d62b00eSchristos     }
9097d62b00eSchristos   };
9107d62b00eSchristos 
9117d62b00eSchristos   /* Abstract base class to unify DWARF-32 and DWARF-64 name table
9127d62b00eSchristos      output.  */
9137d62b00eSchristos   class offset_vec
9147d62b00eSchristos   {
9157d62b00eSchristos   protected:
9167d62b00eSchristos     const bfd_endian dwarf5_byte_order;
9177d62b00eSchristos   public:
9187d62b00eSchristos     explicit offset_vec (bfd_endian dwarf5_byte_order_)
9197d62b00eSchristos       : dwarf5_byte_order (dwarf5_byte_order_)
9207d62b00eSchristos     {}
9217d62b00eSchristos 
9227d62b00eSchristos     /* Call std::vector::reserve for NELEM elements.  */
9237d62b00eSchristos     virtual void reserve (size_t nelem) = 0;
9247d62b00eSchristos 
9257d62b00eSchristos     /* Call std::vector::push_back with store_unsigned_integer byte
9267d62b00eSchristos        reordering for ELEM.  */
9277d62b00eSchristos     virtual void push_back_reorder (size_t elem) = 0;
9287d62b00eSchristos 
9297d62b00eSchristos     /* Return expected output size in bytes.  */
9307d62b00eSchristos     virtual size_t bytes () const = 0;
9317d62b00eSchristos 
9327d62b00eSchristos     /* Write name table to FILE.  */
9337d62b00eSchristos     virtual void file_write (FILE *file) const = 0;
9347d62b00eSchristos   };
9357d62b00eSchristos 
9367d62b00eSchristos   /* Template to unify DWARF-32 and DWARF-64 output.  */
9377d62b00eSchristos   template<typename OffsetSize>
9387d62b00eSchristos   class offset_vec_tmpl : public offset_vec
9397d62b00eSchristos   {
9407d62b00eSchristos   public:
9417d62b00eSchristos     explicit offset_vec_tmpl (bfd_endian dwarf5_byte_order_)
9427d62b00eSchristos       : offset_vec (dwarf5_byte_order_)
9437d62b00eSchristos     {}
9447d62b00eSchristos 
9457d62b00eSchristos     /* Implement offset_vec::reserve.  */
9467d62b00eSchristos     void reserve (size_t nelem) override
9477d62b00eSchristos     {
9487d62b00eSchristos       m_vec.reserve (nelem);
9497d62b00eSchristos     }
9507d62b00eSchristos 
9517d62b00eSchristos     /* Implement offset_vec::push_back_reorder.  */
9527d62b00eSchristos     void push_back_reorder (size_t elem) override
9537d62b00eSchristos     {
9547d62b00eSchristos       m_vec.push_back (elem);
9557d62b00eSchristos       /* Check for overflow.  */
9567d62b00eSchristos       gdb_assert (m_vec.back () == elem);
9577d62b00eSchristos       store_unsigned_integer (reinterpret_cast<gdb_byte *> (&m_vec.back ()),
9587d62b00eSchristos 			      sizeof (m_vec.back ()), dwarf5_byte_order, elem);
9597d62b00eSchristos     }
9607d62b00eSchristos 
9617d62b00eSchristos     /* Implement offset_vec::bytes.  */
9627d62b00eSchristos     size_t bytes () const override
9637d62b00eSchristos     {
9647d62b00eSchristos       return m_vec.size () * sizeof (m_vec[0]);
9657d62b00eSchristos     }
9667d62b00eSchristos 
9677d62b00eSchristos     /* Implement offset_vec::file_write.  */
9687d62b00eSchristos     void file_write (FILE *file) const override
9697d62b00eSchristos     {
9707d62b00eSchristos       ::file_write (file, m_vec);
9717d62b00eSchristos     }
9727d62b00eSchristos 
9737d62b00eSchristos   private:
9747d62b00eSchristos     std::vector<OffsetSize> m_vec;
9757d62b00eSchristos   };
9767d62b00eSchristos 
9777d62b00eSchristos   /* Base class to unify DWARF-32 and DWARF-64 .debug_names output
9787d62b00eSchristos      respecting name table width.  */
9797d62b00eSchristos   class dwarf
9807d62b00eSchristos   {
9817d62b00eSchristos   public:
9827d62b00eSchristos     offset_vec &name_table_string_offs, &name_table_entry_offs;
9837d62b00eSchristos 
9847d62b00eSchristos     dwarf (offset_vec &name_table_string_offs_,
9857d62b00eSchristos 	   offset_vec &name_table_entry_offs_)
9867d62b00eSchristos       : name_table_string_offs (name_table_string_offs_),
9877d62b00eSchristos 	name_table_entry_offs (name_table_entry_offs_)
9887d62b00eSchristos     {
9897d62b00eSchristos     }
9907d62b00eSchristos   };
9917d62b00eSchristos 
9927d62b00eSchristos   /* Template to unify DWARF-32 and DWARF-64 .debug_names output
9937d62b00eSchristos      respecting name table width.  */
9947d62b00eSchristos   template<typename OffsetSize>
9957d62b00eSchristos   class dwarf_tmpl : public dwarf
9967d62b00eSchristos   {
9977d62b00eSchristos   public:
9987d62b00eSchristos     explicit dwarf_tmpl (bfd_endian dwarf5_byte_order_)
9997d62b00eSchristos       : dwarf (m_name_table_string_offs, m_name_table_entry_offs),
10007d62b00eSchristos 	m_name_table_string_offs (dwarf5_byte_order_),
10017d62b00eSchristos 	m_name_table_entry_offs (dwarf5_byte_order_)
10027d62b00eSchristos     {}
10037d62b00eSchristos 
10047d62b00eSchristos   private:
10057d62b00eSchristos     offset_vec_tmpl<OffsetSize> m_name_table_string_offs;
10067d62b00eSchristos     offset_vec_tmpl<OffsetSize> m_name_table_entry_offs;
10077d62b00eSchristos   };
10087d62b00eSchristos 
10097d62b00eSchristos   /* Store value of each symbol.  */
10107d62b00eSchristos   std::unordered_map<c_str_view, std::set<symbol_value>, c_str_view_hasher>
10117d62b00eSchristos     m_name_to_value_set;
10127d62b00eSchristos 
10137d62b00eSchristos   /* Tables of DWARF-5 .debug_names.  They are in object file byte
10147d62b00eSchristos      order.  */
10157d62b00eSchristos   std::vector<uint32_t> m_bucket_table;
10167d62b00eSchristos   std::vector<uint32_t> m_hash_table;
10177d62b00eSchristos 
10187d62b00eSchristos   const bfd_endian m_dwarf5_byte_order;
10197d62b00eSchristos   dwarf_tmpl<uint32_t> m_dwarf32;
10207d62b00eSchristos   dwarf_tmpl<uint64_t> m_dwarf64;
10217d62b00eSchristos   dwarf &m_dwarf;
10227d62b00eSchristos   offset_vec &m_name_table_string_offs, &m_name_table_entry_offs;
10237d62b00eSchristos   debug_str_lookup m_debugstrlookup;
10247d62b00eSchristos 
10257d62b00eSchristos   /* Map each used .debug_names abbreviation tag parameter to its
10267d62b00eSchristos      index value.  */
10277d62b00eSchristos   std::unordered_map<index_key, int, index_key_hasher> m_indexkey_to_idx;
10287d62b00eSchristos 
10297d62b00eSchristos   /* Next unused .debug_names abbreviation tag for
10307d62b00eSchristos      m_indexkey_to_idx.  */
10317d62b00eSchristos   int m_idx_next = 1;
10327d62b00eSchristos 
10337d62b00eSchristos   /* .debug_names abbreviation table.  */
10347d62b00eSchristos   data_buf m_abbrev_table;
10357d62b00eSchristos 
10367d62b00eSchristos   /* .debug_names entry pool.  */
10377d62b00eSchristos   data_buf m_entry_pool;
10387d62b00eSchristos 
10397d62b00eSchristos   /* Temporary storage for Ada names.  */
10407d62b00eSchristos   auto_obstack m_string_obstack;
1041*6881a400Schristos 
1042*6881a400Schristos   cu_index_map m_cu_index_htab;
10437d62b00eSchristos };
10447d62b00eSchristos 
10457d62b00eSchristos /* Return iff any of the needed offsets does not fit into 32-bit
10467d62b00eSchristos    .debug_names section.  */
10477d62b00eSchristos 
10487d62b00eSchristos static bool
10497d62b00eSchristos check_dwarf64_offsets (dwarf2_per_objfile *per_objfile)
10507d62b00eSchristos {
1051*6881a400Schristos   for (const auto &per_cu : per_objfile->per_bfd->all_units)
10527d62b00eSchristos     {
1053*6881a400Schristos       if (to_underlying (per_cu->sect_off)
1054*6881a400Schristos 	  >= (static_cast<uint64_t> (1) << 32))
10557d62b00eSchristos 	return true;
10567d62b00eSchristos     }
10577d62b00eSchristos   return false;
10587d62b00eSchristos }
10597d62b00eSchristos 
10607d62b00eSchristos /* Assert that FILE's size is EXPECTED_SIZE.  Assumes file's seek
10617d62b00eSchristos    position is at the end of the file.  */
10627d62b00eSchristos 
10637d62b00eSchristos static void
10647d62b00eSchristos assert_file_size (FILE *file, size_t expected_size)
10657d62b00eSchristos {
10667d62b00eSchristos   const auto file_size = ftell (file);
10677d62b00eSchristos   if (file_size == -1)
10687d62b00eSchristos     perror_with_name (("ftell"));
10697d62b00eSchristos   gdb_assert (file_size == expected_size);
10707d62b00eSchristos }
10717d62b00eSchristos 
10727d62b00eSchristos /* Write a gdb index file to OUT_FILE from all the sections passed as
10737d62b00eSchristos    arguments.  */
10747d62b00eSchristos 
10757d62b00eSchristos static void
10767d62b00eSchristos write_gdbindex_1 (FILE *out_file,
10777d62b00eSchristos 		  const data_buf &cu_list,
10787d62b00eSchristos 		  const data_buf &types_cu_list,
10797d62b00eSchristos 		  const data_buf &addr_vec,
10807d62b00eSchristos 		  const data_buf &symtab_vec,
10817d62b00eSchristos 		  const data_buf &constant_pool)
10827d62b00eSchristos {
10837d62b00eSchristos   data_buf contents;
10847d62b00eSchristos   const offset_type size_of_header = 6 * sizeof (offset_type);
10857d62b00eSchristos   offset_type total_len = size_of_header;
10867d62b00eSchristos 
10877d62b00eSchristos   /* The version number.  */
1088*6881a400Schristos   contents.append_offset (8);
10897d62b00eSchristos 
10907d62b00eSchristos   /* The offset of the CU list from the start of the file.  */
1091*6881a400Schristos   contents.append_offset (total_len);
10927d62b00eSchristos   total_len += cu_list.size ();
10937d62b00eSchristos 
10947d62b00eSchristos   /* The offset of the types CU list from the start of the file.  */
1095*6881a400Schristos   contents.append_offset (total_len);
10967d62b00eSchristos   total_len += types_cu_list.size ();
10977d62b00eSchristos 
10987d62b00eSchristos   /* The offset of the address table from the start of the file.  */
1099*6881a400Schristos   contents.append_offset (total_len);
11007d62b00eSchristos   total_len += addr_vec.size ();
11017d62b00eSchristos 
11027d62b00eSchristos   /* The offset of the symbol table from the start of the file.  */
1103*6881a400Schristos   contents.append_offset (total_len);
11047d62b00eSchristos   total_len += symtab_vec.size ();
11057d62b00eSchristos 
11067d62b00eSchristos   /* The offset of the constant pool from the start of the file.  */
1107*6881a400Schristos   contents.append_offset (total_len);
11087d62b00eSchristos   total_len += constant_pool.size ();
11097d62b00eSchristos 
11107d62b00eSchristos   gdb_assert (contents.size () == size_of_header);
11117d62b00eSchristos 
11127d62b00eSchristos   contents.file_write (out_file);
11137d62b00eSchristos   cu_list.file_write (out_file);
11147d62b00eSchristos   types_cu_list.file_write (out_file);
11157d62b00eSchristos   addr_vec.file_write (out_file);
11167d62b00eSchristos   symtab_vec.file_write (out_file);
11177d62b00eSchristos   constant_pool.file_write (out_file);
11187d62b00eSchristos 
11197d62b00eSchristos   assert_file_size (out_file, total_len);
11207d62b00eSchristos }
11217d62b00eSchristos 
1122*6881a400Schristos /* Write the contents of the internal "cooked" index.  */
1123*6881a400Schristos 
1124*6881a400Schristos static void
1125*6881a400Schristos write_cooked_index (cooked_index_vector *table,
1126*6881a400Schristos 		    const cu_index_map &cu_index_htab,
1127*6881a400Schristos 		    struct mapped_symtab *symtab)
1128*6881a400Schristos {
1129*6881a400Schristos   const char *main_for_ada = main_name ();
1130*6881a400Schristos 
1131*6881a400Schristos   for (const cooked_index_entry *entry : table->all_entries ())
1132*6881a400Schristos     {
1133*6881a400Schristos       const auto it = cu_index_htab.find (entry->per_cu);
1134*6881a400Schristos       gdb_assert (it != cu_index_htab.cend ());
1135*6881a400Schristos 
1136*6881a400Schristos       const char *name = entry->full_name (&symtab->m_string_obstack);
1137*6881a400Schristos 
1138*6881a400Schristos       if (entry->per_cu->lang () == language_ada)
1139*6881a400Schristos 	{
1140*6881a400Schristos 	  /* We want to ensure that the Ada main function's name
1141*6881a400Schristos 	     appears verbatim in the index.  However, this name will
1142*6881a400Schristos 	     be of the form "_ada_mumble", and will be rewritten by
1143*6881a400Schristos 	     ada_decode.  So, recognize it specially here and add it
1144*6881a400Schristos 	     to the index by hand.  */
1145*6881a400Schristos 	  if (entry->tag == DW_TAG_subprogram
1146*6881a400Schristos 	      && strcmp (main_for_ada, name) == 0)
1147*6881a400Schristos 	    {
1148*6881a400Schristos 	      /* Leave it alone.  */
1149*6881a400Schristos 	    }
1150*6881a400Schristos 	  else
1151*6881a400Schristos 	    {
1152*6881a400Schristos 	      /* In order for the index to work when read back into
1153*6881a400Schristos 		 gdb, it has to use the encoded name, with any
1154*6881a400Schristos 		 suffixes stripped.  */
1155*6881a400Schristos 	      std::string encoded = ada_encode (name, false);
1156*6881a400Schristos 	      name = obstack_strdup (&symtab->m_string_obstack,
1157*6881a400Schristos 				     encoded.c_str ());
1158*6881a400Schristos 	    }
1159*6881a400Schristos 	}
1160*6881a400Schristos       else if (entry->per_cu->lang () == language_cplus
1161*6881a400Schristos 	       && (entry->flags & IS_LINKAGE) != 0)
1162*6881a400Schristos 	{
1163*6881a400Schristos 	  /* GDB never put C++ linkage names into .gdb_index.  The
1164*6881a400Schristos 	     theory here is that a linkage name will normally be in
1165*6881a400Schristos 	     the minimal symbols anyway, so including it in the index
1166*6881a400Schristos 	     is usually redundant -- and the cases where it would not
1167*6881a400Schristos 	     be redundant are rare and not worth supporting.  */
1168*6881a400Schristos 	  continue;
1169*6881a400Schristos 	}
1170*6881a400Schristos       else if ((entry->flags & IS_TYPE_DECLARATION) != 0)
1171*6881a400Schristos 	{
1172*6881a400Schristos 	  /* Don't add type declarations to the index.  */
1173*6881a400Schristos 	  continue;
1174*6881a400Schristos 	}
1175*6881a400Schristos 
1176*6881a400Schristos       gdb_index_symbol_kind kind;
1177*6881a400Schristos       if (entry->tag == DW_TAG_subprogram)
1178*6881a400Schristos 	kind = GDB_INDEX_SYMBOL_KIND_FUNCTION;
1179*6881a400Schristos       else if (entry->tag == DW_TAG_variable
1180*6881a400Schristos 	       || entry->tag == DW_TAG_constant
1181*6881a400Schristos 	       || entry->tag == DW_TAG_enumerator)
1182*6881a400Schristos 	kind = GDB_INDEX_SYMBOL_KIND_VARIABLE;
1183*6881a400Schristos       else if (entry->tag == DW_TAG_module
1184*6881a400Schristos 	       || entry->tag == DW_TAG_common_block)
1185*6881a400Schristos 	kind = GDB_INDEX_SYMBOL_KIND_OTHER;
1186*6881a400Schristos       else
1187*6881a400Schristos 	kind = GDB_INDEX_SYMBOL_KIND_TYPE;
1188*6881a400Schristos 
1189*6881a400Schristos       add_index_entry (symtab, name, (entry->flags & IS_STATIC) != 0,
1190*6881a400Schristos 		       kind, it->second);
1191*6881a400Schristos     }
1192*6881a400Schristos }
1193*6881a400Schristos 
11947d62b00eSchristos /* Write contents of a .gdb_index section for OBJFILE into OUT_FILE.
11957d62b00eSchristos    If OBJFILE has an associated dwz file, write contents of a .gdb_index
11967d62b00eSchristos    section for that dwz file into DWZ_OUT_FILE.  If OBJFILE does not have an
11977d62b00eSchristos    associated dwz file, DWZ_OUT_FILE must be NULL.  */
11987d62b00eSchristos 
11997d62b00eSchristos static void
1200*6881a400Schristos write_gdbindex (dwarf2_per_objfile *per_objfile,
1201*6881a400Schristos 		cooked_index_vector *table,
1202*6881a400Schristos 		FILE *out_file, FILE *dwz_out_file)
12037d62b00eSchristos {
12047d62b00eSchristos   mapped_symtab symtab;
12057d62b00eSchristos   data_buf objfile_cu_list;
12067d62b00eSchristos   data_buf dwz_cu_list;
12077d62b00eSchristos 
1208*6881a400Schristos   /* While we're scanning CU's create a table that maps a dwarf2_per_cu_data
12097d62b00eSchristos      (which is what addrmap records) to its index (which is what is recorded
12107d62b00eSchristos      in the index file).  This will later be needed to write the address
12117d62b00eSchristos      table.  */
1212*6881a400Schristos   cu_index_map cu_index_htab;
1213*6881a400Schristos   cu_index_htab.reserve (per_objfile->per_bfd->all_units.size ());
1214*6881a400Schristos 
1215*6881a400Schristos   /* Store out the .debug_type CUs, if any.  */
1216*6881a400Schristos   data_buf types_cu_list;
12177d62b00eSchristos 
12187d62b00eSchristos   /* The CU list is already sorted, so we don't need to do additional
12197d62b00eSchristos      work here.  Also, the debug_types entries do not appear in
1220*6881a400Schristos      all_units, but only in their own hash table.  */
12217d62b00eSchristos 
1222*6881a400Schristos   int counter = 0;
1223*6881a400Schristos   int types_counter = 0;
1224*6881a400Schristos   for (int i = 0; i < per_objfile->per_bfd->all_units.size (); ++i)
12257d62b00eSchristos     {
1226*6881a400Schristos       dwarf2_per_cu_data *per_cu
1227*6881a400Schristos 	= per_objfile->per_bfd->all_units[i].get ();
12287d62b00eSchristos 
1229*6881a400Schristos       int &this_counter = per_cu->is_debug_types ? types_counter : counter;
12307d62b00eSchristos 
1231*6881a400Schristos       const auto insertpair = cu_index_htab.emplace (per_cu, this_counter);
12327d62b00eSchristos       gdb_assert (insertpair.second);
12337d62b00eSchristos 
1234*6881a400Schristos       /* The all_units list contains CUs read from the objfile as well as
12357d62b00eSchristos 	 from the eventual dwz file.  We need to place the entry in the
12367d62b00eSchristos 	 corresponding index.  */
1237*6881a400Schristos       data_buf &cu_list = (per_cu->is_debug_types
1238*6881a400Schristos 			   ? types_cu_list
1239*6881a400Schristos 			   : per_cu->is_dwz ? dwz_cu_list : objfile_cu_list);
12407d62b00eSchristos       cu_list.append_uint (8, BFD_ENDIAN_LITTLE,
12417d62b00eSchristos 			   to_underlying (per_cu->sect_off));
1242*6881a400Schristos       if (per_cu->is_debug_types)
1243*6881a400Schristos 	{
1244*6881a400Schristos 	  signatured_type *sig_type = (signatured_type *) per_cu;
1245*6881a400Schristos 	  cu_list.append_uint (8, BFD_ENDIAN_LITTLE,
1246*6881a400Schristos 			       to_underlying (sig_type->type_offset_in_tu));
1247*6881a400Schristos 	  cu_list.append_uint (8, BFD_ENDIAN_LITTLE,
1248*6881a400Schristos 			       sig_type->signature);
12497d62b00eSchristos 	}
1250*6881a400Schristos       else
1251*6881a400Schristos 	cu_list.append_uint (8, BFD_ENDIAN_LITTLE, per_cu->length ());
1252*6881a400Schristos 
1253*6881a400Schristos       ++this_counter;
1254*6881a400Schristos     }
1255*6881a400Schristos 
1256*6881a400Schristos   write_cooked_index (table, cu_index_htab, &symtab);
12577d62b00eSchristos 
12587d62b00eSchristos   /* Dump the address map.  */
12597d62b00eSchristos   data_buf addr_vec;
1260*6881a400Schristos   for (auto map : table->get_addrmaps ())
1261*6881a400Schristos     write_address_map (map, addr_vec, cu_index_htab);
12627d62b00eSchristos 
12637d62b00eSchristos   /* Now that we've processed all symbols we can shrink their cu_indices
12647d62b00eSchristos      lists.  */
1265*6881a400Schristos   symtab.minimize ();
12667d62b00eSchristos 
12677d62b00eSchristos   data_buf symtab_vec, constant_pool;
1268*6881a400Schristos   if (symtab.n_elements == 0)
1269*6881a400Schristos     symtab.data.resize (0);
1270*6881a400Schristos 
12717d62b00eSchristos   write_hash_table (&symtab, symtab_vec, constant_pool);
12727d62b00eSchristos 
12737d62b00eSchristos   write_gdbindex_1(out_file, objfile_cu_list, types_cu_list, addr_vec,
12747d62b00eSchristos 		   symtab_vec, constant_pool);
12757d62b00eSchristos 
12767d62b00eSchristos   if (dwz_out_file != NULL)
12777d62b00eSchristos     write_gdbindex_1 (dwz_out_file, dwz_cu_list, {}, {}, {}, {});
12787d62b00eSchristos   else
12797d62b00eSchristos     gdb_assert (dwz_cu_list.empty ());
12807d62b00eSchristos }
12817d62b00eSchristos 
12827d62b00eSchristos /* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension.  */
12837d62b00eSchristos static const gdb_byte dwarf5_gdb_augmentation[] = { 'G', 'D', 'B', 0 };
12847d62b00eSchristos 
12857d62b00eSchristos /* Write a new .debug_names section for OBJFILE into OUT_FILE, write
12867d62b00eSchristos    needed addition to .debug_str section to OUT_FILE_STR.  Return how
12877d62b00eSchristos    many bytes were expected to be written into OUT_FILE.  */
12887d62b00eSchristos 
12897d62b00eSchristos static void
12907d62b00eSchristos write_debug_names (dwarf2_per_objfile *per_objfile,
1291*6881a400Schristos 		   cooked_index_vector *table,
12927d62b00eSchristos 		   FILE *out_file, FILE *out_file_str)
12937d62b00eSchristos {
12947d62b00eSchristos   const bool dwarf5_is_dwarf64 = check_dwarf64_offsets (per_objfile);
12957d62b00eSchristos   struct objfile *objfile = per_objfile->objfile;
12967d62b00eSchristos   const enum bfd_endian dwarf5_byte_order
12977d62b00eSchristos     = gdbarch_byte_order (objfile->arch ());
12987d62b00eSchristos 
12997d62b00eSchristos   /* The CU list is already sorted, so we don't need to do additional
13007d62b00eSchristos      work here.  Also, the debug_types entries do not appear in
1301*6881a400Schristos      all_units, but only in their own hash table.  */
13027d62b00eSchristos   data_buf cu_list;
13037d62b00eSchristos   data_buf types_cu_list;
1304*6881a400Schristos   debug_names nametable (per_objfile, dwarf5_is_dwarf64, dwarf5_byte_order);
1305*6881a400Schristos   int counter = 0;
1306*6881a400Schristos   int types_counter = 0;
1307*6881a400Schristos   for (int i = 0; i < per_objfile->per_bfd->all_units.size (); ++i)
13087d62b00eSchristos     {
1309*6881a400Schristos       dwarf2_per_cu_data *per_cu
1310*6881a400Schristos 	= per_objfile->per_bfd->all_units[i].get ();
13117d62b00eSchristos 
1312*6881a400Schristos       int &this_counter = per_cu->is_debug_types ? types_counter : counter;
1313*6881a400Schristos       data_buf &this_list = per_cu->is_debug_types ? types_cu_list : cu_list;
1314*6881a400Schristos 
1315*6881a400Schristos       nametable.add_cu (per_cu, this_counter);
1316*6881a400Schristos       this_list.append_uint (nametable.dwarf5_offset_size (),
1317*6881a400Schristos 			     dwarf5_byte_order,
1318*6881a400Schristos 			     to_underlying (per_cu->sect_off));
1319*6881a400Schristos       ++this_counter;
13207d62b00eSchristos     }
13217d62b00eSchristos 
1322*6881a400Schristos    /* Verify that all units are represented.  */
1323*6881a400Schristos   gdb_assert (counter == per_objfile->per_bfd->all_comp_units.size ());
1324*6881a400Schristos   gdb_assert (types_counter == per_objfile->per_bfd->all_type_units.size ());
1325*6881a400Schristos 
1326*6881a400Schristos   for (const cooked_index_entry *entry : table->all_entries ())
1327*6881a400Schristos     nametable.insert (entry);
1328*6881a400Schristos 
13297d62b00eSchristos   nametable.build ();
13307d62b00eSchristos 
13317d62b00eSchristos   /* No addr_vec - DWARF-5 uses .debug_aranges generated by GCC.  */
13327d62b00eSchristos 
13337d62b00eSchristos   const offset_type bytes_of_header
13347d62b00eSchristos     = ((dwarf5_is_dwarf64 ? 12 : 4)
13357d62b00eSchristos        + 2 + 2 + 7 * 4
13367d62b00eSchristos        + sizeof (dwarf5_gdb_augmentation));
13377d62b00eSchristos   size_t expected_bytes = 0;
13387d62b00eSchristos   expected_bytes += bytes_of_header;
13397d62b00eSchristos   expected_bytes += cu_list.size ();
13407d62b00eSchristos   expected_bytes += types_cu_list.size ();
13417d62b00eSchristos   expected_bytes += nametable.bytes ();
13427d62b00eSchristos   data_buf header;
13437d62b00eSchristos 
13447d62b00eSchristos   if (!dwarf5_is_dwarf64)
13457d62b00eSchristos     {
13467d62b00eSchristos       const uint64_t size64 = expected_bytes - 4;
13477d62b00eSchristos       gdb_assert (size64 < 0xfffffff0);
13487d62b00eSchristos       header.append_uint (4, dwarf5_byte_order, size64);
13497d62b00eSchristos     }
13507d62b00eSchristos   else
13517d62b00eSchristos     {
13527d62b00eSchristos       header.append_uint (4, dwarf5_byte_order, 0xffffffff);
13537d62b00eSchristos       header.append_uint (8, dwarf5_byte_order, expected_bytes - 12);
13547d62b00eSchristos     }
13557d62b00eSchristos 
13567d62b00eSchristos   /* The version number.  */
13577d62b00eSchristos   header.append_uint (2, dwarf5_byte_order, 5);
13587d62b00eSchristos 
13597d62b00eSchristos   /* Padding.  */
13607d62b00eSchristos   header.append_uint (2, dwarf5_byte_order, 0);
13617d62b00eSchristos 
13627d62b00eSchristos   /* comp_unit_count - The number of CUs in the CU list.  */
1363*6881a400Schristos   header.append_uint (4, dwarf5_byte_order, counter);
13647d62b00eSchristos 
13657d62b00eSchristos   /* local_type_unit_count - The number of TUs in the local TU
13667d62b00eSchristos      list.  */
1367*6881a400Schristos   header.append_uint (4, dwarf5_byte_order, types_counter);
13687d62b00eSchristos 
13697d62b00eSchristos   /* foreign_type_unit_count - The number of TUs in the foreign TU
13707d62b00eSchristos      list.  */
13717d62b00eSchristos   header.append_uint (4, dwarf5_byte_order, 0);
13727d62b00eSchristos 
13737d62b00eSchristos   /* bucket_count - The number of hash buckets in the hash lookup
13747d62b00eSchristos      table.  */
13757d62b00eSchristos   header.append_uint (4, dwarf5_byte_order, nametable.bucket_count ());
13767d62b00eSchristos 
13777d62b00eSchristos   /* name_count - The number of unique names in the index.  */
13787d62b00eSchristos   header.append_uint (4, dwarf5_byte_order, nametable.name_count ());
13797d62b00eSchristos 
13807d62b00eSchristos   /* abbrev_table_size - The size in bytes of the abbreviations
13817d62b00eSchristos      table.  */
13827d62b00eSchristos   header.append_uint (4, dwarf5_byte_order, nametable.abbrev_table_bytes ());
13837d62b00eSchristos 
13847d62b00eSchristos   /* augmentation_string_size - The size in bytes of the augmentation
13857d62b00eSchristos      string.  This value is rounded up to a multiple of 4.  */
13867d62b00eSchristos   static_assert (sizeof (dwarf5_gdb_augmentation) % 4 == 0, "");
13877d62b00eSchristos   header.append_uint (4, dwarf5_byte_order, sizeof (dwarf5_gdb_augmentation));
1388*6881a400Schristos   header.append_array (dwarf5_gdb_augmentation);
13897d62b00eSchristos 
13907d62b00eSchristos   gdb_assert (header.size () == bytes_of_header);
13917d62b00eSchristos 
13927d62b00eSchristos   header.file_write (out_file);
13937d62b00eSchristos   cu_list.file_write (out_file);
13947d62b00eSchristos   types_cu_list.file_write (out_file);
13957d62b00eSchristos   nametable.file_write (out_file, out_file_str);
13967d62b00eSchristos 
13977d62b00eSchristos   assert_file_size (out_file, expected_bytes);
13987d62b00eSchristos }
13997d62b00eSchristos 
14007d62b00eSchristos /* This represents an index file being written (work-in-progress).
14017d62b00eSchristos 
14027d62b00eSchristos    The data is initially written to a temporary file.  When the finalize method
14037d62b00eSchristos    is called, the file is closed and moved to its final location.
14047d62b00eSchristos 
14057d62b00eSchristos    On failure (if this object is being destroyed with having called finalize),
14067d62b00eSchristos    the temporary file is closed and deleted.  */
14077d62b00eSchristos 
14087d62b00eSchristos struct index_wip_file
14097d62b00eSchristos {
14107d62b00eSchristos   index_wip_file (const char *dir, const char *basename,
14117d62b00eSchristos 		  const char *suffix)
14127d62b00eSchristos   {
14137d62b00eSchristos     filename = (std::string (dir) + SLASH_STRING + basename
14147d62b00eSchristos 		+ suffix);
14157d62b00eSchristos 
14167d62b00eSchristos     filename_temp = make_temp_filename (filename);
14177d62b00eSchristos 
1418*6881a400Schristos     scoped_fd out_file_fd = gdb_mkostemp_cloexec (filename_temp.data (),
1419*6881a400Schristos 						  O_BINARY);
14207d62b00eSchristos     if (out_file_fd.get () == -1)
14217d62b00eSchristos       perror_with_name (("mkstemp"));
14227d62b00eSchristos 
14237d62b00eSchristos     out_file = out_file_fd.to_file ("wb");
14247d62b00eSchristos 
14257d62b00eSchristos     if (out_file == nullptr)
14267d62b00eSchristos       error (_("Can't open `%s' for writing"), filename_temp.data ());
14277d62b00eSchristos 
14287d62b00eSchristos     unlink_file.emplace (filename_temp.data ());
14297d62b00eSchristos   }
14307d62b00eSchristos 
14317d62b00eSchristos   void finalize ()
14327d62b00eSchristos   {
14337d62b00eSchristos     /* We want to keep the file.  */
14347d62b00eSchristos     unlink_file->keep ();
14357d62b00eSchristos 
14367d62b00eSchristos     /* Close and move the str file in place.  */
14377d62b00eSchristos     unlink_file.reset ();
14387d62b00eSchristos     if (rename (filename_temp.data (), filename.c_str ()) != 0)
14397d62b00eSchristos       perror_with_name (("rename"));
14407d62b00eSchristos   }
14417d62b00eSchristos 
14427d62b00eSchristos   std::string filename;
14437d62b00eSchristos   gdb::char_vector filename_temp;
14447d62b00eSchristos 
14457d62b00eSchristos   /* Order matters here; we want FILE to be closed before
14467d62b00eSchristos      FILENAME_TEMP is unlinked, because on MS-Windows one cannot
14477d62b00eSchristos      delete a file that is still open.  So, we wrap the unlinker in an
14487d62b00eSchristos      optional and emplace it once we know the file name.  */
14497d62b00eSchristos   gdb::optional<gdb::unlinker> unlink_file;
14507d62b00eSchristos 
14517d62b00eSchristos   gdb_file_up out_file;
14527d62b00eSchristos };
14537d62b00eSchristos 
14547d62b00eSchristos /* See dwarf-index-write.h.  */
14557d62b00eSchristos 
14567d62b00eSchristos void
1457*6881a400Schristos write_dwarf_index (dwarf2_per_objfile *per_objfile, const char *dir,
14587d62b00eSchristos 		   const char *basename, const char *dwz_basename,
14597d62b00eSchristos 		   dw_index_kind index_kind)
14607d62b00eSchristos {
14617d62b00eSchristos   struct objfile *objfile = per_objfile->objfile;
14627d62b00eSchristos 
1463*6881a400Schristos   if (per_objfile->per_bfd->index_table == nullptr)
1464*6881a400Schristos     error (_("No debugging symbols"));
1465*6881a400Schristos   cooked_index_vector *table
1466*6881a400Schristos     = per_objfile->per_bfd->index_table->index_for_writing ();
14677d62b00eSchristos 
14687d62b00eSchristos   if (per_objfile->per_bfd->types.size () > 1)
14697d62b00eSchristos     error (_("Cannot make an index when the file has multiple .debug_types sections"));
14707d62b00eSchristos 
14717d62b00eSchristos 
1472*6881a400Schristos   gdb_assert ((objfile->flags & OBJF_NOT_FILENAME) == 0);
14737d62b00eSchristos 
14747d62b00eSchristos   const char *index_suffix = (index_kind == dw_index_kind::DEBUG_NAMES
14757d62b00eSchristos 			      ? INDEX5_SUFFIX : INDEX4_SUFFIX);
14767d62b00eSchristos 
14777d62b00eSchristos   index_wip_file objfile_index_wip (dir, basename, index_suffix);
14787d62b00eSchristos   gdb::optional<index_wip_file> dwz_index_wip;
14797d62b00eSchristos 
14807d62b00eSchristos   if (dwz_basename != NULL)
14817d62b00eSchristos       dwz_index_wip.emplace (dir, dwz_basename, index_suffix);
14827d62b00eSchristos 
14837d62b00eSchristos   if (index_kind == dw_index_kind::DEBUG_NAMES)
14847d62b00eSchristos     {
14857d62b00eSchristos       index_wip_file str_wip_file (dir, basename, DEBUG_STR_SUFFIX);
14867d62b00eSchristos 
1487*6881a400Schristos       write_debug_names (per_objfile, table, objfile_index_wip.out_file.get (),
14887d62b00eSchristos 			 str_wip_file.out_file.get ());
14897d62b00eSchristos 
14907d62b00eSchristos       str_wip_file.finalize ();
14917d62b00eSchristos     }
14927d62b00eSchristos   else
1493*6881a400Schristos     write_gdbindex (per_objfile, table, objfile_index_wip.out_file.get (),
14947d62b00eSchristos 		    (dwz_index_wip.has_value ()
14957d62b00eSchristos 		     ? dwz_index_wip->out_file.get () : NULL));
14967d62b00eSchristos 
14977d62b00eSchristos   objfile_index_wip.finalize ();
14987d62b00eSchristos 
14997d62b00eSchristos   if (dwz_index_wip.has_value ())
15007d62b00eSchristos     dwz_index_wip->finalize ();
15017d62b00eSchristos }
15027d62b00eSchristos 
15037d62b00eSchristos /* Implementation of the `save gdb-index' command.
15047d62b00eSchristos 
15057d62b00eSchristos    Note that the .gdb_index file format used by this command is
15067d62b00eSchristos    documented in the GDB manual.  Any changes here must be documented
15077d62b00eSchristos    there.  */
15087d62b00eSchristos 
15097d62b00eSchristos static void
15107d62b00eSchristos save_gdb_index_command (const char *arg, int from_tty)
15117d62b00eSchristos {
15127d62b00eSchristos   const char dwarf5space[] = "-dwarf-5 ";
15137d62b00eSchristos   dw_index_kind index_kind = dw_index_kind::GDB_INDEX;
15147d62b00eSchristos 
15157d62b00eSchristos   if (!arg)
15167d62b00eSchristos     arg = "";
15177d62b00eSchristos 
15187d62b00eSchristos   arg = skip_spaces (arg);
15197d62b00eSchristos   if (strncmp (arg, dwarf5space, strlen (dwarf5space)) == 0)
15207d62b00eSchristos     {
15217d62b00eSchristos       index_kind = dw_index_kind::DEBUG_NAMES;
15227d62b00eSchristos       arg += strlen (dwarf5space);
15237d62b00eSchristos       arg = skip_spaces (arg);
15247d62b00eSchristos     }
15257d62b00eSchristos 
15267d62b00eSchristos   if (!*arg)
15277d62b00eSchristos     error (_("usage: save gdb-index [-dwarf-5] DIRECTORY"));
15287d62b00eSchristos 
15297d62b00eSchristos   for (objfile *objfile : current_program_space->objfiles ())
15307d62b00eSchristos     {
15317d62b00eSchristos       /* If the objfile does not correspond to an actual file, skip it.  */
1532*6881a400Schristos       if ((objfile->flags & OBJF_NOT_FILENAME) != 0)
15337d62b00eSchristos 	continue;
15347d62b00eSchristos 
15357d62b00eSchristos       dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
15367d62b00eSchristos 
15377d62b00eSchristos       if (per_objfile != NULL)
15387d62b00eSchristos 	{
15397d62b00eSchristos 	  try
15407d62b00eSchristos 	    {
15417d62b00eSchristos 	      const char *basename = lbasename (objfile_name (objfile));
15427d62b00eSchristos 	      const dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
15437d62b00eSchristos 	      const char *dwz_basename = NULL;
15447d62b00eSchristos 
15457d62b00eSchristos 	      if (dwz != NULL)
15467d62b00eSchristos 		dwz_basename = lbasename (dwz->filename ());
15477d62b00eSchristos 
1548*6881a400Schristos 	      write_dwarf_index (per_objfile, arg, basename, dwz_basename,
15497d62b00eSchristos 				 index_kind);
15507d62b00eSchristos 	    }
15517d62b00eSchristos 	  catch (const gdb_exception_error &except)
15527d62b00eSchristos 	    {
15537d62b00eSchristos 	      exception_fprintf (gdb_stderr, except,
15547d62b00eSchristos 				 _("Error while writing index for `%s': "),
15557d62b00eSchristos 				 objfile_name (objfile));
15567d62b00eSchristos 	    }
15577d62b00eSchristos 	    }
15587d62b00eSchristos 
15597d62b00eSchristos     }
15607d62b00eSchristos }
15617d62b00eSchristos 
15627d62b00eSchristos void _initialize_dwarf_index_write ();
15637d62b00eSchristos void
15647d62b00eSchristos _initialize_dwarf_index_write ()
15657d62b00eSchristos {
15667d62b00eSchristos   cmd_list_element *c = add_cmd ("gdb-index", class_files,
15677d62b00eSchristos 				 save_gdb_index_command, _("\
15687d62b00eSchristos Save a gdb-index file.\n\
15697d62b00eSchristos Usage: save gdb-index [-dwarf-5] DIRECTORY\n\
15707d62b00eSchristos \n\
15717d62b00eSchristos No options create one file with .gdb-index extension for pre-DWARF-5\n\
15727d62b00eSchristos compatible .gdb_index section.  With -dwarf-5 creates two files with\n\
15737d62b00eSchristos extension .debug_names and .debug_str for DWARF-5 .debug_names section."),
15747d62b00eSchristos 	       &save_cmdlist);
15757d62b00eSchristos   set_cmd_completer (c, filename_completer);
15767d62b00eSchristos }
1577