2011-05-26 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 81b20c7edfc0b40138a38c3327b4b780c297fa41..01a94675ea97f3495fe328f01433e7bc8b9a131b 100644 (file)
@@ -243,22 +243,24 @@ struct dwarf2_per_objfile
 
 static struct dwarf2_per_objfile *dwarf2_per_objfile;
 
-/* names of the debugging sections */
+/* Default names of the debugging sections.  */
 
 /* Note that if the debugging section has been compressed, it might
    have a name like .zdebug_info.  */
 
-#define INFO_SECTION     "debug_info"
-#define ABBREV_SECTION   "debug_abbrev"
-#define LINE_SECTION     "debug_line"
-#define LOC_SECTION      "debug_loc"
-#define MACINFO_SECTION  "debug_macinfo"
-#define STR_SECTION      "debug_str"
-#define RANGES_SECTION   "debug_ranges"
-#define TYPES_SECTION    "debug_types"
-#define FRAME_SECTION    "debug_frame"
-#define EH_FRAME_SECTION "eh_frame"
-#define GDB_INDEX_SECTION "gdb_index"
+static const struct dwarf2_debug_sections dwarf2_elf_names = {
+  { ".debug_info", ".zdebug_info" },
+  { ".debug_abbrev", ".zdebug_abbrev" },
+  { ".debug_line", ".zdebug_line" },
+  { ".debug_loc", ".zdebug_loc" },
+  { ".debug_macinfo", ".zdebug_macinfo" },
+  { ".debug_str", ".zdebug_str" },
+  { ".debug_ranges", ".zdebug_ranges" },
+  { ".debug_types", ".zdebug_types" },
+  { ".debug_frame", ".zdebug_frame" },
+  { ".eh_frame", NULL },
+  { ".gdb_index", ".zgdb_index" }
+};
 
 /* local data types */
 
@@ -470,9 +472,6 @@ struct signatured_type
 {
   ULONGEST signature;
 
-  /* Offset in .debug_types of the TU (type_unit) for this type.  */
-  unsigned int offset;
-
   /* Offset in .debug_types of the type defined by this TU.  */
   unsigned int type_offset;
 
@@ -1338,10 +1337,13 @@ static const char *dwarf2_physname (char *name, struct die_info *die,
                                    struct dwarf2_cu *cu);
 
 /* Try to locate the sections we need for DWARF 2 debugging
-   information and return true if we have enough to do something.  */
+   information and return true if we have enough to do something.
+   NAMES points to the dwarf2 section names, or is NULL if the standard
+   ELF names are used.  */
 
 int
-dwarf2_has_info (struct objfile *objfile)
+dwarf2_has_info (struct objfile *objfile,
+                 const struct dwarf2_debug_sections *names)
 {
   dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
   if (!dwarf2_per_objfile)
@@ -1354,23 +1356,28 @@ dwarf2_has_info (struct objfile *objfile)
       set_objfile_data (objfile, dwarf2_objfile_data_key, data);
       dwarf2_per_objfile = data;
 
-      bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
+      bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections,
+                             (void *) names);
       dwarf2_per_objfile->objfile = objfile;
     }
   return (dwarf2_per_objfile->info.asection != NULL
          && dwarf2_per_objfile->abbrev.asection != NULL);
 }
 
-/* When loading sections, we can either look for ".<name>", or for
* ".z<name>", which indicates a compressed section.  */
+/* When loading sections, we look either for uncompressed section or for
  compressed section names.  */
 
 static int
-section_is_p (const char *section_name, const char *name)
+section_is_p (const char *section_name,
+              const struct dwarf2_section_names *names)
 {
-  return (section_name[0] == '.'
-         && (strcmp (section_name + 1, name) == 0
-             || (section_name[1] == 'z'
-                 && strcmp (section_name + 2, name) == 0)));
+  if (names->normal != NULL
+      && strcmp (section_name, names->normal) == 0)
+    return 1;
+  if (names->compressed != NULL
+      && strcmp (section_name, names->compressed) == 0)
+    return 1;
+  return 0;
 }
 
 /* This function is mapped across the sections and remembers the
@@ -1378,44 +1385,51 @@ section_is_p (const char *section_name, const char *name)
    in.  */
 
 static void
-dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
+dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
 {
-  if (section_is_p (sectp->name, INFO_SECTION))
+  const struct dwarf2_debug_sections *names;
+
+  if (vnames == NULL)
+    names = &dwarf2_elf_names;
+  else
+    names = (const struct dwarf2_debug_sections *) vnames;
+
+  if (section_is_p (sectp->name, &names->info))
     {
       dwarf2_per_objfile->info.asection = sectp;
       dwarf2_per_objfile->info.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, ABBREV_SECTION))
+  else if (section_is_p (sectp->name, &names->abbrev))
     {
       dwarf2_per_objfile->abbrev.asection = sectp;
       dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, LINE_SECTION))
+  else if (section_is_p (sectp->name, &names->line))
     {
       dwarf2_per_objfile->line.asection = sectp;
       dwarf2_per_objfile->line.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, LOC_SECTION))
+  else if (section_is_p (sectp->name, &names->loc))
     {
       dwarf2_per_objfile->loc.asection = sectp;
       dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, MACINFO_SECTION))
+  else if (section_is_p (sectp->name, &names->macinfo))
     {
       dwarf2_per_objfile->macinfo.asection = sectp;
       dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, STR_SECTION))
+  else if (section_is_p (sectp->name, &names->str))
     {
       dwarf2_per_objfile->str.asection = sectp;
       dwarf2_per_objfile->str.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, FRAME_SECTION))
+  else if (section_is_p (sectp->name, &names->frame))
     {
       dwarf2_per_objfile->frame.asection = sectp;
       dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, EH_FRAME_SECTION))
+  else if (section_is_p (sectp->name, &names->eh_frame))
     {
       flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
 
@@ -1425,17 +1439,17 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
           dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp);
         }
     }
-  else if (section_is_p (sectp->name, RANGES_SECTION))
+  else if (section_is_p (sectp->name, &names->ranges))
     {
       dwarf2_per_objfile->ranges.asection = sectp;
       dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, TYPES_SECTION))
+  else if (section_is_p (sectp->name, &names->types))
     {
       dwarf2_per_objfile->types.asection = sectp;
       dwarf2_per_objfile->types.size = bfd_get_section_size (sectp);
     }
-  else if (section_is_p (sectp->name, GDB_INDEX_SECTION))
+  else if (section_is_p (sectp->name, &names->gdb_index))
     {
       dwarf2_per_objfile->gdb_index.asection = sectp;
       dwarf2_per_objfile->gdb_index.size = bfd_get_section_size (sectp);
@@ -1636,7 +1650,8 @@ dwarf2_section_size (struct objfile *objfile,
    SECTION_NAME.  */
 
 void
-dwarf2_get_section_info (struct objfile *objfile, const char *section_name,
+dwarf2_get_section_info (struct objfile *objfile,
+                         enum dwarf2_section_enum sect,
                          asection **sectp, gdb_byte **bufp,
                          bfd_size_type *sizep)
 {
@@ -1653,12 +1668,17 @@ dwarf2_get_section_info (struct objfile *objfile, const char *section_name,
       *sizep = 0;
       return;
     }
-  if (section_is_p (section_name, EH_FRAME_SECTION))
-    info = &data->eh_frame;
-  else if (section_is_p (section_name, FRAME_SECTION))
-    info = &data->frame;
-  else
-    gdb_assert_not_reached ("unexpected section");
+  switch (sect)
+    {
+    case DWARF2_DEBUG_FRAME:
+      info = &data->frame;
+      break;
+    case DWARF2_EH_FRAME:
+      info = &data->eh_frame;
+      break;
+    default:
+      gdb_assert_not_reached ("unexpected section");
+    }
 
   dwarf2_read_section (objfile, info);
 
@@ -1918,7 +1938,6 @@ create_signatured_type_table_from_index (struct objfile *objfile,
       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;
@@ -3093,13 +3112,24 @@ create_debug_types_hash_table (struct objfile *objfile)
       type_sig = obstack_alloc (&objfile->objfile_obstack, sizeof (*type_sig));
       memset (type_sig, 0, sizeof (*type_sig));
       type_sig->signature = signature;
-      type_sig->offset = offset;
       type_sig->type_offset = type_offset;
       type_sig->per_cu.objfile = objfile;
       type_sig->per_cu.from_debug_types = 1;
+      type_sig->per_cu.offset = offset;
 
       slot = htab_find_slot (types_htab, type_sig, INSERT);
       gdb_assert (slot != NULL);
+      if (*slot != NULL)
+       {
+         const struct signatured_type *dup_sig = *slot;
+
+         complaint (&symfile_complaints,
+                    _("debug type entry at offset 0x%x is duplicate to the "
+                      "entry at offset 0x%x, signature 0x%s"),
+                    offset, dup_sig->per_cu.offset,
+                    phex (signature, sizeof (signature)));
+         gdb_assert (signature == dup_sig->signature);
+       }
       *slot = type_sig;
 
       if (dwarf2_die_debug)
@@ -3264,8 +3294,8 @@ process_psymtab_comp_unit (struct objfile *objfile,
 
   if (this_cu->from_debug_types)
     {
-      /* offset,length haven't been set yet for type units.  */
-      this_cu->offset = cu.header.offset;
+      /* LENGTH has not been set yet for type units.  */
+      gdb_assert (this_cu->offset == cu.header.offset);
       this_cu->length = cu.header.length + cu.header.initial_length_size;
     }
   else if (comp_unit_die->tag == DW_TAG_partial_unit)
@@ -3390,7 +3420,7 @@ process_type_comp_unit (void **slot, void *info)
   gdb_assert (dwarf2_per_objfile->types.readin);
   process_psymtab_comp_unit (objfile, this_cu,
                             dwarf2_per_objfile->types.buffer,
-                            dwarf2_per_objfile->types.buffer + entry->offset,
+                            dwarf2_per_objfile->types.buffer + this_cu->offset,
                             dwarf2_per_objfile->types.size);
 
   return 1;
@@ -4609,10 +4639,10 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
   struct delayed_method_info *mi;
   for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i)
     {
-      char *physname;
+      const char *physname;
       struct fn_fieldlist *fn_flp
        = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
-      physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
+      physname = dwarf2_physname ((char *) mi->name, mi->die, cu);
       fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
     }
 }
@@ -6365,6 +6395,41 @@ dwarf2_default_access_attribute (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
+/* Look for DW_AT_data_member_location.  Set *OFFSET to the byte
+   offset.  If the attribute was not found return 0, otherwise return
+   1.  If it was found but could not properly be handled, set *OFFSET
+   to 0.  */
+
+static int
+handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
+                            LONGEST *offset)
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
+  if (attr != NULL)
+    {
+      *offset = 0;
+
+      /* Note that we do not check for a section offset first here.
+        This is because DW_AT_data_member_location is new in DWARF 4,
+        so if we see it, we can assume that a constant form is really
+        a constant and not a section offset.  */
+      if (attr_form_is_constant (attr))
+       *offset = dwarf2_get_attr_constant_value (attr, 0);
+      else if (attr_form_is_section_offset (attr))
+       dwarf2_complex_location_expr_complaint ();
+      else if (attr_form_is_block (attr))
+       *offset = decode_locdesc (DW_BLOCK (attr), cu);
+      else
+       dwarf2_complex_location_expr_complaint ();
+
+      return 1;
+    }
+
+  return 0;
+}
+
 /* Add an aggregate field to the field list.  */
 
 static void
@@ -6413,6 +6478,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
     {
+      LONGEST offset;
+
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -6432,22 +6499,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get bit offset of field.  */
-      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
-      if (attr)
-       {
-          int byte_offset = 0;
-
-          if (attr_form_is_section_offset (attr))
-           dwarf2_complex_location_expr_complaint ();
-          else if (attr_form_is_constant (attr))
-            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-          else if (attr_form_is_block (attr))
-            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
-         else
-           dwarf2_complex_location_expr_complaint ();
-
-          SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
-       }
+      if (handle_data_member_location (die, cu, &offset))
+       SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
       attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr)
        {
@@ -6519,7 +6572,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
         (so through at least 3.2.1) incorrectly generate
         DW_TAG_variable tags.  */
 
-      char *physname;
+      const char *physname;
 
       /* Get name of field.  */
       fieldname = dwarf2_name (die, cu);
@@ -6540,7 +6593,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get physical name.  */
-      physname = (char *) dwarf2_physname (fieldname, die, cu);
+      physname = dwarf2_physname (fieldname, die, cu);
 
       /* The name is already allocated along with this objfile, so we don't
         need to duplicate it for the type.  */
@@ -6550,23 +6603,11 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     }
   else if (die->tag == DW_TAG_inheritance)
     {
-      /* C++ base class field.  */
-      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
-      if (attr)
-       {
-          int byte_offset = 0;
+      LONGEST offset;
 
-          if (attr_form_is_section_offset (attr))
-           dwarf2_complex_location_expr_complaint ();
-          else if (attr_form_is_constant (attr))
-            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-          else if (attr_form_is_block (attr))
-            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
-         else
-           dwarf2_complex_location_expr_complaint ();
-
-          SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
-       }
+      /* C++ base class field.  */
+      if (handle_data_member_location (die, cu, &offset))
+       SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
       FIELD_BITSIZE (*fp) = 0;
       FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = type_name_no_tag (fp->type);
@@ -6781,7 +6822,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
     }
   else
     {
-      char *physname = (char *) dwarf2_physname (fieldname, die, cu);
+      const char *physname = dwarf2_physname (fieldname, die, cu);
       fnp->physname = physname ? physname : "";
     }
 
@@ -7676,22 +7717,13 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
       child_die = die->child;
       while (child_die && child_die->tag)
        {
+         LONGEST offset;
+
          sym = new_symbol (child_die, NULL, cu);
-         attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
-         if (sym != NULL && attr != NULL)
+         if (sym != NULL
+             && handle_data_member_location (child_die, cu, &offset))
            {
-             CORE_ADDR byte_offset = 0;
-
-             if (attr_form_is_section_offset (attr))
-               dwarf2_complex_location_expr_complaint ();
-             else if (attr_form_is_constant (attr))
-               byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-             else if (attr_form_is_block (attr))
-               byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
-             else
-               dwarf2_complex_location_expr_complaint ();
-
-             SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset;
+             SYMBOL_VALUE_ADDRESS (sym) = base + offset;
              add_symbol_to_list (sym, &global_symbols);
            }
          child_die = sibling_die (child_die);
@@ -11701,7 +11733,7 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
               die->offset, cu->objfile->name);
 
       gdb_assert (sig_type->per_cu.from_debug_types);
-      offset = sig_type->offset + sig_type->type_offset;
+      offset = sig_type->per_cu.offset + sig_type->type_offset;
       this_type = get_die_type_at_offset (offset, &sig_type->per_cu);
     }
   else
@@ -13092,6 +13124,18 @@ dwarf_stack_op_name (unsigned op)
       return "DW_OP_GNU_uninit";
     case DW_OP_GNU_implicit_pointer:
       return "DW_OP_GNU_implicit_pointer";
+    case DW_OP_GNU_entry_value:
+      return "DW_OP_GNU_entry_value";
+    case DW_OP_GNU_const_type:
+      return "DW_OP_GNU_const_type";
+    case DW_OP_GNU_regval_type:
+      return "DW_OP_GNU_regval_type";
+    case DW_OP_GNU_deref_type:
+      return "DW_OP_GNU_deref_type";
+    case DW_OP_GNU_convert:
+      return "DW_OP_GNU_convert";
+    case DW_OP_GNU_reinterpret:
+      return "DW_OP_GNU_reinterpret";
     default:
       return NULL;
     }
@@ -13316,7 +13360,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
        case DW_FORM_ref_sig8:
          if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL)
            fprintf_unfiltered (f, "signatured type, offset: 0x%x",
-                               DW_SIGNATURED_TYPE (&die->attrs[i])->offset);
+                         DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset);
          else
            fprintf_unfiltered (f, "signatured type, offset: unknown");
          break;
@@ -13650,6 +13694,17 @@ dwarf2_fetch_die_location_block (unsigned int offset,
   return retval;
 }
 
+/* Return the type of the DIE at DIE_OFFSET in the CU named by
+   PER_CU.  */
+
+struct type *
+dwarf2_get_die_type (unsigned int die_offset,
+                    struct dwarf2_per_cu_data *per_cu)
+{
+  dw2_setup (per_cu->objfile);
+  return get_die_type_at_offset (die_offset, per_cu);
+}
+
 /* Follow the signature attribute ATTR in SRC_DIE.
    On entry *REF_CU is the CU of SRC_DIE.
    On exit *REF_CU is the CU of the result.  */
@@ -13713,7 +13768,7 @@ lookup_signatured_type_at_offset (struct objfile *objfile, unsigned int offset)
   /* This is only used to lookup previously recorded types.
      If we didn't find it, it's our bug.  */
   gdb_assert (type_sig != NULL);
-  gdb_assert (offset == type_sig->offset);
+  gdb_assert (offset == type_sig->per_cu.offset);
 
   return type_sig;
 }
@@ -13752,7 +13807,7 @@ read_signatured_type (struct objfile *objfile,
   struct cleanup *back_to, *free_cu_cleanup;
 
   dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
-  types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset;
+  types_ptr = dwarf2_per_objfile->types.buffer + type_sig->per_cu.offset;
 
   gdb_assert (type_sig->per_cu.cu == NULL);
 
@@ -15880,7 +15935,7 @@ write_one_signatured_type (void **slot, void *d)
                  psymtab->n_static_syms, info->cu_index,
                  1);
 
-  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->offset);
+  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->per_cu.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);
This page took 0.03614 seconds and 4 git commands to generate.