Fix crash when creating index from index
authorTom Tromey <tromey@adacore.com>
Thu, 21 Apr 2022 17:20:22 +0000 (11:20 -0600)
committerTom Tromey <tromey@adacore.com>
Wed, 4 May 2022 14:38:05 +0000 (08:38 -0600)
My patches yesterday to unify the DWARF index base classes had a bug
-- namely, I did the wholesale dynamic_cast-to-static_cast too hastily
and introduced a crash.  This can be seen by trying to add an index to
a file that has an index, or by running a test like gdb-index-cxx.exp
using the cc-with-debug-names.exp target board.

This patch fixes the crash by introducing a new virtual method and
removing some of the static casts.

gdb/dwarf2/cooked-index.h
gdb/dwarf2/index-write.c
gdb/dwarf2/mapped-index.h

index 21bda8698c1eb4c70c7e9ae073b56fb444346f89..a460351612f52ba5e44fc0b2f3853cad3c381bc3 100644 (file)
@@ -295,6 +295,11 @@ public:
      "main".  This will return NULL if no such entry is available.  */
   const cooked_index_entry *get_main () const;
 
+  cooked_index_vector *index_for_writing () override
+  {
+    return this;
+  }
+
   quick_symbol_functions_up make_quick_functions () const override;
 
 private:
index 62a7466bcfef3e6d9f53858cf429dd7d7b97e1fc..dfa74ddad8e9422684d2056cc98a1559c5d2e6d5 100644 (file)
@@ -1163,8 +1163,9 @@ write_cooked_index (cooked_index_vector *table,
    associated dwz file, DWZ_OUT_FILE must be NULL.  */
 
 static void
-write_gdbindex (dwarf2_per_objfile *per_objfile, FILE *out_file,
-               FILE *dwz_out_file)
+write_gdbindex (dwarf2_per_objfile *per_objfile,
+               cooked_index_vector *table,
+               FILE *out_file, FILE *dwz_out_file)
 {
   mapped_symtab symtab;
   data_buf objfile_cu_list;
@@ -1218,9 +1219,6 @@ write_gdbindex (dwarf2_per_objfile *per_objfile, FILE *out_file,
       ++this_counter;
     }
 
-  cooked_index_vector *table
-    = (static_cast<cooked_index_vector *>
-       (per_objfile->per_bfd->index_table.get ()));
   write_cooked_index (table, cu_index_htab, &symtab);
 
   /* Dump the address map.  */
@@ -1256,6 +1254,7 @@ static const gdb_byte dwarf5_gdb_augmentation[] = { 'G', 'D', 'B', 0 };
 
 static void
 write_debug_names (dwarf2_per_objfile *per_objfile,
+                  cooked_index_vector *table,
                   FILE *out_file, FILE *out_file_str)
 {
   const bool dwarf5_is_dwarf64 = check_dwarf64_offsets (per_objfile);
@@ -1291,9 +1290,6 @@ write_debug_names (dwarf2_per_objfile *per_objfile,
                          - per_objfile->per_bfd->tu_stats.nr_tus));
   gdb_assert (types_counter == per_objfile->per_bfd->tu_stats.nr_tus);
 
-  cooked_index_vector *table
-    = (static_cast<cooked_index_vector *>
-       (per_objfile->per_bfd->index_table.get ()));
   for (const cooked_index_entry *entry : table->all_entries ())
     nametable.insert (entry);
 
@@ -1431,15 +1427,10 @@ write_dwarf_index (dwarf2_per_objfile *per_objfile, const char *dir,
 {
   struct objfile *objfile = per_objfile->objfile;
 
+  if (per_objfile->per_bfd->index_table == nullptr)
+    error (_("No debugging symbols"));
   cooked_index_vector *table
-    = (static_cast<cooked_index_vector *>
-       (per_objfile->per_bfd->index_table.get ()));
-  if (table == nullptr)
-    {
-      if (per_objfile->per_bfd->index_table != nullptr)
-       error (_("Cannot use an index to create the index"));
-      error (_("No debugging symbols"));
-    }
+    = per_objfile->per_bfd->index_table->index_for_writing ();
 
   if (per_objfile->per_bfd->types.size () > 1)
     error (_("Cannot make an index when the file has multiple .debug_types sections"));
@@ -1460,13 +1451,13 @@ write_dwarf_index (dwarf2_per_objfile *per_objfile, const char *dir,
     {
       index_wip_file str_wip_file (dir, basename, DEBUG_STR_SUFFIX);
 
-      write_debug_names (per_objfile, objfile_index_wip.out_file.get (),
+      write_debug_names (per_objfile, table, objfile_index_wip.out_file.get (),
                         str_wip_file.out_file.get ());
 
       str_wip_file.finalize ();
     }
   else
-    write_gdbindex (per_objfile, objfile_index_wip.out_file.get (),
+    write_gdbindex (per_objfile, table, objfile_index_wip.out_file.get (),
                    (dwz_index_wip.has_value ()
                     ? dwz_index_wip->out_file.get () : NULL));
 
index e5d77469925ca01406984c57aeeb66ab785a96e3..7d71347f9f4b7e7022eef80796d3a85b121af3a7 100644 (file)
@@ -1,6 +1,6 @@
 /* Base class for mapped indices
 
-   Copyright (C) 2021 Free Software Foundation, Inc.
+   Copyright (C) 2021, 2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -47,6 +47,8 @@ struct name_component
   offset_type idx;
 };
 
+class cooked_index_vector;
+
 /* Base class of all DWARF scanner types.  */
 
 struct dwarf_scanner_base
@@ -66,6 +68,11 @@ struct dwarf_scanner_base
   {
     return true;
   }
+
+  /* This is called when writing an index.  For a cooked index, it
+     will return 'this' as a cooked index.  For other forms, it will
+     throw an exception with an appropriate error message.  */
+  virtual cooked_index_vector *index_for_writing () = 0;
 };
 
 /* Base class containing bits shared by both .gdb_index and
@@ -109,6 +116,11 @@ struct mapped_index_base : public dwarf_scanner_base
     find_name_components_bounds (const lookup_name_info &ln_no_params,
                                 enum language lang,
                                 dwarf2_per_objfile *per_objfile) const;
+
+  cooked_index_vector *index_for_writing () override
+  {
+    error (_("Cannot use an index to create the index"));
+  }
 };
 
 #endif /* GDB_DWARF2_MAPPED_INDEX_H */