* configure.in: Added gnuserv everywhere sn appears.
[deliverable/binutils-gdb.git] / gdb / dwarfread.c
index 8c13087095f1b032e8c287a19584cbec01ccd0e4..529f01b3ff5edfb9091c1f2f67437026d43d27ba 100644 (file)
@@ -1,5 +1,6 @@
 /* DWARF debugging format support for GDB.
-   Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996
+   Free Software Foundation, Inc.
    Written by Fred Fish at Cygnus Support.  Portions based on dbxread.c,
    mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port.
 
@@ -17,7 +18,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
 
@@ -51,16 +52,7 @@ other things to work on, if you get bored. :-)
 #include "complaints.h"
 
 #include <fcntl.h>
-#include <string.h>
-
-#ifndef        NO_SYS_FILE
-#include <sys/file.h>
-#endif
-
-/* FIXME -- convert this to SEEK_SET a la POSIX, move to config files.  */
-#ifndef L_SET
-#define L_SET 0
-#endif
+#include "gdb_string.h"
 
 /* Some macros to provide DIE info for complaints. */
 
@@ -174,6 +166,11 @@ struct complaint not_row_major =
   "DIE @ 0x%x \"%s\", array not row major; not handled correctly", 0, 0
 };
 
+struct complaint missing_at_name =
+{
+  "DIE @ 0x%x, AT_name tag missing", 0, 0
+};
+
 typedef unsigned int DIE_REF;  /* Reference to a DIE */
 
 #ifndef GCC_PRODUCER
@@ -327,6 +324,7 @@ static int dbsize;  /* Size of dwarf info in bytes */
 static int dbroff;     /* Relative offset from start of .debug section */
 static char *lnbase;   /* Base pointer to line section */
 static int isreg;      /* Kludge to identify register variables */
+static int optimized_out;  /* Kludge to identify optimized out variables */
 /* Kludge to identify basereg references.  Nonzero if we have an offset
    relative to a basereg.  */
 static int offreg;
@@ -440,6 +438,9 @@ static const struct language_defn *cu_language_defn;
 /* Forward declarations of static functions so we don't have to worry
    about ordering within this file.  */
 
+static void
+free_utypes PARAMS ((PTR));
+
 static int
 attribute_size PARAMS ((unsigned int));
 
@@ -730,7 +731,7 @@ dwarf_build_psymtabs (objfile, section_offsets, mainline, dbfoff, dbfsize,
   dbsize = dbfsize;
   dbbase = xmalloc (dbsize);
   dbroff = 0;
-  if ((bfd_seek (abfd, dbfoff, L_SET) != 0) ||
+  if ((bfd_seek (abfd, dbfoff, SEEK_SET) != 0) ||
       (bfd_read (dbbase, dbsize, 1, abfd) != dbsize))
     {
       free (dbbase);
@@ -892,6 +893,33 @@ alloc_utype (die_ref, utypep)
   return (utypep);
 }
 
+/*
+
+LOCAL FUNCTION
+
+       free_utypes -- free the utypes array and reset pointer & count
+
+SYNOPSIS
+
+       static void free_utypes (PTR dummy)
+
+DESCRIPTION
+
+       Called via do_cleanups to free the utypes array, reset the pointer to NULL,
+       and set numutypes back to zero.  This ensures that the utypes does not get
+       referenced after being freed.
+ */
+
+static void
+free_utypes (dummy)
+     PTR dummy;
+{
+  free (utypes);
+  utypes = NULL;
+  numutypes = 0;
+}
+
+
 /*
 
 LOCAL FUNCTION
@@ -936,7 +964,7 @@ decode_die_type (dip)
     }
   else
     {
-      type = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+      type = dwarf_fundamental_type (current_objfile, FT_VOID);
     }
   return (type);
 }
@@ -1693,6 +1721,7 @@ enum_type (dip, objfile)
   unsigned short blocksz;
   struct symbol *sym;
   int nbytes;
+  int unsigned_enum = 1;
   
   if ((type = lookup_utype (dip -> die_ref)) == NULL)
     {
@@ -1753,6 +1782,8 @@ enum_type (dip, objfile)
          SYMBOL_CLASS (sym) = LOC_CONST;
          SYMBOL_TYPE (sym) = type;
          SYMBOL_VALUE (sym) = list -> field.bitpos;
+         if (SYMBOL_VALUE (sym) < 0)
+           unsigned_enum = 0;
          add_symbol_to_list (sym, list_in_scope);
        }
       /* Now create the vector of fields, and record how big it is. This is
@@ -1762,6 +1793,8 @@ enum_type (dip, objfile)
         vector. */
       if (nfields > 0)
        {
+         if (unsigned_enum)
+           TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
          TYPE_NFIELDS (type) = nfields;
          TYPE_FIELDS (type) = (struct field *)
            obstack_alloc (&objfile->symbol_obstack, sizeof (struct field) * nfields);
@@ -1805,6 +1838,16 @@ read_func_scope (dip, thisdie, enddie, objfile)
 {
   register struct context_stack *new;
   
+  /* AT_name is absent if the function is described with an
+     AT_abstract_origin tag.
+     Ignore the function description for now to avoid GDB core dumps.
+     FIXME: Add code to handle AT_abstract_origin tags properly.  */
+  if (dip -> at_name == NULL)
+    {
+      complain (&missing_at_name, DIE_ID);
+      return;
+    }
+
   if (objfile -> ei.entry_point >= dip -> at_low_pc &&
       objfile -> ei.entry_point <  dip -> at_high_pc)
     {
@@ -1918,21 +1961,19 @@ read_file_scope (dip, thisdie, enddie, objfile)
     }
   numutypes = (enddie - thisdie) / 4;
   utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *));
-  back_to = make_cleanup (free, utypes);
+  back_to = make_cleanup (free_utypes, NULL);
   memset (utypes, 0, numutypes * sizeof (struct type *));
   memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
   start_symtab (dip -> at_name, dip -> at_comp_dir, dip -> at_low_pc);
   decode_line_numbers (lnbase);
   process_dies (thisdie + dip -> die_length, enddie, objfile);
 
-  symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile, 0);
+  symtab = end_symtab (dip -> at_high_pc, objfile, 0);
   if (symtab != NULL)
     {
       symtab -> language = cu_language;
     }      
   do_cleanups (back_to);
-  utypes = NULL;
-  numutypes = 0;
 }
 
 /*
@@ -2151,6 +2192,9 @@ DESCRIPTION
 
        Given pointer to a string of bytes that define a location, compute
        the location and return the value.
+       A location description containing no atoms indicates that the
+       object is optimized out. The global optimized_out flag is set for
+       those, the return value is meaningless.
 
        When computing values involving the current value of the frame pointer,
        the value zero is used, which results in a value relative to the frame
@@ -2189,9 +2233,11 @@ locval (loc)
   stack[stacki] = 0;
   isreg = 0;
   offreg = 0;
+  optimized_out = 1;
   loc_value_size = TARGET_FT_LONG_SIZE (current_objfile);
   while (loc < end)
     {
+      optimized_out = 0;
       loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED,
                                      current_objfile);
       loc += SIZEOF_LOC_ATOM_CODE;
@@ -2290,7 +2336,7 @@ read_ofile_symtab (pst)
   foffset = DBFOFF(pst) + dbroff;
   base_section_offsets = pst->section_offsets;
   baseaddr = ANOFFSET (pst->section_offsets, 0);
-  if (bfd_seek (abfd, foffset, L_SET) ||
+  if (bfd_seek (abfd, foffset, SEEK_SET) ||
       (bfd_read (dbbase, dbsize, 1, abfd) != dbsize))
     {
       free (dbbase);
@@ -2306,7 +2352,7 @@ read_ofile_symtab (pst)
   lnbase = NULL;
   if (LNFOFF (pst))
     {
-      if (bfd_seek (abfd, LNFOFF (pst), L_SET) ||
+      if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) ||
          (bfd_read ((PTR) lnsizedata, sizeof (lnsizedata), 1, abfd) !=
           sizeof (lnsizedata)))
        {
@@ -2315,7 +2361,7 @@ read_ofile_symtab (pst)
       lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH,
                               GET_UNSIGNED, pst -> objfile);
       lnbase = xmalloc (lnsize);
-      if (bfd_seek (abfd, LNFOFF (pst), L_SET) ||
+      if (bfd_seek (abfd, LNFOFF (pst), SEEK_SET) ||
          (bfd_read (lnbase, lnsize, 1, abfd) != lnsize))
        {
          free (lnbase);
@@ -2506,8 +2552,8 @@ add_enum_psymbol (dip, objfile)
       while (scan < listend)
        {
          scan += TARGET_FT_LONG_SIZE (objfile);
-         ADD_PSYMBOL_TO_LIST (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST,
-                              objfile -> static_psymbols, 0, cu_language,
+         add_psymbol_to_list (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST,
+                              &objfile -> static_psymbols, 0, 0, cu_language,
                               objfile);
          scan += strlen (scan) + 1;
        }
@@ -2539,34 +2585,34 @@ add_partial_symbol (dip, objfile)
   switch (dip -> die_tag)
     {
     case TAG_global_subroutine:
-      ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
-                          VAR_NAMESPACE, LOC_BLOCK,
-                          objfile -> global_psymbols,
-                          dip -> at_low_pc, cu_language, objfile);
+      add_psymbol_to_list (dip -> at_name, strlen (dip -> at_name),
+                               VAR_NAMESPACE, LOC_BLOCK,
+                               &objfile -> global_psymbols,
+                               0, dip -> at_low_pc, cu_language, objfile);
       break;
     case TAG_global_variable:
-      ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
+      add_psymbol_to_list (dip -> at_name, strlen (dip -> at_name),
                           VAR_NAMESPACE, LOC_STATIC,
-                          objfile -> global_psymbols,
-                          0, cu_language, objfile);
+                          &objfile -> global_psymbols,
+                          0, 0, cu_language, objfile);
       break;
     case TAG_subroutine:
-      ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
-                          VAR_NAMESPACE, LOC_BLOCK,
-                          objfile -> static_psymbols,
-                          dip -> at_low_pc, cu_language, objfile);
+      add_psymbol_to_list (dip -> at_name, strlen (dip -> at_name),
+                               VAR_NAMESPACE, LOC_BLOCK,
+                               &objfile -> static_psymbols,
+                               0, dip -> at_low_pc, cu_language, objfile);
       break;
     case TAG_local_variable:
-      ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
+      add_psymbol_to_list (dip -> at_name, strlen (dip -> at_name),
                           VAR_NAMESPACE, LOC_STATIC,
-                          objfile -> static_psymbols,
-                          0, cu_language, objfile);
+                          &objfile -> static_psymbols,
+                          0, 0, cu_language, objfile);
       break;
     case TAG_typedef:
-      ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
+      add_psymbol_to_list (dip -> at_name, strlen (dip -> at_name),
                           VAR_NAMESPACE, LOC_TYPEDEF,
-                          objfile -> static_psymbols,
-                          0, cu_language, objfile);
+                          &objfile -> static_psymbols,
+                          0, 0, cu_language, objfile);
       break;
     case TAG_class_type:
     case TAG_structure_type:
@@ -2575,17 +2621,17 @@ add_partial_symbol (dip, objfile)
       /* Do not add opaque aggregate definitions to the psymtab.  */
       if (!dip -> has_at_byte_size)
        break;
-      ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
+      add_psymbol_to_list (dip -> at_name, strlen (dip -> at_name),
                           STRUCT_NAMESPACE, LOC_TYPEDEF,
-                          objfile -> static_psymbols,
-                          0, cu_language, objfile);
+                          &objfile -> static_psymbols,
+                          0, 0, cu_language, objfile);
       if (cu_language == language_cplus)
        {
          /* For C++, these implicitly act as typedefs as well. */
-         ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
+         add_psymbol_to_list (dip -> at_name, strlen (dip -> at_name),
                               VAR_NAMESPACE, LOC_TYPEDEF,
-                              objfile -> static_psymbols,
-                              0, cu_language, objfile);
+                              &objfile -> static_psymbols,
+                              0, 0, cu_language, objfile);
        }
       break;
     }
@@ -2885,6 +2931,7 @@ new_symbol (dip, objfile)
     {
       sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack,
                                             sizeof (struct symbol));
+      OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
       SYMBOL_NAME (sym) = create_name (dip -> at_name,
                                       &objfile->symbol_obstack);
@@ -2903,13 +2950,15 @@ new_symbol (dip, objfile)
       switch (dip -> die_tag)
        {
        case TAG_label:
-         SYMBOL_VALUE (sym) = dip -> at_low_pc;
+         SYMBOL_VALUE_ADDRESS (sym) = dip -> at_low_pc;
          SYMBOL_CLASS (sym) = LOC_LABEL;
          break;
        case TAG_global_subroutine:
        case TAG_subroutine:
-         SYMBOL_VALUE (sym) = dip -> at_low_pc;
+         SYMBOL_VALUE_ADDRESS (sym) = dip -> at_low_pc;
          SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+         if (dip -> at_prototyped)
+           TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
          SYMBOL_CLASS (sym) = LOC_BLOCK;
          if (dip -> die_tag == TAG_global_subroutine)
            {
@@ -2934,7 +2983,11 @@ new_symbol (dip, objfile)
            {
              SYMBOL_VALUE (sym) = locval (dip -> at_location);
              add_symbol_to_list (sym, list_in_scope);
-             if (isreg)
+             if (optimized_out)
+               {
+                 SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+               }
+             else if (isreg)
                {
                  SYMBOL_CLASS (sym) = LOC_REGISTER;
                }
@@ -3031,6 +3084,7 @@ synthesize_typedef (dip, objfile, type)
     {
       sym = (struct symbol *)
        obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
+      OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
       SYMBOL_NAME (sym) = create_name (dip -> at_name,
                                       &objfile->symbol_obstack);
This page took 0.029547 seconds and 4 git commands to generate.