]> Git Repo - binutils.git/blobdiff - gdb/dwarfread.c
* lib/gdb.exp (setup_xfail_format): New function.
[binutils.git] / gdb / dwarfread.c
index 3d034e1ea079c8549134b7810fdc0f0d4ba0b9b4..09b7f10ee4f2142d74940611b616e23d09963fcd 100644 (file)
@@ -54,10 +54,6 @@ other things to work on, if you get bored. :-)
 #include <fcntl.h>
 #include "gdb_string.h"
 
-#ifndef        NO_SYS_FILE
-#include <sys/file.h>
-#endif
-
 /* Some macros to provide DIE info for complaints. */
 
 #define DIE_ID (curdie!=NULL ? curdie->die_ref : 0)
@@ -318,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 */
@@ -327,13 +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 */
-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;
-/* 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,
@@ -442,6 +448,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));
 
@@ -558,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 *));
@@ -894,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
@@ -938,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);
 }
@@ -1051,7 +1087,7 @@ struct_type (dip, thisdie, enddie, objfile)
              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);
+         list -> field.bitpos = 8 * locval (&mbr);
          /* Handle bit fields. */
          list -> field.bitsize = mbr.at_bit_size;
          if (BITS_BIG_ENDIAN)
@@ -1935,7 +1971,7 @@ 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);
@@ -1948,8 +1984,6 @@ read_file_scope (dip, thisdie, enddie, objfile)
       symtab -> language = cu_language;
     }      
   do_cleanups (back_to);
-  utypes = NULL;
-  numutypes = 0;
 }
 
 /*
@@ -2162,23 +2196,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 global optimized_out flag is set for
-       those, the return value is meaningless.
+       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.
@@ -2190,30 +2224,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;
-  optimized_out = 1;
+  dip -> isreg = 0;
+  dip -> offreg = 0;
+  dip -> optimized_out = 1;
   loc_value_size = TARGET_FT_LONG_SIZE (current_objfile);
   while (loc < end)
     {
-      optimized_out = 0;
+      dip -> optimized_out = 0;
       loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED,
                                      current_objfile);
       loc += SIZEOF_LOC_ATOM_CODE;
@@ -2230,15 +2266,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;
@@ -2528,8 +2564,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;
        }
@@ -2561,34 +2597,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:
@@ -2597,17 +2633,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;
     }
@@ -2926,13 +2962,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)
            {
@@ -2946,7 +2984,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;
@@ -2955,42 +2993,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 (optimized_out)
+             int loc = locval (dip);
+             if (dip -> optimized_out)
                {
                  SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
                }
-             else if (isreg)
+             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
            {
This page took 0.042239 seconds and 4 git commands to generate.