Only use the per-BFD object to write a DWARF index

The DWARF index does not need access to the objfile or per-objfile
objects when writing -- it's entirely based on the objfile-independent
per-BFD data.

This patch implements this idea by changing the entire API to only be
passed the per-BFD object.  This simplifies some lifetime reasoning
for the next patch.

This patch removes some code that ensures that the BFD came from a
file.  It seems to me that checking for the existence of a build-id is
good enough for the index cache.
This commit is contained in:
Tom Tromey 2022-04-13 11:21:20 -06:00
parent 71797f1221
commit 542a33e348
5 changed files with 48 additions and 60 deletions

View file

@ -89,23 +89,17 @@ index_cache::disable ()
/* See dwarf-index-cache.h. */ /* See dwarf-index-cache.h. */
void void
index_cache::store (dwarf2_per_objfile *per_objfile) index_cache::store (dwarf2_per_bfd *per_bfd)
{ {
objfile *obj = per_objfile->objfile;
if (!enabled ()) if (!enabled ())
return; return;
/* If the objfile does not correspond to an actual file, skip it. */
if ((obj->flags & OBJF_NOT_FILENAME) != 0)
return;
/* Get build id of objfile. */ /* Get build id of objfile. */
const bfd_build_id *build_id = build_id_bfd_get (obj->obfd.get ()); const bfd_build_id *build_id = build_id_bfd_get (per_bfd->obfd);
if (build_id == nullptr) if (build_id == nullptr)
{ {
index_cache_debug ("objfile %s has no build id", index_cache_debug ("objfile %s has no build id",
objfile_name (obj)); bfd_get_filename (per_bfd->obfd));
return; return;
} }
@ -113,7 +107,7 @@ index_cache::store (dwarf2_per_objfile *per_objfile)
/* Get build id of dwz file, if present. */ /* Get build id of dwz file, if present. */
gdb::optional<std::string> dwz_build_id_str; gdb::optional<std::string> dwz_build_id_str;
const dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd); const dwz_file *dwz = dwarf2_get_dwz_file (per_bfd);
const char *dwz_build_id_ptr = NULL; const char *dwz_build_id_ptr = NULL;
if (dwz != nullptr) if (dwz != nullptr)
@ -148,18 +142,18 @@ index_cache::store (dwarf2_per_objfile *per_objfile)
} }
index_cache_debug ("writing index cache for objfile %s", index_cache_debug ("writing index cache for objfile %s",
objfile_name (obj)); bfd_get_filename (per_bfd->obfd));
/* Write the index itself to the directory, using the build id as the /* Write the index itself to the directory, using the build id as the
filename. */ filename. */
write_dwarf_index (per_objfile, m_dir.c_str (), write_dwarf_index (per_bfd, m_dir.c_str (),
build_id_str.c_str (), dwz_build_id_ptr, build_id_str.c_str (), dwz_build_id_ptr,
dw_index_kind::GDB_INDEX); dw_index_kind::GDB_INDEX);
} }
catch (const gdb_exception_error &except) catch (const gdb_exception_error &except)
{ {
index_cache_debug ("couldn't store index cache for objfile %s: %s", index_cache_debug ("couldn't store index cache for objfile %s: %s",
objfile_name (obj), except.what ()); bfd_get_filename (per_bfd->obfd), except.what ());
} }
} }

View file

@ -24,6 +24,8 @@
#include "gdbsupport/array-view.h" #include "gdbsupport/array-view.h"
#include "symfile.h" #include "symfile.h"
class dwarf2_per_bfd;
/* Base of the classes used to hold the resources of the indices loaded from /* Base of the classes used to hold the resources of the indices loaded from
the cache (e.g. mmapped files). */ the cache (e.g. mmapped files). */
@ -53,7 +55,7 @@ public:
void disable (); void disable ();
/* Store an index for the specified object file in the cache. */ /* Store an index for the specified object file in the cache. */
void store (dwarf2_per_objfile *per_objfile); void store (dwarf2_per_bfd *per_bfd);
/* Look for an index file matching BUILD_ID. If found, return the contents /* Look for an index file matching BUILD_ID. If found, return the contents
as an array_view and store the underlying resources (allocated memory, as an array_view and store the underlying resources (allocated memory,

View file

@ -524,7 +524,7 @@ write_address_map (const addrmap *addrmap, data_buf &addr_vec,
class debug_names class debug_names
{ {
public: public:
debug_names (dwarf2_per_objfile *per_objfile, bool is_dwarf64, debug_names (dwarf2_per_bfd *per_bfd, bool is_dwarf64,
bfd_endian dwarf5_byte_order) bfd_endian dwarf5_byte_order)
: m_dwarf5_byte_order (dwarf5_byte_order), : m_dwarf5_byte_order (dwarf5_byte_order),
m_dwarf32 (dwarf5_byte_order), m_dwarf32 (dwarf5_byte_order),
@ -534,7 +534,7 @@ public:
: static_cast<dwarf &> (m_dwarf32)), : static_cast<dwarf &> (m_dwarf32)),
m_name_table_string_offs (m_dwarf.name_table_string_offs), m_name_table_string_offs (m_dwarf.name_table_string_offs),
m_name_table_entry_offs (m_dwarf.name_table_entry_offs), m_name_table_entry_offs (m_dwarf.name_table_entry_offs),
m_debugstrlookup (per_objfile) m_debugstrlookup (per_bfd)
{} {}
int dwarf5_offset_size () const int dwarf5_offset_size () const
@ -787,23 +787,23 @@ private:
{ {
public: public:
/* Object constructor to be called for current DWARF2_PER_OBJFILE. /* Object constructor to be called for current DWARF2_PER_BFD.
All .debug_str section strings are automatically stored. */ All .debug_str section strings are automatically stored. */
debug_str_lookup (dwarf2_per_objfile *per_objfile) debug_str_lookup (dwarf2_per_bfd *per_bfd)
: m_abfd (per_objfile->objfile->obfd.get ()), : m_abfd (per_bfd->obfd),
m_per_objfile (per_objfile) m_per_bfd (per_bfd)
{ {
per_objfile->per_bfd->str.read (per_objfile->objfile); gdb_assert (per_bfd->str.readin);
if (per_objfile->per_bfd->str.buffer == NULL) if (per_bfd->str.buffer == NULL)
return; return;
for (const gdb_byte *data = per_objfile->per_bfd->str.buffer; for (const gdb_byte *data = per_bfd->str.buffer;
data < (per_objfile->per_bfd->str.buffer data < (per_bfd->str.buffer
+ per_objfile->per_bfd->str.size);) + per_bfd->str.size);)
{ {
const char *const s = reinterpret_cast<const char *> (data); const char *const s = reinterpret_cast<const char *> (data);
const auto insertpair const auto insertpair
= m_str_table.emplace (c_str_view (s), = m_str_table.emplace (c_str_view (s),
data - per_objfile->per_bfd->str.buffer); data - per_bfd->str.buffer);
if (!insertpair.second) if (!insertpair.second)
complaint (_("Duplicate string \"%s\" in " complaint (_("Duplicate string \"%s\" in "
".debug_str section [in module %s]"), ".debug_str section [in module %s]"),
@ -820,7 +820,7 @@ private:
const auto it = m_str_table.find (c_str_view (s)); const auto it = m_str_table.find (c_str_view (s));
if (it != m_str_table.end ()) if (it != m_str_table.end ())
return it->second; return it->second;
const size_t offset = (m_per_objfile->per_bfd->str.size const size_t offset = (m_per_bfd->str.size
+ m_str_add_buf.size ()); + m_str_add_buf.size ());
m_str_table.emplace (c_str_view (s), offset); m_str_table.emplace (c_str_view (s), offset);
m_str_add_buf.append_cstr0 (s); m_str_add_buf.append_cstr0 (s);
@ -836,7 +836,7 @@ private:
private: private:
std::unordered_map<c_str_view, size_t, c_str_view_hasher> m_str_table; std::unordered_map<c_str_view, size_t, c_str_view_hasher> m_str_table;
bfd *const m_abfd; bfd *const m_abfd;
dwarf2_per_objfile *m_per_objfile; dwarf2_per_bfd *m_per_bfd;
/* Data to add at the end of .debug_str for new needed symbol names. */ /* Data to add at the end of .debug_str for new needed symbol names. */
data_buf m_str_add_buf; data_buf m_str_add_buf;
@ -1048,9 +1048,9 @@ private:
.debug_names section. */ .debug_names section. */
static bool static bool
check_dwarf64_offsets (dwarf2_per_objfile *per_objfile) check_dwarf64_offsets (dwarf2_per_bfd *per_bfd)
{ {
for (const auto &per_cu : per_objfile->per_bfd->all_units) for (const auto &per_cu : per_bfd->all_units)
{ {
if (to_underlying (per_cu->sect_off) if (to_underlying (per_cu->sect_off)
>= (static_cast<uint64_t> (1) << 32)) >= (static_cast<uint64_t> (1) << 32))
@ -1199,7 +1199,7 @@ write_cooked_index (cooked_index *table,
associated dwz file, DWZ_OUT_FILE must be NULL. */ associated dwz file, DWZ_OUT_FILE must be NULL. */
static void static void
write_gdbindex (dwarf2_per_objfile *per_objfile, cooked_index *table, write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table,
FILE *out_file, FILE *dwz_out_file) FILE *out_file, FILE *dwz_out_file)
{ {
mapped_symtab symtab; mapped_symtab symtab;
@ -1211,7 +1211,7 @@ write_gdbindex (dwarf2_per_objfile *per_objfile, cooked_index *table,
in the index file). This will later be needed to write the address in the index file). This will later be needed to write the address
table. */ table. */
cu_index_map cu_index_htab; cu_index_map cu_index_htab;
cu_index_htab.reserve (per_objfile->per_bfd->all_units.size ()); cu_index_htab.reserve (per_bfd->all_units.size ());
/* Store out the .debug_type CUs, if any. */ /* Store out the .debug_type CUs, if any. */
data_buf types_cu_list; data_buf types_cu_list;
@ -1222,10 +1222,9 @@ write_gdbindex (dwarf2_per_objfile *per_objfile, cooked_index *table,
int counter = 0; int counter = 0;
int types_counter = 0; int types_counter = 0;
for (int i = 0; i < per_objfile->per_bfd->all_units.size (); ++i) for (int i = 0; i < per_bfd->all_units.size (); ++i)
{ {
dwarf2_per_cu_data *per_cu dwarf2_per_cu_data *per_cu = per_bfd->all_units[i].get ();
= per_objfile->per_bfd->all_units[i].get ();
int &this_counter = per_cu->is_debug_types ? types_counter : counter; int &this_counter = per_cu->is_debug_types ? types_counter : counter;
@ -1288,26 +1287,24 @@ static const gdb_byte dwarf5_gdb_augmentation[] = { 'G', 'D', 'B', 0 };
many bytes were expected to be written into OUT_FILE. */ many bytes were expected to be written into OUT_FILE. */
static void static void
write_debug_names (dwarf2_per_objfile *per_objfile, cooked_index *table, write_debug_names (dwarf2_per_bfd *per_bfd, cooked_index *table,
FILE *out_file, FILE *out_file_str) FILE *out_file, FILE *out_file_str)
{ {
const bool dwarf5_is_dwarf64 = check_dwarf64_offsets (per_objfile); const bool dwarf5_is_dwarf64 = check_dwarf64_offsets (per_bfd);
struct objfile *objfile = per_objfile->objfile;
const enum bfd_endian dwarf5_byte_order const enum bfd_endian dwarf5_byte_order
= gdbarch_byte_order (objfile->arch ()); = bfd_big_endian (per_bfd->obfd) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
/* The CU list is already sorted, so we don't need to do additional /* The CU list is already sorted, so we don't need to do additional
work here. Also, the debug_types entries do not appear in work here. Also, the debug_types entries do not appear in
all_units, but only in their own hash table. */ all_units, but only in their own hash table. */
data_buf cu_list; data_buf cu_list;
data_buf types_cu_list; data_buf types_cu_list;
debug_names nametable (per_objfile, dwarf5_is_dwarf64, dwarf5_byte_order); debug_names nametable (per_bfd, dwarf5_is_dwarf64, dwarf5_byte_order);
int counter = 0; int counter = 0;
int types_counter = 0; int types_counter = 0;
for (int i = 0; i < per_objfile->per_bfd->all_units.size (); ++i) for (int i = 0; i < per_bfd->all_units.size (); ++i)
{ {
dwarf2_per_cu_data *per_cu dwarf2_per_cu_data *per_cu = per_bfd->all_units[i].get ();
= per_objfile->per_bfd->all_units[i].get ();
int &this_counter = per_cu->is_debug_types ? types_counter : counter; int &this_counter = per_cu->is_debug_types ? types_counter : counter;
data_buf &this_list = per_cu->is_debug_types ? types_cu_list : cu_list; data_buf &this_list = per_cu->is_debug_types ? types_cu_list : cu_list;
@ -1320,8 +1317,8 @@ write_debug_names (dwarf2_per_objfile *per_objfile, cooked_index *table,
} }
/* Verify that all units are represented. */ /* Verify that all units are represented. */
gdb_assert (counter == per_objfile->per_bfd->all_comp_units.size ()); gdb_assert (counter == per_bfd->all_units.size ());
gdb_assert (types_counter == per_objfile->per_bfd->all_type_units.size ()); gdb_assert (types_counter == per_bfd->all_type_units.size ());
for (const cooked_index_entry *entry : table->all_entries ()) for (const cooked_index_entry *entry : table->all_entries ())
nametable.insert (entry); nametable.insert (entry);
@ -1454,22 +1451,17 @@ struct index_wip_file
/* See dwarf-index-write.h. */ /* See dwarf-index-write.h. */
void void
write_dwarf_index (dwarf2_per_objfile *per_objfile, const char *dir, write_dwarf_index (dwarf2_per_bfd *per_bfd, const char *dir,
const char *basename, const char *dwz_basename, const char *basename, const char *dwz_basename,
dw_index_kind index_kind) dw_index_kind index_kind)
{ {
struct objfile *objfile = per_objfile->objfile; if (per_bfd->index_table == nullptr)
if (per_objfile->per_bfd->index_table == nullptr)
error (_("No debugging symbols")); error (_("No debugging symbols"));
cooked_index *table = per_objfile->per_bfd->index_table->index_for_writing (); cooked_index *table = per_bfd->index_table->index_for_writing ();
if (per_objfile->per_bfd->types.size () > 1) if (per_bfd->types.size () > 1)
error (_("Cannot make an index when the file has multiple .debug_types sections")); error (_("Cannot make an index when the file has multiple .debug_types sections"));
gdb_assert ((objfile->flags & OBJF_NOT_FILENAME) == 0);
const char *index_suffix = (index_kind == dw_index_kind::DEBUG_NAMES const char *index_suffix = (index_kind == dw_index_kind::DEBUG_NAMES
? INDEX5_SUFFIX : INDEX4_SUFFIX); ? INDEX5_SUFFIX : INDEX4_SUFFIX);
@ -1483,13 +1475,13 @@ write_dwarf_index (dwarf2_per_objfile *per_objfile, const char *dir,
{ {
index_wip_file str_wip_file (dir, basename, DEBUG_STR_SUFFIX); index_wip_file str_wip_file (dir, basename, DEBUG_STR_SUFFIX);
write_debug_names (per_objfile, table, objfile_index_wip.out_file.get (), write_debug_names (per_bfd, table, objfile_index_wip.out_file.get (),
str_wip_file.out_file.get ()); str_wip_file.out_file.get ());
str_wip_file.finalize (); str_wip_file.finalize ();
} }
else else
write_gdbindex (per_objfile, table, objfile_index_wip.out_file.get (), write_gdbindex (per_bfd, table, objfile_index_wip.out_file.get (),
(dwz_index_wip.has_value () (dwz_index_wip.has_value ()
? dwz_index_wip->out_file.get () : NULL)); ? dwz_index_wip->out_file.get () : NULL));
@ -1544,8 +1536,8 @@ save_gdb_index_command (const char *arg, int from_tty)
if (dwz != NULL) if (dwz != NULL)
dwz_basename = lbasename (dwz->filename ()); dwz_basename = lbasename (dwz->filename ());
write_dwarf_index (per_objfile, arg, basename, dwz_basename, write_dwarf_index (per_objfile->per_bfd, arg, basename,
index_kind); dwz_basename, index_kind);
} }
catch (const gdb_exception_error &except) catch (const gdb_exception_error &except)
{ {

View file

@ -33,7 +33,7 @@
same, but for the dwz file's index. */ same, but for the dwz file's index. */
extern void write_dwarf_index extern void write_dwarf_index
(dwarf2_per_objfile *per_objfile, const char *dir, const char *basename, (dwarf2_per_bfd *per_bfd, const char *dir, const char *basename,
const char *dwz_basename, dw_index_kind index_kind); const char *dwz_basename, dw_index_kind index_kind);
#endif /* DWARF_INDEX_WRITE_H */ #endif /* DWARF_INDEX_WRITE_H */

View file

@ -3424,7 +3424,7 @@ dwarf2_build_psymtabs (struct objfile *objfile)
dwarf2_build_psymtabs_hard (per_objfile); dwarf2_build_psymtabs_hard (per_objfile);
/* (maybe) store an index in the cache. */ /* (maybe) store an index in the cache. */
global_index_cache.store (per_objfile); global_index_cache.store (per_objfile->per_bfd);
} }
catch (const gdb_exception_error &except) catch (const gdb_exception_error &except)
{ {