* dvp-dis.c (print_dma): Change length from 16 to 8.
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 02dda144c37517e04720d942a75ca36498bccd2b..b01c990405de19e8a3c90e2d0a1e52ccd82a6609 100644 (file)
@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "bfd.h"
+#include "elf-bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "symfile.h"
@@ -147,9 +148,9 @@ static unsigned int dwarf_str_size;
 /* The data in a compilation unit header looks like this.  */
 struct comp_unit_head
   {
-    int length;
+    unsigned int length;
     short version;
-    int abbrev_offset;
+    unsigned int abbrev_offset;
     unsigned char addr_size;
   };
 
@@ -522,6 +523,15 @@ static struct complaint dwarf2_unsupported_const_value_attr =
    whatever scope is currently getting read. */
 static int address_size;
 
+/* Some elf32 object file formats while linked for a 32 bit address
+   space contain debug information that has assumed 64 bit
+   addresses. Eg 64 bit MIPS target produced by GCC/GAS/LD where the
+   symbol table contains 32bit address values while its .debug_info
+   section contains 64 bit address values.
+   ADDRESS_SIGNIFICANT_SIZE specifies the number significant bits in
+   the ADDRESS_SIZE bytes read from the file */
+static int address_significant_size;
+
 /* Externals references.  */
 extern int info_verbose;       /* From main.c; nonzero => verbose */
 
@@ -687,6 +697,8 @@ static void free_die_list PARAMS ((struct die_info *));
 
 static void process_die PARAMS ((struct die_info *, struct objfile *));
 
+static char *dwarf2_linkage_name PARAMS ((struct die_info *));
+
 static char *dwarf_tag_name PARAMS ((unsigned int));
 
 static char *dwarf_attr_name PARAMS ((unsigned int));
@@ -905,6 +917,9 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
   int comp_unit_has_pc_info;
   CORE_ADDR lowpc, highpc;
 
+  /* Number of bytes of any addresses that are signficant */
+  address_significant_size = get_elf_backend_data (abfd)->s->arch_size / 8;
+
   info_ptr = dwarf_info_buffer;
   abbrev_ptr = dwarf_abbrev_buffer;
 
@@ -930,6 +945,27 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
          error ("Dwarf Error: wrong version in compilation unit header.");
          return;
        }
+      if (cu_header.abbrev_offset >= dwarf_abbrev_size)
+       {
+         error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6).",
+                (long) cu_header.abbrev_offset,
+                (long) (beg_of_comp_unit - dwarf_info_buffer));
+         return;
+       }
+      if (beg_of_comp_unit + cu_header.length + 4
+         > dwarf_info_buffer + dwarf_info_size)
+       {
+         error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).",
+                (long) cu_header.length,
+                (long) (beg_of_comp_unit - dwarf_info_buffer));
+         return;
+       }
+      if (address_size < address_significant_size)
+       {
+         error ("Dwarf Error: bad address size (%ld) in compilation unit header (offset 0x%lx + 11).",
+                (long) cu_header.addr_size,
+                (long) (beg_of_comp_unit - dwarf_info_buffer));
+       }
 
       /* Read the abbrevs for this compilation unit into a table */
       dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
@@ -962,8 +998,11 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
       /* Store the function that reads in the rest of the symbol table */
       pst->read_symtab = dwarf2_psymtab_to_symtab;
 
-      /* Read the rest of the partial symbols from this comp unit */
-      info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc);
+      /* Check if comp unit has_children.
+         If so, read the rest of the partial symbols from this comp unit.
+         If not, there's no more debug_info for this comp unit. */
+      if (comp_unit_die.has_children)
+         info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc);
 
       /* If the compilation unit didn't have an explicit address range,
         then use the information extracted from its child dies.  */
@@ -1002,9 +1041,16 @@ scan_partial_symbols (info_ptr, objfile, lowpc, highpc)
 {
   bfd *abfd = objfile->obfd;
   struct partial_die_info pdi;
-  int nesting_level = 1;       /* we've already read in comp_unit_die */
-  int has_pc_info;
 
+  /* This function is called after we've read in the comp_unit_die in
+     order to read its children.  We start the nesting level at 1 since
+     we have pushed 1 level down in order to read the comp unit's children.
+     The comp unit itself is at level 0, so we stop reading when we pop
+     back to that level. */
+
+  int nesting_level = 1;
+  int has_pc_info;
+  
   *lowpc  = ((CORE_ADDR) -1);
   *highpc = ((CORE_ADDR) 0);
 
@@ -1480,6 +1526,7 @@ read_file_scope (die, objfile)
   memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
 
   start_symtab (name, comp_dir, lowpc);
+  record_debugformat ("DWARF 2");
 
   /* Decode line number information if present.  */
   attr = dwarf_attr (die, DW_AT_stmt_list);
@@ -1511,13 +1558,9 @@ read_func_scope (die, objfile)
   CORE_ADDR highpc;
   struct die_info *child_die;
   struct attribute *attr;
-  char *name = NULL;
+  char *name;
 
-  attr = dwarf_attr (die, DW_AT_name);
-  if (attr)
-    {
-      name = DW_STRING (attr);
-    }
+  name = dwarf2_linkage_name (die);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
@@ -1711,22 +1754,22 @@ dwarf2_add_field (fip, die, objfile)
       attr = dwarf_attr (die, DW_AT_bit_size);
       if (attr)
        {
-         fp->bitsize = DW_UNSND (attr);
+         FIELD_BITSIZE (*fp) = DW_UNSND (attr);
        }
       else
        {
-         fp->bitsize = 0;
+         FIELD_BITSIZE (*fp) = 0;
        }
 
       /* Get bit offset of field.  */
       attr = dwarf_attr (die, DW_AT_data_member_location);
       if (attr)
        {
-         fp->bitpos =
+         FIELD_BITPOS (*fp) =
            decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
        }
       else
-       fp->bitpos = 0;
+       FIELD_BITPOS (*fp) = 0;
       attr = dwarf_attr (die, DW_AT_bit_offset);
       if (attr)
        {
@@ -1737,7 +1780,7 @@ dwarf2_add_field (fip, die, objfile)
                 anonymous object to the MSB of the field.  We don't
                 have to do anything special since we don't need to
                 know the size of the anonymous object.  */
-             fp->bitpos += DW_UNSND (attr);
+             FIELD_BITPOS (*fp) += DW_UNSND (attr);
            }
          else
            {
@@ -1766,8 +1809,8 @@ dwarf2_add_field (fip, die, objfile)
                     bit field.  */
                  anonymous_size = TYPE_LENGTH (fp->type);
                }
-             fp->bitpos +=
-               anonymous_size * bits_per_byte - bit_offset - fp->bitsize;
+             FIELD_BITPOS (*fp) += anonymous_size * bits_per_byte
+               - bit_offset - FIELD_BITSIZE (*fp);
            }
        }
 
@@ -1788,33 +1831,29 @@ dwarf2_add_field (fip, die, objfile)
     }
   else if (die->tag == DW_TAG_variable)
     {
-      char *physname = "";
+      char *physname;
+      char *cp;
 
       /* C++ static member.
         Get physical name, extract field name from physical name.  */
-      attr = dwarf_attr (die, DW_AT_name);
-      if (attr && DW_STRING (attr))
-       {
-         char *cp;
-
-         physname = DW_STRING (attr);
+      physname = dwarf2_linkage_name (die);
+      if (physname == NULL)
+       return;
 
-         cp = physname;
-         while (*cp && !is_cplus_marker (*cp))
-           cp++;
-         if (*cp)
-           fieldname = cp + 1;
-       }
-      if (*physname == '\0' || *fieldname == '\0')
+      cp = physname;
+      while (*cp && !is_cplus_marker (*cp))
+       cp++;
+      if (*cp)
+       fieldname = cp + 1;
+      if (*fieldname == '\0')
        {
          complain (&dwarf2_bad_static_member_name, physname);
        }
 
-      fp->bitpos = -1;
-      fp->bitsize = (long) obsavestring (physname, strlen (physname),
-                                        &objfile->type_obstack);
-      fp->type = die_type (die, objfile);
-      fp->name = obsavestring (fieldname, strlen (fieldname),
+      SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
+                                           &objfile->type_obstack));
+      FIELD_TYPE (*fp) = die_type (die, objfile);
+      FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
                               &objfile->type_obstack);
     }
   else if (die->tag == DW_TAG_inheritance)
@@ -1822,10 +1861,10 @@ dwarf2_add_field (fip, die, objfile)
       /* C++ base class field.  */
       attr = dwarf_attr (die, DW_AT_data_member_location);
       if (attr)
-       fp->bitpos = decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
-      fp->bitsize = 0;
-      fp->type = die_type (die, objfile);
-      fp->name = type_name_no_tag (fp->type);
+       FIELD_BITPOS (*fp) = decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
+      FIELD_BITSIZE (*fp) = 0;
+      FIELD_TYPE (*fp) = die_type (die, objfile);
+      FIELD_NAME (*fp) = type_name_no_tag (fp->type);
       fip->nbaseclasses++;
     }
 }
@@ -1964,15 +2003,13 @@ dwarf2_add_member_fn (fip, die, type, objfile)
   int i;
   struct fn_field *fnp;
   char *fieldname;
-  char *physname = "";
+  char *physname;
   struct nextfnfield *new_fnfield;
 
   /* Extract member function name from mangled name.  */
-  attr = dwarf_attr (die, DW_AT_name);
-  if (attr && DW_STRING (attr))
-    {
-      physname = DW_STRING (attr);
-    }
+  physname = dwarf2_linkage_name (die);
+  if (physname == NULL)
+    return;
   if ((physname[0] == '_' && physname[1] == '_'
         && strchr ("0123456789Qt", physname[2]))
       || DESTRUCTOR_PREFIX_P (physname))
@@ -2049,7 +2086,8 @@ dwarf2_add_member_fn (fip, die, type, objfile)
 
   /* Fill in the member function field info.  */
   fnp = &new_fnfield->fnfield;
-  fnp->physname = physname;
+  fnp->physname = obsavestring (physname, strlen (physname),
+                               &objfile->type_obstack);
   fnp->type = alloc_type (objfile);
   if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
     {
@@ -2384,10 +2422,10 @@ read_enumeration (die, objfile)
                                    * sizeof (struct field));
                    }
 
-                 fields[num_fields].name = SYMBOL_NAME (sym);
-                 fields[num_fields].type = NULL;
-                 fields[num_fields].bitpos = SYMBOL_VALUE (sym);
-                 fields[num_fields].bitsize = 0;
+                 FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym);
+                 FIELD_TYPE (fields[num_fields]) = NULL;
+                 FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
+                 FIELD_BITSIZE (fields[num_fields]) = 0;
 
                  num_fields++;
                }
@@ -2458,8 +2496,7 @@ read_array_type (die, objfile)
          /* Default bounds to an array with unspecified length.  */
          low = 0;
          high = -1;
-         if (cu_language == DW_LANG_Fortran77
-             || cu_language == DW_LANG_Fortran90)
+         if (cu_language == language_fortran)
            {
              /* FORTRAN implies a lower bound of 1, if not given.  */
              low = 1;
@@ -3176,6 +3213,12 @@ read_partial_die (part_die, abfd, info_ptr, has_pc_info)
       switch (attr.name)
        {
        case DW_AT_name:
+
+         /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name.  */
+         if (part_die->name == NULL)
+           part_die->name = DW_STRING (&attr);
+         break;
+       case DW_AT_MIPS_linkage_name:
          part_die->name = DW_STRING (&attr);
          break;
        case DW_AT_low_pc:
@@ -3484,11 +3527,27 @@ read_address (abfd, buf)
 {
   CORE_ADDR retval = 0;
 
-  if (address_size == 4)
+  switch (address_size)
     {
+    case 4:
       retval = bfd_get_32 (abfd, (bfd_byte *) buf);
-    } else {                   /* *THE* alternative is 8, right? */
+      break;
+    case 8:
       retval = bfd_get_64 (abfd, (bfd_byte *) buf);
+      break;
+    default:
+      /* *THE* alternative is 8, right? */
+      abort ();
+    }
+  /* If the address being read is larger than the address that is
+     applicable for the object file format then mask it down to the
+     correct size.  Take care to avoid unnecessary shift or shift
+     overflow */
+  if (address_size > address_significant_size
+      && address_significant_size < sizeof (CORE_ADDR))
+    {
+      CORE_ADDR mask = ((CORE_ADDR) 0) - 1;
+      retval &= ~(mask << (address_significant_size * 8));
     }
   return retval;
 }
@@ -3629,22 +3688,21 @@ set_cu_language (lang)
     {
     case DW_LANG_C89:
     case DW_LANG_C:
-    case DW_LANG_Fortran77:
       cu_language = language_c;
       break;
     case DW_LANG_C_plus_plus:
       cu_language = language_cplus;
       break;
+    case DW_LANG_Fortran77:
+    case DW_LANG_Fortran90:
+      cu_language = language_fortran;
+      break;
     case DW_LANG_Mips_Assembler:
       cu_language = language_asm;
       break;
     case DW_LANG_Ada83:
     case DW_LANG_Cobol74:
     case DW_LANG_Cobol85:
-#if 0
-    case DW_LANG_Fortran77:    /* moved up top for now */
-#endif
-    case DW_LANG_Fortran90:
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
@@ -3819,7 +3877,7 @@ dwarf_decode_lines (offset, comp_dir, abfd)
   while (line_ptr < line_end)
     {
       /* state machine registers  */
-      unsigned int address = 0;
+      CORE_ADDR address = 0;
       unsigned int file = 1;
       unsigned int line = 1;
       unsigned int column = 0;
@@ -4005,19 +4063,19 @@ new_symbol (die, type, objfile)
      struct objfile *objfile;
 {
   struct symbol *sym = NULL;
+  char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
   CORE_ADDR addr;
 
-  attr = dwarf_attr (die, DW_AT_name);
-  if (attr && DW_STRING (attr))
+  name = dwarf2_linkage_name (die);
+  if (name)
     {
       sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
                                             sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = obsavestring (DW_STRING (attr),
-                                       strlen (DW_STRING (attr)),
+      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
                                        &objfile->symbol_obstack);
 
       /* Default assumptions.
@@ -4614,6 +4672,23 @@ sibling_die (die)
     }
 }
 
+/* Get linkage name of a die, return NULL if not found.  */
+
+static char *
+dwarf2_linkage_name (die)
+     struct die_info *die;
+{
+  struct attribute *attr;
+
+  attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+  if (attr && DW_STRING (attr))
+    return DW_STRING (attr);
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    return DW_STRING (attr);
+  return NULL;
+}
+
 /* Convert a DIE tag into its string name.  */
 
 static char *
This page took 0.029981 seconds and 4 git commands to generate.