* lib/gdb.exp(gdb_step_for_stub): New function.
[deliverable/binutils-gdb.git] / gdb / dwarfread.c
index ec6182d367db07b1d81272a1f121a25e33504578..07358bda79033071807de17b937e0fba7085b31d 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
@@ -300,8 +297,8 @@ struct dieinfo {
   unsigned long                at_bit_size;
   BLOCK *              at_element_list;
   unsigned long                at_stmt_list;
-  unsigned long                at_low_pc;
-  unsigned long                at_high_pc;
+  CORE_ADDR            at_low_pc;
+  CORE_ADDR            at_high_pc;
   unsigned long                at_language;
   unsigned long                at_member;
   unsigned long                at_discr;
@@ -317,6 +314,23 @@ struct dieinfo {
   unsigned int         has_at_stmt_list:1;
   unsigned int         has_at_byte_size:1;
   unsigned int         short_element_list:1;
+
+  /* Kludge to identify register variables */
+
+  unsigned int         isreg;
+
+  /* Kludge to identify optimized out variables */
+
+  unsigned int         optimized_out;
+
+  /* Kludge to identify basereg references.
+     Nonzero if we have an offset relative to a basereg.  */
+
+  unsigned int         offreg;
+
+  /* Kludge to identify which base register is it relative to.  */
+
+  unsigned int         basereg;
 };
 
 static int diecount;   /* Approximate count of dies for compilation unit */
@@ -326,12 +340,6 @@ static char *dbbase;       /* Base pointer to dwarf info */
 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 */
-/* Kludge to identify basereg references.  Nonzero if we have an offset
-   relative to a basereg.  */
-static int offreg;
-/* Which base register is it relative to?  */
-static int basereg;
 
 /* This value is added to each symbol value.  FIXME:  Generalize to 
    the section_offsets structure used by dbxread (once this is done,
@@ -342,37 +350,29 @@ static CORE_ADDR baseaddr;        /* Add to each symbol value */
    only used to pass one value (baseaddr) at the moment.  */
 static struct section_offsets *base_section_offsets;
 
-/* Each partial symbol table entry contains a pointer to private data for the
-   read_symtab() function to use when expanding a partial symbol table entry
-   to a full symbol table entry.  For DWARF debugging info, this data is
-   contained in the following structure and macros are provided for easy
-   access to the members given a pointer to a partial symbol table entry.
-
-   dbfoff      Always the absolute file offset to the start of the ".debug"
-               section for the file containing the DIE's being accessed.
-
-   dbroff      Relative offset from the start of the ".debug" access to the
-               first DIE to be accessed.  When building the partial symbol
-               table, this value will be zero since we are accessing the
-               entire ".debug" section.  When expanding a partial symbol
-               table entry, this value will be the offset to the first
-               DIE for the compilation unit containing the symbol that
-               triggers the expansion.
-
-   dblength    The size of the chunk of DIE's being examined, in bytes.
-
-   lnfoff      The absolute file offset to the line table fragment.  Ignored
-               when building partial symbol tables, but used when expanding
-               them, and contains the absolute file offset to the fragment
-               of the ".line" section containing the line numbers for the
-               current compilation unit.
- */
+/* We put a pointer to this structure in the read_symtab_private field
+   of the psymtab.  */
 
 struct dwfinfo {
-  file_ptr dbfoff;     /* Absolute file offset to start of .debug section */
-  int dbroff;          /* Relative offset from start of .debug section */
-  int dblength;                /* Size of the chunk of DIE's being examined */
-  file_ptr lnfoff;     /* Absolute file offset to line table fragment */
+  /* Always the absolute file offset to the start of the ".debug"
+     section for the file containing the DIE's being accessed.  */
+  file_ptr dbfoff;
+  /* Relative offset from the start of the ".debug" section to the
+     first DIE to be accessed.  When building the partial symbol
+     table, this value will be zero since we are accessing the
+     entire ".debug" section.  When expanding a partial symbol
+     table entry, this value will be the offset to the first
+     DIE for the compilation unit containing the symbol that
+     triggers the expansion.  */
+  int dbroff;
+  /* The size of the chunk of DIE's being examined, in bytes.  */
+  int dblength;
+  /* The absolute file offset to the line table fragment.  Ignored
+     when building partial symbol tables, but used when expanding
+     them, and contains the absolute file offset to the fragment
+     of the ".line" section containing the line numbers for the
+     current compilation unit.  */
+  file_ptr lnfoff;
 };
 
 #define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff)
@@ -448,10 +448,13 @@ 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));
 
-static unsigned long
+static CORE_ADDR
 target_to_host PARAMS ((char *, int, int, struct objfile *));
 
 static void
@@ -480,9 +483,6 @@ scan_compilation_units PARAMS ((char *, char *, file_ptr,
 static void
 add_partial_symbol PARAMS ((struct dieinfo *, struct objfile *));
 
-static void
-init_psymbol_list PARAMS ((struct objfile *, int));
-
 static void
 basicdieinfo PARAMS ((struct dieinfo *, char *, struct objfile *));
 
@@ -567,7 +567,7 @@ synthesize_typedef PARAMS ((struct dieinfo *, struct objfile *,
                            struct type *));
 
 static int
-locval PARAMS ((char *));
+locval PARAMS ((struct dieinfo *));
 
 static void
 set_cu_language PARAMS ((struct dieinfo *));
@@ -741,7 +741,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);
@@ -903,6 +903,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
@@ -947,7 +974,7 @@ decode_die_type (dip)
     }
   else
     {
-      type = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+      type = dwarf_fundamental_type (current_objfile, FT_VOID);
     }
   return (type);
 }
@@ -1059,10 +1086,10 @@ struct_type (dip, thisdie, enddie, objfile)
          list -> field.name =
              obsavestring (mbr.at_name, strlen (mbr.at_name),
                            &objfile -> type_obstack);
-         list -> field.type = decode_die_type (&mbr);
-         list -> field.bitpos = 8 * locval (mbr.at_location);
+         FIELD_TYPE (list->field) = decode_die_type (&mbr);
+         FIELD_BITPOS (list->field) = 8 * locval (&mbr);
          /* Handle bit fields. */
-         list -> field.bitsize = mbr.at_bit_size;
+         FIELD_BITSIZE (list->field) = mbr.at_bit_size;
          if (BITS_BIG_ENDIAN)
            {
              /* For big endian bits, the at_bit_offset gives the
@@ -1070,7 +1097,7 @@ struct_type (dip, thisdie, enddie, 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. */
-             list -> field.bitpos += mbr.at_bit_offset;
+             FIELD_BITPOS (list->field) += mbr.at_bit_offset;
            }
          else
            {
@@ -1100,7 +1127,7 @@ struct_type (dip, thisdie, enddie, objfile)
                         a debug information size optimization. */
                      anonymous_size = TYPE_LENGTH (list -> field.type);
                    }
-                 list -> field.bitpos +=
+                 FIELD_BITPOS (list->field) +=
                    anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size;
                }
            }
@@ -1704,6 +1731,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)
     {
@@ -1743,9 +1771,9 @@ enum_type (dip, objfile)
          new = (struct nextfield *) alloca (sizeof (struct nextfield));
          new -> next = list;
          list = new;
-         list -> field.type = NULL;
-         list -> field.bitsize = 0;
-         list -> field.bitpos =
+         FIELD_TYPE (list->field) = NULL;
+         FIELD_BITSIZE (list->field) = 0;
+         FIELD_BITPOS (list->field) =
            target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED,
                            objfile);
          scan += TARGET_FT_LONG_SIZE (objfile);
@@ -1763,7 +1791,9 @@ enum_type (dip, objfile)
          SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
          SYMBOL_CLASS (sym) = LOC_CONST;
          SYMBOL_TYPE (sym) = type;
-         SYMBOL_VALUE (sym) = list -> field.bitpos;
+         SYMBOL_VALUE (sym) = FIELD_BITPOS (list->field);
+         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
@@ -1773,6 +1803,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);
@@ -1816,6 +1848,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)
     {
@@ -1929,21 +1971,20 @@ 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);
+  record_debugformat ("DWARF 1");
   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;
 }
 
 /*
@@ -2156,20 +2197,23 @@ LOCAL FUNCTION
 
 SYNOPSIS
 
-       static int locval (char *loc)
+       static int locval (struct dieinfo *dip)
 
 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 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
        pointer, rather than the absolute value.  This is what GDB wants
        anyway.
     
-       When the result is a register number, the global isreg flag is set,
-       otherwise it is cleared.  This is a kludge until we figure out a better
+       When the result is a register number, the isreg flag is set, otherwise
+       it is cleared.  This is a kludge until we figure out a better
        way to handle the problem.  Gdb's design does not mesh well with the
        DWARF notion of a location computing interpreter, which is a shame
        because the flexibility goes unused.
@@ -2181,28 +2225,32 @@ NOTES
  */
 
 static int
-locval (loc)
-     char *loc;
+locval (dip)
+     struct dieinfo *dip;
 {
   unsigned short nbytes;
   unsigned short locsize;
   auto long stack[64];
   int stacki;
+  char *loc;
   char *end;
   int loc_atom_code;
   int loc_value_size;
   
+  loc = dip -> at_location;
   nbytes = attribute_size (AT_location);
   locsize = target_to_host (loc, nbytes, GET_UNSIGNED, current_objfile);
   loc += nbytes;
   end = loc + locsize;
   stacki = 0;
   stack[stacki] = 0;
-  isreg = 0;
-  offreg = 0;
+  dip -> isreg = 0;
+  dip -> offreg = 0;
+  dip -> optimized_out = 1;
   loc_value_size = TARGET_FT_LONG_SIZE (current_objfile);
   while (loc < end)
     {
+      dip -> optimized_out = 0;
       loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED,
                                      current_objfile);
       loc += SIZEOF_LOC_ATOM_CODE;
@@ -2219,15 +2267,15 @@ locval (loc)
                                                     GET_UNSIGNED,
                                                     current_objfile));
            loc += loc_value_size;
-           isreg = 1;
+           dip -> isreg = 1;
            break;
          case OP_BASEREG:
            /* push value of register (number) */
            /* Actually, we compute the value as if register has 0, so the
               value ends up being the offset from that register.  */
-           offreg = 1;
-           basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED,
-                                     current_objfile);
+           dip -> offreg = 1;
+           dip -> basereg = target_to_host (loc, loc_value_size, GET_UNSIGNED,
+                                            current_objfile);
            loc += loc_value_size;
            stack[++stacki] = 0;
            break;
@@ -2301,7 +2349,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);
@@ -2317,7 +2365,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)))
        {
@@ -2326,7 +2374,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);
@@ -2480,54 +2528,6 @@ dwarf_psymtab_to_symtab (pst)
 
 /*
 
-LOCAL FUNCTION
-
-       init_psymbol_list -- initialize storage for partial symbols
-
-SYNOPSIS
-
-       static void init_psymbol_list (struct objfile *objfile, int total_symbols)
-
-DESCRIPTION
-
-       Initializes storage for all of the partial symbols that will be
-       created by dwarf_build_psymtabs and subsidiaries.
- */
-
-static void
-init_psymbol_list (objfile, total_symbols)
-     struct objfile *objfile;
-     int total_symbols;
-{
-  /* Free any previously allocated psymbol lists.  */
-  
-  if (objfile -> global_psymbols.list)
-    {
-      mfree (objfile -> md, (PTR)objfile -> global_psymbols.list);
-    }
-  if (objfile -> static_psymbols.list)
-    {
-      mfree (objfile -> md, (PTR)objfile -> static_psymbols.list);
-    }
-  
-  /* Current best guess is that there are approximately a twentieth
-     of the total symbols (in a debugging file) are global or static
-     oriented symbols */
-  
-  objfile -> global_psymbols.size = total_symbols / 10;
-  objfile -> static_psymbols.size = total_symbols / 10;
-  objfile -> global_psymbols.next =
-    objfile -> global_psymbols.list = (struct partial_symbol *)
-      xmmalloc (objfile -> md, objfile -> global_psymbols.size
-                            * sizeof (struct partial_symbol));
-  objfile -> static_psymbols.next =
-    objfile -> static_psymbols.list = (struct partial_symbol *)
-      xmmalloc (objfile -> md, objfile -> static_psymbols.size
-                            * sizeof (struct partial_symbol));
-}
-
-/*
-
 LOCAL FUNCTION
 
        add_enum_psymbol -- add enumeration members to partial symbol table
@@ -2565,8 +2565,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;
        }
@@ -2598,34 +2598,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:
@@ -2634,17 +2634,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;
     }
@@ -2944,6 +2944,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);
@@ -2962,13 +2963,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)
            {
@@ -2982,7 +2985,7 @@ new_symbol (dip, objfile)
        case TAG_global_variable:
          if (dip -> at_location != NULL)
            {
-             SYMBOL_VALUE (sym) = locval (dip -> at_location);
+             SYMBOL_VALUE_ADDRESS (sym) = locval (dip);
              add_symbol_to_list (sym, &global_symbols);
              SYMBOL_CLASS (sym) = LOC_STATIC;
              SYMBOL_VALUE (sym) += baseaddr;
@@ -2991,38 +2994,52 @@ new_symbol (dip, objfile)
        case TAG_local_variable:
          if (dip -> at_location != NULL)
            {
-             SYMBOL_VALUE (sym) = locval (dip -> at_location);
-             add_symbol_to_list (sym, list_in_scope);
-             if (isreg)
+             int loc = locval (dip);
+             if (dip -> optimized_out)
+               {
+                 SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+               }
+             else if (dip -> isreg)
                {
                  SYMBOL_CLASS (sym) = LOC_REGISTER;
                }
-             else if (offreg)
+             else if (dip -> offreg)
                {
                  SYMBOL_CLASS (sym) = LOC_BASEREG;
-                 SYMBOL_BASEREG (sym) = basereg;
+                 SYMBOL_BASEREG (sym) = dip -> basereg;
                }
              else
                {
                  SYMBOL_CLASS (sym) = LOC_STATIC;
                  SYMBOL_VALUE (sym) += baseaddr;
                }
+             if (SYMBOL_CLASS (sym) == LOC_STATIC)
+               {
+                 /* LOC_STATIC address class MUST use SYMBOL_VALUE_ADDRESS,
+                    which may store to a bigger location than SYMBOL_VALUE. */
+                 SYMBOL_VALUE_ADDRESS (sym) = loc;
+               }
+             else
+               {
+                 SYMBOL_VALUE (sym) = loc;
+               }
+             add_symbol_to_list (sym, list_in_scope);
            }
          break;
        case TAG_formal_parameter:
          if (dip -> at_location != NULL)
            {
-             SYMBOL_VALUE (sym) = locval (dip -> at_location);
+             SYMBOL_VALUE (sym) = locval (dip);
            }
          add_symbol_to_list (sym, list_in_scope);
-         if (isreg)
+         if (dip -> isreg)
            {
              SYMBOL_CLASS (sym) = LOC_REGPARM;
            }
-         else if (offreg)
+         else if (dip -> offreg)
            {
              SYMBOL_CLASS (sym) = LOC_BASEREG_ARG;
-             SYMBOL_BASEREG (sym) = basereg;
+             SYMBOL_BASEREG (sym) = dip -> basereg;
            }
          else
            {
@@ -3090,6 +3107,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);
@@ -3797,16 +3815,18 @@ NOTES
        use it as signed data, then we need to explicitly sign extend the
        result until the bfd library is able to do this for us.
 
+       FIXME: Would a 32 bit target ever need an 8 byte result?
+
  */
 
-static unsigned long
+static CORE_ADDR
 target_to_host (from, nbytes, signextend, objfile)
      char *from;
      int nbytes;
      int signextend;           /* FIXME:  Unused */
      struct objfile *objfile;
 {
-  unsigned long rtnval;
+  CORE_ADDR rtnval;
 
   switch (nbytes)
     {
This page took 0.034472 seconds and 4 git commands to generate.