Removed superflous code.
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 6434246ab82e715f460123e662cbf13a46bd5e86..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)
@@ -1710,22 +1758,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)
        {
@@ -1736,7 +1784,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
            {
@@ -1765,8 +1813,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);
            }
        }
 
@@ -1806,11 +1854,10 @@ dwarf2_add_field (fip, die, objfile)
          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)
@@ -1818,10 +1865,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++;
     }
 }
@@ -2023,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;
@@ -2379,10 +2427,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++;
                }
@@ -2453,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;
@@ -2530,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);
        }
@@ -2757,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)
@@ -3485,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;
 }
@@ -3630,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:
@@ -3764,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)
@@ -3783,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;
     }
@@ -3800,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 =
@@ -3820,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;
@@ -3870,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.031478 seconds and 4 git commands to generate.