+/* DWP file .debug_{cu,tu}_index section format:
+ [ref: http://gcc.gnu.org/wiki/DebugFissionDWP]
+
+ Both index sections have the same format, and serve to map a 64-bit
+ signature to a set of section numbers. Each section begins with a header,
+ followed by a hash table of 64-bit signatures, a parallel table of 32-bit
+ indexes, and a pool of 32-bit section numbers. The index sections will be
+ aligned at 8-byte boundaries in the file.
+
+ The index section header contains two unsigned 32-bit values (using the
+ byte order of the application binary):
+
+ N, the number of compilation units or type units in the index
+ M, the number of slots in the hash table
+
+ (We assume that N and M will not exceed 2^32 - 1.)
+
+ The size of the hash table, M, must be 2^k such that 2^k > 3*N/2.
+
+ The hash table begins at offset 8 in the section, and consists of an array
+ of M 64-bit slots. Each slot contains a 64-bit signature (using the byte
+ order of the application binary). Unused slots in the hash table are 0.
+ (We rely on the extreme unlikeliness of a signature being exactly 0.)
+
+ The parallel table begins immediately after the hash table
+ (at offset 8 + 8 * M from the beginning of the section), and consists of an
+ array of 32-bit indexes (using the byte order of the application binary),
+ corresponding 1-1 with slots in the hash table. Each entry in the parallel
+ table contains a 32-bit index into the pool of section numbers. For unused
+ hash table slots, the corresponding entry in the parallel table will be 0.
+
+ Given a 64-bit compilation unit signature or a type signature S, an entry
+ in the hash table is located as follows:
+
+ 1) Calculate a primary hash H = S & MASK(k), where MASK(k) is a mask with
+ the low-order k bits all set to 1.
+
+ 2) Calculate a secondary hash H' = (((S >> 32) & MASK(k)) | 1).
+
+ 3) If the hash table entry at index H matches the signature, use that
+ entry. If the hash table entry at index H is unused (all zeroes),
+ terminate the search: the signature is not present in the table.
+
+ 4) Let H = (H + H') modulo M. Repeat at Step 3.
+
+ Because M > N and H' and M are relatively prime, the search is guaranteed
+ to stop at an unused slot or find the match.
+
+ The pool of section numbers begins immediately following the hash table
+ (at offset 8 + 12 * M from the beginning of the section). The pool of
+ section numbers consists of an array of 32-bit words (using the byte order
+ of the application binary). Each item in the array is indexed starting
+ from 0. The hash table entry provides the index of the first section
+ number in the set. Additional section numbers in the set follow, and the
+ set is terminated by a 0 entry (section number 0 is not used in ELF).
+
+ In each set of section numbers, the .debug_info.dwo or .debug_types.dwo
+ section must be the first entry in the set, and the .debug_abbrev.dwo must
+ be the second entry. Other members of the set may follow in any order. */
+
+/* Create a hash table to map DWO IDs to their CU/TU entry in
+ .debug_{info,types}.dwo in DWP_FILE.
+ Returns NULL if there isn't one.
+ Note: This function processes DWP files only, not DWO files. */
+
+static struct dwp_hash_table *
+create_dwp_hash_table (struct dwp_file *dwp_file, int is_debug_types)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *dbfd = dwp_file->dbfd;
+ char *index_ptr, *index_end;
+ struct dwarf2_section_info *index;
+ uint32_t version, nr_units, nr_slots;
+ struct dwp_hash_table *htab;
+
+ if (is_debug_types)
+ index = &dwp_file->sections.tu_index;
+ else
+ index = &dwp_file->sections.cu_index;
+
+ if (dwarf2_section_empty_p (index))
+ return NULL;
+ dwarf2_read_section (objfile, index);
+
+ index_ptr = index->buffer;
+ index_end = index_ptr + index->size;
+
+ version = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 8; /* Skip the unused word. */
+ nr_units = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 4;
+ nr_slots = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 4;
+
+ if (version != 1)
+ {
+ error (_("Dwarf Error: unsupported DWP file version (%u)"
+ " [in module %s]"),
+ version, dwp_file->name);
+ }
+ if (nr_slots != (nr_slots & -nr_slots))
+ {
+ error (_("Dwarf Error: number of slots in DWP hash table (%u)"
+ " is not power of 2 [in module %s]"),
+ nr_slots, dwp_file->name);
+ }
+
+ htab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_hash_table);
+ htab->nr_units = nr_units;
+ htab->nr_slots = nr_slots;
+ htab->hash_table = index_ptr;
+ htab->unit_table = htab->hash_table + sizeof (uint64_t) * nr_slots;
+ htab->section_pool = htab->unit_table + sizeof (uint32_t) * nr_slots;
+
+ return htab;
+}
+
+/* Update SECTIONS with the data from SECTP.
+
+ This function is like the other "locate" section routines that are
+ passed to bfd_map_over_sections, but in this context the sections to
+ read comes from the DWP hash table, not the full ELF section table.
+
+ The result is non-zero for success, or zero if an error was found. */
+
+static int
+locate_virtual_dwo_sections (asection *sectp,
+ struct virtual_dwo_sections *sections)
+{
+ const struct dwop_section_names *names = &dwop_section_names;
+
+ if (section_is_p (sectp->name, &names->abbrev_dwo))
+ {
+ /* There can be only one. */
+ if (sections->abbrev.asection != NULL)
+ return 0;
+ sections->abbrev.asection = sectp;
+ sections->abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->info_dwo)
+ || section_is_p (sectp->name, &names->types_dwo))
+ {
+ /* There can be only one. */
+ if (sections->info_or_types.asection != NULL)
+ return 0;
+ sections->info_or_types.asection = sectp;
+ sections->info_or_types.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->line_dwo))
+ {
+ /* There can be only one. */
+ if (sections->line.asection != NULL)
+ return 0;
+ sections->line.asection = sectp;
+ sections->line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->loc_dwo))
+ {
+ /* There can be only one. */
+ if (sections->loc.asection != NULL)
+ return 0;
+ sections->loc.asection = sectp;
+ sections->loc.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macinfo_dwo))
+ {
+ /* There can be only one. */
+ if (sections->macinfo.asection != NULL)
+ return 0;
+ sections->macinfo.asection = sectp;
+ sections->macinfo.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macro_dwo))
+ {
+ /* There can be only one. */
+ if (sections->macro.asection != NULL)
+ return 0;
+ sections->macro.asection = sectp;
+ sections->macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+ {
+ /* There can be only one. */
+ if (sections->str_offsets.asection != NULL)
+ return 0;
+ sections->str_offsets.asection = sectp;
+ sections->str_offsets.size = bfd_get_section_size (sectp);
+ }
+ else
+ {
+ /* No other kind of section is valid. */
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Create a dwo_unit object for the DWO with signature SIGNATURE.
+ HTAB is the hash table from the DWP file.
+ SECTION_INDEX is the index of the DWO in HTAB. */
+
+static struct dwo_unit *
+create_dwo_in_dwp (struct dwp_file *dwp_file,
+ const struct dwp_hash_table *htab,
+ uint32_t section_index,
+ ULONGEST signature, int is_debug_types)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *dbfd = dwp_file->dbfd;
+ const char *kind = is_debug_types ? "TU" : "CU";
+ struct dwo_file *dwo_file;
+ struct dwo_unit *dwo_unit;
+ struct virtual_dwo_sections sections;
+ void **dwo_file_slot;
+ char *virtual_dwo_name;
+ struct dwarf2_section_info *cutu;
+ struct cleanup *cleanups;
+ int i;
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Reading %s %u/0x%s in DWP file: %s\n",
+ kind,
+ section_index, phex (signature, sizeof (signature)),
+ dwp_file->name);
+ }
+
+ /* Fetch the sections of this DWO.
+ Put a limit on the number of sections we look for so that bad data
+ doesn't cause us to loop forever. */
+
+#define MAX_NR_DWO_SECTIONS \
+ (1 /* .debug_info or .debug_types */ \
+ + 1 /* .debug_abbrev */ \
+ + 1 /* .debug_line */ \
+ + 1 /* .debug_loc */ \
+ + 1 /* .debug_str_offsets */ \
+ + 1 /* .debug_macro */ \
+ + 1 /* .debug_macinfo */ \
+ + 1 /* trailing zero */)
+
+ memset (§ions, 0, sizeof (sections));
+ cleanups = make_cleanup (null_cleanup, 0);
+
+ for (i = 0; i < MAX_NR_DWO_SECTIONS; ++i)
+ {
+ asection *sectp;
+ uint32_t section_nr =
+ read_4_bytes (dbfd,
+ htab->section_pool
+ + (section_index + i) * sizeof (uint32_t));
+
+ if (section_nr == 0)
+ break;
+ if (section_nr >= dwp_file->num_sections)
+ {
+ error (_("Dwarf Error: bad DWP hash table, section number too large"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+
+ sectp = dwp_file->elf_sections[section_nr];
+ if (! locate_virtual_dwo_sections (sectp, §ions))
+ {
+ error (_("Dwarf Error: bad DWP hash table, invalid section found"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+ }
+
+ if (i < 2
+ || sections.info_or_types.asection == NULL
+ || sections.abbrev.asection == NULL)
+ {
+ error (_("Dwarf Error: bad DWP hash table, missing DWO sections"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+ if (i == MAX_NR_DWO_SECTIONS)
+ {
+ error (_("Dwarf Error: bad DWP hash table, too many DWO sections"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+
+ /* It's easier for the rest of the code if we fake a struct dwo_file and
+ have dwo_unit "live" in that. At least for now.
+
+ The DWP file can be made up of a random collection of CUs and TUs.
+ However, for each CU + set of TUs that came from the same original DWO
+ file, we want to combine them back into a virtual DWO file to save space
+ (fewer struct dwo_file objects to allocated). Remember that for really
+ large apps there can be on the order of 8K CUs and 200K TUs, or more. */
+
+ virtual_dwo_name =
+ xstrprintf ("virtual-dwo/%d-%d-%d-%d",
+ sections.abbrev.asection ? sections.abbrev.asection->id : 0,
+ sections.line.asection ? sections.line.asection->id : 0,
+ sections.loc.asection ? sections.loc.asection->id : 0,
+ (sections.str_offsets.asection
+ ? sections.str_offsets.asection->id
+ : 0));
+ make_cleanup (xfree, virtual_dwo_name);
+ /* Can we use an existing virtual DWO file? */
+ dwo_file_slot = lookup_dwo_file_slot (virtual_dwo_name);
+ /* Create one if necessary. */
+ if (*dwo_file_slot == NULL)
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
+ virtual_dwo_name);
+ }
+ dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
+ dwo_file->name = obstack_copy0 (&objfile->objfile_obstack,
+ virtual_dwo_name,
+ strlen (virtual_dwo_name));
+ dwo_file->sections.abbrev = sections.abbrev;
+ dwo_file->sections.line = sections.line;
+ dwo_file->sections.loc = sections.loc;
+ dwo_file->sections.macinfo = sections.macinfo;
+ dwo_file->sections.macro = sections.macro;
+ dwo_file->sections.str_offsets = sections.str_offsets;
+ /* The "str" section is global to the entire DWP file. */
+ dwo_file->sections.str = dwp_file->sections.str;
+ /* The info or types section is assigned later to dwo_unit,
+ there's no need to record it in dwo_file.
+ Also, we can't simply record type sections in dwo_file because
+ we record a pointer into the vector in dwo_unit. As we collect more
+ types we'll grow the vector and eventually have to reallocate space
+ for it, invalidating all the pointers into the current copy. */
+ *dwo_file_slot = dwo_file;
+ }
+ else
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
+ virtual_dwo_name);
+ }
+ dwo_file = *dwo_file_slot;
+ }
+ do_cleanups (cleanups);
+
+ dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit->dwo_file = dwo_file;
+ dwo_unit->signature = signature;
+ dwo_unit->info_or_types_section =
+ obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct dwarf2_section_info));
+ *dwo_unit->info_or_types_section = sections.info_or_types;
+ /* offset, length, type_offset_in_tu are set later. */
+
+ return dwo_unit;
+}
+
+/* Lookup the DWO with SIGNATURE in DWP_FILE. */
+
+static struct dwo_unit *
+lookup_dwo_in_dwp (struct dwp_file *dwp_file,
+ const struct dwp_hash_table *htab,
+ ULONGEST signature, int is_debug_types)
+{
+ bfd *dbfd = dwp_file->dbfd;
+ uint32_t mask = htab->nr_slots - 1;
+ uint32_t hash = signature & mask;
+ uint32_t hash2 = ((signature >> 32) & mask) | 1;
+ unsigned int i;
+ void **slot;
+ struct dwo_unit find_dwo_cu, *dwo_cu;
+
+ memset (&find_dwo_cu, 0, sizeof (find_dwo_cu));
+ find_dwo_cu.signature = signature;
+ slot = htab_find_slot (dwp_file->loaded_cutus, &find_dwo_cu, INSERT);
+
+ if (*slot != NULL)
+ return *slot;
+
+ /* Use a for loop so that we don't loop forever on bad debug info. */
+ for (i = 0; i < htab->nr_slots; ++i)
+ {
+ ULONGEST signature_in_table;
+
+ signature_in_table =
+ read_8_bytes (dbfd, htab->hash_table + hash * sizeof (uint64_t));
+ if (signature_in_table == signature)
+ {
+ uint32_t section_index =
+ read_4_bytes (dbfd, htab->unit_table + hash * sizeof (uint32_t));
+
+ *slot = create_dwo_in_dwp (dwp_file, htab, section_index,
+ signature, is_debug_types);
+ return *slot;
+ }
+ if (signature_in_table == 0)
+ return NULL;
+ hash = (hash + hash2) & mask;
+ }
+
+ error (_("Dwarf Error: bad DWP hash table, lookup didn't terminate"
+ " [in module %s]"),
+ dwp_file->name);
+}
+
+/* Subroutine of open_dwop_file to simplify it.