* xcoffexec.c (exec_ops): child_attach and child_create_inferior
[deliverable/binutils-gdb.git] / gdb / mipsread.c
index 4695bdd58769f335b2bcab05da50942a31b49379..90dd8af5a2d11439a8a8dba24850cf8c8f8602b4 100644 (file)
@@ -20,7 +20,7 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* This module provides three functions: mipscoff_symfile_init,
-   which initializes to read a symbol file; mipscoff_new_init, which 
+   which initializes to read a symbol file; mipscoff_new_init, which
    discards existing cached information when all symbols are being
    discarded; and mipscoff_symfile_read, which reads a symbol table
    from a file.
@@ -43,7 +43,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
    This module can read all four of the known byte-order combinations,
    on any type of host.  However, it does make (and check) the assumption
-   that the external form of a symbol table structure (on disk) 
+   that the external form of a symbol table structure (on disk)
    occupies the same number of bytes as the internal form (in a struct).
    Fixing this is possible but requires larger structural changes.  */
 
@@ -54,26 +54,27 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbtypes.h"
 #include "gdbcore.h"
 #include "symfile.h"
+#include "objfiles.h"
 #include "obstack.h"
 #include "buildsym.h"
+
+#ifdef USG
+#include <sys/types.h>
+#define L_SET 0
+#define L_INCR 1
+#endif
+
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/stat.h>
-#ifdef CMUCS
-#include <mips/syms.h>
-#else /* not CMUCS */
-#ifndef LANGUAGE_C
-#define        LANGUAGE_C
-#endif
-#include "symconst.h"
-#include "sym.h"
-#endif /* not CMUCS */
 
-#include "coff/mips.h"
-#include "libaout.h"           /* FIXME Secret internal BFD stuff for a.out */
+#include "coff/mips.h"         /* COFF-like aspects of ecoff files */
+#include "coff/ecoff-ext.h"    /* External forms of ecoff sym structures */
+
+#include "libbfd.h"            /* FIXME Secret internal BFD stuff (bfd_read) */
+#include "libaout.h"           /* FIXME Secret internal BFD stuff for a.out */
 #include "aout/aout64.h"
-#include "aout/stab_gnu.h"     /* We always use GNU stabs, not native, now */
-#include "coff/ecoff-ext.h"
+#include "aout/stab_gnu.h"     /* STABS information */
 
 struct coff_exec {
        struct external_filehdr f;
@@ -112,37 +113,59 @@ struct symloc {
 /* Things we import explicitly from other modules */
 
 extern int          info_verbose;
-extern struct block *block_for_pc();
-extern void         sort_symtab_syms();
 
 /* Various complaints about symbol reading that don't abort the process */
-   
-struct complaint bad_file_number_complaint = 
+
+struct complaint bad_file_number_complaint =
        {"bad file number %d", 0, 0};
 
-struct complaint unknown_ext_complaint = 
+struct complaint index_complaint =
+       {"bad aux index at symbol %s", 0, 0};
+
+struct complaint aux_index_complaint =
+       {"bad proc end in aux found from symbol %s", 0, 0};
+
+struct complaint unknown_ext_complaint =
        {"unknown external symbol %s", 0, 0};
 
-struct complaint unknown_sym_complaint = 
+struct complaint unknown_sym_complaint =
        {"unknown local symbol %s", 0, 0};
 
-struct complaint unknown_st_complaint = 
+struct complaint unknown_st_complaint =
        {"with type %d", 0, 0};
 
-struct complaint block_overflow_complaint = 
+struct complaint block_overflow_complaint =
        {"block containing %s overfilled", 0, 0};
 
-struct complaint basic_type_complaint = 
+struct complaint basic_type_complaint =
        {"cannot map MIPS basic type 0x%x", 0, 0};
 
-struct complaint unknown_type_qual_complaint = 
+struct complaint unknown_type_qual_complaint =
        {"unknown type qualifier 0x%x", 0, 0};
 
-struct complaint array_bitsize_complaint = 
+struct complaint array_bitsize_complaint =
        {"size of array target type not known, assuming %d bits", 0, 0};
 
-struct complaint bad_tag_guess_complaint = 
-       {"guessed tag type incorrectly", 0, 0};
+struct complaint bad_tag_guess_complaint =
+       {"guessed tag type of %s incorrectly", 0, 0};
+
+struct complaint block_member_complaint =
+       {"declaration block contains unhandled symbol type %d", 0, 0};
+
+struct complaint stEnd_complaint =
+       {"stEnd with storage class %d not handled", 0, 0};
+
+struct complaint unknown_mips_symtype_complaint =
+       {"unknown symbol type 0x%x", 0, 0};
+
+struct complaint stab_unknown_complaint =
+       {"unknown stabs symbol %s", 0, 0};
+
+struct complaint pdr_for_nonsymbol_complaint =
+       {"PDR for %s, but no symbol", 0, 0};
+
+struct complaint pdr_static_symbol_complaint =
+       {"can't handle PDR for static proc at 0x%x", 0, 0};
 
 /* Macros and extra defs */
 
@@ -166,10 +189,6 @@ struct complaint bad_tag_guess_complaint =
 \f
 /* Things that really are local to this module */
 
-/* GDB symtable for the current compilation unit */
-
-static struct symtab *cur_stab;
-
 /* MIPS symtab header for the current file */
 
 static HDRR    *cur_hdr;
@@ -208,50 +227,89 @@ struct type *builtin_type_string;
 /* Forward declarations */
 
 static void
-fixup_symtab ();
+fixup_symtab PARAMS ((HDRR *, char *, int, bfd *));
+
+static void
+read_mips_symtab PARAMS ((struct objfile *));
 
 static void
-read_mips_symtab ();
+read_the_mips_symtab PARAMS ((bfd *, CORE_ADDR *));
 
 static int
-upgrade_type ();
+upgrade_type PARAMS ((struct type **, int, union aux_ext *, int));
+
+static void
+parse_partial_symbols PARAMS ((int, struct objfile *));
+
+static int
+cross_ref PARAMS ((union aux_ext *, struct type **, enum type_code, char **,
+                  int));
+
+static void
+fixup_sigtramp PARAMS ((void));
+
+static struct symbol *
+new_symbol PARAMS ((char *));
+
+static struct type *
+new_type PARAMS ((char *));
+
+static struct block *
+new_block PARAMS ((int));
+
+static struct symtab *
+new_symtab PARAMS ((char *, int, int, struct objfile *));
+
+static struct linetable *
+new_linetable PARAMS ((int));
+
+static struct blockvector *
+new_bvect PARAMS ((int));
+
+static struct type *
+parse_type PARAMS ((union aux_ext *, int *, int));
+
+static struct symbol *
+mylookup_symbol PARAMS ((char *, struct block *, enum namespace,
+                        enum address_class));
+
+static struct block *
+shrink_block PARAMS ((struct block *, struct symtab *));
+
+static PTR
+xzalloc PARAMS ((unsigned int));
 
 static void
-parse_partial_symbols();
+sort_blocks PARAMS ((struct symtab *));
 
 static int
-cross_ref();
+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
-fixup_sigtramp();
-
-static struct symbol   *new_symbol();
-static struct type     *new_type();
-static struct block    *new_block();
-static struct symtab   *new_symtab();
-static struct linetable        *new_linetable();
-static struct blockvector *new_bvect();
-
-static struct type     *parse_type();
-static struct symbol   *mylookup_symbol();
-static struct block    *shrink_block();
-static void sort_blocks();
-
-static int compare_symtabs();
-static int compare_psymtabs();
-static int compare_blocks();
-
-static struct partial_symtab *new_psymtab();
-static struct partial_symtab *parse_fdr();
-static int compare_psymbols();
-
-static void psymtab_to_symtab_1();
-static void add_block();
-static void add_symbol();
-static int  add_line();
-static struct linetable *shrink_linetable();
-static char* mips_next_symbol_text ();
+psymtab_to_symtab_1 PARAMS ((struct partial_symtab *, char *));
 
+static void
+add_block PARAMS ((struct block *, struct symtab *));
+
+static void
+add_symbol PARAMS ((struct symbol *, struct block *));
+
+static int
+add_line PARAMS ((struct linetable *, int, CORE_ADDR, int));
+
+static struct linetable *
+shrink_linetable PARAMS ((struct linetable *));
+
+static char *
+mips_next_symbol_text PARAMS ((void));
 \f
 /* Things we export to other modules */
 
@@ -260,63 +318,76 @@ static char* mips_next_symbol_text ();
 
 CORE_ADDR sigtramp_address, sigtramp_end;
 
-/* The entry point (starting address) of the file, if it is an executable.  */
-
-extern CORE_ADDR startup_file_start;   /* From blockframe.c */
-extern CORE_ADDR startup_file_end;     /* From blockframe.c */
-
-void
-mipscoff_new_init()
+static void
+mipscoff_new_init (ignore)
+     struct objfile *ignore;
 {
-  /* If we have a file symbol header lying around, blow it away.  */
-  if (cur_hdr)
-    free ((char *)cur_hdr);
-  cur_hdr = 0;
 }
 
-void
-mipscoff_symfile_init (sf)
-     struct sym_fns *sf;
+static void
+mipscoff_symfile_init (objfile)
+     struct objfile *objfile;
 {
-  sf->sym_private = NULL;
+  if (objfile -> sym_private != NULL)
+    {
+      mfree (objfile -> md, objfile -> sym_private);
+    }
+  objfile -> sym_private = NULL;
 }
 
-void
-mipscoff_symfile_read(sf, addr, mainline)
-     struct sym_fns *sf;
+static void
+mipscoff_symfile_read (objfile, addr, mainline)
+     struct objfile *objfile;
      CORE_ADDR addr;
      int mainline;
 {
-  bfd *abfd = sf->objfile->obfd;
-  int desc;
-
-/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
-   desc = fileno ((FILE *)(abfd->iostream));   /* Raw file descriptor */
-/* End of warning */
-
   init_minimal_symbol_collection ();
   make_cleanup (discard_minimal_symbols, 0);
 
   /* Now that the executable file is positioned at symbol table,
      process it and define symbols accordingly.  */
 
-  read_mips_symtab(sf->objfile, desc);
+  read_mips_symtab(objfile);
 
   /* Install any minimal symbols that have been collected as the current
      minimal symbols for this objfile. */
 
-  install_minimal_symbols (sf -> objfile);
+  install_minimal_symbols (objfile);
 }
-  
+
+/* Perform any local cleanups required when we are done with a particular
+   objfile.  I.E, we are in the process of discarding all symbol information
+   for an objfile, freeing up all memory held for it, and unlinking the
+   objfile struct from the global list of known objfiles. */
+
+static void
+mipscoff_symfile_finish (objfile)
+     struct objfile *objfile;
+{
+  if (objfile -> sym_private != NULL)
+    {
+      mfree (objfile -> md, objfile -> sym_private);
+    }
+
+  /* If we have a file symbol header lying around, blow it away.  */
+
+  if (cur_hdr)
+    {
+      free ((PTR)cur_hdr);
+    }
+  cur_hdr = 0;
+}
+
 /* Allocate zeroed memory */
 
-static char *
+static PTR
 xzalloc(size)
+     unsigned int size;
 {
-       char           *p = xmalloc(size);
+  PTR p = xmalloc (size);
 
-       memset(p, 0, size);
-       return p;
+  memset (p, 0, size);
+  return p;
 }
 
 /* Exported procedure: Builds a symtab from the PST partial one.
@@ -328,8 +399,6 @@ static void
 mipscoff_psymtab_to_symtab(pst)
        struct partial_symtab *pst;
 {
-       struct symtab  *ret;
-       int             i;
 
        if (!pst)
                return;
@@ -356,9 +425,9 @@ mipscoff_psymtab_to_symtab(pst)
 /* Exported procedure: Is PC in the signal trampoline code */
 
 int
-in_sigtramp(pc, name)
+in_sigtramp(pc, ignore)
        CORE_ADDR pc;
-       char *name;
+       char *ignore;           /* function name */
 {
        if (sigtramp_address == 0)
                fixup_sigtramp();
@@ -367,13 +436,12 @@ in_sigtramp(pc, name)
 \f
 /* File-level interface functions */
 
-/* Read the symtab information from file FSYM into memory.  Also,
+/* Read the symtab information from file ABFD into memory.  Also,
    return address just past end of our text segment in *END_OF_TEXT_SEGP.  */
 
-static
-read_the_mips_symtab(abfd, fsym, end_of_text_segp)
-       bfd             *abfd;
-       int             fsym;
+static void
+read_the_mips_symtab(abfd, end_of_text_segp)
+       bfd             *abfd;
        CORE_ADDR       *end_of_text_segp;
 {
        int             stsize, st_hdrsize;
@@ -382,10 +450,11 @@ read_the_mips_symtab(abfd, fsym, end_of_text_segp)
        HDRR            st_hdr;
        /* Header for executable/object file we read symbols from */
        struct coff_exec filhdr;
+       int val;
 
        /* We need some info from the initial headers */
-       lseek(fsym, 0L, 0);
-       myread(fsym, (char *)&filhdr, sizeof filhdr);
+       val = bfd_seek(abfd, 0L, L_SET);
+       val = bfd_read((PTR)&filhdr, sizeof filhdr, 1, abfd);
 
        if (end_of_text_segp)
                *end_of_text_segp =
@@ -396,14 +465,14 @@ read_the_mips_symtab(abfd, fsym, end_of_text_segp)
        st_hdrsize = bfd_h_get_32 (abfd, filhdr.f.f_nsyms);
        st_filptr  = bfd_h_get_32 (abfd, filhdr.f.f_symptr);
        if (st_filptr == 0)
-               return 0;
+               return;
 
-       lseek(fsym, st_filptr, L_SET);
+       bfd_seek (abfd, st_filptr, L_SET);
        if (st_hdrsize != sizeof (hdr_ext)) {   /* Profanity check */
                error ("Wrong header size: %d, not %d", st_hdrsize,
                        sizeof (hdr_ext));
        }
-       if (read(fsym, &hdr_ext, st_hdrsize) != st_hdrsize)
+       if (bfd_read((PTR)&hdr_ext, st_hdrsize, 1, abfd) != st_hdrsize)
                goto readerr;
        ecoff_swap_hdr_in (abfd, &hdr_ext, &st_hdr);
 
@@ -414,8 +483,8 @@ read_the_mips_symtab(abfd, fsym, end_of_text_segp)
        /* Allocate space for the symbol table.  Read it in.  */
        cur_hdr = (HDRR *) xmalloc(stsize + st_hdrsize);
 
-       memcpy(cur_hdr, &hdr_ext, st_hdrsize);
-       if (read(fsym, (char *) cur_hdr + st_hdrsize, stsize) != stsize)
+       memcpy((PTR)cur_hdr, (PTR)&hdr_ext, st_hdrsize);
+       if (bfd_read((char *)cur_hdr + st_hdrsize, stsize, 1, abfd) != stsize)
                goto readerr;
 
        /* Fixup file_pointers in it */
@@ -454,6 +523,7 @@ fixup_symtab (hdr, data, f_ptr, abfd)
        /* This function depends on the external and internal forms
           of the MIPS symbol table taking identical space.  Check this
           assumption at compile-time.  */
+#if 0  /* FIXME: Unused */
        static check_hdr1[1 + sizeof (struct hdr_ext) - sizeof (HDRR)] = {0};
        static check_hdr2[1 + sizeof (HDRR) - sizeof (struct hdr_ext)] = {0};
        static check_fdr1[1 + sizeof (struct fdr_ext) - sizeof (FDR)] = {0};
@@ -466,6 +536,7 @@ fixup_symtab (hdr, data, f_ptr, abfd)
        static check_ext2[1 + sizeof (EXTR) - sizeof (struct ext_ext)] = {0};
        static check_rfd1[1 + sizeof (struct rfd_ext) - sizeof (RFDT)] = {0};
        static check_rfd2[1 + sizeof (RFDT) - sizeof (struct rfd_ext)] = {0};
+#endif
 
        /* Swap in the header record.  */
        ecoff_swap_hdr_in (abfd, hdr, hdr);
@@ -626,17 +697,16 @@ fdr_name(name)
 
 
 /* Read in and parse the symtab of the file DESC. INCREMENTAL says
-   whether we are adding to the general symtab or not. 
+   whether we are adding to the general symtab or not.
    FIXME:  INCREMENTAL is currently always zero, though it should not be. */
 
 static void
-read_mips_symtab (objfile, desc)
+read_mips_symtab (objfile)
        struct objfile *objfile;
-       int desc;
 {
        CORE_ADDR end_of_text_seg;
 
-       read_the_mips_symtab(objfile->obfd, desc, &end_of_text_seg);
+       read_the_mips_symtab(objfile->obfd, &end_of_text_seg);
 
        parse_partial_symbols(end_of_text_seg, objfile);
 
@@ -688,7 +758,8 @@ static struct parse_stack {
 
 /* Enter a new lexical context */
 
-static push_parse_stack()
+static void
+push_parse_stack()
 {
        struct parse_stack *new;
 
@@ -711,7 +782,8 @@ static push_parse_stack()
 
 /* Exit a lexical context */
 
-static pop_parse_stack()
+static void
+pop_parse_stack()
 {
        if (!top_stack)
                return;
@@ -734,8 +806,8 @@ static struct mips_pending {
 
 /* Check whether we already saw symbol SH in file FH as undefined */
 
-static
-struct mips_pending *is_pending_symbol(fh, sh)
+static struct mips_pending *
+is_pending_symbol(fh, sh)
        FDR *fh;
        SYMR *sh;
 {
@@ -749,25 +821,9 @@ struct mips_pending *is_pending_symbol(fh, sh)
        return p;
 }
 
-/* Check whether we already saw type T in file FH as undefined */
-
-static
-struct mips_pending *is_pending_type(fh, t)
-       FDR *fh;
-       struct type *t;
-{
-       int             f_idx = fh - (FDR *) cur_hdr->cbFdOffset;
-       register struct mips_pending *p;
-
-       for (p = pending_list[f_idx]; p; p = p->next)
-               if (p->t == t)
-                       break;
-       return p;
-}
-
 /* Add a new undef symbol SH of type T */
 
-static
+static void
 add_pending(fh, sh, t)
        FDR *fh;
        SYMR *sh;
@@ -788,73 +844,29 @@ add_pending(fh, sh, t)
 }
 
 /* Throw away undef entries when done with file index F_IDX */
+/* FIXME -- storage leak.  This is never called!!!   --gnu */
+
+#if 0
 
-static
+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(p);
+               free((PTR)p);
        }
        pending_list[f_idx] = 0;
 }
 
-/* The number of args to a procedure is not explicit in the symtab,
-   this is the list of all those we know of.
-   This makes parsing more reasonable and avoids extra passes */
-
-static struct numarg {
-       struct numarg   *next;          /* link */
-       unsigned         adr;           /* procedure's start address */
-       unsigned         num;           /* arg count */
-} *numargs_list;
-
-/* Record that the procedure at ADR takes NUM arguments. */
-
-static
-got_numargs(adr,num)
-{
-       struct numarg  *n = (struct numarg *) xmalloc(sizeof(struct numarg));
-
-       n->adr = adr;
-       n->num = num;
-       n->next = numargs_list;
-       numargs_list = n;
-}
-
-/* See if we know how many arguments the procedure at ADR takes */
-
-static
-lookup_numargs(adr)
-{
-       struct numarg  *n = numargs_list;
-
-       while (n && n->adr != adr)
-               n = n->next;
-       return (n) ? n->num : -1;
-}
-
-/* Release storage when done with this file */
-
-static void
-free_numargs()
-{
-       struct numarg  *n = numargs_list, *m;
-
-       while (n) {
-               m = n->next;
-               free(n);
-               n = m;
-       }
-       numargs_list = 0;
-}
+#endif
 
-char*
+static char *
 prepend_tag_kind(tag_name, type_code)
      char *tag_name;
-     int type_code;
+     enum type_code type_code;
 {
     char *prefix;
     char *result;
@@ -915,14 +927,14 @@ parse_symbol(sh, ax, bigend)
                class = LOC_STATIC;
                b = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),
                                      GLOBAL_BLOCK);
-               s = new_symbol(sh->iss);
+               s = new_symbol((char *)sh->iss);
                SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
                goto data;
 
            case stStatic:      /* static data, goes into current block. */
                class = LOC_STATIC;
                b = top_stack->cur_block;
-               s = new_symbol(sh->iss);
+               s = new_symbol((char *)sh->iss);
                SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
                goto data;
 
@@ -934,7 +946,7 @@ parse_symbol(sh, ax, bigend)
                } else
                        class = LOC_LOCAL;
                b = top_stack->cur_block;
-               s = new_symbol(sh->iss);
+               s = new_symbol((char *)sh->iss);
                SYMBOL_VALUE(s) = sh->value;
 
 data:          /* Common code for symbols describing data */
@@ -958,7 +970,7 @@ data:               /* Common code for symbols describing data */
                name = (char*)sh->iss;
                /* Special GNU C++ name.  */
                if (name[0] == CPLUS_MARKER && name[1] == 't' && name[2] == 0)
-                   name = "this";
+                   name = "this";      /* FIXME, not alloc'd in obstack */
                s = new_symbol(name);
 
                SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
@@ -980,7 +992,7 @@ data:               /* Common code for symbols describing data */
                break;
 
            case stLabel:       /* label, goes into current block */
-               s = new_symbol(sh->iss);
+               s = new_symbol((char *)sh->iss);
                SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;    /* so that it can be used */
                SYMBOL_CLASS(s) = LOC_LABEL;            /* but not misused */
                SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;
@@ -990,7 +1002,7 @@ data:              /* Common code for symbols describing data */
 
            case stProc:        /* Procedure, usually goes into global block */
            case stStaticProc:  /* Static procedure, goes into current block */
-               s = new_symbol(sh->iss);
+               s = new_symbol((char *)sh->iss);
                SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
                SYMBOL_CLASS(s) = LOC_BLOCK;
                /* Type of the return value */
@@ -1012,8 +1024,8 @@ data:             /* Common code for symbols describing data */
                /* Make a type for the procedure itself */
 #if 0
                /* FIXME:  This has not been tested yet!  See dbxread.c */
-               /* Generate a template for the type of this function.  The 
-                  types of the arguments will be added as we read the symbol 
+               /* 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));
 #else
@@ -1043,164 +1055,182 @@ data:         /* Common code for symbols describing data */
                sh->value = (long) SYMBOL_TYPE(s);
                break;
 
+           /* Beginning of code for structure, union, and enum definitions.
+              They all share a common set of local variables, defined here.  */
+           {
+               enum type_code type_code;
+               SYMR *tsym;
+               int nfields;
+               long max_value;
+               struct field *f;
 
-#ifndef btVoid  /* btVoid was added late. */
-#define btVoid 26
-#endif                         
-/* These new symbol types have been recently added to SGI machines. */
-#ifndef stStruct
-#define stStruct 26
-#endif
-#ifndef stUnion
-#define stUnion 27
-#endif
-#ifndef stEnum
-#define stEnum 28
-#endif
-           case stStruct:
-           case stUnion:
-           case stEnum:
+           case stStruct:      /* Start a block defining a struct type */
+               type_code = TYPE_CODE_STRUCT;
+               goto structured_common;
+
+           case stUnion:       /* Start a block defining a union type */
+               type_code = TYPE_CODE_UNION;
+               goto structured_common;
+
+           case stEnum:        /* Start a block defining an enum type */
+               type_code = TYPE_CODE_ENUM;
+               goto structured_common;
 
            case stBlock:       /* Either a lexical block, or some type */
+               if (sh->sc != scInfo)
+                 goto case_stBlock_code;       /* Lexical block */
+
+               type_code = TYPE_CODE_UNDEF;    /* We have a type.  */
+
+           /* Common code for handling struct, union, enum, and/or as-yet-
+              unknown-type blocks of info about structured data.  `type_code'
+              has been set to the proper TYPE_CODE, if we know it.  */
+           structured_common:
                push_parse_stack();
                top_stack->blocktype = stBlock;
-               if (sh->sc == scInfo) { /* structure/union/enum def */
-                   int type_code =
-                       sh->st == stStruct ? TYPE_CODE_STRUCT
-                     : sh->st == stUnion ? TYPE_CODE_UNION
-                     : sh->st == stEnum ? TYPE_CODE_ENUM
-                     : TYPE_CODE_UNDEF;
-                   int nfields = 0;
-                   SYMR *tsym;
-                   long max_value = 0;
-                   struct field *f;
-
-                   s = new_symbol(sh->iss);
-                   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. */
-                   for (tsym = sh+1; tsym->st != stEnd; tsym++)
-                       if (tsym->st == stMember) {
-                           if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
-                               /* If the type of the member is Nil (or Void)
-                                  assume the tag is an enumeration. */
-                               if (tsym->index == indexNil)
+               s = new_symbol((char *)sh->iss);
+               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;
+               for (tsym = sh+1; tsym->st != stEnd; tsym++)
+                 {
+                   if (tsym->st == stMember) {
+                       if (nfields == 0 && type_code == TYPE_CODE_UNDEF)
+                           /* If the type of the member is Nil (or Void),
+                              assume the tag is an enumeration. */
+                           if (tsym->index == indexNil)
+                               type_code = TYPE_CODE_ENUM;
+                           else {
+                               ecoff_swap_tir_in (bigend,
+                                                  &ax[tsym->index].a_ti,
+                                                  &tir);
+                               if (tir.bt == btNil || tir.bt == btVoid)
                                    type_code = TYPE_CODE_ENUM;
-                               else {
-                                   ecoff_swap_tir_in (bigend,
-                                                      &ax[tsym->index].a_ti,
-                                                      &tir);
-                                   if (tir.bt == btNil || tir.bt == btVoid)
-                                       type_code = TYPE_CODE_ENUM;
-                               }
-                           nfields++;
-                           if (tsym->value > max_value)
-                               max_value = tsym->value;
-                       }
-                       else if (tsym->st == stBlock
-                                || tsym->st == stParsed) {
-                           if (tsym->sc == scVariant) ; /*UNIMPLEMENTED*/
-                           if (tsym->index != 0)
-                               tsym = ((SYMR*)cur_fdr->isymBase)
-                                   + tsym->index-1;
-                       }
-                   
-                   /* There is no guaranteed way to distinguish struct,
-                      unions, and enums at this point.  This is a bug in the
-                      original design (that has been fixed with the
-                      recent addition of the stStruct, stUnion, and stEnum
-                      symbol types.)  The way you can tell is if/when you
-                      see a variable or field of that type:  In that case
-                      the variable's type (in the AUX table) says if the
-                      type is struct, union, or enum,
-                      and points back to the stBlock here.
-                      So you can patch the tag kind up later - but only
-                      if there actually is a variable or field of that type.
-
-                      So until we know for sure, we will guess at this point.
-                      The heuristic is:
-                      If the first member has index==indexNil or a void type,
-                      assume we have an enumeration.
-                      Otherwise, if there is more than one member, and all
-                      the members have offset 0, assume we have a union.
-                      Otherwise, assume we have a struct.
-
-                      The heuristic could guess wrong in the case of
-                      of an enumeration with no members or a union
-                      with one (or zero) members, or when all except the
-                      last field of a struct have width zero.
-                      These are uncommon and/or illegal situations, and
-                      in any case guessing wrong probably doesn't matter much.
-
-                      But if we later do find out we were wrong,
-                      we fixup the tag kind.  Members of an enumeration
-                      must be handled differently from struct/union fields,
-                      and that is harder to patch up, but luckily we
-                      shouldn't need to.  (If there are any enumeration
-                      members, we can tell for sure it's an enum here.) */
-
-                   if (type_code == TYPE_CODE_UNDEF)
-                       if (nfields > 1 && max_value == 0)
-                         type_code = TYPE_CODE_UNION;
-                       else
-                         type_code = TYPE_CODE_STRUCT;
-                   
-                   /* If this type was expected, use its partial definition */
-                   if (pend)
-                       t = is_pending_symbol(cur_fdr, sh)->t;
+                           }
+                       nfields++;
+                       if (tsym->value > max_value)
+                           max_value = tsym->value;
+                   }
+                   else if (tsym->st == stBlock
+                            || tsym->st == stUnion
+                            || tsym->st == stEnum
+                            || tsym->st == stStruct
+                            || tsym->st == stParsed) {
+                       if (tsym->sc == scVariant) ; /*UNIMPLEMENTED*/
+                       if (tsym->index != 0)
+                           tsym = ((SYMR*)cur_fdr->isymBase)
+                               + tsym->index-1;
+                   }
+                   else complain (&block_member_complaint, (char *)tsym->st);
+                 }
+               
+               /* In an stBlock, there is no way to distinguish structs,
+                  unions, and enums at this point.  This is a bug in the
+                  original design (that has been fixed with the
+                  recent addition of the stStruct, stUnion, and stEnum
+                  symbol types.)  The way you can tell is if/when you
+                  see a variable or field of that type.  In that case
+                  the variable's type (in the AUX table) says if the
+                  type is struct, union, or enum,
+                  and points back to the stBlock here.
+                  So you can patch the tag kind up later - but only
+                  if there actually is a variable or field of that type.
+
+                  So until we know for sure, we will guess at this point.
+                  The heuristic is:
+                  If the first member has index==indexNil or a void type,
+                  assume we have an enumeration.
+                  Otherwise, if there is more than one member, and all
+                  the members have offset 0, assume we have a union.
+                  Otherwise, assume we have a struct.
+
+                  The heuristic could guess wrong in the case of
+                  of an enumeration with no members or a union
+                  with one (or zero) members, or when all except the
+                  last field of a struct have width zero.
+                  These are uncommon and/or illegal situations, and
+                  in any case guessing wrong probably doesn't matter much.
+
+                  But if we later do find out we were wrong,
+                  we fixup the tag kind.  Members of an enumeration
+                  must be handled differently from struct/union fields,
+                  and that is harder to patch up, but luckily we
+                  shouldn't need to.  (If there are any enumeration
+                  members, we can tell for sure it's an enum here.) */
+
+               if (type_code == TYPE_CODE_UNDEF)
+                   if (nfields > 1 && max_value == 0)
+                     type_code = TYPE_CODE_UNION;
                    else
-                       t = new_type(prepend_tag_kind(sh->iss, type_code));
-
-                   TYPE_CODE(t) = type_code;
-                   TYPE_LENGTH(t) = sh->value;
-                   TYPE_NFIELDS(t) = nfields;
-                   TYPE_FIELDS(t) = f = (struct field*)
-                     obstack_alloc (&current_objfile -> type_obstack,
-                                    nfields * sizeof (struct field));
-                   
-                   if (type_code == TYPE_CODE_ENUM) {
-                       /* This is a non-empty enum. */
-                       for (tsym = sh + 1; tsym->st == stMember; tsym++) {
-                           struct symbol *enum_sym;
-                           f->bitpos = tsym->value;
-                           f->type = t;
-                           f->name = (char*)tsym->iss;
-                           f->bitsize = 0;
-                           
-                           enum_sym = (struct symbol *)
-                               obstack_alloc (&current_objfile->symbol_obstack,
-                                              sizeof (struct symbol));
-                           memset (enum_sym, 0, sizeof (struct symbol));
-                           SYMBOL_NAME (enum_sym) = f->name;
-                           SYMBOL_CLASS (enum_sym) = LOC_CONST;
-                           SYMBOL_TYPE (enum_sym) = t;
-                           SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;
-                           SYMBOL_VALUE (enum_sym) = tsym->value;
-                           add_symbol(enum_sym, top_stack->cur_block);
-                           
-                           /* Skip the stMembers that we've handled. */
-                           count++;
-                           f++;
-                       }
+                     type_code = TYPE_CODE_STRUCT;
+               
+               /* If this type was expected, use its partial definition */
+               if (pend)
+                   t = is_pending_symbol(cur_fdr, sh)->t;
+               else
+                   t = new_type(prepend_tag_kind((char *)sh->iss,
+                                                 type_code));
+
+               TYPE_CODE(t) = type_code;
+               TYPE_LENGTH(t) = sh->value;
+               TYPE_NFIELDS(t) = nfields;
+               TYPE_FIELDS(t) = f = (struct field*)
+                 obstack_alloc (&current_objfile -> type_obstack,
+                                nfields * sizeof (struct field));
+               
+               if (type_code == TYPE_CODE_ENUM) {
+                   /* This is a non-empty enum. */
+                   for (tsym = sh + 1; tsym->st == stMember; tsym++) {
+                       struct symbol *enum_sym;
+                       f->bitpos = tsym->value;
+                       f->type = t;
+                       f->name = (char*)tsym->iss;
+                       f->bitsize = 0;
+                       
+                       enum_sym = (struct symbol *)
+                           obstack_alloc (&current_objfile->symbol_obstack,
+                                          sizeof (struct symbol));
+                       memset ((PTR)enum_sym, 0, sizeof (struct symbol));
+                       SYMBOL_NAME (enum_sym) = f->name;
+                       SYMBOL_CLASS (enum_sym) = LOC_CONST;
+                       SYMBOL_TYPE (enum_sym) = t;
+                       SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;
+                       SYMBOL_VALUE (enum_sym) = tsym->value;
+                       add_symbol(enum_sym, top_stack->cur_block);
+                       
+                       /* Skip the stMembers that we've handled. */
+                       count++;
+                       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;
-               } else {
-                       /* beginnning of (code) block. Value of symbol
-                          is the displacement from procedure start */
-                       b = new_block(top_stack->maxsyms);
-                       BLOCK_START(b) = sh->value + top_stack->procadr;
-                       BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
-                       top_stack->cur_block = b;
-                       add_block(b, top_stack->cur_st);
                }
+               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;
+               break;
+
+           /* End of local variables shared by struct, union, enum, and
+              block (as yet unknown struct/union/enum) processing.  */
+           }
+
+           case_stBlock_code:
+               /* beginnning of (code) block. Value of symbol
+                  is the displacement from procedure start */
+               push_parse_stack();
+               top_stack->blocktype = stBlock;
+               b = new_block(top_stack->maxsyms);
+               BLOCK_START(b) = sh->value + top_stack->procadr;
+               BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
+               top_stack->cur_block = b;
+               add_block(b, top_stack->cur_st);
                break;
 
            case stEnd:         /* end (of anything) */
@@ -1212,11 +1242,25 @@ data:           /* Common code for symbols describing data */
                            top_stack->blocktype == stStaticProc)) {
                    /* Finished with procedure */
                    struct blockvector *bv = BLOCKVECTOR(top_stack->cur_st);
+                   struct mips_extra_func_info *e;
                    struct block *b;
                    int i;
 
                    BLOCK_END(top_stack->cur_block) += sh->value; /* size */
-                   got_numargs(top_stack->procadr, top_stack->numargs);
+
+                   /* Make up special symbol to contain procedure specific
+                      info */
+                   s = new_symbol(".gdbinfo.");
+                   SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
+                   SYMBOL_CLASS(s) = LOC_CONST;
+                   SYMBOL_TYPE(s) = builtin_type_void;
+                   e = (struct mips_extra_func_info *)
+                     obstack_alloc (&current_objfile->symbol_obstack,
+                                    sizeof (struct mips_extra_func_info));
+                   SYMBOL_VALUE(s) = (int)e;
+                   e->numargs = top_stack->numargs;
+                   add_symbol(s, top_stack->cur_block);
+
                    /* Reallocate symbols, saving memory */
                    b = shrink_block(top_stack->cur_block, top_stack->cur_st);
 
@@ -1236,8 +1280,9 @@ data:             /* Common code for symbols describing data */
                           is the displacement from the procedure`s start
                           address of the end of this block. */
                        BLOCK_END(top_stack->cur_block) = sh->value + top_stack->procadr;
-                       (void) shrink_block(top_stack->cur_block, top_stack->cur_st);
-               }
+                       shrink_block(top_stack->cur_block, top_stack->cur_st);
+               } else complain (&stEnd_complaint, (char *)sh->sc);
+
                pop_parse_stack();      /* restore previous lexical context */
                break;
 
@@ -1250,7 +1295,7 @@ data:             /* Common code for symbols describing data */
                break;
 
            case stTypedef:     /* type definition */
-               s = new_symbol(sh->iss);
+               s = new_symbol((char *)sh->iss);
                SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
                SYMBOL_CLASS(s) = LOC_TYPEDEF;
                SYMBOL_BLOCK_VALUE(s) = top_stack->cur_block;
@@ -1272,7 +1317,8 @@ data:             /* Common code for symbols describing data */
            case stConstant:
                break;          /* constant */
            default:
-               error("Unknown symbol type %x.", sh->st);
+               complain(&unknown_mips_symtype_complaint, (char *)sh->st);
+               break;
        }
        sh->st = stParsed;
        return count;
@@ -1283,7 +1329,8 @@ data:             /* Common code for symbols describing data */
    We must byte-swap the AX entries before we use them; BIGEND says whether
    they are big-endian or little-endian (from fh->fBigendian).  */
 
-static struct type *parse_type(ax, bs, bigend)
+static struct type *
+parse_type(ax, bs, bigend)
        union aux_ext   *ax;
        int     *bs;
        int     bigend;
@@ -1318,20 +1365,21 @@ static struct type *parse_type(ax, bs, bigend)
                 0,                             /* btBit */
                 0,                             /* btPicture */
                 &builtin_type_void,            /* btVoid */
+                &builtin_type_long_long,       /* btLongLong */
+                &builtin_type_unsigned_long_long,/* btULongLong */
        };
 
        TIR            t[1];
        struct type    *tp = 0;
        char           *fmt;
-       int             i;
        union aux_ext *tax;
-       int type_code;
+       enum type_code type_code;
 
        /* 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))) {
-               complain (&basic_type_complaint, t->bt);
+               complain (&basic_type_complaint, (char *)t->bt);
                return builtin_type_int;
        }
        if (map_bt[t->bt]) {
@@ -1367,7 +1415,7 @@ static struct type *parse_type(ax, bs, bigend)
                        break;
                    case btTypedef:
                    default:
-                       complain (&basic_type_complaint, t->bt);
+                       complain (&basic_type_complaint, (char *)t->bt);
                        return builtin_type_int;
                }
        }
@@ -1406,14 +1454,15 @@ static struct type *parse_type(ax, bs, bigend)
                ax += cross_ref(ax, &tp, type_code, &pn, bigend);
                /* reading .o file ? */
                if (UNSAFE_DATA_ADDR(tp))
-                   tp = init_type(type_code, 0, 0, 0, (struct objfile *) NULL);
+                   tp = init_type(type_code, 0, 0, (char *) NULL,
+                                  (struct objfile *) NULL);
                /* SOMEONE OUGHT TO FIX DBXREAD TO DROP "STRUCT" */
                sprintf(name, fmt, pn);
 
                /* Usually, TYPE_CODE(tp) is already type_code.  The main
                   exception is if we guessed wrong re struct/union/enum. */
                if (TYPE_CODE(tp) != type_code) {
-                   complain (&bad_tag_guess_complaint, 0);
+                   complain (&bad_tag_guess_complaint, name);
                    TYPE_CODE(tp) = type_code;
                }
                if (TYPE_NAME(tp) == NULL || strcmp(TYPE_NAME(tp), name) != 0)
@@ -1423,8 +1472,6 @@ static struct type *parse_type(ax, bs, bigend)
 
        /* Deal with range types */
        if (t->bt == btRange) {
-               struct field   *f;
-
                TYPE_NFIELDS (tp) = 2;
                TYPE_FIELDS (tp) =
                  (struct field *) obstack_alloc (&current_objfile -> type_obstack,
@@ -1471,6 +1518,7 @@ again:    PARSE_TQ(tq0);
 static int
 upgrade_type(tpp, tq, ax, bigend)
        struct type  **tpp;
+       int            tq;
        union aux_ext *ax;
        int            bigend;
 {
@@ -1497,7 +1545,8 @@ upgrade_type(tpp, tq, ax, bigend)
 
        case tqArray:
                off = 0;
-               t = init_type(TYPE_CODE_ARRAY, 0, 0, 0, (struct objfile *) NULL);
+               t = init_type(TYPE_CODE_ARRAY, 0, 0, (char *) NULL,
+                             (struct objfile *) NULL);
                TYPE_TARGET_TYPE(t) = *tpp;
 
                /* Determine and record the domain type (type of index) */
@@ -1515,16 +1564,16 @@ upgrade_type(tpp, tq, ax, bigend)
                /* FIXME - Memory leak! */
                if (TYPE_NFIELDS(t))
                    TYPE_FIELDS(t) = (struct field*)
-                       xrealloc((char *) TYPE_FIELDS(t),
+                       xrealloc((PTR) TYPE_FIELDS(t),
                                 (TYPE_NFIELDS(t)+1) * sizeof(struct field));
                else
                    TYPE_FIELDS(t) = (struct field*)
                        xzalloc(sizeof(struct field));
                f = &(TYPE_FIELD(t,TYPE_NFIELDS(t)));
                TYPE_NFIELDS(t)++;
-               memset(f, 0, sizeof(struct field));
+               memset((PTR)f, 0, sizeof(struct field));
 
-/* XXX */      f->type = parse_type(fh->iauxBase + id * sizeof(union aux_ext),
+/* XXX */      f->type = parse_type(id + (union aux_ext *)fh->iauxBase,
                                     &f->bitsize, bigend);
 
                ax++;
@@ -1546,7 +1595,7 @@ upgrade_type(tpp, tq, ax, bigend)
                        TYPE_LENGTH(TYPE_TARGET_TYPE(t)) = id >> 3;
                }
                if (id != rf)
-                       complain (&array_bitsize_complaint, rf);
+                       complain (&array_bitsize_complaint, (char *)rf);
 
                TYPE_LENGTH(t) = (upper < 0) ? 0 :
                        (upper - lower + 1) * (rf >> 3);
@@ -1557,74 +1606,82 @@ upgrade_type(tpp, tq, ax, bigend)
                /* Volatile -- currently ignored */
                return 0;
 
+       case tqConst:
+               /* Const -- currently ignored */
+               return 0;
+
        default:
-               complain (&unknown_type_qual_complaint, tq);
+               complain (&unknown_type_qual_complaint, (char *)tq);
                return 0;
        }
 }
 
 
 /* Parse a procedure descriptor record PR.  Note that the procedure
-   is parsed _after_ the local symbols, now we just make up the
-   extra information we need into a special symbol that we insert
-   in the procedure's main block.  Note also that images that
+   is parsed _after_ the local symbols, now we just insert the extra
+   information we need into a special ".gdbinfo." symbol that has already
+   been placed in the procedure's main block.  Note also that images that
    have been partially stripped (ld -x) have been deprived
    of local symbols, and we have to cope with them here.
    The procedure's code ends at BOUND */
 
-static
-parse_procedure(pr, bound)
+static void
+parse_procedure (pr, bound, have_stabs)
        PDR *pr;
+       int bound;
+       int have_stabs;
 {
-       struct symbol *s, *i;
-       SYMR *sh = (SYMR*)pr->isym;
-       struct block *b;
-       struct mips_extra_func_info *e;
-       char name[100];
-       char *sh_name;
-
-       /* Reuse the MIPS record */
-       e = (struct mips_extra_func_info *) pr;
-       e->numargs = lookup_numargs(pr->adr);
-
-       /* Make up our special symbol */
-       i = new_symbol(".gdbinfo.");
-       SYMBOL_VALUE(i) = (int)e;
-       SYMBOL_NAMESPACE(i) = LABEL_NAMESPACE;
-       SYMBOL_CLASS(i) = LOC_CONST;
-       SYMBOL_TYPE(i) = builtin_type_void;
-
-       /* Make up a name for static procedures. Sigh. */
-       if (sh == (SYMR*)-1) {
-           sprintf(name,".static_procedure@%x",pr->adr);
-           sh_name = savestring(name, strlen(name));
-           s = NULL;
-       }
-       else {
-           sh_name = (char*)sh->iss;
-           s = mylookup_symbol(sh_name, top_stack->cur_block,
-                               VAR_NAMESPACE, LOC_BLOCK);
-       }
-       if (s != 0) {
-               b = SYMBOL_BLOCK_VALUE(s);
-       } else {
-               s = new_symbol(sh_name);
-               SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
-               SYMBOL_CLASS(s) = LOC_BLOCK;
-               /* Donno its type, hope int is ok */
-               SYMBOL_TYPE(s) = lookup_function_type (builtin_type_int);
-               add_symbol(s, top_stack->cur_block);
-               /* Wont have symbols for this one */
-               b = new_block(2);
-               SYMBOL_BLOCK_VALUE(s) = b;
-               BLOCK_FUNCTION(b) = s;
-               BLOCK_START(b) = pr->adr;
-               BLOCK_END(b) = bound;
-               BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
-               add_block(b, top_stack->cur_st);
-       }
-       e->isym = (long)s;
-       add_symbol(i,b);
+    struct symbol *s, *i;
+    SYMR *sh = (SYMR*)pr->isym;
+    struct block *b;
+    struct mips_extra_func_info *e;
+    char *sh_name;
+
+    /* Static procedure at address pr->adr.  Sigh. */
+    if (sh == (SYMR*)-1) {
+       complain (&pdr_static_symbol_complaint, (char *)pr->adr);
+       return;
+    }
+    sh_name = (char*)sh->iss;
+    if (have_stabs)
+       s = lookup_symbol(sh_name, NULL, VAR_NAMESPACE, 0, NULL);
+    else
+       s = mylookup_symbol(sh_name, top_stack->cur_block,
+                           VAR_NAMESPACE, LOC_BLOCK);
+
+    if (s != 0) {
+           b = SYMBOL_BLOCK_VALUE(s);
+    } else {
+           complain (&pdr_for_nonsymbol_complaint, sh_name);
+#if 1
+       return;
+#else    
+/* FIXME -- delete.  We can't do symbol allocation now; it's all done.  */
+           s = new_symbol(sh_name);
+           SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
+           SYMBOL_CLASS(s) = LOC_BLOCK;
+           /* Donno its type, hope int is ok */
+           SYMBOL_TYPE(s) = lookup_function_type (builtin_type_int);
+           add_symbol(s, top_stack->cur_block);
+           /* Wont have symbols for this one */
+           b = new_block(2);
+           SYMBOL_BLOCK_VALUE(s) = b;
+           BLOCK_FUNCTION(b) = s;
+           BLOCK_START(b) = pr->adr;
+           BLOCK_END(b) = bound;
+           BLOCK_SUPERBLOCK(b) = top_stack->cur_block;
+           add_block(b, top_stack->cur_st);
+#endif
+    }
+
+    i = mylookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, LOC_CONST);
+
+    if (i)
+      {
+       e = (struct mips_extra_func_info *)SYMBOL_VALUE(i);
+       e->pdr = *pr;
+       e->pdr.isym = (long)s;
+      }
 }
 
 /* Parse the external symbol ES. Just call parse_symbol() after
@@ -1636,7 +1693,7 @@ parse_procedure(pr, bound)
 
    This routine clobbers top_stack->cur_block and ->cur_st. */
 
-static
+static void
 parse_external(es, skip_procedures, bigend)
        EXTR *es;
        int skip_procedures;
@@ -1652,9 +1709,6 @@ parse_external(es, skip_procedures, bigend)
                cur_fdr = (FDR*)(cur_hdr->cbFdOffset);
                ax = 0;
        }
-       top_stack->cur_st = cur_stab;
-       top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),
-                                                GLOBAL_BLOCK);
 
        /* Reading .o files */
        if (es->asym.sc == scUndefined || es->asym.sc == scNil) {
@@ -1667,9 +1721,10 @@ parse_external(es, skip_procedures, bigend)
                default :       what = "symbol";                      break;
                }
                n_undef_symbols++;
+               /* FIXME:  Turn this into a complaint? */
                if (info_verbose)
-                       printf_filtered("Warning: %s `%s' is undefined (in %s)\n", what,
-                               es->asym.iss, fdr_name(cur_fdr->rss));
+                   printf_filtered("Warning: %s `%s' is undefined (in %s)\n",
+                        what, es->asym.iss, fdr_name((char *)cur_fdr->rss));
                return;
        }
 
@@ -1678,8 +1733,8 @@ parse_external(es, skip_procedures, bigend)
                /* If we have full symbols we do not need more */
                if (skip_procedures)
                        return;
-               if (mylookup_symbol (es->asym.iss, top_stack->cur_block,
-                                       VAR_NAMESPACE, LOC_BLOCK))
+               if (mylookup_symbol ((char *)es->asym.iss, top_stack->cur_block,
+                                    VAR_NAMESPACE, LOC_BLOCK))
                        break;
                /* fall through */
        case stGlobal:
@@ -1701,13 +1756,13 @@ parse_external(es, skip_procedures, bigend)
    numbers can go back and forth, apparently we can live
    with that and do not need to reorder our linetables */
 
-static
+static void
 parse_lines(fh, lt)
        FDR *fh;
        struct linetable *lt;
 {
        unsigned char *base = (unsigned char*)fh->cbLineOffset;
-       int i, j, k;
+       int j, k;
        int delta, count, lineno = 0;
        PDR *pr;
 
@@ -1715,7 +1770,7 @@ parse_lines(fh, lt)
                return;
 
        /* Scan by procedure descriptors */
-       i = 0; j = 0, k = 0;
+       j = 0, k = 0;
        for (pr = (PDR*)IPDFIRST(cur_hdr,fh); j < fh->cpd; j++, pr++) {
                int l, halt;
 
@@ -1760,7 +1815,6 @@ parse_lines(fh, lt)
                }
        }
 }
-
 \f
 /* Master parsing procedure for first-pass reading of file symbols
    into a partial_symtab.
@@ -1770,22 +1824,20 @@ parse_lines(fh, lt)
    the symtab we are reading.  */
 
 static void
-parse_partial_symbols(end_of_text_seg, objfile)
+parse_partial_symbols (end_of_text_seg, objfile)
      int end_of_text_seg;
      struct objfile *objfile;
 {
-    int             f_idx, s_idx;
-/*     int  stat_idx, h_max;*/
+    int                         f_idx, s_idx;
     HDRR               *hdr = cur_hdr;
     /* Running pointers */
-    FDR                *fh;
-    RFDT               *rh;
+    FDR                        *fh;
     register EXTR      *esh;
     register SYMR      *sh;
     struct partial_symtab *pst;
-    
+
     int past_first_source_file = 0;
-    
+
     /* List of current psymtab's include files */
     char **psymtab_include_list;
     int includes_allocated;
@@ -1796,36 +1848,36 @@ parse_partial_symbols(end_of_text_seg, objfile)
     struct partial_symtab **dependency_list;
     int dependencies_used, dependencies_allocated;
     struct cleanup *old_chain;
-    
+
     extern_tab = (EXTR**)obstack_alloc (&objfile->psymbol_obstack,
                                        sizeof(EXTR *) * hdr->iextMax);
-   
+
     includes_allocated = 30;
     includes_used = 0;
     psymtab_include_list = (char **) alloca (includes_allocated *
                                             sizeof (char *));
     next_symbol_text_func = mips_next_symbol_text;
-    
+
     dependencies_allocated = 30;
     dependencies_used = 0;
     dependency_list =
        (struct partial_symtab **) alloca (dependencies_allocated *
                                           sizeof (struct partial_symtab *));
-    
+
     last_source_file = 0;
 
     /*
-     * Big plan: 
+     * Big plan:
      *
      * Only parse the Local and External symbols, and the Relative FDR.
      * Fixup enough of the loader symtab to be able to use it.
      * Allocate space only for the file's portions we need to
      * look at. (XXX)
      */
-    
+
     max_gdbinfo = 0;
     max_glevel = MIN_GLEVEL;
-    
+
     /* Allocate the map FDR -> PST.
        Minor hack: -O3 images might claim some global data belongs
        to FDR -1. We`ll go along with that */
@@ -1837,13 +1889,13 @@ parse_partial_symbols(end_of_text_seg, objfile)
        fdr_to_pst[-1].pst = pst;
        FDR_IDX(pst) = -1;
     }
-    
+
     /* Pass 1 over external syms: Presize and partition the list */
     for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {
        esh = (EXTR *) (hdr->cbExtOffset) + s_idx;
        fdr_to_pst[esh->ifd].n_globals++;
     }
-    
+
     /* Pass 1.5 over files:  partition out global symbol space */
     s_idx = 0;
     for (f_idx = -1; f_idx < hdr->ifdMax; f_idx++) {
@@ -1852,101 +1904,100 @@ parse_partial_symbols(end_of_text_seg, objfile)
        fdr_to_pst[f_idx].n_globals = 0;
     }
 
-/* Pass 2 over external syms: fill in external symbols */
-       for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {
-               enum minimal_symbol_type ms_type = mst_text;
-               esh = (EXTR *) (hdr->cbExtOffset) + s_idx;
+    /* Pass 2 over external syms: fill in external symbols */
+    for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {
+       enum minimal_symbol_type ms_type = mst_text;
+       esh = (EXTR *) (hdr->cbExtOffset) + s_idx;
 
-               extern_tab[fdr_to_pst[esh->ifd].globals_offset
-                          + fdr_to_pst[esh->ifd].n_globals++] = esh;
+       extern_tab[fdr_to_pst[esh->ifd].globals_offset
+                  + fdr_to_pst[esh->ifd].n_globals++] = esh;
 
-               if (esh->asym.sc == scUndefined || esh->asym.sc == scNil)
-                       continue;
+       if (esh->asym.sc == scUndefined || esh->asym.sc == scNil)
+               continue;
 
-               switch (esh->asym.st) {
-               case stProc:
-                       break;
-               case stGlobal:
-                       ms_type = mst_data;
-                       break;
-               case stLabel:
-                       break;
-               default:
-                       ms_type = mst_unknown;
-                       complain (&unknown_ext_complaint,
-                                 (char *)(esh->asym.iss));
-               }
-               prim_record_minimal_symbol ((char *)(esh->asym.iss),
-                                           esh->asym.value,
-                                           ms_type);
+       switch (esh->asym.st) {
+       case stProc:
+               break;
+       case stGlobal:
+               ms_type = mst_data;
+               break;
+       case stLabel:
+               break;
+       default:
+               ms_type = mst_unknown;
+               complain (&unknown_ext_complaint, (char *)esh->asym.iss);
        }
+       prim_record_minimal_symbol ((char *)esh->asym.iss,
+                                   esh->asym.value,
+                                   ms_type);
+    }
 
-       /* Pass 3 over files, over local syms: fill in static symbols */
-       for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
-           struct partial_symtab *save_pst;
-           EXTR **ext_ptr;
-           cur_fdr = fh = f_idx + (FDR *)(cur_hdr->cbFdOffset);
+    /* Pass 3 over files, over local syms: fill in static symbols */
+    for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
+       struct partial_symtab *save_pst;
+       EXTR **ext_ptr;
+       cur_fdr = fh = f_idx + (FDR *)(cur_hdr->cbFdOffset);
 
-           if (fh->csym == 0) {
-               fdr_to_pst[f_idx].pst = NULL;
-               continue;
-           }
-           pst = start_psymtab_common (objfile, 0, (char*)fh->rss,
-                                       fh->cpd ? fh->adr : 0,
-                                       objfile->global_psymbols.next,
-                                       objfile->static_psymbols.next);
-           pst->read_symtab_private = (char *)
-               obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
-
-           save_pst = pst;
-           /* Make everything point to everything. */
-           FDR_IDX(pst) = f_idx;
-           fdr_to_pst[f_idx].pst = pst;
-           fh->ioptBase = (int)pst;
-           
-           CUR_HDR(pst) = cur_hdr;
-           
-           /* The way to turn this into a symtab is to call... */
-           pst->read_symtab = mipscoff_psymtab_to_symtab;
-           
-           pst->texthigh = pst->textlow;
-           
+       if (fh->csym == 0) {
+           fdr_to_pst[f_idx].pst = NULL;
+           continue;
+       }
+       pst = start_psymtab_common (objfile, 0, (char*)fh->rss,
+                                   fh->cpd ? fh->adr : 0,
+                                   objfile->global_psymbols.next,
+                                   objfile->static_psymbols.next);
+       pst->read_symtab_private = (char *)
+           obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+
+       save_pst = pst;
+       /* Make everything point to everything. */
+       FDR_IDX(pst) = f_idx;
+       fdr_to_pst[f_idx].pst = pst;
+       fh->ioptBase = (int)pst;
+       
+       CUR_HDR(pst) = cur_hdr;
+       
+       /* The way to turn this into a symtab is to call... */
+       pst->read_symtab = mipscoff_psymtab_to_symtab;
+       
+       pst->texthigh = pst->textlow;
+       
 #if 0      /* This is done in start_psymtab_common */
-           pst->globals_offset = global_psymbols.next - global_psymbols.list;
-           pst->statics_offset = static_psymbols.next - static_psymbols.list;
-           
-           pst->n_global_syms = 0;
-           pst->n_static_syms = 0;
+       pst->globals_offset = global_psymbols.next - global_psymbols.list;
+       pst->statics_offset = static_psymbols.next - static_psymbols.list;
+       
+       pst->n_global_syms = 0;
+       pst->n_static_syms = 0;
 #endif
-           
-           /* The second symbol must be @stab.
-              This symbol is emitted by mips-tfile to signal
-              that the current object file uses encapsulated stabs
-              instead of mips ecoff for local symbols.
-              (It is the second symbol because the first symbol is
-              the stFile used to signal the start of a file). */
-           if (fh->csym >= 2
-               && strcmp((char *)(((SYMR *)fh->isymBase)[1].iss),
-                         stabs_symbol) == 0) {
-               for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) {
-                   int type_code;
-                   char *namestring;
-                   sh = cur_sdx + (SYMR *) fh->isymBase;
-                   type_code = MIPS_UNMARK_STAB(sh->index);
-                   if (!MIPS_IS_STAB(sh)) {
-                       if (sh->st == stProc || sh->st == stStaticProc) {
-                           long procaddr = sh->value;
-                           sh = AUX_GET_ISYM (fh->fBigendian,
-                                  sh->index + (union aux_ext *)(fh->iauxBase))
-                               + (SYMR *) fh->isymBase - 1;
-                           if (sh->st == stEnd) {
-                               long high = procaddr + sh->value;
-                               if (high > pst->texthigh)
-                                   pst->texthigh = high;
-                           }
+       
+       /* The second symbol must be @stab.
+          This symbol is emitted by mips-tfile to signal
+          that the current object file uses encapsulated stabs
+          instead of mips ecoff for local symbols.
+          (It is the second symbol because the first symbol is
+          the stFile used to signal the start of a file). */
+       if (fh->csym >= 2
+           && strcmp((char *)(((SYMR *)fh->isymBase)[1].iss),
+                     stabs_symbol) == 0) {
+           for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) {
+               int type_code;
+               char *namestring;
+               sh = cur_sdx + (SYMR *) fh->isymBase;
+               type_code = MIPS_UNMARK_STAB(sh->index);
+               if (!MIPS_IS_STAB(sh)) {
+                   if (sh->st == stProc || sh->st == stStaticProc) {
+                       long procaddr = sh->value;
+                       sh = AUX_GET_ISYM (fh->fBigendian,
+                              sh->index + (union aux_ext *)(fh->iauxBase))
+                           + (SYMR *) fh->isymBase - 1;
+                       if (sh->st == stEnd) {
+                           long high = procaddr + sh->value;
+                           if (high > pst->texthigh)
+                               pst->texthigh = high;
                        }
-                       continue;
                    }
+                   continue;
+               }
 #define SET_NAMESTRING() namestring = (char*)sh->iss
 #define CUR_SYMBOL_TYPE type_code
 #define CUR_SYMBOL_VALUE sh->value
@@ -1958,133 +2009,163 @@ parse_partial_symbols(end_of_text_seg, objfile)
   if ((val) > save_pst->texthigh) save_pst->texthigh = (val);
 #include "partial-stab.h"
 #undef addr
-               }
            }
-           else {
-               register struct partial_symbol *psym;
-               for (cur_sdx = 0; cur_sdx < fh->csym; ) {
-                   char *name;
-                   int class;
-                   sh = cur_sdx + (SYMR *) fh->isymBase;
-                   
-                   if (MIPS_IS_STAB(sh)) {
-                       cur_sdx++;
-                       continue;
-                   }
+       }
+       else {
+           for (cur_sdx = 0; cur_sdx < fh->csym; ) {
+               char *name;
+               enum address_class class;
+               sh = cur_sdx + (SYMR *) fh->isymBase;
+               
+               if (MIPS_IS_STAB(sh)) {
+                   cur_sdx++;
+                   continue;
+               }
 
-                   if (sh->sc == scUndefined || sh->sc == scNil ||
-                       sh->index == 0xfffff) {
-                       /* FIXME, premature? */
-                       cur_sdx++;
+               if (sh->sc == scUndefined || sh->sc == scNil ||
+                   sh->index == 0xfffff) {
+                   /* FIXME, premature? */
+                   cur_sdx++;
+                   continue;
+               }
+               
+               name = (char *)(sh->iss);
+               
+               switch (sh->st) {
+                   long high;
+                   long procaddr;
+                   int new_sdx;
+
+                 case stProc:          /* Asm labels apparently */
+                 case stStaticProc:            /* Function */
+                   ADD_PSYMBOL_TO_LIST(name, strlen(name),
+                                       VAR_NAMESPACE, LOC_BLOCK,
+                                       objfile->static_psymbols, sh->value);
+                   /* Skip over procedure to next one. */
+                   if (sh->index >= hdr->iauxMax)
+                     {
+                       /* Should not happen, but does when cross-compiling
+                          with the MIPS compiler.  FIXME -- pull later.  */
+                       complain (&index_complaint, name);
+                       new_sdx = cur_sdx+1;    /* Don't skip at all */
+                     }
+                   else
+                     new_sdx = AUX_GET_ISYM (fh->fBigendian,
+                               sh->index + (union aux_ext *)fh->iauxBase);
+                   procaddr = sh->value;
+
+                   if (new_sdx <= cur_sdx)
+                     {
+                       /* This should not happen either... FIXME.  */
+                       complain (&aux_index_complaint, name);
+                       new_sdx = cur_sdx + 1;  /* Don't skip backward */
+                     }
+
+                   cur_sdx = new_sdx;
+                   sh = cur_sdx + (SYMR *) fh->isymBase - 1;
+                   if (sh->st != stEnd)
                        continue;
-                   }
-                   
-                   name = (char *)(sh->iss);
-                   
-                   switch (sh->st) {
-                       long high;
-                       long procaddr;
-                     case stProc:              /* Asm labels apparently */
-                     case stStaticProc:                /* Function */
+                   high = procaddr + sh->value;
+                   if (high > pst->texthigh)
+                       pst->texthigh = high;
+                   continue;
+
+                 case stStatic:                        /* Variable */
+                   class = LOC_STATIC;
+                   break;
+
+                 case stTypedef:                       /* Typedef */
+                   class = LOC_TYPEDEF;
+                   break;
+
+                 case stConstant:              /* Constant decl */
+                   class = LOC_CONST;
+                   break;
+
+                 case stUnion:
+                 case stStruct:
+                 case stEnum:
+                 case stBlock:                 /* { }, str, un, enum*/
+                   if (sh->sc == scInfo) {
                        ADD_PSYMBOL_TO_LIST(name, strlen(name),
-                                           VAR_NAMESPACE, LOC_BLOCK,
+                                           STRUCT_NAMESPACE, LOC_TYPEDEF,
                                            objfile->static_psymbols, sh->value);
-                       /* Skip over procedure to next one. */
-                       cur_sdx = AUX_GET_ISYM (fh->fBigendian,
-                                 sh->index + (union aux_ext *)fh->iauxBase);
-                       procaddr = sh->value;
-                       
-                       sh = cur_sdx + (SYMR *) fh->isymBase - 1;
-                       if (sh->st != stEnd)
-                           continue;
-                       high = procaddr + sh->value;
-                       if (high > pst->texthigh)
-                           pst->texthigh = high;
-                       continue;
-                     case stStatic:                    /* Variable */
-                       class = LOC_STATIC;
-                       break;
-                     case stTypedef:                   /* Typedef */
-                       class = LOC_TYPEDEF;
-                       break;
-                     case stConstant:          /* Constant decl */
-                       class = LOC_CONST;
-                       break;
-                     case stBlock:                     /* { }, str, un, enum*/
-                       if (sh->sc == scInfo) {
-                           ADD_PSYMBOL_TO_LIST(name, strlen(name),
-                                               STRUCT_NAMESPACE, LOC_TYPEDEF,
-                                               objfile->static_psymbols, sh->value);
-                       }
-                       /* Skip over the block */
-                       cur_sdx = sh->index;
-                       continue;
-                     case stFile:                      /* File headers */
-                     case stLabel:                     /* Labels */
-                     case stEnd:                       /* Ends of files */
-                       goto skip;
-                     default:
-                       /* Both complaints are valid:  one gives symbol name,
-                          the other the offending symbol type.  */
-                       complain (&unknown_sym_complaint, (char *)sh->iss);
-                       complain (&unknown_st_complaint, sh->st);
-                       cur_sdx++;
-                       continue;
-                   }
-                   /* Use this gdb symbol */
-                   ADD_PSYMBOL_TO_LIST(name, strlen(name),
-                                       VAR_NAMESPACE, class,
-                                       objfile->static_psymbols, sh->value);
-                 skip:
-                   cur_sdx++;          /* Go to next file symbol */
-               }
-
-               /* Now do enter the external symbols. */
-               ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
-               cur_sdx = fdr_to_pst[f_idx].n_globals;
-               PST_PRIVATE(save_pst)->extern_count = cur_sdx;
-               PST_PRIVATE(save_pst)->extern_tab = ext_ptr;
-               for (; --cur_sdx >= 0; ext_ptr++) {
-                   enum address_class class;
-                   if ((*ext_ptr)->ifd != f_idx)
-                       abort();
-                   sh = &(*ext_ptr)->asym;
-                   switch (sh->st) {
-                     case stProc:
-                       class = LOC_BLOCK;
-                       break;
-                     case stLabel:
-                       class = LOC_LABEL;
-                       break;
-                     default:
-                       complain (&unknown_ext_complaint, sh->iss);
-                     case stGlobal:
-                       class = LOC_STATIC;
-                       break;
                    }
-                   if (objfile->global_psymbols.next >=
-                       objfile->global_psymbols.list + objfile->global_psymbols.size)
-                       extend_psymbol_list (&objfile->global_psymbols, objfile);
-                   psym = objfile->global_psymbols.next++;
-                   SYMBOL_NAME (psym) = (char*)sh->iss;
-                   SYMBOL_NAMESPACE (psym) = VAR_NAMESPACE;
-                   SYMBOL_CLASS (psym) = class;
-                   SYMBOL_VALUE_ADDRESS (psym) = (CORE_ADDR)sh->value;
+                   /* Skip over the block */
+                   cur_sdx = sh->index;
+                   continue;
+
+                 case stFile:                  /* File headers */
+                 case stLabel:                 /* Labels */
+                 case stEnd:                   /* Ends of files */
+                   goto skip;
+
+                 default:
+                   /* Both complaints are valid:  one gives symbol name,
+                      the other the offending symbol type.  */
+                   complain (&unknown_sym_complaint, (char *)sh->iss);
+                   complain (&unknown_st_complaint, (char *)sh->st);
+                   cur_sdx++;
+                   continue;
                }
+               /* Use this gdb symbol */
+               ADD_PSYMBOL_TO_LIST(name, strlen(name),
+                                   VAR_NAMESPACE, class,
+                                   objfile->static_psymbols, sh->value);
+             skip:
+               cur_sdx++;              /* Go to next file symbol */
            }
 
-           end_psymtab (save_pst, psymtab_include_list, includes_used,
-                        -1, save_pst->texthigh,
-                        dependency_list, dependencies_used);
-           if (entry_point < save_pst->texthigh
-               && entry_point >= save_pst->textlow) {
-               startup_file_start = save_pst->textlow;
-               startup_file_end = save_pst->texthigh;
+           /* Now do enter the external symbols. */
+           ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
+           cur_sdx = fdr_to_pst[f_idx].n_globals;
+           PST_PRIVATE(save_pst)->extern_count = cur_sdx;
+           PST_PRIVATE(save_pst)->extern_tab = ext_ptr;
+           for (; --cur_sdx >= 0; ext_ptr++) {
+               register struct partial_symbol *psym;
+               enum address_class class;
+
+               if ((*ext_ptr)->ifd != f_idx)
+                   abort();
+               sh = &(*ext_ptr)->asym;
+               switch (sh->st) {
+                 case stProc:
+                   class = LOC_BLOCK;
+                   break;
+                 case stLabel:
+                   class = LOC_LABEL;
+                   break;
+                 default:
+                   complain (&unknown_ext_complaint, (char *)sh->iss);
+                   /* Fall through, pretend it's global.  */
+                 case stGlobal:
+                   class = LOC_STATIC;
+                   break;
+               }
+               if (objfile->global_psymbols.next >=
+                   objfile->global_psymbols.list + objfile->global_psymbols.size)
+                   extend_psymbol_list (&objfile->global_psymbols, objfile);
+               psym = objfile->global_psymbols.next++;
+               SYMBOL_NAME (psym) = (char*)sh->iss;
+               SYMBOL_NAMESPACE (psym) = VAR_NAMESPACE;
+               SYMBOL_CLASS (psym) = class;
+               SYMBOL_VALUE_ADDRESS (psym) = (CORE_ADDR)sh->value;
            }
        }
 
-       /* Mark the last code address, and remember it for later */
-       hdr->cbDnOffset = end_of_text_seg;
+       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)
+         {
+           objfile -> ei.entry_file_lowpc = save_pst->textlow;
+           objfile -> ei.entry_file_highpc = save_pst->texthigh;
+         }
+    }
+
+    /* Mark the last code address, and remember it for later */
+    hdr->cbDnOffset = end_of_text_seg;
 
     /* Now scan the FDRs for dependencies */
     for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {
@@ -2114,7 +2195,7 @@ parse_partial_symbols(end_of_text_seg, objfile)
        for (s_idx = s_id0; s_idx < fh->crfd; s_idx++) {
            RFDT *rh = (RFDT *) (fh->rfdBase) + s_idx;
            if (*rh < 0 || *rh >= hdr->ifdMax)
-               complain(&bad_file_number_complaint, *rh);
+               complain(&bad_file_number_complaint, (char *)*rh);
            else
                pst->dependencies[s_idx-s_id0] = fdr_to_pst[*rh].pst;
        }
@@ -2205,61 +2286,31 @@ mips_next_symbol_text ()
    for turning the partial symtab PST into a symtab, recurring
    first on all dependent psymtabs.  The argument FILENAME is
    only passed so we can see in debug stack traces what file
-   is being read. */
+   is being read.
+
+   This function has a split personality, based on whether the
+   symbol table contains ordinary ecoff symbols, or stabs-in-ecoff.
+   The flow of control and even the memory allocation differs.  FIXME.  */
 
 static void
 psymtab_to_symtab_1(pst, filename)
      struct partial_symtab *pst;
      char *filename;
 {
-    int have_stabs;
-    int             i, f_max;
+    int i;
     struct symtab  *st;
     FDR *fh;
-    int maxlines;
     struct linetable *lines;
+    int bound;
 
     if (pst->readin)
        return;
     pst->readin = 1;
-    
-    /* How many symbols will we need */
-    /* FIXME, this does not count enum values. */
-    f_max = pst->n_global_syms + pst->n_static_syms;
-    if (FDR_IDX(pst) == -1) {
-       fh = 0;
-       maxlines = 0;
-    } else {
-       fh = (FDR *) (cur_hdr->cbFdOffset) + FDR_IDX(pst);
-       f_max += fh->csym + fh->cpd;
-       maxlines = 2 * fh->cline;
-    }
 
-    /* See comment in parse_partial_symbols about the @stabs sentinel. */
-    have_stabs =
-       fh && fh->csym >= 2
-           && strcmp((char *)(((SYMR *)fh->isymBase)[1].iss), stabs_symbol)
-               == 0;
-
-    if (!have_stabs) {
-       if (fh)
-           st = new_symtab (pst->filename, 2 * f_max, maxlines,
-                            pst->objfile);
-       else
-           st = new_symtab ("unknown", f_max, 0, pst->objfile);
-       lines = LINETABLE(st);
-       pending_list = (struct mips_pending **) cur_hdr->cbOptOffset;
-       if (pending_list == 0) {
-           pending_list = (struct mips_pending **)
-               xzalloc(cur_hdr->ifdMax * sizeof(struct mips_pending *));
-           cur_hdr->cbOptOffset = (int)pending_list;
-       }
-    }
-    
     /* Read in all partial symbtabs on which this one is dependent.
        NOTE that we do have circular dependencies, sigh.  We solved
        that by setting pst->readin before this point.  */
-    
+
     for (i = 0; i < pst->number_of_dependencies; i++)
        if (!pst->dependencies[i]->readin) {
            /* Inform about additional files to be read in.  */
@@ -2275,23 +2326,120 @@ psymtab_to_symtab_1(pst, filename)
                    fflush (stdout);
                }
            /* We only pass the filename for debug purposes */
-           psymtab_to_symtab_1(pst->dependencies[i], 
+           psymtab_to_symtab_1(pst->dependencies[i],
                                pst->dependencies[i]->filename);
        }
-    
-    cur_fdr = fh;
+
     /* Now read the symbols for this symtab */
-    
-    current_objfile = pst -> objfile;
-    if (!have_stabs) {
-       cur_fd = FDR_IDX(pst);
-       cur_stab = st;
+
+    current_objfile = pst->objfile;
+    cur_fd = FDR_IDX(pst);
+    fh = (cur_fd == -1) ? 0 : (FDR *) (cur_hdr->cbFdOffset) + FDR_IDX(pst);
+    cur_fdr = fh;
+
+    /* BOUND is the highest core address of this file's procedures */
+    bound = (cur_fd == cur_hdr->ifdMax - 1) ?
+                   cur_hdr->cbDnOffset :
+                   fh[1].adr;
+
+    /* See comment in parse_partial_symbols about the @stabs sentinel. */
+    if (fh && fh->csym >= 2
+           && strcmp((char *)(((SYMR *)fh->isymBase)[1].iss), stabs_symbol)
+               == 0) {
+
+       /*
+        * This symbol table contains stabs-in-ecoff entries.
+        */
+
+       PDR *pr;
        
+       /* Parse local symbols first */
+
+       if (fh->csym <= 2)      /* FIXME, this blows psymtab->symtab ptr */
+         {
+           current_objfile = NULL;
+           return;
+         }
+       for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) {
+           register SYMR       *sh = cur_sdx + (SYMR *) fh->isymBase;
+           char *name = (char*)sh->iss;
+           CORE_ADDR valu = sh->value;
+           if (MIPS_IS_STAB(sh)) {
+               int type_code = MIPS_UNMARK_STAB(sh->index);
+               process_one_symbol (type_code, 0, valu, name, /*FIXME*/ 0,
+                                   pst->objfile);
+               if (type_code == N_FUN) {
+                   /* Make up special symbol to contain
+                      procedure specific info */
+                   struct mips_extra_func_info *e =
+                     (struct mips_extra_func_info *)
+                       obstack_alloc(&current_objfile->symbol_obstack,
+                                     sizeof(struct mips_extra_func_info));
+                   struct symbol *s = new_symbol(".gdbinfo.");
+                   SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
+                   SYMBOL_CLASS(s) = LOC_CONST;
+                   SYMBOL_TYPE(s) = builtin_type_void;
+                   SYMBOL_VALUE(s) = (int)e;
+                   add_symbol_to_list (s, &local_symbols);
+               }
+           }
+           else if (sh->st == stLabel && sh->index != indexNil) {
+               /* Handle encoded stab line number. */
+               record_line (current_subfile, sh->index, valu);
+           }
+           else complain (&stab_unknown_complaint, (char *)sh->iss);
+       }
+       st = end_symtab (pst->texthigh, 0, 0, pst->objfile);
+
+       /* Sort the symbol table now, we are done adding symbols to it.
+          We must do this before parse_procedure calls lookup_symbol.  */
+       sort_symtab_syms(st);
+
+       /* This may not be necessary for stabs symtabs.  FIXME.  */
+       sort_blocks (st);
+
+       /* Fill in procedure info next.  We need to look-ahead to
+          find out where each procedure's code ends.  */
+
+       for (i = 0; i <= fh->cpd-1; i++) {
+           pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + i;
+           parse_procedure (pr, i < fh->cpd-1 ? pr[1].adr : bound, 1);
+       }
+    } else {
+
+       /*
+        * This symbol table contains ordinary ecoff entries.
+        */
+
+       int f_max;
+       int maxlines;
+       EXTR **ext_ptr;
+
+       /* How many symbols will we need */
+       /* FIXME, this does not count enum values. */
+       f_max = pst->n_global_syms + pst->n_static_syms;
+       if (fh == 0) {
+           maxlines = 0;
+           st = new_symtab ("unknown", f_max, 0, pst->objfile);
+       } else {
+           f_max += fh->csym + fh->cpd;
+           maxlines = 2 * fh->cline;
+           st = new_symtab (pst->filename, 2 * f_max, maxlines, pst->objfile);
+       }
+
+       lines = LINETABLE(st);
+       pending_list = (struct mips_pending **) cur_hdr->cbOptOffset;
+       if (pending_list == 0) {
+           pending_list = (struct mips_pending **)
+               xzalloc(cur_hdr->ifdMax * sizeof(struct mips_pending *));
+           cur_hdr->cbOptOffset = (int)pending_list;
+       }
+
        /* Get a new lexical context */
        
        push_parse_stack();
-       top_stack->cur_st = cur_stab;
-       top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(cur_stab),
+       top_stack->cur_st = st;
+       top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(st),
                                                 STATIC_BLOCK);
        BLOCK_START(top_stack->cur_block) = fh ? fh->adr : 0;
        BLOCK_END(top_stack->cur_block) = 0;
@@ -2300,75 +2448,42 @@ psymtab_to_symtab_1(pst, filename)
        top_stack->cur_type = 0;
        top_stack->procadr = 0;
        top_stack->numargs = 0;
-    }
-    
-    /* Parse locals and procedures */
-    if (fh) {
-       SYMR *sh;
-       PDR *pr;
-       int f_idx = cur_fd;
-       char *fh_name = (char*)fh->rss;
-       
-       /* Parse local symbols first */
-       
-       
-       if (have_stabs) {
-           if (fh->csym <= 2)
-             {
-               current_objfile = NULL;
-               return;
-             }
-           for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) {
-               register SYMR   *sh = cur_sdx + (SYMR *) fh->isymBase;
-               char *name = (char*)sh->iss;
-               CORE_ADDR valu = sh->value;
-               if (MIPS_IS_STAB(sh)) {
-                   int type_code = MIPS_UNMARK_STAB(sh->index);
-                   process_one_symbol (type_code, 0, valu, name, /*FIXME*/ 0);
-               }
-               else if (sh->st == stLabel && sh->index != indexNil) {
-                   /* Handle encoded stab line number. */
-                   record_line (current_subfile, sh->index, valu);
-               }
-           }
-           st = end_symtab (pst->texthigh, 0, 0, pst->objfile);
-       }
-       else {
-           /* BOUND is the highest core address of this file's procedures */
-           int bound =  cur_fd == cur_hdr->ifdMax - 1 ? cur_hdr->cbDnOffset
-               : fh[1].adr;
+
+       if (fh) {
+           SYMR *sh;
+           PDR *pr;
+
+           /* Parse local symbols first */
+
            for (cur_sdx = 0; cur_sdx < fh->csym; ) {
                sh = (SYMR *) (fh->isymBase) + cur_sdx;
-               cur_sdx += parse_symbol(sh, fh->iauxBase, fh->fBigendian);
+               cur_sdx += parse_symbol(sh, (union aux_ent *)fh->iauxBase,
+                                       fh->fBigendian);
            }
 
-           /* Procedures next, note we need to look-ahead to
-              find out where the procedure's code ends */
+           /* Linenumbers.  At the end, check if we can save memory */
 
-           if (fh->cpd > 0)
-             for (i = 0; i < fh->cpd-1; i++) {
-               pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + i;
-               parse_procedure(pr, pr[1].adr); /* next proc up */
-             }
-           if (fh->cpd) {
-               pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + i;
-               parse_procedure(pr, bound);     /* next file up */
-           }
-           /* Linenumbers. At the end, check if we can save memory */
            parse_lines(fh, lines);
            if (lines->nitems < fh->cline)
                lines = shrink_linetable(lines);
+
+           /* Fill in procedure info next.  We need to look-ahead to
+              find out where each procedure's code ends.  */
+
+           for (i = 0; i <= fh->cpd-1; i++) {
+               pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + i;
+               parse_procedure(pr, i < fh->cpd-1 ? pr[1].adr : bound, 0);
+           }
        }
 
-    }
-    if (!have_stabs) {
-       EXTR **ext_ptr;
        LINETABLE(st) = lines;
-    
+
        /* .. and our share of externals.
-          XXX use the global list to speed up things here. how ? 
+          XXX use the global list to speed up things here. how?
           FIXME, Maybe quit once we have found the right number of ext's? */
-       /* parse_external clobbers top_stack->cur_block and ->cur_st here. */
+       top_stack->cur_st = st;
+       top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),
+                                                GLOBAL_BLOCK);
        top_stack->blocktype = stFile;
        top_stack->maxsyms =
            cur_hdr->isymMax + cur_hdr->ipdMax + cur_hdr->iextMax;
@@ -2376,7 +2491,7 @@ psymtab_to_symtab_1(pst, filename)
        ext_ptr = PST_PRIVATE(pst)->extern_tab;
        for (i = PST_PRIVATE(pst)->extern_count; --i >= 0; ext_ptr++)
            parse_external(*ext_ptr, 1, fh->fBigendian);
-    
+
        /* If there are undefined, tell the user */
        if (n_undef_symbols) {
            printf_filtered("File %s contains %d unresolved references:",
@@ -2387,13 +2502,13 @@ psymtab_to_symtab_1(pst, filename)
 
        }
        pop_parse_stack();
+
+       /* Sort the symbol table now, we are done adding symbols to it.*/
+       sort_symtab_syms(st);
+
+       sort_blocks (st);
     }
-    
-    /* Sort the symbol table now, we are done adding symbols to it.*/
-    sort_symtab_syms(st);
 
-    sort_blocks (st);
-    
     /* Now link the psymtab and the symtab.  */
     pst->symtab = st;
 
@@ -2411,7 +2526,7 @@ static int
 cross_ref(ax, tpp, type_code, pname, bigend)
      union aux_ext *ax;
      struct type **tpp;
-     int type_code; /* Use to alloc new type if none is found. */
+     enum type_code type_code; /* Use to alloc new type if none is found. */
      char **pname;
      int bigend;
 {
@@ -2434,7 +2549,7 @@ cross_ref(ax, tpp, type_code, pname, bigend)
                *pname = "<undefined>";
        } else {
                /*
-                * Find the relative file descriptor and the symbol in it 
+                * Find the relative file descriptor and the symbol in it
                 */
                FDR            *fh = get_rfd(cur_fd, rf);
                SYMR           *sh;
@@ -2446,7 +2561,7 @@ cross_ref(ax, tpp, type_code, pname, bigend)
                 * it in a list of pending symbols, to be processed later when
                 * the file f will be.  In any event, we collect the name for
                 * the type here. Which is why we made a first pass at
-                * strings. 
+                * strings.
                 */
                sh = (SYMR *) (fh->isymBase) + rn->index;
 
@@ -2464,7 +2579,8 @@ cross_ref(ax, tpp, type_code, pname, bigend)
                    if (p)
                        *tpp = p->t;
                    else {
-                       *tpp = init_type(type_code, 0, 0, 0, (struct objfile *) NULL);
+                       *tpp = init_type(type_code, 0, 0, (char *) NULL,
+                                        (struct objfile *) NULL);
                        add_pending(fh, sh, *tpp);
                    }
                }
@@ -2500,7 +2616,8 @@ mylookup_symbol (name, block, namespace, class)
                        return sym;
                bot++;
        }
-       if (block = BLOCK_SUPERBLOCK (block))
+       block = BLOCK_SUPERBLOCK (block);
+       if (block)
                return mylookup_symbol (name, block, namespace, class);
        return 0;
 }
@@ -2550,7 +2667,7 @@ add_block(b,s)
 {
        struct blockvector *bv = BLOCKVECTOR(s);
 
-       bv = (struct blockvector *)xrealloc((char *) bv,
+       bv = (struct blockvector *)xrealloc((PTR) bv,
                                            sizeof(struct blockvector) +
                                                 BLOCKVECTOR_NBLOCKS(bv)
                                                 * sizeof(bv->block));
@@ -2581,52 +2698,18 @@ add_line(lt, lineno, adr, last)
        lt->item[lt->nitems++].pc = adr << 2;
        return lineno;
 }
-
-
 \f
-/* Comparison functions, used when sorting things */
-
-/*  Symtabs must be ordered viz the code segments they cover */
-
-static int
-compare_symtabs( s1, s2)
-       struct symtab **s1, **s2;
-{
-       /* "most specific" first */
-
-       register struct block *b1, *b2;
-       b1 = BLOCKVECTOR_BLOCK(BLOCKVECTOR(*s1),GLOBAL_BLOCK);
-       b2 = BLOCKVECTOR_BLOCK(BLOCKVECTOR(*s2),GLOBAL_BLOCK);
-       if (BLOCK_END(b1) == BLOCK_END(b2))
-               return BLOCK_START(b1) - BLOCK_START(b2);
-       return BLOCK_END(b1) - BLOCK_END(b2);
-}
-
-
-/*  Partial Symtabs, same */
-
-static int
-compare_psymtabs( s1, s2)
-       struct partial_symtab **s1, **s2;
-{
-       /* Perf twist: put the ones with no code at the end */
-
-       register int a = (*s1)->textlow;
-       register int b = (*s2)->textlow;
-       if (a == 0)
-               return b;
-       if (b == 0)
-               return -a;
-       return a - b;
-}
-
+/* Sorting and reordering procedures */
 
 /* Blocks with a smaller low bound should come first */
 
-static int compare_blocks(b1,b2)
-       struct block **b1, **b2;
+static int
+compare_blocks(arg1, arg2)
+     const void *arg1, *arg2;
 {
        register int addr_diff;
+       struct block **b1 = (struct block **) arg1;
+       struct block **b2 = (struct block **) arg2;
 
        addr_diff = (BLOCK_START((*b1))) - (BLOCK_START((*b2)));
        if (addr_diff == 0)
@@ -2634,9 +2717,6 @@ static int compare_blocks(b1,b2)
        return addr_diff;
 }
 
-\f
-/* Sorting and reordering procedures */
-
 /* Sort the blocks of a symtab S.
    Reorder the blocks in the blockvector by code-address,
    as required by some MI search routines */
@@ -2680,7 +2760,7 @@ sort_blocks(s)
        BLOCK_START(BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK)) =
                BLOCK_START(BLOCKVECTOR_BLOCK(bv,FIRST_LOCAL_BLOCK));
 
-       BLOCK_START(BLOCKVECTOR_BLOCK(bv,STATIC_BLOCK)) = 
+       BLOCK_START(BLOCKVECTOR_BLOCK(bv,STATIC_BLOCK)) =
                BLOCK_START(BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK));
        BLOCK_END  (BLOCKVECTOR_BLOCK(bv,STATIC_BLOCK)) =
                BLOCK_END  (BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK));
@@ -2692,8 +2772,7 @@ sort_blocks(s)
 /* Allocate a new symtab for NAME.  Needs an estimate of how many symbols
    MAXSYMS and linenumbers MAXLINES we'll put in it */
 
-static
-struct symtab *
+static struct symtab *
 new_symtab(name, maxsyms, maxlines, objfile)
        char *name;
        int maxsyms;
@@ -2724,55 +2803,60 @@ new_psymtab(name, objfile)
        struct objfile *objfile;
 {
   struct partial_symtab *psymtab;
-  
+
   /* FIXME -- why (char *) -1 rather than NULL? */
   psymtab = allocate_psymtab (name == (char *) -1 ? "<no name>" : name,
                              objfile);
-  
+
   /* Keep a backpointer to the file's symbols */
 
   psymtab -> read_symtab_private = (char *)
     obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
   CUR_HDR(psymtab) = cur_hdr;
-  
+
   /* The way to turn this into a symtab is to call... */
   psymtab->read_symtab = mipscoff_psymtab_to_symtab;
   return (psymtab);
 }
 
 
-/* Allocate a linetable array of the given SIZE */
+/* Allocate a linetable array of the given SIZE.  Since the struct
+   already includes one item, we subtract one when calculating the
+   proper size to allocate.  */
 
 static struct linetable *
 new_linetable(size)
+       int size;
 {
        struct linetable *l;
 
-       size = size * sizeof(l->item) + sizeof(struct linetable);
+       size = (size-1) * sizeof(l->item) + sizeof(struct linetable);
        l = (struct linetable *)xmalloc(size);
        l->nitems = 0;
        return l;
 }
 
 /* Oops, too big. Shrink it.  This was important with the 2.4 linetables,
-   I am not so sure about the 3.4 ones */
+   I am not so sure about the 3.4 ones.
+
+   Since the struct linetable already includes one item, we subtract one when
+   calculating the proper size to allocate.  */
 
 static struct linetable *
 shrink_linetable(lt)
        struct linetable * lt;
 {
-       struct linetable *l = new_linetable(lt->nitems);
 
-       memcpy(l, lt, lt->nitems * sizeof(l->item) + sizeof(struct linetable));
-       free (lt);
-       return l;
+       return (struct linetable *) xrealloc ((PTR)lt,
+                                       sizeof(struct linetable)
+                                       + (lt->nitems - 1) * sizeof(lt->item));
 }
 
 /* Allocate and zero a new blockvector of NBLOCKS blocks. */
 
-static
-struct blockvector *
+static struct blockvector *
 new_bvect(nblocks)
+       int nblocks;
 {
        struct blockvector *bv;
        int size;
@@ -2787,14 +2871,13 @@ new_bvect(nblocks)
 
 /* Allocate and zero a new block of MAXSYMS symbols */
 
-static
-struct block *
+static struct block *
 new_block(maxsyms)
+       int maxsyms;
 {
        int size = sizeof(struct block) + (maxsyms-1) * sizeof(struct symbol *);
-       struct block *b = (struct block *)xzalloc(size);
 
-       return b;
+       return (struct block *)xzalloc (size);
 }
 
 /* Ooops, too big. Shrink block B in symtab S to its minimal size.
@@ -2811,8 +2894,8 @@ shrink_block(b, s)
 
        /* Just reallocate it and fix references to the old one */
 
-       new = (struct block *) xrealloc ((char *)b, sizeof(struct block) +
-               (BLOCK_NSYMS(b)-1) * sizeof(struct symbol *));
+       new = (struct block *) xrealloc ((PTR)b, sizeof(struct block) +
+               (BLOCK_NSYMS(b)-1) * sizeof(struct symbol *));
 
        /* Should chase pointers to old one.  Fortunately, that`s just
           the block`s function and inferior blocks */
@@ -2828,23 +2911,21 @@ shrink_block(b, s)
 
 /* Create a new symbol with printname NAME */
 
-static
-struct symbol *
+static struct symbol *
 new_symbol(name)
        char *name;
 {
-       struct symbol *s = (struct symbol *) 
+       struct symbol *s = (struct symbol *)
                obstack_alloc (&current_objfile->symbol_obstack, sizeof (struct symbol));
 
-       memset (s, 0, sizeof (*s));
+       memset ((PTR)s, 0, sizeof (*s));
        SYMBOL_NAME(s) = name;
        return s;
 }
 
 /* Create a new type with printname NAME */
 
-static
-struct type *
+static struct type *
 new_type(name)
        char *name;
 {
@@ -2882,23 +2963,29 @@ fixup_sigtramp()
 
        /* Most programs do not play with signals */
        if (s == 0)
-               return;
-
-       b0 = SYMBOL_BLOCK_VALUE(s);
+         s = lookup_symbol("_sigtramp", 0, VAR_NAMESPACE, 0, NULL);
+       else
+         {
+           b0 = SYMBOL_BLOCK_VALUE(s);
 
-       /* A label of sigvec, to be more precise */
-       s = lookup_symbol("sigtramp", b0, VAR_NAMESPACE, 0, NULL);
+           /* A label of sigvec, to be more precise */
+           s = lookup_symbol("sigtramp", b0, VAR_NAMESPACE, 0, NULL);
+         }
 
        /* But maybe this program uses its own version of sigvec */
        if (s == 0)
                return;
 
-       sigtramp_address = SYMBOL_VALUE(s);
-       sigtramp_end = sigtramp_address + 0x88; /* black magic */
-
        /* Did we or MIPSco fix the library ? */
        if (SYMBOL_CLASS(s) == LOC_BLOCK)
-               return;
+         {
+           sigtramp_address = BLOCK_START(SYMBOL_BLOCK_VALUE(s));
+           sigtramp_end = BLOCK_END(SYMBOL_BLOCK_VALUE(s));
+           return;
+         }
+
+       sigtramp_address = SYMBOL_VALUE(s);
+       sigtramp_end = sigtramp_address + 0x88; /* black magic */
 
        /* But what symtab does it live in ? */
        st = find_pc_symtab(SYMBOL_VALUE(s));
@@ -2910,7 +2997,8 @@ fixup_sigtramp()
         */
        SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;
        SYMBOL_CLASS(s) = LOC_BLOCK;
-       SYMBOL_TYPE(s) = init_type(TYPE_CODE_FUNC, 4, 0, 0, (struct objfile *) NULL);
+       SYMBOL_TYPE(s) = init_type(TYPE_CODE_FUNC, 4, 0, (char *) NULL,
+                                  (struct objfile *) NULL);
        TYPE_TARGET_TYPE(SYMBOL_TYPE(s)) = builtin_type_void;
 
        /* Need a block to allocate .gdbinfo. in */
@@ -2931,20 +3019,22 @@ fixup_sigtramp()
 
                e->numargs = 0; /* the kernel thinks otherwise */
                /* align_longword(sigcontext + SIGFRAME) */
-               e->framesize = 0x150;
-               e->framereg = SP_REGNUM;
-               e->pcreg = 31;
-               e->regmask = -2;
-               e->regoffset = -(41 * sizeof(int));
-               e->fregmask = -1;
-               e->fregoffset = -(37 * sizeof(int));
-               e->isym = (long)s;
-
+               e->pdr.frameoffset = 0x150;
+               e->pdr.framereg = SP_REGNUM;
+               e->pdr.pcreg = 31;
+               e->pdr.regmask = -2;
+               e->pdr.regoffset = -(41 * sizeof(int));
+               e->pdr.fregmask = -1;
+               e->pdr.fregoffset = -(37 * sizeof(int));
+               e->pdr.isym = (long)s;
+
+               current_objfile = st->objfile; /* Keep new_symbol happy */
                s = new_symbol(".gdbinfo.");
                SYMBOL_VALUE(s) = (int) e;
                SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
                SYMBOL_CLASS(s) = LOC_CONST;
                SYMBOL_TYPE(s) = builtin_type_void;
+               current_objfile = NULL;
        }
 
        BLOCK_SYM(b,BLOCK_NSYMS(b)++) = s;
@@ -2952,33 +3042,48 @@ fixup_sigtramp()
 \f
 /* Initialization */
 
-static struct sym_fns ecoff_sym_fns = {"ecoff", 5,
-               mipscoff_new_init, mipscoff_symfile_init,
-               mipscoff_symfile_read};
+static struct sym_fns ecoff_sym_fns =
+{
+  "ecoff",             /* sym_name: name or name prefix of BFD target type */
+  5,                   /* sym_namelen: number of significant sym_name chars */
+  mipscoff_new_init,   /* sym_new_init: init anything gbl to entire symtab */
+  mipscoff_symfile_init,/* sym_init: read initial info, setup for sym_read() */
+  mipscoff_symfile_read,/* sym_read: read a symbol file into symtab */
+  mipscoff_symfile_finish,/* sym_finish: finished with file, cleanup */
+  NULL                 /* next: pointer to next struct sym_fns */
+};
+
 
+void
 _initialize_mipsread ()
 {
        add_symtab_fns (&ecoff_sym_fns);
 
        /* Missing basic types */
+
        builtin_type_string =
-           init_type (TYPE_CODE_PASCAL_ARRAY,
-                      1, 0, "string",
-                      (struct objfile *) NULL);
+           init_type(TYPE_CODE_PASCAL_ARRAY,
+                     TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                     0, "string",
+                     (struct objfile *) NULL);
        builtin_type_complex =
            init_type(TYPE_CODE_FLT,
-                     2 * sizeof(float), 0, "complex",
+                     TARGET_COMPLEX_BIT / TARGET_CHAR_BIT,
+                     0, "complex",
                      (struct objfile *) NULL);
        builtin_type_double_complex =
            init_type(TYPE_CODE_FLT,
-                     2 * sizeof(double), 0, "double_complex",
+                     TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT,
+                     0, "double complex",
                      (struct objfile *) NULL);
        builtin_type_fixed_dec =
-           init_type(TYPE_CODE_INT, sizeof(int),
-                     0, "fixed_decimal",
+           init_type(TYPE_CODE_INT,
+                     TARGET_INT_BIT / TARGET_CHAR_BIT,
+                     0, "fixed decimal",
                      (struct objfile *) NULL);
        builtin_type_float_dec =
-           init_type(TYPE_CODE_FLT, sizeof(double),
-                     0, "floating_decimal",
+           init_type(TYPE_CODE_FLT,
+                     TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                     0, "floating decimal",
                      (struct objfile *) NULL);
 }
This page took 0.060712 seconds and 4 git commands to generate.