* dwarf2read.c (struct dwarf2_per_objfile) <n_type_comp_units,
authorTom Tromey <tromey@redhat.com>
Fri, 23 Jul 2010 22:15:13 +0000 (22:15 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 23 Jul 2010 22:15:13 +0000 (22:15 +0000)
type_comp_units>: New fields.
(dw2_get_cu): New function.
(create_cus_from_index): Remove unused argument.
(create_signatured_type_hash_from_index): New function.
(create_addrmap_from_index): Update.
(dwarf2_read_index): Handle version 2.
(dw2_find_last_source_symtab, dw2_forget_cached_source_info)
(dw2_lookup_symtab, dw2_do_expand_symtabs_matching)
(dw2_print_stats, dw2_expand_all_symtabs)
(dw2_expand_symtabs_with_filename, dw2_find_symbol_file)
(dw2_expand_symtabs_matching, dw2_map_symbol_filenames): Update.
(dwarf2_initialize_objfile): Call create_debug_types_hash_table.
(allocate_signatured_type_hash_table): New function.
(add_signatured_type_cu_to_list): Likewise.
(create_debug_types_hash_table): Use them.  Set type_comp_units.
(read_signatured_type): Ensure section data is available.
(add_address_entry): Don't record empty ranges.
(struct signatured_type_index_data): New.
(write_one_signatured_type): New function.
(write_psymtabs_to_index): Write type CUs.
(save_gdb_index_command): Update comment.
(process_type_comp_unit): Move inititalization of
from_debug_types...
(create_debug_types_hash_table): ... here.

gdb/ChangeLog
gdb/dwarf2read.c

index e2062d82fecf9aeaad463a1aa48956b6a4ed6405..f89375e728fac65e5e95b979f984597ae90b211a 100644 (file)
@@ -1,3 +1,31 @@
+2010-07-23  Tom Tromey  <tromey@redhat.com>
+
+       * dwarf2read.c (struct dwarf2_per_objfile) <n_type_comp_units,
+       type_comp_units>: New fields.
+       (dw2_get_cu): New function.
+       (create_cus_from_index): Remove unused argument.
+       (create_signatured_type_hash_from_index): New function.
+       (create_addrmap_from_index): Update.
+       (dwarf2_read_index): Handle version 2.
+       (dw2_find_last_source_symtab, dw2_forget_cached_source_info)
+       (dw2_lookup_symtab, dw2_do_expand_symtabs_matching)
+       (dw2_print_stats, dw2_expand_all_symtabs)
+       (dw2_expand_symtabs_with_filename, dw2_find_symbol_file)
+       (dw2_expand_symtabs_matching, dw2_map_symbol_filenames): Update.
+       (dwarf2_initialize_objfile): Call create_debug_types_hash_table.
+       (allocate_signatured_type_hash_table): New function.
+       (add_signatured_type_cu_to_list): Likewise.
+       (create_debug_types_hash_table): Use them.  Set type_comp_units.
+       (read_signatured_type): Ensure section data is available.
+       (add_address_entry): Don't record empty ranges.
+       (struct signatured_type_index_data): New.
+       (write_one_signatured_type): New function.
+       (write_psymtabs_to_index): Write type CUs.
+       (save_gdb_index_command): Update comment.
+       (process_type_comp_unit): Move inititalization of
+       from_debug_types...
+       (create_debug_types_hash_table): ... here.
+
 2010-07-23  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * gdb_gcore.sh (tmpfile): Remove the variable, its initialization,
index 6f0472657bf9a11141cbbef74187a5915656cd5d..f4eb1f7370285f2bd74ea63bfb9e3861015efb74 100644 (file)
@@ -180,6 +180,12 @@ struct dwarf2_per_objfile
   /* The number of compilation units in ALL_COMP_UNITS.  */
   int n_comp_units;
 
+  /* The number of .debug_types-related CUs.  */
+  int n_type_comp_units;
+
+  /* The .debug_types-related CUs.  */
+  struct dwarf2_per_cu_data **type_comp_units;
+
   /* A chain of compilation units that are currently read in, so that
      they can be freed later.  */
   struct dwarf2_per_cu_data *read_in_chain;
@@ -1190,6 +1196,8 @@ static struct type *set_die_type (struct die_info *, struct type *,
 
 static void create_all_comp_units (struct objfile *);
 
+static int create_debug_types_hash_table (struct objfile *objfile);
+
 static void load_full_comp_unit (struct dwarf2_per_cu_data *,
                                 struct objfile *);
 
@@ -1227,6 +1235,8 @@ static gdb_byte *partial_read_comp_unit_head (struct comp_unit_head *header,
 static void init_cu_die_reader (struct die_reader_specs *reader,
                                struct dwarf2_cu *cu);
 
+static htab_t allocate_signatured_type_hash_table (struct objfile *objfile);
+
 #if WORDS_BIGENDIAN
 
 /* Convert VALUE between big- and little-endian.  */
@@ -1603,6 +1613,18 @@ dw2_instantiate_symtab (struct objfile *objfile,
   return per_cu->v.quick->symtab;
 }
 
+/* Return the CU given its index.  */
+static struct dwarf2_per_cu_data *
+dw2_get_cu (int index)
+{
+  if (index >= dwarf2_per_objfile->n_comp_units)
+    {
+      index -= dwarf2_per_objfile->n_comp_units;
+      return dwarf2_per_objfile->type_comp_units[index];
+    }
+  return dwarf2_per_objfile->all_comp_units[index];
+}
+
 /* A helper function that knows how to read a 64-bit value in a way
    that doesn't make gdb die.  Returns 1 if the conversion went ok, 0
    otherwise.  */
@@ -1629,11 +1651,10 @@ extract_cu_value (const char *bytes, ULONGEST *result)
    the CU objects for this objfile.  Return 0 if something went wrong,
    1 if everything went ok.  */
 static int
-create_cus_from_index (struct objfile *objfile, struct mapped_index *index,
-                      const gdb_byte *cu_list, offset_type cu_list_elements)
+create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
+                      offset_type cu_list_elements)
 {
   offset_type i;
-  const char *entry;
 
   dwarf2_per_objfile->n_comp_units = cu_list_elements / 2;
   dwarf2_per_objfile->all_comp_units
@@ -1664,6 +1685,58 @@ create_cus_from_index (struct objfile *objfile, struct mapped_index *index,
   return 1;
 }
 
+/* Create the signatured type hash table from the index.  */
+static int
+create_signatured_type_hash_from_index (struct objfile *objfile,
+                                       const gdb_byte *bytes,
+                                       offset_type elements)
+{
+  offset_type i;
+  htab_t type_hash;
+
+  dwarf2_per_objfile->n_type_comp_units = elements / 3;
+  dwarf2_per_objfile->type_comp_units
+    = obstack_alloc (&objfile->objfile_obstack,
+                    dwarf2_per_objfile->n_type_comp_units
+                    * sizeof (struct dwarf2_per_cu_data *));
+
+  type_hash = allocate_signatured_type_hash_table (objfile);
+
+  for (i = 0; i < elements; i += 3)
+    {
+      struct signatured_type *type_sig;
+      ULONGEST offset, type_offset, signature;
+      void **slot;
+
+      if (!extract_cu_value (bytes, &offset)
+         || !extract_cu_value (bytes + 8, &type_offset))
+       return 0;
+      signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
+      bytes += 3 * 8;
+
+      type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                                struct signatured_type);
+      type_sig->signature = signature;
+      type_sig->offset = offset;
+      type_sig->type_offset = type_offset;
+      type_sig->per_cu.from_debug_types = 1;
+      type_sig->per_cu.offset = offset;
+      type_sig->per_cu.objfile = objfile;
+      type_sig->per_cu.v.quick
+       = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                         struct dwarf2_per_cu_quick_data);
+
+      slot = htab_find_slot (type_hash, type_sig, INSERT);
+      *slot = type_sig;
+
+      dwarf2_per_objfile->type_comp_units[i / 3] = &type_sig->per_cu;
+    }
+
+  dwarf2_per_objfile->signatured_types = type_hash;
+
+  return 1;
+}
+
 /* Read the address map data from the mapped index, and use it to
    populate the objfile's psymtabs_addrmap.  */
 static void
@@ -1695,7 +1768,7 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index)
       iter += 4;
       
       addrmap_set_empty (mutable_map, lo + baseaddr, hi + baseaddr - 1,
-                        dwarf2_per_objfile->all_comp_units[cu_index]);
+                        dw2_get_cu (cu_index));
     }
 
   objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map,
@@ -1762,8 +1835,9 @@ dwarf2_read_index (struct objfile *objfile)
   char *addr;
   struct mapped_index *map;
   offset_type *metadata;
-  const gdb_byte *cu_list;
-  offset_type cu_list_elements;
+  const gdb_byte *cu_list, *types_list;
+  offset_type version, cu_list_elements, types_list_elements;
+  int i;
 
   if (dwarf2_per_objfile->gdb_index.asection == NULL
       || dwarf2_per_objfile->gdb_index.size == 0)
@@ -1772,26 +1846,58 @@ dwarf2_read_index (struct objfile *objfile)
 
   addr = dwarf2_per_objfile->gdb_index.buffer;
   /* Version check.  */
-  if (MAYBE_SWAP (*(offset_type *) addr) != 1)
+  version = MAYBE_SWAP (*(offset_type *) addr);
+  if (version == 1)
+    {
+      /* Index version 1 neglected to account for .debug_types.  So,
+        if we see .debug_types, we cannot use this index.  */
+      if (dwarf2_per_objfile->types.asection != NULL
+         && dwarf2_per_objfile->types.size != 0)
+       return 0;
+    }
+  else if (version != 2)
     return 0;
 
   map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
   map->total_size = dwarf2_per_objfile->gdb_index.size;
 
   metadata = (offset_type *) (addr + sizeof (offset_type));
-  cu_list = addr + MAYBE_SWAP (metadata[0]);
-  cu_list_elements = ((MAYBE_SWAP (metadata[1]) - MAYBE_SWAP (metadata[0]))
+
+  i = 0;
+  cu_list = addr + MAYBE_SWAP (metadata[i]);
+  cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
                      / 8);
-  map->address_table = addr + MAYBE_SWAP (metadata[1]);
-  map->address_table_size = (MAYBE_SWAP (metadata[2])
-                            - MAYBE_SWAP (metadata[1]));
-  map->index_table = (offset_type *) (addr + MAYBE_SWAP (metadata[2]));
-  map->index_table_slots = ((MAYBE_SWAP (metadata[3])
-                            - MAYBE_SWAP (metadata[2]))
+  ++i;
+
+  if (version == 2)
+    {
+      types_list = addr + MAYBE_SWAP (metadata[i]);
+      types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
+                             - MAYBE_SWAP (metadata[i]))
+                            / 8);
+      ++i;
+    }
+
+  map->address_table = addr + MAYBE_SWAP (metadata[i]);
+  map->address_table_size = (MAYBE_SWAP (metadata[i + 1])
+                            - MAYBE_SWAP (metadata[i]));
+  ++i;
+
+  map->index_table = (offset_type *) (addr + MAYBE_SWAP (metadata[i]));
+  map->index_table_slots = ((MAYBE_SWAP (metadata[i + 1])
+                            - MAYBE_SWAP (metadata[i]))
                            / (2 * sizeof (offset_type)));
-  map->constant_pool = addr + MAYBE_SWAP (metadata[3]);
+  ++i;
 
-  if (!create_cus_from_index (objfile, map, cu_list, cu_list_elements))
+  map->constant_pool = addr + MAYBE_SWAP (metadata[i]);
+
+  if (!create_cus_from_index (objfile, cu_list, cu_list_elements))
+    return 0;
+
+  if (version == 2
+      && types_list_elements
+      && !create_signatured_type_hash_from_index (objfile, types_list,
+                                                 types_list_elements))
     return 0;
 
   create_addrmap_from_index (objfile, map);
@@ -1918,8 +2024,7 @@ dw2_find_last_source_symtab (struct objfile *objfile)
   int index;
   dw2_setup (objfile);
   index = dwarf2_per_objfile->n_comp_units - 1;
-  return dw2_instantiate_symtab (objfile,
-                                dwarf2_per_objfile->all_comp_units[index]);
+  return dw2_instantiate_symtab (objfile, dw2_get_cu (index));
 }
 
 static void
@@ -1928,9 +2033,10 @@ dw2_forget_cached_source_info (struct objfile *objfile)
   int i;
 
   dw2_setup (objfile);
-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+                  + dwarf2_per_objfile->n_type_comp_units); ++i)
     {
-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
 
       if (cu->v.quick->full_names)
        {
@@ -1952,10 +2058,11 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
   struct dwarf2_per_cu_data *base_cu = NULL;
 
   dw2_setup (objfile);
-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+                  + dwarf2_per_objfile->n_type_comp_units); ++i)
     {
       int j;
-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
 
       if (cu->v.quick->symtab)
        continue;
@@ -2047,8 +2154,8 @@ dw2_do_expand_symtabs_matching (struct objfile *objfile, const char *name)
          for (i = 0; i < len; ++i)
            {
              offset_type cu_index = MAYBE_SWAP (vec[i + 1]);
-             struct dwarf2_per_cu_data *cu;
-             cu = dwarf2_per_objfile->all_comp_units[cu_index];
+             struct dwarf2_per_cu_data *cu = dw2_get_cu (cu_index);
+
              dw2_instantiate_symtab (objfile, cu);
            }
        }
@@ -2070,9 +2177,10 @@ dw2_print_stats (struct objfile *objfile)
 
   dw2_setup (objfile);
   count = 0;
-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+                  + dwarf2_per_objfile->n_type_comp_units); ++i)
     {
-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
 
       if (!cu->v.quick->symtab)
        ++count;
@@ -2106,9 +2214,11 @@ dw2_expand_all_symtabs (struct objfile *objfile)
   int i;
 
   dw2_setup (objfile);
-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+
+  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+                  + dwarf2_per_objfile->n_type_comp_units); ++i)
     {
-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
 
       dw2_instantiate_symtab (objfile, cu);
     }
@@ -2121,10 +2231,11 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile,
   int i;
 
   dw2_setup (objfile);
-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+                  + dwarf2_per_objfile->n_type_comp_units); ++i)
     {
       int j;
-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
 
       if (cu->v.quick->symtab)
        continue;
@@ -2165,7 +2276,7 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name)
      should be rewritten so that it doesn't require a custom hook.  It
      could just use the ordinary symbol tables.  */
   /* vec[0] is the length, which must always be >0.  */
-  cu = dwarf2_per_objfile->all_comp_units[MAYBE_SWAP (vec[1])];
+  cu = dw2_get_cu (MAYBE_SWAP (vec[1]));
 
   dw2_require_line_header (objfile, cu);
   if (!cu->v.quick->lines)
@@ -2204,10 +2315,11 @@ dw2_expand_symtabs_matching (struct objfile *objfile,
   if (!dwarf2_per_objfile->index_table)
     return;
 
-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+                  + dwarf2_per_objfile->n_type_comp_units); ++i)
     {
       int j;
-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
 
       cu->v.quick->mark = 0;
       if (cu->v.quick->symtab)
@@ -2252,8 +2364,9 @@ dw2_expand_symtabs_matching (struct objfile *objfile,
       vec_len = MAYBE_SWAP (vec[0]);
       for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
        {
-         struct dwarf2_per_cu_data *cu
-           = dwarf2_per_objfile->all_comp_units[MAYBE_SWAP (vec[vec_idx + 1])];
+         struct dwarf2_per_cu_data *cu;
+
+         cu = dw2_get_cu (MAYBE_SWAP (vec[vec_idx + 1]));
          if (cu->v.quick->mark)
            dw2_instantiate_symtab (objfile, cu);
        }
@@ -2323,10 +2436,11 @@ dw2_map_symbol_filenames (struct objfile *objfile,
   int i;
 
   dw2_setup (objfile);
-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+                  + dwarf2_per_objfile->n_type_comp_units); ++i)
     {
       int j;
-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
 
       if (cu->v.quick->symtab)
        continue;
@@ -2387,10 +2501,12 @@ dwarf2_initialize_objfile (struct objfile *objfile)
 
       dwarf2_per_objfile->using_index = 1;
       create_all_comp_units (objfile);
+      create_debug_types_hash_table (objfile);
 
-      for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+      for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+                      + dwarf2_per_objfile->n_type_comp_units); ++i)
        {
-         struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+         struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
 
          cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
                                        struct dwarf2_per_cu_quick_data);
@@ -2604,6 +2720,34 @@ eq_type_signature (const void *item_lhs, const void *item_rhs)
   return lhs->signature == rhs->signature;
 }
 
+/* Allocate a hash table for signatured types.  */
+
+static htab_t
+allocate_signatured_type_hash_table (struct objfile *objfile)
+{
+  return htab_create_alloc_ex (41,
+                              hash_type_signature,
+                              eq_type_signature,
+                              NULL,
+                              &objfile->objfile_obstack,
+                              hashtab_obstack_allocate,
+                              dummy_obstack_deallocate);
+}
+
+/* A helper function to add a signatured type CU to a list.  */
+
+static int
+add_signatured_type_cu_to_list (void **slot, void *datum)
+{
+  struct signatured_type *sigt = *slot;
+  struct dwarf2_per_cu_data ***datap = datum;
+
+  **datap = &sigt->per_cu;
+  ++*datap;
+
+  return 1;
+}
+
 /* Create the hash table of all entries in the .debug_types section.
    The result is zero if there is an error (e.g. missing .debug_types section),
    otherwise non-zero. */
@@ -2613,6 +2757,7 @@ create_debug_types_hash_table (struct objfile *objfile)
 {
   gdb_byte *info_ptr;
   htab_t types_htab;
+  struct dwarf2_per_cu_data **iter;
 
   dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
   info_ptr = dwarf2_per_objfile->types.buffer;
@@ -2623,13 +2768,7 @@ create_debug_types_hash_table (struct objfile *objfile)
       return 0;
     }
 
-  types_htab = htab_create_alloc_ex (41,
-                                    hash_type_signature,
-                                    eq_type_signature,
-                                    NULL,
-                                    &objfile->objfile_obstack,
-                                    hashtab_obstack_allocate,
-                                    dummy_obstack_deallocate);
+  types_htab = allocate_signatured_type_hash_table (objfile);
 
   if (dwarf2_die_debug)
     fprintf_unfiltered (gdb_stdlog, "Signatured types:\n");
@@ -2677,6 +2816,7 @@ create_debug_types_hash_table (struct objfile *objfile)
       type_sig->offset = offset;
       type_sig->type_offset = type_offset;
       type_sig->per_cu.objfile = objfile;
+      type_sig->per_cu.from_debug_types = 1;
 
       slot = htab_find_slot (types_htab, type_sig, INSERT);
       gdb_assert (slot != NULL);
@@ -2691,6 +2831,16 @@ create_debug_types_hash_table (struct objfile *objfile)
 
   dwarf2_per_objfile->signatured_types = types_htab;
 
+  dwarf2_per_objfile->n_type_comp_units = htab_elements (types_htab);
+  dwarf2_per_objfile->type_comp_units
+    = obstack_alloc (&objfile->objfile_obstack,
+                    dwarf2_per_objfile->n_type_comp_units
+                    * sizeof (struct dwarf2_per_cu_data *));
+  iter = &dwarf2_per_objfile->type_comp_units[0];
+  htab_traverse_noresize (types_htab, add_signatured_type_cu_to_list, &iter);
+  gdb_assert (iter - &dwarf2_per_objfile->type_comp_units[0]
+             == dwarf2_per_objfile->n_type_comp_units);
+
   return 1;
 }
 
@@ -2959,7 +3109,6 @@ process_type_comp_unit (void **slot, void *info)
   struct dwarf2_per_cu_data *this_cu;
 
   this_cu = &entry->per_cu;
-  this_cu->from_debug_types = 1;
 
   gdb_assert (dwarf2_per_objfile->types.readin);
   process_psymtab_comp_unit (objfile, this_cu,
@@ -12067,13 +12216,16 @@ static void
 read_signatured_type (struct objfile *objfile,
                      struct signatured_type *type_sig)
 {
-  gdb_byte *types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset;
+  gdb_byte *types_ptr;
   struct die_reader_specs reader_specs;
   struct dwarf2_cu *cu;
   ULONGEST signature;
   struct cleanup *back_to, *free_cu_cleanup;
   struct attribute *attr;
 
+  dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
+  types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset;
+
   gdb_assert (type_sig->per_cu.cu == NULL);
 
   cu = xmalloc (sizeof (struct dwarf2_cu));
@@ -13912,6 +14064,10 @@ add_address_entry (struct objfile *objfile,
   char addr[8];
   CORE_ADDR baseaddr;
 
+  /* Don't bother recording empty ranges.  */
+  if (pst->textlow == pst->texthigh)
+    return;
+
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   store_unsigned_integer (addr, 8, BFD_ENDIAN_LITTLE, pst->textlow - baseaddr);
@@ -13957,13 +14113,53 @@ unlink_if_set (void *p)
     unlink (*filename);
 }
 
+/* A helper struct used when iterating over debug_types.  */
+struct signatured_type_index_data
+{
+  struct objfile *objfile;
+  struct mapped_symtab *symtab;
+  struct obstack *types_list;
+  int cu_index;
+};
+
+/* A helper function that writes a single signatured_type to an
+   obstack.  */
+static int
+write_one_signatured_type (void **slot, void *d)
+{
+  struct signatured_type_index_data *info = d;
+  struct signatured_type *entry = (struct signatured_type *) *slot;
+  struct dwarf2_per_cu_data *cu = &entry->per_cu;
+  struct partial_symtab *psymtab = cu->v.psymtab;
+  gdb_byte val[8];
+
+  write_psymbols (info->symtab,
+                 info->objfile->global_psymbols.list + psymtab->globals_offset,
+                 psymtab->n_global_syms, info->cu_index);
+  write_psymbols (info->symtab,
+                 info->objfile->static_psymbols.list + psymtab->statics_offset,
+                 psymtab->n_static_syms, info->cu_index);
+
+  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->offset);
+  obstack_grow (info->types_list, val, 8);
+  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset);
+  obstack_grow (info->types_list, val, 8);
+  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature);
+  obstack_grow (info->types_list, val, 8);
+
+  ++info->cu_index;
+
+  return 1;
+}
+
 /* Create an index file for OBJFILE in the directory DIR.  */
 static void
 write_psymtabs_to_index (struct objfile *objfile, const char *dir)
 {
   struct cleanup *cleanup;
   char *filename, *cleanup_filename;
-  struct obstack contents, addr_obstack, constant_pool, symtab_obstack, cu_list;
+  struct obstack contents, addr_obstack, constant_pool, symtab_obstack;
+  struct obstack cu_list, types_cu_list;
   int i;
   FILE *out_file;
   struct mapped_symtab *symtab;
@@ -13999,6 +14195,12 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
   obstack_init (&cu_list);
   make_cleanup_obstack_free (&cu_list);
 
+  obstack_init (&types_cu_list);
+  make_cleanup_obstack_free (&types_cu_list);
+
+  /* The list is already sorted, so we don't need to do additional
+     work here.  Also, the debug_types entries do not appear in
+     all_comp_units, but only in their own hash table.  */
   for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
     {
       struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
@@ -14020,6 +14222,19 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
       obstack_grow (&cu_list, val, 8);
     }
 
+  /* Write out the .debug_type entries, if any.  */
+  if (dwarf2_per_objfile->signatured_types)
+    {
+      struct signatured_type_index_data sig_data;
+
+      sig_data.objfile = objfile;
+      sig_data.symtab = symtab;
+      sig_data.types_list = &types_cu_list;
+      sig_data.cu_index = dwarf2_per_objfile->n_comp_units;
+      htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
+                             write_one_signatured_type, &sig_data);
+    }
+
   obstack_init (&constant_pool);
   make_cleanup_obstack_free (&constant_pool);
   obstack_init (&symtab_obstack);
@@ -14028,11 +14243,11 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
 
   obstack_init (&contents);
   make_cleanup_obstack_free (&contents);
-  size_of_contents = 5 * sizeof (offset_type);
+  size_of_contents = 6 * sizeof (offset_type);
   total_len = size_of_contents;
 
   /* The version number.  */
-  val = MAYBE_SWAP (1);
+  val = MAYBE_SWAP (2);
   obstack_grow (&contents, &val, sizeof (val));
 
   /* The offset of the CU list from the start of the file.  */
@@ -14040,6 +14255,11 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
   obstack_grow (&contents, &val, sizeof (val));
   total_len += obstack_object_size (&cu_list);
 
+  /* The offset of the types CU list from the start of the file.  */
+  val = MAYBE_SWAP (total_len);
+  obstack_grow (&contents, &val, sizeof (val));
+  total_len += obstack_object_size (&types_cu_list);
+
   /* The offset of the address table from the start of the file.  */
   val = MAYBE_SWAP (total_len);
   obstack_grow (&contents, &val, sizeof (val));
@@ -14059,6 +14279,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
 
   write_obstack (out_file, &contents);
   write_obstack (out_file, &cu_list);
+  write_obstack (out_file, &types_cu_list);
   write_obstack (out_file, &addr_obstack);
   write_obstack (out_file, &symtab_obstack);
   write_obstack (out_file, &constant_pool);
@@ -14083,18 +14304,33 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
 
    1. The file header.  This is a sequence of values, of offset_type
    unless otherwise noted:
-   [0] The version number.  Currently 1.
+   [0] The version number.  Currently 1 or 2.  The differences are
+   noted below.  Version 1 did not account for .debug_types sections;
+   the presence of a .debug_types section invalidates any version 1
+   index that may exist.
    [1] The offset, from the start of the file, of the CU list.
+   [1.5] In version 2, the offset, from the start of the file, of the
+   types CU list.  This offset does not appear in version 1.  Note
+   that this can be empty, in which case this offset will be equal to
+   the next offset.
    [2] The offset, from the start of the file, of the address section.
    [3] The offset, from the start of the file, of the symbol table.
    [4] The offset, from the start of the file, of the constant pool.
 
    2. The CU list.  This is a sequence of pairs of 64-bit
-   little-endian values.  The first element in each pair is the offset
-   of a CU in the .debug_info section.  The second element in each
-   pair is the length of that CU.  References to a CU elsewhere in the
-   map are done using a CU index, which is just the 0-based index into
-   this table.
+   little-endian values, sorted by the CU offset.  The first element
+   in each pair is the offset of a CU in the .debug_info section.  The
+   second element in each pair is the length of that CU.  References
+   to a CU elsewhere in the map are done using a CU index, which is
+   just the 0-based index into this table.  Note that if there are
+   type CUs, then conceptually CUs and type CUs form a single list for
+   the purposes of CU indices.
+
+   2.5 The types CU list.  This does not appear in a version 1 index.
+   This is a sequence of triplets of 64-bit little-endian values.  In
+   a triplet, the first value is the CU offset, the second value is
+   the type offset in the CU, and the third value is the type
+   signature.  The types CU list is not sorted.
 
    3. The address section.  The address section consists of a sequence
    of address entries.  Each address entry has three elements.