265 lines
8.3 KiB
Diff
265 lines
8.3 KiB
Diff
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
|
From: Andrew Burgess <aburgess@redhat.com>
|
|
Date: Sat, 25 Nov 2023 10:35:37 +0000
|
|
Subject: gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch
|
|
|
|
;; Back-port upstream commit acc117b57f7 as part of a fix for
|
|
;; non-deterministic gdb-index generation (RH BZ 2232086).
|
|
|
|
gdb: C++-ify mapped_symtab from dwarf2/index-write.c
|
|
|
|
Make static the functions add_index_entry, find_slot, and hash_expand,
|
|
member functions of the mapped_symtab class.
|
|
|
|
Fold an additional snippet of code from write_gdbindex into
|
|
mapped_symtab::minimize, this code relates to minimisation, so this
|
|
seems like a good home for it.
|
|
|
|
Make the n_elements, data, and m_string_obstack member variables of
|
|
mapped_symtab private. Provide a new obstack() member function to
|
|
provide access to the obstack when needed, and also add member
|
|
functions begin(), end(), cbegin(), and cend() so that the
|
|
mapped_symtab class can be treated like a contained and iterated
|
|
over.
|
|
|
|
I've also taken this opportunity to split out the logic for whether
|
|
the hash table (m_data) needs expanding, this is the new function
|
|
hash_needs_expanding. This will be useful in a later commit.
|
|
|
|
There should be no user visible changes after this commit.
|
|
|
|
Approved-By: Tom Tromey <tom@tromey.com>
|
|
|
|
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
|
|
--- a/gdb/dwarf2/index-write.c
|
|
+++ b/gdb/dwarf2/index-write.c
|
|
@@ -187,86 +187,135 @@ struct mapped_symtab
|
|
{
|
|
mapped_symtab ()
|
|
{
|
|
- data.resize (1024);
|
|
+ m_data.resize (1024);
|
|
}
|
|
|
|
- /* Minimize each entry in the symbol table, removing duplicates. */
|
|
+ /* If there are no elements in the symbol table, then reduce the table
|
|
+ size to zero. Otherwise call symtab_index_entry::minimize each entry
|
|
+ in the symbol table. */
|
|
+
|
|
void minimize ()
|
|
{
|
|
- for (symtab_index_entry &item : data)
|
|
+ if (m_element_count == 0)
|
|
+ m_data.resize (0);
|
|
+
|
|
+ for (symtab_index_entry &item : m_data)
|
|
item.minimize ();
|
|
}
|
|
|
|
- offset_type n_elements = 0;
|
|
- std::vector<symtab_index_entry> data;
|
|
+ /* Add an entry to SYMTAB. NAME is the name of the symbol. CU_INDEX is
|
|
+ the index of the CU in which the symbol appears. IS_STATIC is one if
|
|
+ the symbol is static, otherwise zero (global). */
|
|
+
|
|
+ void add_index_entry (const char *name, int is_static,
|
|
+ gdb_index_symbol_kind kind, offset_type cu_index);
|
|
+
|
|
+ /* Access the obstack. */
|
|
+ struct obstack *obstack ()
|
|
+ { return &m_string_obstack; }
|
|
+
|
|
+private:
|
|
+
|
|
+ /* Find a slot in SYMTAB for the symbol NAME. Returns a reference to
|
|
+ the slot.
|
|
+
|
|
+ Function is used only during write_hash_table so no index format
|
|
+ backward compatibility is needed. */
|
|
+
|
|
+ symtab_index_entry &find_slot (const char *name);
|
|
+
|
|
+ /* Expand SYMTAB's hash table. */
|
|
+
|
|
+ void hash_expand ();
|
|
+
|
|
+ /* Return true if the hash table in data needs to grow. */
|
|
+
|
|
+ bool hash_needs_expanding () const
|
|
+ { return 4 * m_element_count / 3 >= m_data.size (); }
|
|
+
|
|
+ /* A vector that is used as a hash table. */
|
|
+ std::vector<symtab_index_entry> m_data;
|
|
+
|
|
+ /* The number of elements stored in the m_data hash. */
|
|
+ offset_type m_element_count = 0;
|
|
|
|
/* Temporary storage for names. */
|
|
auto_obstack m_string_obstack;
|
|
-};
|
|
|
|
-/* Find a slot in SYMTAB for the symbol NAME. Returns a reference to
|
|
- the slot.
|
|
+public:
|
|
+ using iterator = decltype (m_data)::iterator;
|
|
+ using const_iterator = decltype (m_data)::const_iterator;
|
|
|
|
- Function is used only during write_hash_table so no index format backward
|
|
- compatibility is needed. */
|
|
+ iterator begin ()
|
|
+ { return m_data.begin (); }
|
|
|
|
-static symtab_index_entry &
|
|
-find_slot (struct mapped_symtab *symtab, const char *name)
|
|
+ iterator end ()
|
|
+ { return m_data.end (); }
|
|
+
|
|
+ const_iterator cbegin ()
|
|
+ { return m_data.cbegin (); }
|
|
+
|
|
+ const_iterator cend ()
|
|
+ { return m_data.cend (); }
|
|
+};
|
|
+
|
|
+/* See class definition. */
|
|
+
|
|
+symtab_index_entry &
|
|
+mapped_symtab::find_slot (const char *name)
|
|
{
|
|
offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name);
|
|
|
|
- index = hash & (symtab->data.size () - 1);
|
|
- step = ((hash * 17) & (symtab->data.size () - 1)) | 1;
|
|
+ index = hash & (m_data.size () - 1);
|
|
+ step = ((hash * 17) & (m_data.size () - 1)) | 1;
|
|
|
|
for (;;)
|
|
{
|
|
- if (symtab->data[index].name == NULL
|
|
- || strcmp (name, symtab->data[index].name) == 0)
|
|
- return symtab->data[index];
|
|
- index = (index + step) & (symtab->data.size () - 1);
|
|
+ if (m_data[index].name == NULL
|
|
+ || strcmp (name, m_data[index].name) == 0)
|
|
+ return m_data[index];
|
|
+ index = (index + step) & (m_data.size () - 1);
|
|
}
|
|
}
|
|
|
|
-/* Expand SYMTAB's hash table. */
|
|
+/* See class definition. */
|
|
|
|
-static void
|
|
-hash_expand (struct mapped_symtab *symtab)
|
|
+void
|
|
+mapped_symtab::hash_expand ()
|
|
{
|
|
- auto old_entries = std::move (symtab->data);
|
|
+ auto old_entries = std::move (m_data);
|
|
|
|
- symtab->data.clear ();
|
|
- symtab->data.resize (old_entries.size () * 2);
|
|
+ gdb_assert (m_data.size () == 0);
|
|
+ m_data.resize (old_entries.size () * 2);
|
|
|
|
for (auto &it : old_entries)
|
|
if (it.name != NULL)
|
|
{
|
|
- auto &ref = find_slot (symtab, it.name);
|
|
+ auto &ref = this->find_slot (it.name);
|
|
ref = std::move (it);
|
|
}
|
|
}
|
|
|
|
-/* Add an entry to SYMTAB. NAME is the name of the symbol.
|
|
- CU_INDEX is the index of the CU in which the symbol appears.
|
|
- IS_STATIC is one if the symbol is static, otherwise zero (global). */
|
|
+/* See class definition. */
|
|
|
|
-static void
|
|
-add_index_entry (struct mapped_symtab *symtab, const char *name,
|
|
- int is_static, gdb_index_symbol_kind kind,
|
|
- offset_type cu_index)
|
|
+void
|
|
+mapped_symtab::add_index_entry (const char *name, int is_static,
|
|
+ gdb_index_symbol_kind kind,
|
|
+ offset_type cu_index)
|
|
{
|
|
- symtab_index_entry *slot = &find_slot (symtab, name);
|
|
+ symtab_index_entry *slot = &this->find_slot (name);
|
|
if (slot->name == NULL)
|
|
{
|
|
/* This is a new element in the hash table. */
|
|
- ++symtab->n_elements;
|
|
+ ++this->m_element_count;
|
|
|
|
/* We might need to grow the hash table. */
|
|
- if (4 * symtab->n_elements / 3 >= symtab->data.size ())
|
|
+ if (this->hash_needs_expanding ())
|
|
{
|
|
- hash_expand (symtab);
|
|
+ this->hash_expand ();
|
|
|
|
/* This element will have a different slot in the new table. */
|
|
- slot = &find_slot (symtab, name);
|
|
+ slot = &this->find_slot (name);
|
|
|
|
/* But it should still be a new element in the hash table. */
|
|
gdb_assert (slot->name == nullptr);
|
|
@@ -387,7 +436,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
|
|
|
|
/* We add all the index vectors to the constant pool first, to
|
|
ensure alignment is ok. */
|
|
- for (symtab_index_entry &entry : symtab->data)
|
|
+ for (symtab_index_entry &entry : *symtab)
|
|
{
|
|
if (entry.name == NULL)
|
|
continue;
|
|
@@ -416,7 +465,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
|
|
|
|
/* Now write out the hash table. */
|
|
std::unordered_map<c_str_view, offset_type, c_str_view_hasher> str_table;
|
|
- for (const auto &entry : symtab->data)
|
|
+ for (const auto &entry : *symtab)
|
|
{
|
|
offset_type str_off, vec_off;
|
|
|
|
@@ -1151,7 +1200,7 @@ write_cooked_index (cooked_index *table,
|
|
const auto it = cu_index_htab.find (entry->per_cu);
|
|
gdb_assert (it != cu_index_htab.cend ());
|
|
|
|
- const char *name = entry->full_name (&symtab->m_string_obstack);
|
|
+ const char *name = entry->full_name (symtab->obstack ());
|
|
|
|
if (entry->per_cu->lang () == language_ada)
|
|
{
|
|
@@ -1159,7 +1208,7 @@ write_cooked_index (cooked_index *table,
|
|
gdb, it has to use the encoded name, with any
|
|
suffixes stripped. */
|
|
std::string encoded = ada_encode (name, false);
|
|
- name = obstack_strdup (&symtab->m_string_obstack,
|
|
+ name = obstack_strdup (symtab->obstack (),
|
|
encoded.c_str ());
|
|
}
|
|
else if (entry->per_cu->lang () == language_cplus
|
|
@@ -1191,8 +1240,8 @@ write_cooked_index (cooked_index *table,
|
|
else
|
|
kind = GDB_INDEX_SYMBOL_KIND_TYPE;
|
|
|
|
- add_index_entry (symtab, name, (entry->flags & IS_STATIC) != 0,
|
|
- kind, it->second);
|
|
+ symtab->add_index_entry (name, (entry->flags & IS_STATIC) != 0,
|
|
+ kind, it->second);
|
|
}
|
|
}
|
|
|
|
@@ -1267,8 +1316,6 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table,
|
|
symtab.minimize ();
|
|
|
|
data_buf symtab_vec, constant_pool;
|
|
- if (symtab.n_elements == 0)
|
|
- symtab.data.resize (0);
|
|
|
|
write_hash_table (&symtab, symtab_vec, constant_pool);
|
|
|