26#include "gdbsupport/byte-vector.h"
27#include "gdbsupport/filestuff.h"
28#include "gdbsupport/gdb_unlinker.h"
29#include "gdbsupport/pathstuff.h"
30#include "gdbsupport/scoped_fd.h"
36#include "gdb/gdb-index.h"
44#include <forward_list>
46#include <unordered_map>
47#include <unordered_set>
50#define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \
52 gdb_assert ((unsigned int) (value) <= 1); \
53 GDB_INDEX_SYMBOL_STATIC_SET_VALUE((cu_index), (value)); \
57#define DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE(cu_index, value) \
59 gdb_assert ((value) >= GDB_INDEX_SYMBOL_KIND_TYPE \
60 && (value) <= GDB_INDEX_SYMBOL_KIND_OTHER); \
61 GDB_INDEX_SYMBOL_KIND_SET_VALUE((cu_index), (value)); \
65#define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value) \
67 gdb_assert (((value) & ~GDB_INDEX_CU_MASK) == 0); \
68 GDB_INDEX_CU_SET_VALUE((cu_index), (value)); \
79 if (fwrite (data, 1,
size, file) !=
size)
80 error (_(
"couldn't data write to file"));
85template<
typename Elem,
typename Alloc>
87file_write (FILE *file,
const std::vector<Elem, Alloc> &vec)
90 file_write (file, vec.data (), vec.size () * sizeof (vec[0]));
100 std::copy (array.begin (), array.end (),
grow (array.size ()));
107 const size_t size = strlen (cstr) + 1;
116 gdb_byte output = input & 0x7f;
120 m_vec.push_back (output);
128 void append_uint (
size_t len, bfd_endian byte_order, ULONGEST val)
142 return m_vec.size ();
148 return m_vec.empty ();
201 std::vector<symtab_index_entry>
data;
218 index = hash & (
symtab->data.size () - 1);
219 step = ((hash * 17) & (
symtab->data.size () - 1)) | 1;
223 if (
symtab->data[index].name == NULL
224 || strcmp (
name,
symtab->data[index].name) == 0)
225 return symtab->data[index];
226 index = (index + step) & (
symtab->data.size () - 1);
235 auto old_entries = std::move (
symtab->data);
238 symtab->data.resize (old_entries.size () * 2);
240 for (
auto &it : old_entries)
244 ref = std::move (it);
254 int is_static, gdb_index_symbol_kind kind,
264 if (slot.
name == NULL)
270 cu_index_and_attrs = 0;
282 slot.
cu_indices.push_back (cu_index_and_attrs);
302 std::unordered_set<offset_type> seen;
306 gdb_index_symbol_kind kind = GDB_INDEX_SYMBOL_KIND_VALUE (val);
307 if (kind != GDB_INDEX_SYMBOL_KIND_TYPE
308 && kind != GDB_INDEX_SYMBOL_KIND_VARIABLE)
311 val &= ~GDB_INDEX_CU_MASK;
312 return !seen.insert (val).second;
362 return iterative_hash (key.data (),
363 sizeof (key.front ()) * key.size (), 0);
376 std::unordered_map<std::vector<offset_type>,
offset_type,
384 if (entry.
name == NULL)
395 if (found != symbol_hash_table.end ())
410 std::unordered_map<c_str_view, offset_type, c_str_view_hasher> str_table;
411 for (
const auto &entry :
symtab->data)
415 if (entry.name != NULL)
417 const auto insertpair = str_table.emplace (entry.name, cpool.
size ());
418 if (insertpair.second)
420 str_off = insertpair.first->second;
421 vec_off = entry.index_offset;
436typedef std::unordered_map<dwarf2_per_cu_data *, unsigned int>
cu_index_map;
449 int operator() (CORE_ADDR start_addr,
void *obj);
465 CORE_ADDR start, CORE_ADDR end,
unsigned int cu_index)
467 addr_vec.
append_uint (8, BFD_ENDIAN_LITTLE, start);
526 bfd_endian dwarf5_byte_order)
541 return dwarf5_is_dwarf64 ? 8 : 4;
558 dwarf_tag tag = entry->
tag;
560 tag = DW_TAG_structure_type;
561 else if (tag == DW_TAG_enumerator || tag == DW_TAG_constant)
562 tag = DW_TAG_variable;
564 int cu_index = it->second;
579 const auto insertpair
581 std::set<symbol_value> ());
582 std::set<symbol_value> &value_set = insertpair.first->second;
583 value_set.emplace (
symbol_value (tag, cu_index, is_static, kind));
596 if (decoded[0] ==
'<')
598 decoded.c_str () + 1,
599 decoded.length () - 2);
605 const auto insertpair
607 std::set<symbol_value> ());
608 std::set<symbol_value> &value_set = insertpair.first->second;
609 value_set.emplace (
symbol_value (tag, cu_index, is_static, kind));
621 (std::pow (2, std::ceil (std::log2 (
name_count * 4 / 3))));
630 decltype (m_name_to_value_set)::const_iterator it;
632 std::vector<std::forward_list<hash_it_pair>> bucket_hash;
639 const char *
const name = it->first.c_str ();
641 hash_it_pair hashitpair;
642 hashitpair.hash = hash;
644 auto &slot = bucket_hash[hash % bucket_hash.size()];
645 slot.push_front (std::move (hashitpair));
647 for (
size_t bucket_ix = 0; bucket_ix < bucket_hash.size (); ++bucket_ix)
649 const std::forward_list<hash_it_pair> &hashitlist
650 = bucket_hash[bucket_ix];
651 if (hashitlist.empty ())
658 for (
const hash_it_pair &hashitpair : hashitlist)
666 const std::set<symbol_value> &value_set = hashitpair.it->second;
670 gdb_assert (!value_set.empty ());
686 ? DW_IDX_GNU_internal
687 : DW_IDX_GNU_external);
749 size_t expected_bytes = 0;
756 return expected_bytes;
801 const char *
const s =
reinterpret_cast<const char *
> (data);
802 const auto insertpair
805 if (!insertpair.second)
806 complaint (_(
"Duplicate string \"%s\" in "
807 ".debug_str section [in module %s]"),
808 s, bfd_get_filename (
m_abfd));
809 data += strlen (s) + 1;
835 std::unordered_map<c_str_view, size_t, c_str_view_hasher>
m_str_table;
937 template<
typename OffsetSize>
948 m_vec.reserve (nelem);
954 m_vec.push_back (elem);
956 gdb_assert (
m_vec.back () == elem);
994 template<
typename OffsetSize>
1053 if (to_underlying (per_cu->sect_off)
1054 >= (
static_cast<uint64_t
> (1) << 32))
1066 const auto file_size = ftell (file);
1067 if (file_size == -1)
1069 gdb_assert (file_size == expected_size);
1092 total_len += cu_list.
size ();
1096 total_len += types_cu_list.
size ();
1100 total_len += addr_vec.
size ();
1104 total_len += symtab_vec.
size ();
1108 total_len += constant_pool.
size ();
1110 gdb_assert (contents.
size () == size_of_header);
1129 const char *main_for_ada =
main_name ();
1133 const auto it = cu_index_htab.find (entry->per_cu);
1134 gdb_assert (it != cu_index_htab.cend ());
1136 const char *
name = entry->full_name (&
symtab->m_string_obstack);
1145 if (entry->tag == DW_TAG_subprogram
1146 && strcmp (main_for_ada,
name) == 0)
1156 name = obstack_strdup (&
symtab->m_string_obstack,
1176 gdb_index_symbol_kind kind;
1177 if (entry->tag == DW_TAG_subprogram)
1178 kind = GDB_INDEX_SYMBOL_KIND_FUNCTION;
1179 else if (entry->tag == DW_TAG_variable
1180 || entry->tag == DW_TAG_constant
1181 || entry->tag == DW_TAG_enumerator)
1182 kind = GDB_INDEX_SYMBOL_KIND_VARIABLE;
1183 else if (entry->tag == DW_TAG_module
1184 || entry->tag == DW_TAG_common_block)
1185 kind = GDB_INDEX_SYMBOL_KIND_OTHER;
1187 kind = GDB_INDEX_SYMBOL_KIND_TYPE;
1202 FILE *out_file, FILE *dwz_out_file)
1223 int types_counter = 0;
1229 int &this_counter = per_cu->
is_debug_types ? types_counter : counter;
1231 const auto insertpair = cu_index_htab.emplace (per_cu, this_counter);
1232 gdb_assert (insertpair.second);
1239 : per_cu->
is_dwz ? dwz_cu_list : objfile_cu_list);
1267 data_buf symtab_vec, constant_pool;
1268 if (
symtab.n_elements == 0)
1274 symtab_vec, constant_pool);
1276 if (dwz_out_file != NULL)
1279 gdb_assert (dwz_cu_list.
empty ());
1292 FILE *out_file, FILE *out_file_str)
1296 const enum bfd_endian dwarf5_byte_order
1304 debug_names nametable (per_objfile, dwarf5_is_dwarf64, dwarf5_byte_order);
1306 int types_counter = 0;
1312 int &this_counter = per_cu->
is_debug_types ? types_counter : counter;
1315 nametable.
add_cu (per_cu, this_counter);
1327 nametable.
insert (entry);
1334 = ((dwarf5_is_dwarf64 ? 12 : 4)
1337 size_t expected_bytes = 0;
1338 expected_bytes += bytes_of_header;
1339 expected_bytes += cu_list.
size ();
1340 expected_bytes += types_cu_list.
size ();
1341 expected_bytes += nametable.
bytes ();
1344 if (!dwarf5_is_dwarf64)
1346 const uint64_t size64 = expected_bytes - 4;
1347 gdb_assert (size64 < 0xfffffff0);
1348 header.
append_uint (4, dwarf5_byte_order, size64);
1352 header.
append_uint (4, dwarf5_byte_order, 0xffffffff);
1353 header.
append_uint (8, dwarf5_byte_order, expected_bytes - 12);
1363 header.
append_uint (4, dwarf5_byte_order, counter);
1367 header.
append_uint (4, dwarf5_byte_order, types_counter);
1390 gdb_assert (header.
size () == bytes_of_header);
1395 nametable.
file_write (out_file, out_file_str);
1413 filename = (std::string (dir) + SLASH_STRING + basename
1418 scoped_fd out_file_fd = gdb_mkostemp_cloexec (
filename_temp.data (),
1420 if (out_file_fd.get () == -1)
1423 out_file = out_file_fd.to_file (
"wb");
1426 error (_(
"Can't open `%s' for writing"),
filename_temp.data ());
1458 const char *basename,
const char *dwz_basename,
1464 error (_(
"No debugging symbols"));
1469 error (_(
"Cannot make an index when the file has multiple .debug_types sections"));
1478 gdb::optional<index_wip_file> dwz_index_wip;
1480 if (dwz_basename != NULL)
1481 dwz_index_wip.emplace (dir, dwz_basename, index_suffix);
1494 (dwz_index_wip.has_value ()
1495 ? dwz_index_wip->out_file.get () : NULL));
1499 if (dwz_index_wip.has_value ())
1500 dwz_index_wip->finalize ();
1512 const char dwarf5space[] =
"-dwarf-5 ";
1518 arg = skip_spaces (arg);
1519 if (strncmp (arg, dwarf5space, strlen (dwarf5space)) == 0)
1522 arg += strlen (dwarf5space);
1523 arg = skip_spaces (arg);
1527 error (_(
"usage: save gdb-index [-dwarf-5] DIRECTORY"));
1537 if (per_objfile != NULL)
1543 const char *dwz_basename = NULL;
1546 dwz_basename = lbasename (dwz->
filename ());
1551 catch (
const gdb_exception_error &except)
1554 _(
"Error while writing index for `%s': "),
1568Save a gdb-index file.\n\
1569Usage: save gdb-index [-dwarf-5] DIRECTORY\n\
1571No options create one file with .gdb-index extension for pre-DWARF-5\n\
1572compatible .gdb_index section. With -dwarf-5 creates two files with\n\
1573extension .debug_names and .debug_str for DWARF-5 .debug_names section."),
constexpr string_view get()
std::string ada_decode(const char *encoded, bool wrap, bool operators)
std::string ada_encode(const char *decoded, bool fold)
struct cmd_list_element * save_cmdlist
size_t operator()(const c_str_view &x) const
const char * c_str() const
bool operator==(const c_str_view &other) const
c_str_view(const char *cstr)
std::vector< addrmap * > get_addrmaps()
void file_write(FILE *file) const
void append_cstr0(const char *cstr)
void append_array(gdb::array_view< const gdb_byte > array)
void append_uint(size_t len, bfd_endian byte_order, ULONGEST val)
void append_unsigned_leb128(ULONGEST input)
gdb_byte * grow(size_t size)
void append_offset(offset_type value)
debug_str_lookup(dwarf2_per_objfile *per_objfile)
size_t lookup(const char *s)
std::unordered_map< c_str_view, size_t, c_str_view_hasher > m_str_table
dwarf2_per_objfile * m_per_objfile
void file_write(FILE *file) const
dwarf_tmpl(bfd_endian dwarf5_byte_order_)
offset_vec_tmpl< OffsetSize > m_name_table_string_offs
offset_vec_tmpl< OffsetSize > m_name_table_entry_offs
dwarf(offset_vec &name_table_string_offs_, offset_vec &name_table_entry_offs_)
offset_vec & name_table_string_offs
offset_vec & name_table_entry_offs
size_t operator()(const index_key &key) const
index_key(int dwarf_tag_, bool is_static_, unit_kind kind_)
bool operator==(const index_key &other) const
offset_vec_tmpl(bfd_endian dwarf5_byte_order_)
void file_write(FILE *file) const override
void push_back_reorder(size_t elem) override
void reserve(size_t nelem) override
size_t bytes() const override
std::vector< OffsetSize > m_vec
const bfd_endian dwarf5_byte_order
virtual void file_write(FILE *file) const =0
virtual size_t bytes() const =0
virtual void push_back_reorder(size_t elem)=0
virtual void reserve(size_t nelem)=0
offset_vec(bfd_endian dwarf5_byte_order_)
bool operator<(const symbol_value &other) const
symbol_value(int dwarf_tag_, int cu_index_, bool is_static_, unit_kind kind_)
std::vector< uint32_t > m_hash_table
int dwarf5_offset_size() const
void file_write(FILE *file_names, FILE *file_str) const
uint32_t abbrev_table_bytes() const
uint32_t name_count() const
offset_vec & m_name_table_entry_offs
dwarf_tmpl< uint64_t > m_dwarf64
void add_cu(dwarf2_per_cu_data *per_cu, offset_type index)
dwarf_tmpl< uint32_t > m_dwarf32
std::unordered_map< index_key, int, index_key_hasher > m_indexkey_to_idx
offset_vec & m_name_table_string_offs
void insert(const cooked_index_entry *entry)
cu_index_map m_cu_index_htab
std::unordered_map< c_str_view, std::set< symbol_value >, c_str_view_hasher > m_name_to_value_set
debug_str_lookup m_debugstrlookup
debug_names(dwarf2_per_objfile *per_objfile, bool is_dwarf64, bfd_endian dwarf5_byte_order)
auto_obstack m_string_obstack
std::vector< uint32_t > m_bucket_table
const bfd_endian m_dwarf5_byte_order
uint32_t bucket_count() const
size_t operator()(const std::vector< T > &key) const
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **list)
void set_cmd_completer(struct cmd_list_element *cmd, completer_ftype *completer)
#define complaint(FMT,...)
void filename_completer(struct cmd_list_element *ignore, completion_tracker &tracker, const char *text, const char *word)
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
struct dwz_file * dwarf2_get_dwz_file(dwarf2_per_bfd *per_bfd, bool require)
void exception_fprintf(struct ui_file *file, const struct gdb_exception &e, const char *prefix,...)
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
uint32_t dwarf5_djb_hash(const char *str_)
hashval_t mapped_index_string_hash(int index_version, const void *p)
static void write_gdbindex_1(FILE *out_file, const data_buf &cu_list, const data_buf &types_cu_list, const data_buf &addr_vec, const data_buf &symtab_vec, const data_buf &constant_pool)
std::unordered_map< dwarf2_per_cu_data *, unsigned int > cu_index_map
#define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value)
static void write_gdbindex(dwarf2_per_objfile *per_objfile, cooked_index_vector *table, FILE *out_file, FILE *dwz_out_file)
static void assert_file_size(FILE *file, size_t expected_size)
#define DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE(cu_index, value)
static symtab_index_entry & find_slot(struct mapped_symtab *symtab, const char *name)
static void write_cooked_index(cooked_index_vector *table, const cu_index_map &cu_index_htab, struct mapped_symtab *symtab)
#define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value)
static void add_address_entry(data_buf &addr_vec, CORE_ADDR start, CORE_ADDR end, unsigned int cu_index)
static void write_address_map(struct addrmap *addrmap, data_buf &addr_vec, cu_index_map &cu_index_htab)
void _initialize_dwarf_index_write()
static const gdb_byte dwarf5_gdb_augmentation[]
static bool check_dwarf64_offsets(dwarf2_per_objfile *per_objfile)
static void hash_expand(struct mapped_symtab *symtab)
static void file_write(FILE *file, const void *data, size_t size)
static void save_gdb_index_command(const char *arg, int from_tty)
void write_dwarf_index(dwarf2_per_objfile *per_objfile, const char *dir, const char *basename, const char *dwz_basename, dw_index_kind index_kind)
static void write_debug_names(dwarf2_per_objfile *per_objfile, cooked_index_vector *table, FILE *out_file, FILE *out_file_str)
static void add_index_entry(struct mapped_symtab *symtab, const char *name, int is_static, gdb_index_symbol_kind kind, offset_type cu_index)
static void write_hash_table(mapped_symtab *symtab, data_buf &output, data_buf &cpool)
const char * objfile_name(const struct objfile *objfile)
struct program_space * current_program_space
dwarf2_per_objfile * get_dwarf2_per_objfile(struct objfile *objfile)
cu_index_map & cu_index_htab
addrmap_index_data(data_buf &addr_vec_, cu_index_map &cu_index_htab_)
int operator()(CORE_ADDR start_addr, void *obj)
CORE_ADDR previous_cu_start
unsigned int previous_cu_index
virtual int foreach(addrmap_foreach_fn fn)=0
dwarf2_per_cu_data * per_cu
const char * full_name(struct obstack *storage, bool for_main=false) const
gdb::array_view< dwarf2_per_cu_data_up > all_comp_units
std::unique_ptr< dwarf_scanner_base > index_table
gdb::array_view< dwarf2_per_cu_data_up > all_type_units
std::vector< dwarf2_section_info > types
std::vector< dwarf2_per_cu_data_up > all_units
enum language lang(bool strict_p=true) const
unsigned int is_debug_types
unsigned int length() const
struct dwarf2_per_bfd * per_bfd
void read(struct objfile *objfile)
const char * filename() const
index_wip_file(const char *dir, const char *basename, const char *suffix)
gdb::optional< gdb::unlinker > unlink_file
gdb::char_vector filename_temp
std::vector< symtab_index_entry > data
auto_obstack m_string_obstack
struct gdbarch * arch() const
objfiles_range objfiles()
cu_offset type_offset_in_tu
std::vector< offset_type > cu_indices
static bool tag_is_type(dwarf_tag tag)
void perror_with_name(const char *string)