PR gdb/7912:
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 8947f8fc41120ec994a0dc834ae34b01760d51a5..24b1fe6cb12393ea7d62e182233af004f598bc45 100644 (file)
@@ -68,6 +68,7 @@
 #include "gdb_bfd.h"
 #include "f-lang.h"
 #include "source.h"
+#include "filestuff.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -601,6 +602,7 @@ struct dwarf2_per_cu_data
 struct signatured_type
 {
   /* The "per_cu" object of this type.
+     This struct is used iff per_cu.is_debug_types.
      N.B.: This is the first member so that it's easy to convert pointers
      between them.  */
   struct dwarf2_per_cu_data per_cu;
@@ -623,6 +625,11 @@ struct signatured_type
   /* Type units are grouped by their DW_AT_stmt_list entry so that they
      can share them.  This points to the containing symtab.  */
   struct type_unit_group *type_unit_group;
+
+  /* The type.
+     The first time we encounter this type we fully read it in and install it
+     in the symbol tables.  Subsequent times we only need the type.  */
+  struct type *type;
 };
 
 typedef struct signatured_type *sig_type_ptr;
@@ -742,9 +749,12 @@ struct dwo_file
   /* Section info for this file.  */
   struct dwo_sections sections;
 
-  /* Table of CUs in the file.
-     Each element is a struct dwo_unit.  */
-  htab_t cus;
+  /* The CU in the file.
+     We only support one because having more than one requires hacking the
+     dwo_name of each to match, which is highly unlikely to happen.
+     Doing this means all TUs can share comp_dir: We also assume that
+     DW_AT_comp_dir across all TUs in a DWO file will be identical.  */
+  struct dwo_unit *cu;
 
   /* Table of TUs in the file.
      Each element is a struct dwo_unit.  */
@@ -1045,7 +1055,7 @@ struct attribute
        ULONGEST unsnd;
        LONGEST snd;
        CORE_ADDR addr;
-       struct signatured_type *signatured_type;
+       ULONGEST signature;
       }
     u;
   };
@@ -1091,7 +1101,7 @@ struct die_info
 #define DW_BLOCK(attr)     ((attr)->u.blk)
 #define DW_SND(attr)       ((attr)->u.snd)
 #define DW_ADDR(attr)     ((attr)->u.addr)
-#define DW_SIGNATURED_TYPE(attr) ((attr)->u.signatured_type)
+#define DW_SIGNATURE(attr) ((attr)->u.signature)
 
 /* Blocks are a bunch of untyped bytes.  */
 struct dwarf_block
@@ -1602,6 +1612,13 @@ static struct die_info *follow_die_sig (struct die_info *,
                                        struct attribute *,
                                        struct dwarf2_cu **);
 
+static struct type *get_signatured_type (struct die_info *, ULONGEST,
+                                        struct dwarf2_cu *);
+
+static struct type *get_DW_AT_signature_type (struct die_info *,
+                                             struct attribute *,
+                                             struct dwarf2_cu *);
+
 static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
 
 static void read_signatured_type (struct signatured_type *);
@@ -1687,7 +1704,7 @@ static void dwarf2_mark (struct dwarf2_cu *);
 static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
 
 static struct type *get_die_type_at_offset (sect_offset,
-                                           struct dwarf2_per_cu_data *per_cu);
+                                           struct dwarf2_per_cu_data *);
 
 static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
 
@@ -2087,7 +2104,7 @@ dwarf2_get_dwz_file (void)
           bfd_errmsg (bfd_get_error ()));
   cleanup = make_cleanup (xfree, data);
 
-  filename = data;
+  filename = (const char *) data;
   if (!IS_ABSOLUTE_PATH (filename))
     {
       char *abs = gdb_realpath (dwarf2_per_objfile->objfile->name);
@@ -2655,7 +2672,7 @@ read_index_from_section (struct objfile *objfile,
                         const gdb_byte **types_list,
                         offset_type *types_list_elements)
 {
-  const char *addr;
+  const gdb_byte *addr;
   offset_type version;
   offset_type *metadata;
   int i;
@@ -2748,7 +2765,7 @@ to use the section anyway."),
                             / (2 * sizeof (offset_type)));
   ++i;
 
-  map->constant_pool = addr + MAYBE_SWAP (metadata[i]);
+  map->constant_pool = (char *) (addr + MAYBE_SWAP (metadata[i]));
 
   return 1;
 }
@@ -4317,16 +4334,16 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
 
              complaint (&symfile_complaints,
                         _("debug type entry at offset 0x%x is duplicate to"
-                          " the entry at offset 0x%x, signature 0x%s"),
+                          " the entry at offset 0x%x, signature %s"),
                         offset.sect_off, dup_offset.sect_off,
-                        phex (signature, sizeof (signature)));
+                        hex_string (signature));
            }
          *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
 
          if (dwarf2_read_debug)
-           fprintf_unfiltered (gdb_stdlog, "  offset 0x%x, signature 0x%s\n",
+           fprintf_unfiltered (gdb_stdlog, "  offset 0x%x, signature %s\n",
                                offset.sect_off,
-                               phex (signature, sizeof (signature)));
+                               hex_string (signature));
 
          info_ptr += length;
        }
@@ -4634,8 +4651,7 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
     {
       error (_("Dwarf Error: CU at offset 0x%x references unknown DWO"
               " with ID %s [in module %s]"),
-            this_cu->offset.sect_off,
-            phex (signature, sizeof (signature)),
+            this_cu->offset.sect_off, hex_string (signature),
             this_cu->objfile->name);
     }
 
@@ -8389,85 +8405,64 @@ allocate_dwo_unit_table (struct objfile *objfile)
 
 /* Structure used to pass data to create_dwo_debug_info_hash_table_reader.  */
 
-struct create_dwo_info_table_data
+struct create_dwo_cu_data
 {
   struct dwo_file *dwo_file;
-  htab_t cu_htab;
+  struct dwo_unit dwo_unit;
 };
 
-/* die_reader_func for create_dwo_debug_info_hash_table.  */
+/* die_reader_func for create_dwo_cu.  */
 
 static void
-create_dwo_debug_info_hash_table_reader (const struct die_reader_specs *reader,
-                                        const gdb_byte *info_ptr,
-                                        struct die_info *comp_unit_die,
-                                        int has_children,
-                                        void *datap)
+create_dwo_cu_reader (const struct die_reader_specs *reader,
+                     const gdb_byte *info_ptr,
+                     struct die_info *comp_unit_die,
+                     int has_children,
+                     void *datap)
 {
   struct dwarf2_cu *cu = reader->cu;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   sect_offset offset = cu->per_cu->offset;
   struct dwarf2_section_info *section = cu->per_cu->section;
-  struct create_dwo_info_table_data *data = datap;
+  struct create_dwo_cu_data *data = datap;
   struct dwo_file *dwo_file = data->dwo_file;
-  htab_t cu_htab = data->cu_htab;
-  void **slot;
+  struct dwo_unit *dwo_unit = &data->dwo_unit;
   struct attribute *attr;
-  struct dwo_unit *dwo_unit;
 
   attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu);
   if (attr == NULL)
     {
-      error (_("Dwarf Error: debug entry at offset 0x%x is missing"
-              " its dwo_id [in module %s]"),
-            offset.sect_off, dwo_file->dwo_name);
+      complaint (&symfile_complaints,
+                _("Dwarf Error: debug entry at offset 0x%x is missing"
+                  " its dwo_id [in module %s]"),
+                offset.sect_off, dwo_file->dwo_name);
       return;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = DW_UNSND (attr);
   dwo_unit->section = section;
   dwo_unit->offset = offset;
   dwo_unit->length = cu->per_cu->length;
 
-  slot = htab_find_slot (cu_htab, dwo_unit, INSERT);
-  gdb_assert (slot != NULL);
-  if (*slot != NULL)
-    {
-      const struct dwo_unit *dup_dwo_unit = *slot;
-
-      complaint (&symfile_complaints,
-                _("debug entry at offset 0x%x is duplicate to the entry at"
-                  " offset 0x%x, dwo_id 0x%s [in module %s]"),
-                offset.sect_off, dup_dwo_unit->offset.sect_off,
-                phex (dwo_unit->signature, sizeof (dwo_unit->signature)),
-                dwo_file->dwo_name);
-    }
-  else
-    *slot = dwo_unit;
-
   if (dwarf2_read_debug)
-    fprintf_unfiltered (gdb_stdlog, "  offset 0x%x, dwo_id 0x%s\n",
-                       offset.sect_off,
-                       phex (dwo_unit->signature,
-                             sizeof (dwo_unit->signature)));
+    fprintf_unfiltered (gdb_stdlog, "  offset 0x%x, dwo_id %s\n",
+                       offset.sect_off, hex_string (dwo_unit->signature));
 }
 
-/* Create a hash table to map DWO IDs to their CU entry in
-   .debug_info.dwo in DWO_FILE.
-   Note: This function processes DWO files only, not DWP files.
-   Note: A DWO file generally contains one CU, but we don't assume this.  */
+/* Create the dwo_unit for the lone CU in DWO_FILE.
+   Note: This function processes DWO files only, not DWP files.  */
 
-static htab_t
-create_dwo_debug_info_hash_table (struct dwo_file *dwo_file)
+static struct dwo_unit *
+create_dwo_cu (struct dwo_file *dwo_file)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = &dwo_file->sections.info;
   bfd *abfd;
   htab_t cu_htab;
   const gdb_byte *info_ptr, *end_ptr;
-  struct create_dwo_info_table_data create_dwo_info_table_data;
+  struct create_dwo_cu_data create_dwo_cu_data;
+  struct dwo_unit *dwo_unit;
 
   dwarf2_read_section (objfile, section);
   info_ptr = section->buffer;
@@ -8480,19 +8475,22 @@ create_dwo_debug_info_hash_table (struct dwo_file *dwo_file)
   abfd = section->asection->owner;
 
   if (dwarf2_read_debug)
-    fprintf_unfiltered (gdb_stdlog, "Reading .debug_info.dwo for %s:\n",
-                       bfd_get_filename (abfd));
-
-  cu_htab = allocate_dwo_unit_table (objfile);
+    {
+      fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
+                         bfd_section_name (abfd, section->asection),
+                         bfd_get_filename (abfd));
+    }
 
-  create_dwo_info_table_data.dwo_file = dwo_file;
-  create_dwo_info_table_data.cu_htab = cu_htab;
+  create_dwo_cu_data.dwo_file = dwo_file;
+  dwo_unit = NULL;
 
   end_ptr = info_ptr + section->size;
   while (info_ptr < end_ptr)
     {
       struct dwarf2_per_cu_data per_cu;
 
+      memset (&create_dwo_cu_data.dwo_unit, 0,
+             sizeof (create_dwo_cu_data.dwo_unit));
       memset (&per_cu, 0, sizeof (per_cu));
       per_cu.objfile = objfile;
       per_cu.is_debug_types = 0;
@@ -8502,13 +8500,30 @@ create_dwo_debug_info_hash_table (struct dwo_file *dwo_file)
       init_cutu_and_read_dies_no_follow (&per_cu,
                                         &dwo_file->sections.abbrev,
                                         dwo_file,
-                                        create_dwo_debug_info_hash_table_reader,
-                                        &create_dwo_info_table_data);
+                                        create_dwo_cu_reader,
+                                        &create_dwo_cu_data);
+
+      if (create_dwo_cu_data.dwo_unit.dwo_file != NULL)
+       {
+         /* If we've already found one, complain.  We only support one
+            because having more than one requires hacking the dwo_name of
+            each to match, which is highly unlikely to happen.  */
+         if (dwo_unit != NULL)
+           {
+             complaint (&symfile_complaints,
+                        _("Multiple CUs in DWO file %s [in module %s]"),
+                        dwo_file->dwo_name, objfile->name);
+             break;
+           }
+
+         dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+         *dwo_unit = create_dwo_cu_data.dwo_unit;
+       }
 
       info_ptr += per_cu.length;
     }
 
-  return cu_htab;
+  return dwo_unit;
 }
 
 /* DWP file .debug_{cu,tu}_index section format:
@@ -8581,7 +8596,7 @@ 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;
-  const char *index_ptr, *index_end;
+  const gdb_byte *index_ptr, *index_end;
   struct dwarf2_section_info *index;
   uint32_t version, nr_units, nr_slots;
   struct dwp_hash_table *htab;
@@ -8734,9 +8749,9 @@ create_dwo_in_dwp (struct dwp_file *dwp_file,
 
   if (dwarf2_read_debug)
     {
-      fprintf_unfiltered (gdb_stdlog, "Reading %s %u/0x%s in DWP file: %s\n",
+      fprintf_unfiltered (gdb_stdlog, "Reading %s %u/%s in DWP file: %s\n",
                          kind,
-                         section_index, phex (signature, sizeof (signature)),
+                         section_index, hex_string (signature),
                          dwp_file->name);
     }
 
@@ -9059,7 +9074,7 @@ dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_sections_ptr)
 }
 
 /* Initialize the use of the DWO file specified by DWO_NAME and referenced
-   by PER_CU.
+   by PER_CU.  This is for the non-DWP case.
    The result is NULL if DWO_NAME can't be found.  */
 
 static struct dwo_file *
@@ -9087,7 +9102,7 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
 
   bfd_map_over_sections (dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections);
 
-  dwo_file->cus = create_dwo_debug_info_hash_table (dwo_file);
+  dwo_file->cu = create_dwo_cu (dwo_file);
 
   dwo_file->tus = create_debug_types_hash_table (dwo_file,
                                                 dwo_file->sections.types);
@@ -9318,26 +9333,31 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
 
   if (dwo_file != NULL)
     {
-      htab_t htab = is_debug_types ? dwo_file->tus : dwo_file->cus;
+      struct dwo_unit *dwo_cutu = NULL;
 
-      if (htab != NULL)
+      if (is_debug_types && dwo_file->tus)
        {
-         struct dwo_unit find_dwo_cutu, *dwo_cutu;
+         struct dwo_unit find_dwo_cutu;
 
          memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu));
          find_dwo_cutu.signature = signature;
-         dwo_cutu = htab_find (htab, &find_dwo_cutu);
+         dwo_cutu = htab_find (dwo_file->tus, &find_dwo_cutu);
+       }
+      else if (!is_debug_types && dwo_file->cu)
+       {
+         if (signature == dwo_file->cu->signature)
+           dwo_cutu = dwo_file->cu;
+       }
 
-         if (dwo_cutu != NULL)
+      if (dwo_cutu != NULL)
+       {
+         if (dwarf2_read_debug)
            {
-             if (dwarf2_read_debug)
-               {
-                 fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) found: @%s\n",
-                                     kind, dwo_name, hex_string (signature),
-                                     host_address_to_string (dwo_cutu));
-               }
-             return dwo_cutu;
+             fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) found: @%s\n",
+                                 kind, dwo_name, hex_string (signature),
+                                 host_address_to_string (dwo_cutu));
            }
+         return dwo_cutu;
        }
     }
 
@@ -9935,7 +9955,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       struct dwarf2_cu *target_cu = cu;
       struct die_info *target_die;
 
-      target_die = follow_die_ref_or_sig (die, attr, &target_cu);
+      target_die = follow_die_ref (die, attr, &target_cu);
       gdb_assert (target_cu->objfile == objfile);
       if (die_is_declaration (target_die, target_cu))
        {
@@ -11364,16 +11384,9 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   attr = dwarf2_attr_no_follow (die, DW_AT_signature);
   if (attr)
     {
-      struct dwarf2_cu *type_cu = cu;
-      struct die_info *type_die = follow_die_ref_or_sig (die, attr, &type_cu);
-
-      /* We could just recurse on read_structure_type, but we need to call
-        get_die_type to ensure only one type for this DIE is created.
-        This is important, for example, because for c++ classes we need
-        TYPE_NAME set which is only done by new_symbol.  Blech.  */
-      type = read_type_die (type_die, type_cu);
+      type = get_DW_AT_signature_type (die, attr, cu);
 
-      /* TYPE_CU may not be the same as CU.
+      /* The type's CU may not be the same as CU.
         Ensure TYPE is recorded with CU in die_type_hash.  */
       return set_die_type (die, type, cu);
     }
@@ -11691,12 +11704,9 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
   attr = dwarf2_attr_no_follow (die, DW_AT_signature);
   if (attr)
     {
-      struct dwarf2_cu *type_cu = cu;
-      struct die_info *type_die = follow_die_ref_or_sig (die, attr, &type_cu);
+      type = get_DW_AT_signature_type (die, attr, cu);
 
-      type = read_type_die (type_die, type_cu);
-
-      /* TYPE_CU may not be the same as CU.
+      /* The type's CU may not be the same as CU.
         Ensure TYPE is recorded with CU in die_type_hash.  */
       return set_die_type (die, type, cu);
     }
@@ -14323,11 +14333,7 @@ read_attribute_value (const struct die_reader_specs *reader,
       info_ptr += 8;
       break;
     case DW_FORM_ref_sig8:
-      /* Convert the signature to something we can record in DW_UNSND
-        for later lookup.
-         NOTE: This is NULL if the type wasn't found.  */
-      DW_SIGNATURED_TYPE (attr) =
-       lookup_signatured_type (read_8_bytes (abfd, info_ptr));
+      DW_SIGNATURE (attr) = read_8_bytes (abfd, info_ptr);
       info_ptr += 8;
       break;
     case DW_FORM_ref_udata:
@@ -16595,7 +16601,28 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
   return lookup_die_type (die, type_attr, cu);
 }
 
+/* Return an error marker type to use for the ill formed type in DIE/CU.  */
+
+static struct type *
+build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  char *message, *saved;
+
+  message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
+                       objfile->name,
+                       cu->header.offset.sect_off,
+                       die->offset.sect_off);
+  saved = obstack_copy0 (&objfile->objfile_obstack,
+                        message, strlen (message));
+  xfree (message);
+
+  return init_type (TYPE_CODE_ERROR, 0, 0, saved, objfile);
+}
+
 /* Look up the type of DIE in CU using its type attribute ATTR.
+   ATTR must be one of: DW_AT_type, DW_AT_GNAT_descriptive_type,
+   DW_AT_containing_type.
    If there is no type substitute an error marker.  */
 
 static struct type *
@@ -16605,6 +16632,10 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
   struct objfile *objfile = cu->objfile;
   struct type *this_type;
 
+  gdb_assert (attr->name == DW_AT_type
+             || attr->name == DW_AT_GNAT_descriptive_type
+             || attr->name == DW_AT_containing_type);
+
   /* First see if we have it cached.  */
 
   if (attr->form == DW_FORM_GNU_ref_alt)
@@ -16623,66 +16654,41 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
     }
   else if (attr->form == DW_FORM_ref_sig8)
     {
-      struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
-
-      /* sig_type will be NULL if the signatured type is missing from
-        the debug info.  */
-      if (sig_type == NULL)
-       error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
-                "at 0x%x [in module %s]"),
-              die->offset.sect_off, objfile->name);
+      ULONGEST signature = DW_SIGNATURE (attr);
 
-      gdb_assert (sig_type->per_cu.is_debug_types);
-      /* If we haven't filled in type_offset_in_section yet, then we
-        haven't read the type in yet.  */
-      this_type = NULL;
-      if (sig_type->type_offset_in_section.sect_off != 0)
-       {
-         this_type =
-           get_die_type_at_offset (sig_type->type_offset_in_section,
-                                   &sig_type->per_cu);
-       }
+      return get_signatured_type (die, signature, cu);
     }
   else
     {
-      dump_die_for_error (die);
-      error (_("Dwarf Error: Bad type attribute %s [in module %s]"),
-            dwarf_attr_name (attr->name), objfile->name);
+      complaint (&symfile_complaints,
+                _("Dwarf Error: Bad type attribute %s in DIE"
+                  " at 0x%x [in module %s]"),
+                dwarf_attr_name (attr->name), die->offset.sect_off,
+                objfile->name);
+      return build_error_marker_type (cu, die);
     }
 
   /* If not cached we need to read it in.  */
 
   if (this_type == NULL)
     {
-      struct die_info *type_die;
+      struct die_info *type_die = NULL;
       struct dwarf2_cu *type_cu = cu;
 
-      type_die = follow_die_ref_or_sig (die, attr, &type_cu);
-      /* If we found the type now, it's probably because the type came
+      if (is_ref_attr (attr))
+       type_die = follow_die_ref (die, attr, &type_cu);
+      if (type_die == NULL)
+       return build_error_marker_type (cu, die);
+      /* If we find the type now, it's probably because the type came
         from an inter-CU reference and the type's CU got expanded before
         ours.  */
-      this_type = get_die_type (type_die, type_cu);
-      if (this_type == NULL)
-       this_type = read_type_die_1 (type_die, type_cu);
+      this_type = read_type_die (type_die, type_cu);
     }
 
   /* If we still don't have a type use an error marker.  */
 
   if (this_type == NULL)
-    {
-      char *message, *saved;
-
-      /* read_type_die already issued a complaint.  */
-      message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
-                           objfile->name,
-                           cu->header.offset.sect_off,
-                           die->offset.sect_off);
-      saved = obstack_copy0 (&objfile->objfile_obstack,
-                            message, strlen (message));
-      xfree (message);
-
-      this_type = init_type (TYPE_CODE_ERROR, 0, 0, saved, objfile);
-    }
+    return build_error_marker_type (cu, die);
 
   return this_type;
 }
@@ -17416,17 +17422,8 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
                              pulongest (DW_UNSND (&die->attrs[i])));
          break;
        case DW_FORM_ref_sig8:
-         if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL)
-           {
-             struct signatured_type *sig_type =
-               DW_SIGNATURED_TYPE (&die->attrs[i]);
-
-             fprintf_unfiltered (f, "signatured type: 0x%s, offset 0x%x",
-                                 hex_string (sig_type->signature),
-                                 sig_type->per_cu.offset.sect_off);
-           }
-         else
-           fprintf_unfiltered (f, "signatured type, unknown");
+         fprintf_unfiltered (f, "signature: %s",
+                             hex_string (DW_SIGNATURE (&die->attrs[i])));
          break;
        case DW_FORM_string:
        case DW_FORM_strp:
@@ -17774,26 +17771,23 @@ dwarf2_get_die_type (cu_offset die_offset,
   return get_die_type_at_offset (die_offset_sect, per_cu);
 }
 
-/* Follow the signature attribute ATTR in SRC_DIE.
+/* Follow type unit SIG_TYPE referenced by SRC_DIE.
    On entry *REF_CU is the CU of SRC_DIE.
-   On exit *REF_CU is the CU of the result.  */
+   On exit *REF_CU is the CU of the result.
+   Returns NULL if the referenced DIE isn't found.  */
 
 static struct die_info *
-follow_die_sig (struct die_info *src_die, struct attribute *attr,
-               struct dwarf2_cu **ref_cu)
+follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
+                 struct dwarf2_cu **ref_cu)
 {
   struct objfile *objfile = (*ref_cu)->objfile;
   struct die_info temp_die;
-  struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
   struct dwarf2_cu *sig_cu;
   struct die_info *die;
 
-  /* sig_type will be NULL if the signatured type is missing from
-     the debug info.  */
-  if (sig_type == NULL)
-    error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
-            "at 0x%x [in module %s]"),
-          src_die->offset.sect_off, objfile->name);
+  /* While it might be nice to assert sig_type->type == NULL here,
+     we can get here for DW_AT_imported_declaration where we need
+     the DIE not the type.  */
 
   /* If necessary, add it to the queue and load its DIEs.  */
 
@@ -17823,9 +17817,138 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
       return die;
     }
 
-  error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced "
-        "from DIE at 0x%x [in module %s]"),
-        temp_die.offset.sect_off, src_die->offset.sect_off, objfile->name);
+  return NULL;
+}
+
+/* Follow signatured type referenced by ATTR in SRC_DIE.
+   On entry *REF_CU is the CU of SRC_DIE.
+   On exit *REF_CU is the CU of the result.
+   The result is the DIE of the type.
+   If the referenced type cannot be found an error is thrown.  */
+
+static struct die_info *
+follow_die_sig (struct die_info *src_die, struct attribute *attr,
+               struct dwarf2_cu **ref_cu)
+{
+  ULONGEST signature = DW_SIGNATURE (attr);
+  struct signatured_type *sig_type;
+  struct die_info *die;
+
+  gdb_assert (attr->form == DW_FORM_ref_sig8);
+
+  sig_type = lookup_signatured_type (signature);
+  /* sig_type will be NULL if the signatured type is missing from
+     the debug info.  */
+  if (sig_type == NULL)
+    {
+      error (_("Dwarf Error: Cannot find signatured DIE %s referenced"
+               " from DIE at 0x%x [in module %s]"),
+             hex_string (signature), src_die->offset.sect_off,
+            (*ref_cu)->objfile->name);
+    }
+
+  die = follow_die_sig_1 (src_die, sig_type, ref_cu);
+  if (die == NULL)
+    {
+      dump_die_for_error (src_die);
+      error (_("Dwarf Error: Problem reading signatured DIE %s referenced"
+              " from DIE at 0x%x [in module %s]"),
+            hex_string (signature), src_die->offset.sect_off,
+            (*ref_cu)->objfile->name);
+    }
+
+  return die;
+}
+
+/* Get the type specified by SIGNATURE referenced in DIE/CU,
+   reading in and processing the type unit if necessary.  */
+
+static struct type *
+get_signatured_type (struct die_info *die, ULONGEST signature,
+                    struct dwarf2_cu *cu)
+{
+  struct signatured_type *sig_type;
+  struct dwarf2_cu *type_cu;
+  struct die_info *type_die;
+  struct type *type;
+
+  sig_type = lookup_signatured_type (signature);
+  /* sig_type will be NULL if the signatured type is missing from
+     the debug info.  */
+  if (sig_type == NULL)
+    {
+      complaint (&symfile_complaints,
+                _("Dwarf Error: Cannot find signatured DIE %s referenced"
+                  " from DIE at 0x%x [in module %s]"),
+                hex_string (signature), die->offset.sect_off,
+                dwarf2_per_objfile->objfile->name);
+      return build_error_marker_type (cu, die);
+    }
+
+  /* If we already know the type we're done.  */
+  if (sig_type->type != NULL)
+    return sig_type->type;
+
+  type_cu = cu;
+  type_die = follow_die_sig_1 (die, sig_type, &type_cu);
+  if (type_die != NULL)
+    {
+      /* N.B. We need to call get_die_type to ensure only one type for this DIE
+        is created.  This is important, for example, because for c++ classes
+        we need TYPE_NAME set which is only done by new_symbol.  Blech.  */
+      type = read_type_die (type_die, type_cu);
+      if (type == NULL)
+       {
+         complaint (&symfile_complaints,
+                    _("Dwarf Error: Cannot build signatured type %s"
+                      " referenced from DIE at 0x%x [in module %s]"),
+                    hex_string (signature), die->offset.sect_off,
+                    dwarf2_per_objfile->objfile->name);
+         type = build_error_marker_type (cu, die);
+       }
+    }
+  else
+    {
+      complaint (&symfile_complaints,
+                _("Dwarf Error: Problem reading signatured DIE %s referenced"
+                  " from DIE at 0x%x [in module %s]"),
+                hex_string (signature), die->offset.sect_off,
+                dwarf2_per_objfile->objfile->name);
+      type = build_error_marker_type (cu, die);
+    }
+  sig_type->type = type;
+
+  return type;
+}
+
+/* Get the type specified by the DW_AT_signature ATTR in DIE/CU,
+   reading in and processing the type unit if necessary.  */
+
+static struct type *
+get_DW_AT_signature_type (struct die_info *die, struct attribute *attr,
+                         struct dwarf2_cu *cu)
+{
+  /* Yes, DW_AT_signature can use a non-ref_sig8 reference.  */
+  if (is_ref_attr (attr))
+    {
+      struct dwarf2_cu *type_cu = cu;
+      struct die_info *type_die = follow_die_ref (die, attr, &type_cu);
+
+      return read_type_die (type_die, type_cu);
+    }
+  else if (attr->form == DW_FORM_ref_sig8)
+    {
+      return get_signatured_type (die, DW_SIGNATURE (attr), cu);
+    }
+  else
+    {
+      complaint (&symfile_complaints,
+                _("Dwarf Error: DW_AT_signature has bad form %s in DIE"
+                  " at 0x%x [in module %s]"),
+                dwarf_form_name (attr->form), die->offset.sect_off,
+                dwarf2_per_objfile->objfile->name);
+      return build_error_marker_type (cu, die);
+    }
 }
 
 /* Load the DIEs associated with type unit PER_CU into memory.  */
@@ -20299,7 +20422,7 @@ add_address_entry (struct objfile *objfile, struct obstack *obstack,
                   CORE_ADDR start, CORE_ADDR end, unsigned int cu_index)
 {
   offset_type cu_index_to_write;
-  char addr[8];
+  gdb_byte addr[8];
   CORE_ADDR baseaddr;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -20576,7 +20699,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
                     INDEX_SUFFIX, (char *) NULL);
   cleanup = make_cleanup (xfree, filename);
 
-  out_file = fopen (filename, "wb");
+  out_file = gdb_fopen_cloexec (filename, "wb");
   if (!out_file)
     error (_("Can't open `%s' for writing"), filename);
 
This page took 0.044295 seconds and 4 git commands to generate.