> * gdb.texinfo (hbreak, watch): Fix typo, "date" -> "data".
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index e12953d60e6af98d0e6e66cfb101a3e0c7b3423c..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"
@@ -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 */
 
@@ -907,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;
 
@@ -934,14 +947,25 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline)
        }
       if (cu_header.abbrev_offset >= dwarf_abbrev_size)
        {
-         error ("Dwarf Error: bad offset in compilation unit header.");
+         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 (cu_header.length > dwarf_abbrev_size - cu_header.abbrev_offset)
+      if (beg_of_comp_unit + cu_header.length + 4
+         > dwarf_info_buffer + dwarf_info_size)
        {
-         error ("Dwarf Error:  bad length in compilation unit header.");
+         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);
@@ -2472,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;
@@ -3504,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;
 }
@@ -3649,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:
@@ -3839,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;
This page took 0.026277 seconds and 4 git commands to generate.