Removed superflous code.
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 38d80fbba2f285e087990ec7ad6b83e7775d9ad9..ea0af4012ddb42095112e695d9c4673bf82e6680 100644 (file)
@@ -1,5 +1,5 @@
 /* DWARF 2 debugging format support for GDB.
-   Copyright 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
    Inc.  with support from Florida State University (under contract
@@ -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 */
 
@@ -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;
 
@@ -932,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);
@@ -964,16 +998,21 @@ 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);
-
-      /* If the compilation unit didn't have an explicit address range,
-        then use the information extracted from its child dies.  */
-      if (!comp_unit_has_pc_info)
+      /* 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)
        {
-         comp_unit_die.lowpc  = lowpc;
-         comp_unit_die.highpc = highpc;
-        }
+         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.  */
+         if (!comp_unit_has_pc_info)
+           {
+             comp_unit_die.lowpc  = lowpc;
+             comp_unit_die.highpc = highpc;
+           }
+       }
       pst->textlow  = comp_unit_die.lowpc + baseaddr;
       pst->texthigh = comp_unit_die.highpc + baseaddr;
 
@@ -1004,9 +1043,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);
 
@@ -1104,8 +1150,8 @@ add_partial_symbol (pdi, objfile)
     case DW_TAG_subprogram:
       if (pdi->is_external)
        {
-         prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
-                                     mst_text, objfile);
+         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+                                     mst_text, objfile);*/
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
                               VAR_NAMESPACE, LOC_BLOCK,
                               &objfile->global_psymbols,
@@ -1113,8 +1159,8 @@ add_partial_symbol (pdi, objfile)
        }
       else
        {
-         prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
-                                     mst_file_text, objfile);
+         /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
+                                     mst_file_text, objfile);*/
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
                               VAR_NAMESPACE, LOC_BLOCK,
                               &objfile->static_psymbols,
@@ -1151,8 +1197,8 @@ add_partial_symbol (pdi, objfile)
          if (pdi->locdesc == NULL)
            return;
          addr = decode_locdesc (pdi->locdesc, objfile);
-         prim_record_minimal_symbol (pdi->name, addr + baseaddr,
-                                     mst_file_data, objfile);
+         /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
+                                     mst_file_data, objfile);*/
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
                               VAR_NAMESPACE, LOC_STATIC,
                               &objfile->static_psymbols,
@@ -1258,7 +1304,7 @@ psymtab_to_symtab_1 (pst)
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
 
   buildsym_init ();
-  make_cleanup (really_free_pendings, NULL);
+  make_cleanup ((make_cleanup_func) really_free_pendings, NULL);
 
   /* read in the comp_unit header  */
   cu_header.length = read_4_bytes (abfd, info_ptr);
@@ -1276,7 +1322,7 @@ psymtab_to_symtab_1 (pst)
 
   dies = read_comp_unit (info_ptr, abfd);
 
-  make_cleanup (free_die_list, dies);
+  make_cleanup ((make_cleanup_func) free_die_list, dies);
 
   /* Do line number decoding in read_file_scope () */
   process_die (dies, objfile);
@@ -1469,6 +1515,8 @@ read_file_scope (die, objfile)
       set_cu_language (DW_UNSND (attr));
     }
 
+  /* We assume that we're processing GCC output. */
+  processing_gcc_compilation = 2;
 #if 0
     /* FIXME:Do something here.  */
     if (dip->at_producer != NULL)
@@ -2022,7 +2070,8 @@ dwarf2_add_member_fn (fip, die, type, objfile)
                      (fip->nfnfields + DW_FIELD_ALLOC_CHUNK)
                        * sizeof (struct fnfieldlist));
          if (fip->nfnfields == 0)
-           make_cleanup (free_current_contents, &fip->fnfieldlists);
+           make_cleanup ((make_cleanup_func) free_current_contents, 
+                          &fip->fnfieldlists);
        }
       flp = &fip->fnfieldlists[fip->nfnfields];
       flp->name = fieldname;
@@ -2452,8 +2501,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;
@@ -2529,7 +2577,8 @@ read_array_type (die, objfile)
                xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
                                         * sizeof (struct type *));
              if (ndim == 0)
-               make_cleanup (free_current_contents, &range_types);
+               make_cleanup ((make_cleanup_func) free_current_contents, 
+                              &range_types);
            }
          range_types[ndim++] = create_range_type (NULL, index_type, low, high);
        }
@@ -2756,8 +2805,11 @@ read_subroutine_type (die, objfile)
     }
   type = die_type (die, objfile);
   ftype = lookup_function_type (type);
+
+  /* All functions in C++ have prototypes.  */
   attr = dwarf_attr (die, DW_AT_prototyped);
-  if (attr && (DW_UNSND (attr) != 0))
+  if ((attr && (DW_UNSND (attr) != 0))
+      || cu_language == language_cplus)
     TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
 
   if (die->has_children)
@@ -3484,11 +3536,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 +3697,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:
@@ -3763,7 +3830,8 @@ dwarf_decode_lines (offset, comp_dir, abfd)
   line_ptr += 1;
   lh.standard_opcode_lengths = (unsigned char *)
     xmalloc (lh.opcode_base * sizeof (unsigned char));
-  back_to = make_cleanup (free_current_contents, &lh.standard_opcode_lengths);
+  back_to = make_cleanup ((make_cleanup_func) free_current_contents, 
+                          &lh.standard_opcode_lengths);
 
   lh.standard_opcode_lengths[0] = 1;
   for (i = 1; i < lh.opcode_base; ++i)
@@ -3782,7 +3850,7 @@ dwarf_decode_lines (offset, comp_dir, abfd)
            xrealloc (dirs.dirs,
                      (dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *));
          if (dirs.num_dirs == 0)
-           make_cleanup (free_current_contents, &dirs.dirs);
+           make_cleanup ((make_cleanup_func) free_current_contents, &dirs.dirs);
        }
       dirs.dirs[dirs.num_dirs++] = cur_dir;
     }
@@ -3799,7 +3867,8 @@ dwarf_decode_lines (offset, comp_dir, abfd)
                      (files.num_files + FILE_ALLOC_CHUNK)
                        * sizeof (struct fileinfo));
          if (files.num_files == 0)
-           make_cleanup (free_current_contents, &files.files);
+           make_cleanup ((make_cleanup_func) free_current_contents, 
+                          &files.files);
        }
       files.files[files.num_files].name = cur_file;
       files.files[files.num_files].dir =
@@ -3819,7 +3888,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;
@@ -3869,7 +3938,8 @@ dwarf_decode_lines (offset, comp_dir, abfd)
                                  (files.num_files + FILE_ALLOC_CHUNK)
                                    * sizeof (struct fileinfo));
                      if (files.num_files == 0)
-                       make_cleanup (free_current_contents, &files.files);
+                       make_cleanup ((make_cleanup_func) free_current_contents, 
+                                      &files.files);
                    }
                  files.files[files.num_files].name = cur_file;
                  files.files[files.num_files].dir =
This page took 0.02899 seconds and 4 git commands to generate.