* breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function
[deliverable/binutils-gdb.git] / gdb / mipsread.c
index 1ac6f01909383ee603cb94ef42b1d5e8f76276b9..1c70aa7e142e341717652e53bcffa9d6b04ab7c4 100644 (file)
@@ -70,9 +70,6 @@ typedef struct mips_extra_func_info {
 #ifndef RA_REGNUM
 #define RA_REGNUM 0
 #endif
-#ifndef FP0_REGNUM
-#define FP0_REGNUM 0
-#endif
 #endif
 
 #ifdef USG
@@ -110,6 +107,22 @@ typedef struct mips_extra_func_info {
 #include "expression.h"
 #include "language.h"          /* Needed inside partial-stab.h */
 
+/* Provide a default mapping from a ecoff register number to a gdb REGNUM.  */
+#ifndef ECOFF_REG_TO_REGNUM
+#define ECOFF_REG_TO_REGNUM(num) (num)
+#endif
+
+/* Information is passed among various mipsread routines for accessing
+   symbol files.  A pointer to this structure is kept in the sym_private
+   field of the objfile struct.  */
+
+struct ecoff_symfile_info {
+  struct mips_pending **pending_list;
+};
+#define ECOFF_SYMFILE_INFO(o)  ((struct ecoff_symfile_info *)((o)->sym_private))
+#define ECOFF_PENDING_LIST(o)  (ECOFF_SYMFILE_INFO(o)->pending_list)
+
 /* 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.
@@ -128,7 +141,7 @@ struct symloc
   bfd *cur_bfd;
   EXTR *extern_tab;            /* Pointer to external symbols for this file. */
   int extern_count;            /* Size of extern_tab. */
-  struct mips_pending **pending_list;
+  enum language pst_language;
 };
 
 /* Things we import explicitly from other modules */
@@ -162,7 +175,7 @@ struct complaint block_overflow_complaint =
 {"block containing %s overfilled", 0, 0};
 
 struct complaint basic_type_complaint =
-{"cannot map MIPS basic type 0x%x", 0, 0};
+{"cannot map MIPS basic type 0x%x for %s", 0, 0};
 
 struct complaint unknown_type_qual_complaint =
 {"unknown type qualifier 0x%x", 0, 0};
@@ -195,19 +208,24 @@ struct complaint bad_setjmp_pdr_complaint =
 {"fixing bad setjmp PDR from libc", 0, 0};
 
 struct complaint bad_fbitfield_complaint =
-{"can't handle TIR fBitfield", 0, 0};
+{"can't handle TIR fBitfield for %s", 0, 0};
 
 struct complaint bad_rfd_entry_complaint =
-{"bad rfd entry for file %d, index %d", 0, 0};
+{"bad rfd entry for %s: file %d, index %d", 0, 0};
 
 struct complaint unexpected_type_code_complaint =
 {"unexpected type code for %s", 0, 0};
 
-/* Macros and extra defs */
+struct complaint unable_to_cross_ref_complaint =
+{"unable to cross ref btTypedef for %s", 0, 0};
 
-/* Already-parsed symbols are marked specially */
+struct complaint illegal_forward_tq0_complaint =
+{"illegal tq0 in forward typedef for %s", 0, 0};
 
-#define stParsed stType
+struct complaint illegal_forward_bt_complaint =
+{"illegal bt %d in forward typedef for %s", 0, 0};
+
+/* Macros and extra defs */
 
 /* Puns: hard to find whether -g was used and how */
 
@@ -266,15 +284,15 @@ static void
 read_the_mips_symtab PARAMS ((bfd *));
 
 static int
-upgrade_type PARAMS ((struct type **, int, union aux_ext *, int));
+upgrade_type PARAMS ((int, struct type **, int, union aux_ext *, int));
 
 static void
 parse_partial_symbols PARAMS ((struct objfile *,
                               struct section_offsets *));
 
 static int
-cross_ref PARAMS ((union aux_ext *, struct type **, enum type_code, char **,
-                  int));
+cross_ref PARAMS ((int, union aux_ext *, struct type **, enum type_code,
+                  char **, int, char *));
 
 static void
 fixup_sigtramp PARAMS ((void));
@@ -297,8 +315,11 @@ new_linetable PARAMS ((int));
 static struct blockvector *
 new_bvect PARAMS ((int));
 
+static int
+parse_symbol PARAMS ((SYMR *, union aux_ext *, char *, int));
+
 static struct type *
-parse_type PARAMS ((union aux_ext *, int *, int));
+parse_type PARAMS ((int, union aux_ext *, int *, int, char *));
 
 static struct symbol *
 mylookup_symbol PARAMS ((char *, struct block *, enum namespace,
@@ -319,11 +340,6 @@ compare_blocks PARAMS ((const void *, const void *));
 static struct partial_symtab *
 new_psymtab PARAMS ((char *, struct objfile *));
 
-#if 0
-static struct partial_symtab *
-parse_fdr PARAMS ((int, int, struct objfile *));
-#endif
-
 static void
 psymtab_to_symtab_1 PARAMS ((struct partial_symtab *, char *));
 
@@ -366,7 +382,8 @@ mipscoff_symfile_init (objfile)
     {
       mfree (objfile->md, objfile->sym_private);
     }
-  objfile->sym_private = NULL;
+  objfile->sym_private = (PTR)
+    xmmalloc (objfile->md, sizeof (struct ecoff_symfile_info));
 }
 
 static void
@@ -549,8 +566,8 @@ read_mips_symtab (objfile, section_offsets)
 struct pst_map
 {
   struct partial_symtab *pst;  /* the psymtab proper */
-  int n_globals;               /* exported globals (external symbols) */
-  int globals_offset;          /* cumulative */
+  long n_globals;              /* exported globals (external symbols) */
+  long globals_offset;         /* cumulative */
 };
 
 
@@ -568,7 +585,7 @@ static struct parse_stack
   int maxsyms;                 /* Max symbols in this block. */
   struct type *cur_type;       /* Type we parse fields for. */
   int cur_field;               /* Field number in cur_type. */
-  int procadr;                 /* Start addres of this procedure */
+  CORE_ADDR procadr;           /* Start addres of this procedure */
   int numargs;                 /* Its argument count */
 }
 
@@ -617,15 +634,15 @@ pop_parse_stack ()
    duplications we keep a quick fixup table, an array
    of lists of references indexed by file descriptor */
 
-static struct mips_pending
+struct mips_pending
 {
   struct mips_pending *next;   /* link */
   char *s;                     /* the unswapped symbol */
   struct type *t;              /* its partial type descriptor */
-} **pending_list;
+};
 
 
-/* Check whether we already saw symbol SH in file FH as undefined */
+/* Check whether we already saw symbol SH in file FH */
 
 static struct mips_pending *
 is_pending_symbol (fh, sh)
@@ -634,6 +651,7 @@ is_pending_symbol (fh, sh)
 {
   int f_idx = fh - ecoff_data (cur_bfd)->fdr;
   register struct mips_pending *p;
+  struct mips_pending **pending_list = ECOFF_PENDING_LIST (current_objfile);
 
   /* Linear search is ok, list is typically no more than 10 deep */
   for (p = pending_list[f_idx]; p; p = p->next)
@@ -642,7 +660,7 @@ is_pending_symbol (fh, sh)
   return p;
 }
 
-/* Add a new undef symbol SH of type T */
+/* Add a new symbol SH of type T */
 
 static void
 add_pending (fh, sh, t)
@@ -656,35 +674,17 @@ add_pending (fh, sh, t)
   /* Make sure we do not make duplicates */
   if (!p)
     {
-      p = (struct mips_pending *) xmalloc (sizeof (*p));
+      struct mips_pending **pending_list = ECOFF_PENDING_LIST (current_objfile);
+
+      p = ((struct mips_pending *)
+          obstack_alloc (&current_objfile->psymbol_obstack,
+                         sizeof (struct mips_pending)));
       p->s = sh;
       p->t = t;
       p->next = pending_list[f_idx];
       pending_list[f_idx] = p;
     }
 }
-
-/* Throw away undef entries when done with file index F_IDX */
-/* FIXME -- storage leak.  This is never called!!!   --gnu */
-
-#if 0
-
-static void
-free_pending (f_idx)
-     int f_idx;
-{
-  register struct mips_pending *p, *q;
-
-  for (p = pending_list[f_idx]; p; p = q)
-    {
-      q = p->next;
-      free ((PTR) p);
-    }
-  pending_list[f_idx] = 0;
-}
-
-#endif
-
 \f
 
 /* Parsing Routines proper. */
@@ -696,10 +696,7 @@ free_pending (f_idx)
    EXT_SH points to the unswapped symbol, which is needed for struct,
    union, etc., types; it is NULL for an EXTR.  BIGEND says whether
    aux symbols are big-endian or little-endian.  Return count of
-   SYMR's handled (normally one).
-
-   FIXME: This modifies the symbol, but the only way we have to save
-   the modified information is to stuff it back into the BFD data.  */
+   SYMR's handled (normally one).  */
 
 static int
 parse_symbol (sh, ax, ext_sh, bigend)
@@ -721,6 +718,7 @@ parse_symbol (sh, ax, ext_sh, bigend)
   int count = 1;
   enum address_class class;
   TIR tir;
+  long svalue = sh->value;
 
   if (ext_sh == (char *) NULL)
     name = ecoff_data (cur_bfd)->ssext + sh->iss;
@@ -761,14 +759,13 @@ parse_symbol (sh, ax, ext_sh, bigend)
       if (sh->sc == scRegister)
        {
          class = LOC_REGISTER;
-         if (sh->value > 31)
-           sh->value += FP0_REGNUM - 32;
+         svalue = ECOFF_REG_TO_REGNUM (svalue);
        }
       else
        class = LOC_LOCAL;
       b = top_stack->cur_block;
       s = new_symbol (name);
-      SYMBOL_VALUE (s) = sh->value;
+      SYMBOL_VALUE (s) = svalue;
 
     data:                      /* Common code for symbols describing data */
       SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
@@ -780,7 +777,7 @@ parse_symbol (sh, ax, ext_sh, bigend)
          sh->index == 0xfffff)
        SYMBOL_TYPE (s) = builtin_type_int;     /* undefined? */
       else
-       SYMBOL_TYPE (s) = parse_type (ax + sh->index, 0, bigend);
+       SYMBOL_TYPE (s) = parse_type (cur_fd, ax + sh->index, 0, bigend, name);
       /* Value of a data symbol is its memory address */
       break;
 
@@ -799,8 +796,7 @@ parse_symbol (sh, ax, ext_sh, bigend)
        case scRegister:
          /* Pass by value in register.  */
          SYMBOL_CLASS(s) = LOC_REGPARM;
-         if (sh->value > 31)
-           sh->value += FP0_REGNUM-32;
+         svalue = ECOFF_REG_TO_REGNUM (svalue);
          break;
        case scVar:
          /* Pass by reference on stack.  */
@@ -809,14 +805,15 @@ parse_symbol (sh, ax, ext_sh, bigend)
        case scVarRegister:
          /* Pass by reference in register.  */
          SYMBOL_CLASS(s) = LOC_REGPARM_ADDR;
+         svalue = ECOFF_REG_TO_REGNUM (svalue);
          break;
        default:
          /* Pass by value on stack.  */
          SYMBOL_CLASS(s) = LOC_ARG;
          break;
        }
-      SYMBOL_VALUE (s) = sh->value;
-      SYMBOL_TYPE (s) = parse_type (ax + sh->index, 0, bigend);
+      SYMBOL_VALUE (s) = svalue;
+      SYMBOL_TYPE (s) = parse_type (cur_fd, ax + sh->index, 0, bigend, name);
       add_symbol (s, top_stack->cur_block);
 #if 0
       /* FIXME:  This has not been tested.  See dbxread.c */
@@ -844,7 +841,7 @@ parse_symbol (sh, ax, ext_sh, bigend)
       if (sh->sc == scUndefined || sh->sc == scNil)
        t = builtin_type_int;
       else
-       t = parse_type (ax + sh->index + 1, 0, bigend);
+       t = parse_type (cur_fd, ax + sh->index + 1, 0, bigend, name);
       b = top_stack->cur_block;
       if (sh->st == stProc)
        {
@@ -863,7 +860,7 @@ parse_symbol (sh, ax, ext_sh, bigend)
       /* Generate a template for the type of this function.  The
         types of the arguments will be added as we read the symbol
         table. */
-      bcopy (SYMBOL_TYPE (s), lookup_function_type (t), sizeof (struct type));
+      memcpy (lookup_function_type (t), SYMBOL_TYPE (s), sizeof (struct type));
 #else
       SYMBOL_TYPE (s) = lookup_function_type (t);
 #endif
@@ -887,9 +884,6 @@ parse_symbol (sh, ax, ext_sh, bigend)
       top_stack->cur_field = -1;
       top_stack->procadr = sh->value;
       top_stack->numargs = 0;
-
-      sh->value = (long) SYMBOL_TYPE (s);
-      sh->st = stParsed;
       break;
 
       /* Beginning of code for structure, union, and enum definitions.
@@ -926,12 +920,6 @@ parse_symbol (sh, ax, ext_sh, bigend)
        push_parse_stack ();
        top_stack->blocktype = stBlock;
 
-       s = new_symbol (name);
-       SYMBOL_NAMESPACE (s) = STRUCT_NAMESPACE;
-       SYMBOL_CLASS (s) = LOC_TYPEDEF;
-       SYMBOL_VALUE (s) = 0;
-       add_symbol (s, top_stack->cur_block);
-
        /* First count the number of fields and the highest value. */
        nfields = 0;
        max_value = 0;
@@ -973,7 +961,6 @@ parse_symbol (sh, ax, ext_sh, bigend)
              case stUnion:
              case stEnum:
              case stStruct:
-             case stParsed:
                {
 #if 0
                  /* This is a no-op; is it trying to tell us something
@@ -1045,27 +1032,29 @@ parse_symbol (sh, ax, ext_sh, bigend)
          else
            type_code = TYPE_CODE_STRUCT;
 
-       /* If this type was expected, use its partial definition */
+       /* Create a new type or use the pending type.  */
        pend = is_pending_symbol (cur_fdr, ext_sh);
-       if (pend != (struct mips_pending *) NULL)
+       if (pend == (struct mips_pending *) NULL)
+         {
+           t = new_type (NULL);
+           add_pending (cur_fdr, ext_sh, t);
+         }
+       else
          t = pend->t;
+
+       /* Alpha cc unnamed structs do not get a tag name.  */
+       if (sh->iss == 0)
+         TYPE_TAG_NAME (t) = NULL;
        else
-         t = new_type (NULL);
+         TYPE_TAG_NAME (t) = obconcat (&current_objfile->symbol_obstack,
+                                       "", "", name);
 
-       TYPE_TAG_NAME (t) = obconcat (&current_objfile->symbol_obstack,
-                                     "", "", name);
        TYPE_CODE (t) = type_code;
        TYPE_LENGTH (t) = sh->value;
        TYPE_NFIELDS (t) = nfields;
        TYPE_FIELDS (t) = f = ((struct field *)
                               TYPE_ALLOC (t,
                                           nfields * sizeof (struct field)));
-       /* Handle opaque struct definitions.  */
-       if (TYPE_NFIELDS (t) == 0)
-         {
-           TYPE_FLAGS (t) |= TYPE_FLAG_STUB;
-           SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
-         }
 
        if (type_code == TYPE_CODE_ENUM)
          {
@@ -1105,13 +1094,26 @@ parse_symbol (sh, ax, ext_sh, bigend)
                f++;
              }
          }
-       SYMBOL_TYPE (s) = t;
        /* make this the current type */
        top_stack->cur_type = t;
        top_stack->cur_field = 0;
-       /* Mark that symbol has a type, and say which one */
-       sh->value = (long) t;
-       sh->st = stParsed;
+
+       /* Do not create a symbol for alpha cc unnamed structs.  */
+       if (sh->iss == 0)
+         break;
+       s = new_symbol (name);
+       SYMBOL_NAMESPACE (s) = STRUCT_NAMESPACE;
+       SYMBOL_CLASS (s) = LOC_TYPEDEF;
+       SYMBOL_VALUE (s) = 0;
+       SYMBOL_TYPE (s) = t;
+
+       /* gcc puts out an empty struct for an opaque struct definitions.  */
+       if (TYPE_NFIELDS (t) == 0)
+         {
+           TYPE_FLAGS (t) |= TYPE_FLAG_STUB;
+           SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
+         }
+       add_symbol (s, top_stack->cur_block);
        break;
 
        /* End of local variables shared by struct, union, enum, and
@@ -1156,7 +1158,7 @@ parse_symbol (sh, ax, ext_sh, bigend)
          e = ((struct mips_extra_func_info *)
               obstack_alloc (&current_objfile->symbol_obstack,
                              sizeof (struct mips_extra_func_info)));
-         SYMBOL_VALUE (s) = (int) e;
+         SYMBOL_VALUE (s) = (long) e;
          e->numargs = top_stack->numargs;
          add_symbol (s, top_stack->cur_block);
 
@@ -1202,24 +1204,48 @@ parse_symbol (sh, ax, ext_sh, bigend)
       f->name = name;
       f->bitpos = sh->value;
       f->bitsize = 0;
-      f->type = parse_type (ax + sh->index, &f->bitsize, bigend);
+      f->type = parse_type (cur_fd, ax + sh->index, &f->bitsize, bigend, name);
       break;
 
     case stTypedef:            /* type definition */
+      /* Typedefs for forward declarations and opaque structs from alpha cc
+        are handled by cross_ref, skip them.  */
+      if (sh->iss == 0)
+       break;
+
+      /* Parse the type or use the pending type.  */
+      pend = is_pending_symbol (cur_fdr, ext_sh);
+      if (pend == (struct mips_pending *) NULL)
+       {
+         t = parse_type (cur_fd, ax + sh->index, (int *)NULL, bigend, name);
+         add_pending (cur_fdr, ext_sh, t);
+       }
+      else
+       t = pend->t;
+
+      /* mips cc puts out a typedef with the name of the struct for forward
+        declarations. These should not go into the symbol table and
+        TYPE_NAME should not be set for them.
+        They can't be distinguished from an intentional typedef to
+        the same name however:
+        x.h:
+               struct x { int ix; int jx; };
+               struct xx;
+        x.c:
+               typedef struct x x;
+               struct xx {int ixx; int jxx; };
+        generates a cross referencing stTypedef for x and xx.
+        The user visible effect of this is that the type of a pointer
+        to struct foo sometimes is given as `foo *' instead of `struct foo *'.
+        The problem is fixed with alpha cc.  */
+
       s = new_symbol (name);
       SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
       SYMBOL_CLASS (s) = LOC_TYPEDEF;
       SYMBOL_BLOCK_VALUE (s) = top_stack->cur_block;
+      SYMBOL_TYPE (s) = t;
       add_symbol (s, top_stack->cur_block);
-      SYMBOL_TYPE (s) = parse_type (ax + sh->index, 0, bigend);
-      sh->value = (long) SYMBOL_TYPE (s);
-      sh->st = stParsed;
-      if (TYPE_TAG_NAME (SYMBOL_TYPE (s)) != NULL
-          && STREQ (TYPE_TAG_NAME (SYMBOL_TYPE (s)), "<undefined>"))
-       {
-         /* mips cc puts out a stTypedef for opaque struct definitions.  */
-          TYPE_FLAGS (SYMBOL_TYPE (s)) |= TYPE_FLAG_STUB;
-       }
+
       /* Incomplete definitions of structs should not get a name.  */
       if (TYPE_NAME (SYMBOL_TYPE (s)) == NULL
          && (TYPE_NFIELDS (SYMBOL_TYPE (s)) != 0
@@ -1279,10 +1305,12 @@ parse_symbol (sh, ax, ext_sh, bigend)
    they are big-endian or little-endian (from fh->fBigendian).  */
 
 static struct type *
-parse_type (ax, bs, bigend)
+parse_type (fd, ax, bs, bigend, sym_name)
+     int fd;
      union aux_ext *ax;
      int *bs;
      int bigend;
+     char *sym_name;
 {
   /* Null entries in this map are treated specially */
   static struct type **map_bt[] =
@@ -1314,8 +1342,16 @@ parse_type (ax, bs, bigend)
     0,                         /* btBit */
     0,                         /* btPicture */
     &builtin_type_void,                /* btVoid */
-    &builtin_type_long_long,   /* btLongLong */
-    &builtin_type_unsigned_long_long,  /* btULongLong */
+    0,                         /* DEC C++:  Pointer to member */
+    0,                         /* DEC C++:  Virtual function table */
+    0,                         /* DEC C++:  Class (Record) */
+    &builtin_type_long,                /* btLong64  */
+    &builtin_type_unsigned_long, /* btULong64 */
+    &builtin_type_long_long,   /* btLongLong64  */
+    &builtin_type_unsigned_long_long, /* btULongLong64 */
+    &builtin_type_unsigned_long, /* btAdr64 */
+    &builtin_type_long,                /* btInt64  */
+    &builtin_type_unsigned_long, /* btUInt64 */
   };
 
   TIR t[1];
@@ -1326,9 +1362,9 @@ parse_type (ax, bs, bigend)
   /* Use aux as a type information record, map its basic type.  */
   tax = ax;
   ecoff_swap_tir_in (bigend, &tax->a_ti, t);
-  if (t->bt > (sizeof (map_bt) / sizeof (*map_bt)))
+  if (t->bt >= (sizeof (map_bt) / sizeof (*map_bt)))
     {
-      complain (&basic_type_complaint, t->bt);
+      complain (&basic_type_complaint, t->bt, sym_name);
       return builtin_type_int;
     }
   if (map_bt[t->bt])
@@ -1360,8 +1396,12 @@ parse_type (ax, bs, bigend)
          type_code = TYPE_CODE_SET;
          break;
        case btTypedef:
+         /* alpha cc uses this for typedefs. The true type will be
+            obtained by crossreferencing below.  */
+         type_code = TYPE_CODE_ERROR;
+         break;
        default:
-         complain (&basic_type_complaint, t->bt);
+         complain (&basic_type_complaint, t->bt, sym_name);
          return builtin_type_int;
        }
     }
@@ -1388,7 +1428,7 @@ parse_type (ax, bs, bigend)
         corrupt the TIR.  */
       if (bs == (int *)NULL)
        {
-         complain (&bad_fbitfield_complaint, t->bt);
+         complain (&bad_fbitfield_complaint, sym_name);
          return builtin_type_int;
        }
       *bs = AUX_GET_WIDTH (bigend, ax);
@@ -1408,12 +1448,10 @@ parse_type (ax, bs, bigend)
     {
       char *name;
 
-      /* Try to cross reference this type */
-      ax += cross_ref (ax, &tp, type_code, &name, bigend);
-      /* reading .o file ? */
+      /* Try to cross reference this type, build new type on failure.  */
+      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
       if (tp == (struct type *) NULL)
-       tp = init_type (type_code, 0, 0, (char *) NULL,
-                       (struct objfile *) NULL);
+       tp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
 
       /* Make sure that TYPE_CODE(tp) has an expected type code.
         Any type may be returned from cross_ref if file indirect entries
@@ -1422,18 +1460,28 @@ parse_type (ax, bs, bigend)
          && TYPE_CODE (tp) != TYPE_CODE_UNION
          && TYPE_CODE (tp) != TYPE_CODE_ENUM)
        {
-         complain (&unexpected_type_code_complaint, name);
+         complain (&unexpected_type_code_complaint, sym_name);
        }
       else
        {
 
          /* Usually, TYPE_CODE(tp) is already type_code.  The main
-            exception is if we guessed wrong re struct/union/enum. */
+            exception is if we guessed wrong re struct/union/enum.
+            But for struct vs. union a wrong guess is harmless, so
+            don't complain().  */
+         if ((TYPE_CODE (tp) == TYPE_CODE_ENUM
+              && type_code != TYPE_CODE_ENUM)
+             || (TYPE_CODE (tp) != TYPE_CODE_ENUM
+                 && type_code == TYPE_CODE_ENUM))
+           {
+             complain (&bad_tag_guess_complaint, sym_name);
+           }
+
          if (TYPE_CODE (tp) != type_code)
            {
-             complain (&bad_tag_guess_complaint, name);
              TYPE_CODE (tp) = type_code;
            }
+
          /* Do not set the tag name if it is a compiler generated tag name
              (.Fxx or .xxfake or empty) for unnamed struct/union/enums.  */
          if (name[0] == '.' || name[0] == '\0')
@@ -1455,19 +1503,17 @@ parse_type (ax, bs, bigend)
     {
       char *name;
 
-      /* Try to cross reference this type */
-      ax += cross_ref (ax, &tp, type_code, &name, bigend);
-      /* reading .o file ? */
+      /* Try to cross reference this type, build new type on failure.  */
+      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
       if (tp == (struct type *) NULL)
-       tp = init_type (type_code, 0, 0, (char *) NULL,
-                       (struct objfile *) NULL);
+       tp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
 
       /* Make sure that TYPE_CODE(tp) has an expected type code.
         Any type may be returned from cross_ref if file indirect entries
         are corrupted.  */
       if (TYPE_CODE (tp) != TYPE_CODE_RANGE)
        {
-         complain (&unexpected_type_code_complaint, name);
+         complain (&unexpected_type_code_complaint, sym_name);
        }
       else
        {
@@ -1475,7 +1521,7 @@ parse_type (ax, bs, bigend)
             exception is if we guessed wrong re struct/union/enum. */
          if (TYPE_CODE (tp) != type_code)
            {
-             complain (&bad_tag_guess_complaint, name);
+             complain (&bad_tag_guess_complaint, sym_name);
              TYPE_CODE (tp) = type_code;
            }
          if (TYPE_NAME (tp) == NULL || !STREQ (TYPE_NAME (tp), name))
@@ -1483,6 +1529,18 @@ parse_type (ax, bs, bigend)
                                           &current_objfile->type_obstack);
        }
     }
+  if (t->bt == btTypedef)
+    {
+      char *name;
+
+      /* Try to cross reference this type, it should succeed.  */
+      ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name);
+      if (tp == (struct type *) NULL)
+       {
+         complain (&unable_to_cross_ref_complaint, sym_name);
+         tp = builtin_type_int;
+       }
+    }
 
   /* Deal with range types */
   if (t->bt == btRange)
@@ -1504,7 +1562,7 @@ parse_type (ax, bs, bigend)
      than 6 the game will continue in the next aux */
 
 #define PARSE_TQ(tq) \
-       if (t->tq != tqNil) ax += upgrade_type(&tp, t->tq, ax, bigend);
+       if (t->tq != tqNil) ax += upgrade_type(fd, &tp, t->tq, ax, bigend);
 
 again:PARSE_TQ (tq0);
   PARSE_TQ (tq1);
@@ -1531,7 +1589,8 @@ again:PARSE_TQ (tq0);
    Returns the number of aux symbols we parsed. */
 
 static int
-upgrade_type (tpp, tq, ax, bigend)
+upgrade_type (fd, tpp, tq, ax, bigend)
+     int fd;
      struct type **tpp;
      int tq;
      union aux_ext *ax;
@@ -1573,12 +1632,13 @@ upgrade_type (tpp, tq, ax, bigend)
          rf = AUX_GET_ISYM (bigend, ax);
          off++;
        }
-      fh = get_rfd (cur_fd, rf);
+      fh = get_rfd (fd, rf);
 
-      indx = parse_type ((ecoff_data (cur_bfd)->external_aux
+      indx = parse_type (fd,
+                        (ecoff_data (cur_bfd)->external_aux
                          + fh->iauxBase
                          + id),
-                        (int *) NULL, bigend);
+                        (int *) NULL, bigend, "<array index>");
 
       /* Get the bounds, and create the array type.  */
       ax++;
@@ -1840,7 +1900,6 @@ parse_external (es, skip_procedures, bigend)
       /* Note that the case of a symbol with indexNil must be handled
         anyways by parse_symbol().  */
       parse_symbol (&es->asym, ax, (char *) NULL, bigend);
-      /* Note that parse_symbol changed es->asym.  */
       break;
     default:
       break;
@@ -1864,7 +1923,7 @@ parse_lines (fh, pr, lt)
   int delta, count, lineno = 0;
   unsigned long first_off = pr->adr;
 
-  if (fh->cbLineOffset == 0)
+  if (fh->cbLine == 0)
     return;
 
   base = ecoff_data (cur_bfd)->line + fh->cbLineOffset;
@@ -1873,7 +1932,7 @@ parse_lines (fh, pr, lt)
   k = 0;
   for (j = 0; j < fh->cpd; j++, pr++)
     {
-      int l, halt;
+      long l, halt;
       unsigned long adr;
 
       /* No code for this one */
@@ -1962,6 +2021,7 @@ parse_partial_symbols (objfile, section_offsets)
   int dependencies_used, dependencies_allocated;
   struct cleanup *old_chain;
   char *name;
+  enum language prev_language;
 
   extern_tab = (EXTR *) obstack_alloc (&objfile->psymbol_obstack,
                                       sizeof (EXTR) * hdr->iextMax);
@@ -2004,6 +2064,14 @@ parse_partial_symbols (objfile, section_offsets)
     FDR_IDX (pst) = -1;
   }
 
+  /* Allocate the global pending list.  */
+  ECOFF_PENDING_LIST (objfile) = 
+    ((struct mips_pending **)
+     obstack_alloc (&objfile->psymbol_obstack,
+                   hdr->ifdMax * sizeof (struct mips_pending *)));
+  memset ((PTR) ECOFF_PENDING_LIST (objfile), 0,
+         hdr->ifdMax * sizeof (struct mips_pending *));
+
   /* Pass 0 over external syms: swap them in.  */
   ext_block = (EXTR *) xmalloc (hdr->iextMax * sizeof (EXTR));
   make_cleanup (free, ext_block);
@@ -2047,6 +2115,9 @@ parse_partial_symbols (objfile, section_offsets)
        {
        case stProc:
          break;
+       case stStaticProc:
+         ms_type = mst_file_text;
+         break;
        case stGlobal:
           if (ext_in->asym.sc == scData
              || ext_in->asym.sc == scSData
@@ -2098,18 +2169,38 @@ parse_partial_symbols (objfile, section_offsets)
       memset ((PTR) pst->read_symtab_private, 0, sizeof (struct symloc));
 
       save_pst = pst;
-      /* Make everything point to everything. */
       FDR_IDX (pst) = f_idx;
-      fdr_to_pst[f_idx].pst = pst;
-
-      /* FIXME: This tampers with data from BFD.  */
-      fh->ioptBase = (int) pst;
-
       CUR_BFD (pst) = cur_bfd;
 
       /* The way to turn this into a symtab is to call... */
       pst->read_symtab = mipscoff_psymtab_to_symtab;
 
+      /* Set up language for the pst.
+         The language from the FDR is used if it is unambigious (e.g. cfront
+        with native cc and g++ will set the language to C).
+        Otherwise we have to deduce the language from the filename.
+        Native ecoff has every header file in a separate FDR, so
+        deduce_language_from_filename will return language_unknown for
+        a header file, which is not what we want.
+        But the FDRs for the header files are after the FDR for the source
+        file, so we can assign the language of the source file to the
+        following header files. Then we save the language in the private
+        pst data so that we can reuse it when building symtabs.  */
+      prev_language = psymtab_language;
+
+      switch (fh->lang)
+       {
+       case langCplusplusV2:
+         psymtab_language = language_cplus;
+         break;
+       default:
+         psymtab_language = deduce_language_from_filename (fdr_name (fh));
+         break;
+       }
+      if (psymtab_language == language_unknown)
+       psymtab_language = prev_language;
+      PST_PRIVATE (pst)->pst_language = psymtab_language;
+
       pst->texthigh = pst->textlow;
 
       /* For stabs-in-ecoff files, the second symbol must be @stab.
@@ -2349,6 +2440,7 @@ parse_partial_symbols (objfile, section_offsets)
              switch (psh->st)
                {
                case stProc:
+               case stStaticProc:
                  class = LOC_BLOCK;
                  break;
                case stLabel:
@@ -2370,9 +2462,12 @@ parse_partial_symbols (objfile, section_offsets)
            }
        }
 
-      end_psymtab (save_pst, psymtab_include_list, includes_used,
-                  -1, save_pst->texthigh,
-                  dependency_list, dependencies_used);
+      /* Link pst to FDR. end_psymtab returns NULL if the psymtab was
+        empty and put on the free list.  */
+      fdr_to_pst[f_idx].pst = end_psymtab (save_pst,
+                                          psymtab_include_list, includes_used,
+                                          -1, save_pst->texthigh,
+                                          dependency_list, dependencies_used);
       if (objfile->ei.entry_point >= save_pst->textlow &&
          objfile->ei.entry_point < save_pst->texthigh)
        {
@@ -2384,39 +2479,25 @@ parse_partial_symbols (objfile, section_offsets)
   /* Now scan the FDRs for dependencies */
   for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++)
     {
-      int s_id0 = 0;
       fh = f_idx + ecoff_data (cur_bfd)->fdr;
       pst = fdr_to_pst[f_idx].pst;
 
+      if (pst == (struct partial_symtab *)NULL)
+       continue;
+
       /* This should catch stabs-in-ecoff. */
       if (fh->crfd <= 1)
        continue;
 
-      if (fh->cpd == 0)
-       {               /* If there are no functions defined here ... */
-         /* ...then presumably a .h file: drop reverse depends .h->.c */
-         for (; s_id0 < fh->crfd; s_id0++)
-           {
-             RFDT rh;
-
-             (*swap_rfd_in) (cur_bfd,
-                             ((char *) ecoff_data (cur_bfd)->external_rfd
-                              + (fh->rfdBase + s_id0) * external_rfd_size),
-                             &rh);
-             if (rh == f_idx)
-               {
-                 s_id0++;      /* Skip self-dependency */
-                 break;
-               }
-           }
-       }
-      pst->number_of_dependencies = fh->crfd - s_id0;
+      /* Skip the first file indirect entry as it is a self dependency
+        for source files or a reverse .h -> .c dependency for header files.  */
+      pst->number_of_dependencies = 0;
       pst->dependencies =
        ((struct partial_symtab **)
         obstack_alloc (&objfile->psymbol_obstack,
-                       (pst->number_of_dependencies
+                       ((fh->crfd - 1)
                         * sizeof (struct partial_symtab *))));
-      for (s_idx = s_id0; s_idx < fh->crfd; s_idx++)
+      for (s_idx = 1; s_idx < fh->crfd; s_idx++)
        {
          RFDT rh;
 
@@ -2425,106 +2506,24 @@ parse_partial_symbols (objfile, section_offsets)
                           + (fh->rfdBase + s_idx) * external_rfd_size),
                          &rh);
          if (rh < 0 || rh >= hdr->ifdMax)
-           complain (&bad_file_number_complaint, rh);
-         else
-           pst->dependencies[s_idx - s_id0] = fdr_to_pst[rh].pst;
-       }
-    }
-  do_cleanups (old_chain);
-}
-
-
-#if 0
-/* Do the initial analisys of the F_IDX-th file descriptor.
-   Allocates a partial symtab for it, and builds the list
-   of dependent files by recursion. LEV says at which level
-   of recursion we are called (to pretty up debug traces) */
-
-static struct partial_symtab *
-parse_fdr (f_idx, lev, objfile)
-     int f_idx;
-     int lev;
-     struct objfile *objfile;
-{
-  const bfd_size_type external_rfd_size
-    = ecoff_backend (cur_bfd)->external_rfd_size;
-  void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *))
-    = ecoff_backend (cur_bfd)->swap_rfd_in;
-  register FDR *fh;
-  register struct partial_symtab *pst;
-  int s_idx, s_id0;
-
-  fh = ecoff_data (cur_bfd)->fdr + f_idx;
-
-  /* Use this to indicate into which symtab this file was parsed */
-  if (fh->ioptBase)
-    return (struct partial_symtab *) fh->ioptBase;
-
-  /* Debuggability level */
-  if (compare_glevel (max_glevel, fh->glevel) < 0)
-    max_glevel = fh->glevel;
-
-  /* Make a new partial_symtab */
-  pst = new_psymtab (fdr_name (fh), objfile);
-  if (fh->cpd == 0)
-    {
-      pst->textlow = 0;
-      pst->texthigh = 0;
-    }
-  else
-    {
-      pst->textlow = fh->adr;
-      pst->texthigh = fh->cpd; /* To be fixed later */
-    }
-
-  /* Make everything point to everything. */
-  FDR_IDX (pst) = f_idx;
-  fdr_to_pst[f_idx].pst = pst;
-  fh->ioptBase = (int) pst;
-
-  /* Analyze its dependencies */
-  if (fh->crfd <= 1)
-    return pst;
-
-  s_id0 = 0;
-  if (fh->cpd == 0)
-    {                          /* If there are no functions defined here ... */
-      /* ...then presumably a .h file: drop reverse depends .h->.c */
-      for (; s_id0 < fh->crfd; s_id0++)
-       {
-         RFDT rh;
-
-         (*swap_rfd_in) (cur_bfd,
-                         ((char *) ecoff_data (cur_bfd)->external_rfd
-                          + (fh->rfdBase + s_id0) * external_rfd_size),
-                         &rh);
-         if (rh == f_idx)
            {
-             s_id0++;          /* Skip self-dependency */
-             break;
+             complain (&bad_file_number_complaint, rh);
+             continue;
            }
-       }
-    }
-  pst->number_of_dependencies = fh->crfd - s_id0;
-  pst->dependencies = ((struct partial_symtab **)
-                      obstack_alloc (&objfile->psymbol_obstack,
-                                     (pst->number_of_dependencies
-                                      * sizeof (struct partial_symtab *))));
-  for (s_idx = s_id0; s_idx < fh->crfd; s_idx++)
-    {
-      RFDT rh;
 
-      (*swap_rfd_in) (cur_bfd,
-                     ((char *) ecoff_data (cur_bfd)->external_rfd
-                      + (fh->rfdBase + s_idx) * external_rfd_size),
-                     &rh);
-      pst->dependencies[s_idx - s_id0] = parse_fdr (rh, lev + 1, objfile);
-    }
+         /* Skip self dependencies of header files.  */
+         if (rh == f_idx)
+           continue;
 
-  return pst;
+         /* Do not add to dependeny list if psymtab was empty.  */
+         if (fdr_to_pst[rh].pst == (struct partial_symtab *)NULL)
+           continue;
+         pst->dependencies[pst->number_of_dependencies++] = fdr_to_pst[rh].pst;
+       }
+    }
+  do_cleanups (old_chain);
 }
 
-#endif
 
 static char *
 mips_next_symbol_text ()
@@ -2562,8 +2561,6 @@ psymtab_to_symtab_1 (pst, filename)
     = ecoff_backend (cur_bfd)->external_pdr_size;
   void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
     = ecoff_backend (cur_bfd)->swap_sym_in;
-  void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
-    = ecoff_backend (cur_bfd)->swap_sym_out;
   void (* const swap_pdr_in) PARAMS ((bfd *, PTR, PDR *))
     = ecoff_backend (cur_bfd)->swap_pdr_in;
   int i;
@@ -2637,7 +2634,7 @@ psymtab_to_symtab_1 (pst, filename)
       char *pdr_ptr;
       char *pdr_end;
       int first_pdr;
-      unsigned long first_off;
+      unsigned long first_off = 0;
 
       /* This symbol table contains stabs-in-ecoff entries.  */
 
@@ -2677,7 +2674,7 @@ psymtab_to_symtab_1 (pst, filename)
                  SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
                  SYMBOL_CLASS (s) = LOC_CONST;
                  SYMBOL_TYPE (s) = builtin_type_void;
-                 SYMBOL_VALUE (s) = (int) e;
+                 SYMBOL_VALUE (s) = (long) e;
                  add_symbol_to_list (s, &local_symbols);
                }
            }
@@ -2743,17 +2740,15 @@ psymtab_to_symtab_1 (pst, filename)
          f_max += fh->csym + fh->cpd;
          maxlines = 2 * fh->cline;
          st = new_symtab (pst->filename, 2 * f_max, maxlines, pst->objfile);
+
+         /* The proper language was already determined when building
+            the psymtab, use it.  */
+         st->language = PST_PRIVATE (pst)->pst_language;
        }
 
+      psymtab_language = st->language;
+
       lines = LINETABLE (st);
-      pending_list = PST_PRIVATE (pst)->pending_list;
-      if (pending_list == 0)
-       {
-         pending_list = ((struct mips_pending **)
-                         xzalloc (ecoff_data (cur_bfd)->symbolic_header.ifdMax
-                                  * sizeof (struct mips_pending *)));
-         PST_PRIVATE (pst)->pending_list = pending_list;
-       }
 
       /* Get a new lexical context */
 
@@ -2788,9 +2783,6 @@ psymtab_to_symtab_1 (pst, filename)
                                (ecoff_data (cur_bfd)->external_aux
                                 + fh->iauxBase),
                                sym_ptr, fh->fBigendian);
-             /* FIXME: We must swap the modified symbol back out,
-                although we would rather not.  See parse_symbol.  */
-             (*swap_sym_out) (cur_bfd, &sh, sym_ptr);
              sym_ptr += c * external_sym_size;
            }
 
@@ -2882,16 +2874,25 @@ psymtab_to_symtab_1 (pst, filename)
    Return value says how many aux symbols we ate. */
 
 static int
-cross_ref (ax, tpp, type_code, pname, bigend)
+cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name)
+     int fd;
      union aux_ext *ax;
      struct type **tpp;
      enum type_code type_code; /* Use to alloc new type if none is found. */
      char **pname;
      int bigend;
+     char *sym_name;
 {
   RNDXR rn[1];
   unsigned int rf;
   int result = 1;
+  FDR *fh;
+  char *esh;
+  SYMR sh;
+  int xref_fd;
+  struct mips_pending *pend;
+
+  *tpp = (struct type *)NULL;
 
   ecoff_swap_rndx_in (bigend, &ax->a_rndx, rn);
 
@@ -2906,88 +2907,149 @@ cross_ref (ax, tpp, type_code, pname, bigend)
       rf = rn->rfd;
     }
 
+  /* mips cc uses a rf of -1 for opaque struct definitions.
+     Set TYPE_FLAG_STUB for these types so that check_stub_type will
+     resolve them if the struct gets defined in another compilation unit.  */
   if (rf == -1)
     {
-      /* Ooops */
       *pname = "<undefined>";
+      *tpp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
+      TYPE_FLAGS (*tpp) |= TYPE_FLAG_STUB;
+      return result;
+    }
+
+  /* mips cc uses an escaped rn->index of 0 for struct return types
+     of procedures that were compiled without -g. These will always remain
+     undefined.  */
+  if (rn->rfd == 0xfff && rn->index == 0)
+    {
+      *pname = "<undefined>";
+      return result;
+    }
+
+  /* Find the relative file descriptor and the symbol in it.  */
+  fh = get_rfd (fd, rf);
+  xref_fd = fh - ecoff_data (cur_bfd)->fdr;
+
+  if (rn->index >= fh->csym)
+    {
+      /* File indirect entry is corrupt.  */
+      *pname = "<illegal>";
+      complain (&bad_rfd_entry_complaint,
+               sym_name, xref_fd, rn->index);
+      return result;
+    }
+
+  /* If we have processed this symbol then we left a forwarding
+     pointer to the type in the pending list.  If not, we`ll put
+     it in a list of pending types, to be processed later when
+     the file will be.  In any event, we collect the name for the
+     type here.  */
+
+  esh = ((char *) ecoff_data (cur_bfd)->external_sym
+        + ((fh->isymBase + rn->index)
+           * ecoff_backend (cur_bfd)->external_sym_size));
+  (*ecoff_backend (cur_bfd)->swap_sym_in) (cur_bfd, esh, &sh);
+
+  /* Make sure that this type of cross reference can be handled.  */
+  if (sh.sc != scInfo
+      || (sh.st != stBlock && sh.st != stTypedef
+         && sh.st != stStruct && sh.st != stUnion
+         && sh.st != stEnum))
+    {
+      /* File indirect entry is corrupt.  */
+      *pname = "<illegal>";
+      complain (&bad_rfd_entry_complaint,
+               sym_name, xref_fd, rn->index);
+      return result;
     }
+
+  *pname = ecoff_data (cur_bfd)->ss + fh->issBase + sh.iss;
+
+  pend = is_pending_symbol (fh, esh);
+  if (pend)
+    *tpp = pend->t;
   else
     {
-      /*
-       * Find the relative file descriptor and the symbol in it
-       */
-      FDR *fh = get_rfd (cur_fd, rf);
-      char *esh;
-      SYMR sh;
-      struct type *t;
+      /* We have not yet seen this type.  */
 
-      if (rn->index >= fh->csym)
+      if (sh.iss == 0 && sh.st == stTypedef)
        {
-         /* File indirect entry is corrupt.  */
-         *tpp = (struct type *)NULL;
-         *pname = "<illegal>";
-         complain (&bad_rfd_entry_complaint,
-                   fh - ecoff_data (cur_bfd)->fdr, rn->index);
-         return result;
-       }
+         TIR tir;
+
+         /* alpha cc puts out a stTypedef with a sh.iss of zero for
+            two cases:
+            a) forward declarations of structs/unions/enums which are not
+               defined in this compilation unit.
+               For these the type will be void. This is a bad design decision
+               as cross referencing across compilation units is impossible
+               due to the missing name.
+            b) forward declarations of structs/unions/enums which are defined
+               later in this file or in another file in the same compilation
+               unit.  Simply cross reference those again to get the
+               true type.
+            The forward references are not entered in the pending list and
+            in the symbol table.  */
+
+         ecoff_swap_tir_in (bigend,
+                            &(ecoff_data (cur_bfd)->external_aux
+                              + fh->iauxBase + sh.index)->a_ti,
+                            &tir);
+         if (tir.tq0 != tqNil)
+           complain (&illegal_forward_tq0_complaint, sym_name);
+         switch (tir.bt)
+           {
+           case btVoid:
+             *tpp = init_type (type_code, 0, 0, (char *) NULL,
+                               current_objfile);
+             *pname = "<undefined>";
+             break;
 
-      /* If we have processed this symbol then we left a forwarding
-        pointer to the corresponding GDB symbol.  If not, we`ll put
-        it in a list of pending symbols, to be processed later when
-        the file will be.  In any event, we collect the name for the
-        type here.  Which is why we made a first pass at strings.  */
-
-      esh = ((char *) ecoff_data (cur_bfd)->external_sym
-            + ((fh->isymBase + rn->index)
-               * ecoff_backend (cur_bfd)->external_sym_size));
-      (*ecoff_backend (cur_bfd)->swap_sym_in) (cur_bfd, esh, &sh);
-
-      /* Careful, we might be looking at .o files */
-      if (sh.iss == 0)
-       *pname = "<undefined>";
-      else if (rn->rfd == 0xfff && rn->index == 0)
-       /* For structs, unions and enums, rn->rfd is 0xfff and the index
-          is a relative symbol number for the type, but an index of 0
-          seems to mean that we don't know.  This is said to fix a problem
-          with "info func opendir" on an SGI showing
-          "struct BSDopendir.c *BSDopendir();".  */
-       {
-         *tpp = (struct type *)NULL;
-         *pname = "<unknown>";
-         return result;
-       }
-      else if ((sh.st != stBlock && sh.st != stTypedef && sh.st != stParsed)
-              || sh.sc != scInfo)
-       {
-         /* File indirect entry is corrupt.  */
-         *tpp = (struct type *)NULL;
-         *pname = "<illegal>";
-         complain (&bad_rfd_entry_complaint,
-                   fh - ecoff_data (cur_bfd)->fdr, rn->index);
+           case btStruct:
+           case btUnion:
+           case btEnum:
+             cross_ref (xref_fd,
+                        (ecoff_data (cur_bfd)->external_aux
+                         + fh->iauxBase + sh.index + 1),
+                        tpp, type_code, pname,
+                        fh->fBigendian, sym_name);
+             break;
+
+           default:
+             complain (&illegal_forward_bt_complaint, tir.bt, sym_name);
+             *tpp = init_type (type_code, 0, 0, (char *) NULL,
+                               current_objfile);
+             break;
+           }
          return result;
        }
-      else
-       *pname = ecoff_data (cur_bfd)->ss + fh->issBase + sh.iss;
-
-      /* Have we parsed it ? */
-      if (sh.value != 0 && sh.st == stParsed)
+      else if (sh.st == stTypedef)
        {
-         t = (struct type *) sh.value;
-         *tpp = t;
+         /* Parse the type for a normal typedef. This might recursively call
+            cross_ref till we get a non typedef'ed type.
+            FIXME: This is not correct behaviour, but gdb currently
+            cannot handle typedefs without type copying. But type copying is
+            impossible as we might have mutual forward references between
+            two files and the copied type would not get filled in when
+            we later parse its definition.   */
+         *tpp = parse_type (xref_fd,
+                            (ecoff_data (cur_bfd)->external_aux
+                             + fh->iauxBase + sh.index),
+                            (int *)NULL,
+                            fh->fBigendian,
+                            (ecoff_data (cur_bfd)->ss
+                             + fh->issBase + sh.iss));
        }
       else
        {
-         /* Avoid duplicates */
-         struct mips_pending *p = is_pending_symbol (fh, esh);
-         if (p)
-           *tpp = p->t;
-         else
-           {
-             *tpp = init_type (type_code, 0, 0, (char *) NULL,
-                               (struct objfile *) NULL);
-             add_pending (fh, esh, *tpp);
-           }
+         /* Cross reference to a struct/union/enum which is defined
+            in another file in the same compilation unit but that file
+            has not been parsed yet.
+            Initialize the type only, it will be filled in when
+            it's definition is parsed.  */
+         *tpp = init_type (type_code, 0, 0, (char *) NULL, current_objfile);
        }
+      add_pending (fh, esh, *tpp);
     }
 
   /* We used one auxent normally, two if we got a "next one" rf. */
@@ -3344,6 +3406,8 @@ new_symbol (name)
 
   memset ((PTR) s, 0, sizeof (*s));
   SYMBOL_NAME (s) = name;
+  SYMBOL_LANGUAGE (s) = psymtab_language;
+  SYMBOL_INIT_DEMANGLED_NAME (s, &current_objfile->symbol_obstack);
   return s;
 }
 
@@ -3377,7 +3441,7 @@ fixup_sigtramp ()
 {
   struct symbol *s;
   struct symtab *st;
-  struct block *b, *b0;
+  struct block *b, *b0 = NULL;
 
   sigtramp_address = -1;
 
@@ -3422,7 +3486,7 @@ fixup_sigtramp ()
   SYMBOL_NAMESPACE (s) = VAR_NAMESPACE;
   SYMBOL_CLASS (s) = LOC_BLOCK;
   SYMBOL_TYPE (s) = init_type (TYPE_CODE_FUNC, 4, 0, (char *) NULL,
-                              (struct objfile *) NULL);
+                              st->objfile);
   TYPE_TARGET_TYPE (SYMBOL_TYPE (s)) = builtin_type_void;
 
   /* Need a block to allocate MIPS_EFI_SYMBOL_NAME in */
@@ -3456,7 +3520,7 @@ fixup_sigtramp ()
 
     current_objfile = st->objfile;     /* Keep new_symbol happy */
     s = new_symbol (MIPS_EFI_SYMBOL_NAME);
-    SYMBOL_VALUE (s) = (int) e;
+    SYMBOL_VALUE (s) = (long) e;
     SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE;
     SYMBOL_CLASS (s) = LOC_CONST;
     SYMBOL_TYPE (s) = builtin_type_void;
This page took 0.038824 seconds and 4 git commands to generate.