#define yyerrflag and yynerrs to avoid global name conflicts.
[deliverable/binutils-gdb.git] / gdb / coffread.c
index f6a9c8a132bd9e75de840a62f6c5bd1e97ea3b5c..33e014da2f92dec865faf8912655c04261c2385b 100644 (file)
@@ -2,39 +2,44 @@
    Design and support routines derived from dbxread.c, and UMAX COFF
    specific routines written 9/1/87 by David D. Johnson, Brown University.
    Revised 11/27/87 ddj@cs.brown.edu
-   Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
+   Copyright (C) 1987-1991 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
-GDB is free software; you can redistribute it and/or modify
+This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-GDB is distributed in the hope that it will be useful,
+This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GDB; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 \f
+#include <stdio.h>
 #include "defs.h"
 #include "param.h"
-#ifdef COFF_FORMAT
 #include "symtab.h"
+#include "breakpoint.h"
+#include "bfd.h"
+#include "symfile.h"
 
-#ifdef USG
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
+#if defined (TDESC)
+/* Need to get C_VERSION and friends.  */
 #include <a.out.h>
-#include <stdio.h>
+#else /* not TDESC */
+#include <intel-coff.h>
+#endif /* not TDESC */
+
 #include <obstack.h>
-#include <sys/param.h>
-#include <sys/file.h>
+#include <string.h>
+
+#include "internalcoff.h"      /* Internal format of COFF symbols in BFD */
+#include "libcoff.h"           /* FIXME secret internal data from BFD */
 
 static void add_symbol_to_list ();
 static void read_coff_symtab ();
@@ -53,11 +58,18 @@ static char *getfilename ();
 static char *getsymname ();
 static int init_lineno ();
 static void enter_linenos ();
+static void read_one_sym ();
 
 extern int fclose ();
 extern void free_all_symtabs ();
 extern void free_all_psymtabs ();
 
+/* To be an sdb debug type, type must have at least a basic or primary
+   derived type.  Using this rather than checking against T_NULL is
+   said to prevent core dumps if we try to operate on Michael Bloom
+   dbx-in-coff file.  */
+
+#define SDB_TYPE(type) (BTYPE(type) | (type & N_TMASK))
 
 /* Name of source file whose symbol data we are now processing.
    This comes from a symbol named ".file".  */
@@ -84,11 +96,9 @@ static CORE_ADDR end_of_text_addr;
 static FILE *nlist_stream_global;
 static int nlist_nsyms_global;
 
-/* The file, a.out  and text section headers of the symbol file */
+/* The entry point (starting address) of the file, if it is an executable.  */
 
-static FILHDR file_hdr;
-static SCNHDR text_hdr;
-static AOUTHDR aout_hdr;
+static CORE_ADDR entry_point;
 
 /* The index in the symbol table of the last coff symbol that was processed.  */
 
@@ -118,8 +128,23 @@ static int prev_line_number;
 
 static int line_vector_length;
 
+#ifdef TDESC
+#include "tdesc.h"
+#define SEM
+int int_sem_val = 's' << 24 | 'e' << 16 | 'm' << 8 | '.';
+int temp_sem_val;
+int last_coffsem = 2;
+#if 0
+  /* This isn't used currently.  */
+int last_coffsyn = 0;
+#endif
+int debug_info = 0;    /*used by tdesc */
+extern dc_dcontext_t tdesc_handle;
+extern int safe_to_init_tdesc_context;
+#endif
+
 /* Chain of typedefs of pointers to empty struct/union types.
-   They are chained thru the SYMBOL_VALUE.  */
+   They are chained thru the SYMBOL_VALUE_CHAIN.  */
 
 #define HASHSIZE 127
 static struct symbol *opaque_type_chain[HASHSIZE];
@@ -176,9 +201,14 @@ struct pending_block *pending_blocks;
 extern CORE_ADDR startup_file_start;   /* From blockframe.c */
 extern CORE_ADDR startup_file_end;     /* From blockframe.c */
 
-/* File name symbols were loaded from.  */
+/* Complaints about various problems in the file being read  */
+
+struct complaint ef_complaint = 
+  {"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0};
+
+struct complaint lineno_complaint =
+  {"Line number pointer %d lower than start of line numbers", 0, 0};
 
-static char *symfile;
 \f
 /* Look up a coff type-number index.  Return the address of the slot
    where the type for that index is stored.
@@ -368,7 +398,7 @@ make_blockvector ()
 
 /* Manage the vector of line numbers.  */
 
-static
+static void
 record_line (line, pc)
      int line;
      CORE_ADDR pc;
@@ -401,9 +431,18 @@ start_symtab ()
   context_stack = 0;
   within_function = 0;
   last_source_file = 0;
+#ifdef TDESC
+  last_coffsem = 2;
+#if 0
+  /* This isn't used currently.  */
+  last_coffsyn = 0;
+#endif
+#endif
 
-  /* Initialize the source file information for this file.  */
+  /* Initialize the source file line number information for this file.  */
 
+  if (line_vector)             /* Unlikely, but maybe possible? */
+    free (line_vector);
   line_vector_index = 0;
   line_vector_length = 1000;
   prev_line_number = -2;       /* Force first line number to be explicit */
@@ -412,7 +451,8 @@ start_symtab ()
             + line_vector_length * sizeof (struct linetable_entry));
 }
 
-/* Save the vital information for use when closing off the current file.
+/* Save the vital information from when starting to read a file,
+   for use when closing off the current file.
    NAME is the file name the symbols came from, START_ADDR is the first
    text address for the file, and SIZE is the number of bytes of text.  */
 
@@ -426,8 +466,8 @@ complete_symtab (name, start_addr, size)
   cur_src_start_addr = start_addr;
   cur_src_end_addr = start_addr + size;
 
-  if (aout_hdr.entry < cur_src_end_addr
-      && aout_hdr.entry >= cur_src_start_addr)
+  if (entry_point < cur_src_end_addr
+      && entry_point >= cur_src_start_addr)
     {
       startup_file_start = cur_src_start_addr;
       startup_file_end = cur_src_end_addr;
@@ -469,7 +509,8 @@ end_symtab ()
       return;
     }
 
-  /* Create the two top-level blocks for this file.  */
+  /* Create the two top-level blocks for this file (STATIC_BLOCK and
+     GLOBAL_BLOCK).  */
   finish_block (0, &file_symbols, 0, cur_src_start_addr, cur_src_end_addr);
   finish_block (0, &global_symbols, 0, cur_src_start_addr, cur_src_end_addr);
 
@@ -484,6 +525,7 @@ end_symtab ()
   symtab->blockvector = blockvector;
   symtab->free_code = free_linetable;
   symtab->filename = last_source_file;
+  symtab->dirname = NULL;
   lv = line_vector;
   lv->nitems = line_vector_index;
   symtab->linetable = (struct linetable *)
@@ -492,6 +534,20 @@ end_symtab ()
   symtab->nlines = 0;
   symtab->line_charpos = 0;
 
+  symtab->language = language_unknown;
+  symtab->fullname = NULL;
+
+#ifdef TDESC
+  symtab->coffsem = last_coffsem;
+#if 0
+  /* This isn't used currently.  Besides, if this is really about "syntax",
+     it shouldn't need to stick around past symbol read-in time.  */
+  symtab->coffsyn = last_coffsyn;
+#endif
+#endif
+
+  free_named_symtabs (symtab->filename);
+
   /* Link the new symtab into the list of such.  */
   symtab->next = symtab_list;
   symtab_list = symtab;
@@ -502,281 +558,180 @@ end_symtab ()
   last_source_file = 0;
 }
 \f
-/* Accumulate the misc functions in bunches of 127.
-   At the end, copy them all into one newly allocated structure.  */
-
-#define MISC_BUNCH_SIZE 127
-
-struct misc_bunch
-{
-  struct misc_bunch *next;
-  struct misc_function contents[MISC_BUNCH_SIZE];
-};
-
-/* Bunch currently being filled up.
-   The next field points to chain of filled bunches.  */
-
-static struct misc_bunch *misc_bunch;
-
-/* Number of slots filled in current bunch.  */
-
-static int misc_bunch_index;
-
-/* Total number of misc functions recorded so far.  */
-
-static int misc_count;
-
-static void
-init_misc_functions ()
-{
-  misc_count = 0;
-  misc_bunch = 0;
-  misc_bunch_index = MISC_BUNCH_SIZE;
-}
-
 static void
 record_misc_function (name, address)
      char *name;
      CORE_ADDR address;
 {
-  register struct misc_bunch *new;
-
-  if (misc_bunch_index == MISC_BUNCH_SIZE)
-    {
-      new = (struct misc_bunch *) xmalloc (sizeof (struct misc_bunch));
-      misc_bunch_index = 0;
-      new->next = misc_bunch;
-      misc_bunch = new;
-    }
-  misc_bunch->contents[misc_bunch_index].name = savestring (name, strlen (name));
-  misc_bunch->contents[misc_bunch_index].address = address;
-  misc_bunch->contents[misc_bunch_index].type = mf_unknown;
-  misc_bunch_index++;
-  misc_count++;
+#ifdef TDESC
+  /* We don't want TDESC entry points on the misc_function_vector */
+  if (name[0] == '@') return;
+#endif
+  /* mf_text isn't true, but apparently COFF doesn't tell us what it really
+     is, so this guess is more useful than mf_unknown.  */
+  prim_record_misc_function (savestring (name, strlen (name)),
+                            address,
+                            (int)mf_text);
 }
+\f
+/* coff_symfile_init ()
+   is the coff-specific initialization routine for reading symbols.
+   It is passed a struct sym_fns which contains, among other things,
+   the BFD for the file whose symbols are being read, and a slot for
+   a pointer to "private data" which we fill with cookies and other
+   treats for coff_symfile_read ().
+
+   We will only be called if this is a COFF or COFF-like file.
+   BFD handles figuring out the format of the file, and code in symtab.c
+   uses BFD's determination to vector to us.
+
+   The ultimate result is a new symtab (or, FIXME, eventually a psymtab).  */
+
+struct coff_symfile_info {
+  file_ptr min_lineno_offset;          /* Where in file lowest line#s are */
+  file_ptr max_lineno_offset;          /* 1+last byte of line#s in file */
+};
 
-/* if we see a function symbol, we do record_misc_function.
- * however, if it turns out the next symbol is '.bf', then
- * we call here to undo the misc definition
- */
-static void
-unrecord_misc_function ()
+void
+coff_symfile_init (sf)
+     struct sym_fns *sf;
 {
-  if (misc_bunch_index == 0)
-    error ("Internal error processing symbol table, at symbol %d.",
-          symnum);
-  misc_bunch_index--;
-  misc_count--;
-}
+  bfd *abfd = sf->sym_bfd;
 
+  /* Allocate struct to keep track of the symfile */
+  /* FIXME memory leak */
+  sf->sym_private = xmalloc (sizeof (struct coff_symfile_info));
 
-static int
-compare_misc_functions (fn1, fn2)
-     struct misc_function *fn1, *fn2;
-{
-  /* Return a signed result based on unsigned comparisons
-     so that we sort into unsigned numeric order.  */
-  if (fn1->address < fn2->address)
-    return -1;
-  if (fn1->address > fn2->address)
-    return 1;
-  return 0;
-}
-
-static void
-discard_misc_bunches ()
-{
-  register struct misc_bunch *next;
+#if defined (TDESC)
+  safe_to_init_tdesc_context  = 0;
+#endif
 
-  while (misc_bunch)
+  /* Save startup file's range of PC addresses to help blockframe.c
+     decide where the bottom of the stack is.  */
+  if (bfd_get_file_flags (abfd) & EXEC_P)
     {
-      next = misc_bunch->next;
-      free (misc_bunch);
-      misc_bunch = next;
+      /* Executable file -- record its entry point so we'll recognize
+        the startup file because it contains the entry point.  */
+      entry_point = bfd_get_start_address (abfd);
+    }
+  else
+    {
+      /* Examination of non-executable.o files.  Short-circuit this stuff.  */
+      /* ~0 will not be in any file, we hope.  */
+      entry_point = ~0;
+      /* set the startup file to be an empty range.  */
+      startup_file_start = 0;
+      startup_file_end = 0;
     }
 }
 
+/* This function is called for every section; it finds the outer limits
+   of the line table (minimum and maximum file offset) so that the
+   mainline code can read the whole thing for efficiency.  */
+
+/* ARGSUSED */
 static void
-condense_misc_bunches ()
+find_linenos (abfd, asect, vpinfo)
+     bfd *abfd;
+     sec_ptr asect;
+     void *vpinfo;
 {
-  register int i, j;
-  register struct misc_bunch *bunch;
-#ifdef NAMES_HAVE_UNDERSCORE
-  int offset = 1;
-#else
-  int offset = 0;
-#endif
-
-  misc_function_vector
-    = (struct misc_function *)
-      xmalloc (misc_count * sizeof (struct misc_function));
-
-  j = 0;
-  bunch = misc_bunch;
-  while (bunch)
+  struct coff_symfile_info *info;
+  int size, count;
+  file_ptr offset, maxoff;
+
+/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+  count = asect->lineno_count;
+/* End of warning */
+
+  if (count == 0)
+    return;
+#if !defined (LINESZ)
+/* Just in case, you never know what to expect from those
+   COFF header files.  */
+#define LINESZ (sizeof (struct lineno))
+#endif /* No LINESZ.  */
+  size = count * LINESZ;
+
+  info = (struct coff_symfile_info *)vpinfo;
+/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+  offset = asect->line_filepos;
+/* End of warning */
+
+  if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
+    info->min_lineno_offset = offset;
+
+  maxoff = offset + size;
+  if (maxoff > info->max_lineno_offset)
+    info->max_lineno_offset = maxoff;
+#ifdef TDESC
+  /* While we're at it, find the debug_info.  It's in the s_relptr
+     (or, in BFD-speak, rel_filepos) of the text segment section header.  */
+  if (strcmp (bfd_section_name (abfd, asect), ".text") == 0)
     {
-      for (i = 0; i < misc_bunch_index; i++)
+      /* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+      debug_info = asect->rel_filepos;
+      /* End of warning */
+      if (tdesc_handle)
        {
-         register char *tmp;
-
-         misc_function_vector[j] = bunch->contents[i];
-         tmp = misc_function_vector[j].name;
-         misc_function_vector[j].name = (tmp[0] == '_' ? tmp + offset : tmp);
-         j++;
+         dc_terminate (tdesc_handle);
+         tdesc_handle = 0;
        }
-      bunch = bunch->next;
-      misc_bunch_index = MISC_BUNCH_SIZE;
     }
-
-  misc_function_count = j;
-
-  /* Sort the misc functions by address.  */
-
-  qsort (misc_function_vector, j, sizeof (struct misc_function),
-        compare_misc_functions);
+#endif /* TDESC */
 }
 
-/* Call sort_syms to sort alphabetically
-   the symbols of each block of each symtab.  */
 
-static int
-compare_symbols (s1, s2)
-     struct symbol **s1, **s2;
-{
-  /* Names that are less should come first.  */
-  register int namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
-  if (namediff != 0) return namediff;
-  /* For symbols of the same name, registers should come first.  */
-  return ((SYMBOL_CLASS (*s2) == LOC_REGISTER)
-         - (SYMBOL_CLASS (*s1) == LOC_REGISTER));
-}
+/* The BFD for this file -- only good while we're actively reading
+   symbols into a psymtab or a symtab.  */
 
-static void
-sort_syms ()
-{
-  register struct symtab *s;
-  register int i, nbl;
-  register struct blockvector *bv;
-  register struct block *b;
+static bfd *symfile_bfd;
 
-  for (s = symtab_list; s; s = s->next)
-    {
-      bv = BLOCKVECTOR (s);
-      nbl = BLOCKVECTOR_NBLOCKS (bv);
-      for (i = 0; i < nbl; i++)
-       {
-         b = BLOCKVECTOR_BLOCK (bv, i);
-         if (BLOCK_SHOULD_SORT (b))
-                 qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
-                        sizeof (struct symbol *), compare_symbols);
-       }
-    }
-}
-\f
-/* This is the symbol-file command.  Read the file, analyze its symbols,
-   and add a struct symtab to symtab_list.  */
+/* Read a symbol file, after initialization by coff_symfile_init.  */
+/* FIXME!  Addr and Mainline are not used yet -- this will not work for
+   shared libraries or add_file!  */
 
+/* ARGSUSED */
 void
-symbol_file_command (name)
-     char *name;
+coff_symfile_read (sf, addr, mainline)
+     struct sym_fns *sf;
+     CORE_ADDR addr;
+     int mainline;
 {
+  struct coff_symfile_info *info = (struct coff_symfile_info *)sf->sym_private;
+  bfd *abfd = sf->sym_bfd;
+  char *name = bfd_get_filename (abfd);
   int desc;
+  register int val;
   int num_symbols;
-  int num_sections;
   int symtab_offset;
-  extern void close ();
-  register int val;
-  struct cleanup *old_chain;
-
-  dont_repeat ();
-
-  if (name == 0)
-    {
-      if (symtab_list && !query ("Discard symbol table? ", 0))
-       error ("Not confirmed.");
-      if (symfile)
-       free (symfile);
-      symfile = 0;
-      free_all_symtabs ();
-      return;
-    }
+  int stringtab_offset;
 
-  name = tilde_expand (name);
-  make_cleanup (free, name);
+  symfile_bfd = abfd;                  /* Kludge for swap routines */
 
-  if (symtab_list && !query ("Load new symbol table from \"%s\"? ", name))
-    error ("Not confirmed.");
-
-  if (symfile)
-    free (symfile);
-  symfile = 0;
-
-  {
-    char *absolute_name;
-
-    desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name);
-    if (desc < 0)
-      perror_with_name (name);
-    else
-      name = absolute_name;
-  }
-
-  old_chain = make_cleanup (close, desc);
-  make_cleanup (free_current_contents, &name);
-
-  if ((num_symbols = read_file_hdr (desc, &file_hdr)) < 0)
-    error ("File \"%s\" not in executable format.", name);
-
-  /* If an a.out header is present, read it in.  If not (e.g. a .o file)
-     deal with its absence.  */
-  if (file_hdr.f_opthdr == 0
-      || read_aout_hdr (desc, &aout_hdr, file_hdr.f_opthdr) < 0)
-    {
-      /* We will not actually be able to run code, since backtraces would
-        fly off the bottom of the stack (there is no way to reliably
-        detect bottom of stack), but that's fine since the kernel won't
-        run something without an a.out header anyway.  Passive examination
-        of .o files is one place this might make sense.  */
-      /* ~0 will not be in any file.  */
-      aout_hdr.entry = ~0;
-      /* set the startup file to be an empty range.  */
-      startup_file_start = 0;
-      startup_file_end = 0;
-    }
-
-  if (num_symbols == 0)
-    {
-      free_all_symtabs ();
-      error ("%s does not have a symbol-table.\n", name);
-    }
-
-  printf ("Reading symbol data from %s...", name);
-  fflush (stdout);
-
-  /* Throw away the old symbol table.  */
-
-  free_all_symtabs ();
-  free_all_psymtabs ();                /* Make sure that partial_symtab_list */
-                               /* is 0 also. */
-
-  num_sections = file_hdr.f_nscns;
-  symtab_offset = file_hdr.f_symptr;
-
-  if (read_section_hdr (desc, _TEXT, &text_hdr, num_sections) < 0)
-    error ("\"%s\": can't read text section header", name);
+/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+   desc = fileno ((FILE *)(abfd->iostream));           /* File descriptor */
+   num_symbols = bfd_get_symcount (abfd);      /* How many syms */
+   symtab_offset = obj_sym_filepos (abfd);     /* Symbol table file offset */
+   stringtab_offset = symtab_offset + num_symbols * SYMESZ;  /* String tab */
+/* End of warning */
 
   /* Read the line number table, all at once.  */
+  info->min_lineno_offset = 0;
+  info->max_lineno_offset = 0;
+  bfd_map_over_sections (abfd, find_linenos, info);
 
-  val = init_lineno (desc, text_hdr.s_lnnoptr, text_hdr.s_nlnno);
+  val = init_lineno (desc, info->min_lineno_offset, 
+                    info->max_lineno_offset - info->min_lineno_offset);
   if (val < 0)
     error ("\"%s\": error reading line numbers\n", name);
 
   /* Now read the string table, all at once.  */
 
-  val = init_stringtab (desc, symtab_offset + num_symbols * SYMESZ);
+  val = init_stringtab (desc, stringtab_offset);
   if (val < 0)
     {
-      free_all_symtabs ();
+      free_all_symtabs ();             /* FIXME blows whole symtab */
       printf ("\"%s\": can't get string table", name);
       fflush (stdout);
       return;
@@ -788,7 +743,7 @@ symbol_file_command (name)
   if (val < 0)
     perror_with_name (name);
 
-  init_misc_functions ();
+  init_misc_bunches ();
   make_cleanup (discard_misc_bunches, 0);
 
   /* Now that the executable file is positioned at symbol table,
@@ -800,34 +755,22 @@ symbol_file_command (name)
 
   /* Sort symbols alphabetically within each block.  */
 
-  sort_syms ();
+  sort_all_symtab_syms ();
 
-  /* Go over the misc functions and install them in vector.  */
+  /* Go over the misc symbol bunches and install them in vector.  */
 
-  condense_misc_bunches ();
-
-  /* Don't allow char * to have a typename (else would get caddr_t.)  */
-
-  TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
+  condense_misc_bunches (!mainline);
 
   /* Make a default for file to list.  */
 
-  select_source_symtab (0);
-
-  symfile = savestring (name, strlen (name));
-
-  do_cleanups (old_chain);
-
-  printf ("done.\n");
-  fflush (stdout);
+  select_source_symtab (0);    /* FIXME, this might be too slow, see dbxread */
 }
 
-/* Return name of file symbols were loaded from, or 0 if none..  */
-
-char *
-get_sym_file ()
+void
+coff_new_init ()
 {
-  return symfile;
+  /* There seems to be nothing to do except free_all_symtabs and set
+     symfile to zero, which is done by our caller.  */
 }
 \f
 /* Simplified internal version of coff symbol table information */
@@ -835,7 +778,7 @@ get_sym_file ()
 struct coff_symbol {
   char *c_name;
   int c_symnum;                /* symbol number of this entry */
-  int c_nsyms;         /* 1 if syment only, 2 if syment + auxent */
+  int c_nsyms;         /* 1 if syment only, 2 if syment + auxent, etc */
   long c_value;
   int c_sclass;
   int c_secnum;
@@ -857,15 +800,19 @@ read_coff_symtab (desc, nsyms)
   register struct context_stack *new;
   struct coff_symbol coff_symbol;
   register struct coff_symbol *cs = &coff_symbol;
-  static SYMENT main_sym;
-  static AUXENT main_aux;
+  static struct internal_syment main_sym;
+  static union internal_auxent main_aux;
   struct coff_symbol fcn_cs_saved;
-  static SYMENT fcn_sym_saved;
-  static AUXENT fcn_aux_saved;
+  static struct internal_syment fcn_sym_saved;
+  static union internal_auxent fcn_aux_saved;
 
+  /* A .file is open.  */
+  int in_source_file = 0;
   int num_object_files = 0;
   int next_file_symnum = -1;
-  char *filestring;
+
+  /* Name of the current file.  */
+  char *filestring = "";
   int depth;
   int fcn_first_line;
   int fcn_last_line;
@@ -886,6 +833,8 @@ read_coff_symtab (desc, nsyms)
   last_source_file = 0;
   bzero (opaque_type_chain, sizeof opaque_type_chain);
 
+  if (type_vector)                     /* Get rid of previous one */
+    free (type_vector);
   type_vector_length = 160;
   type_vector = (struct typevector *)
                xmalloc (sizeof (struct typevector)
@@ -900,10 +849,15 @@ read_coff_symtab (desc, nsyms)
       QUIT;                    /* Make this command interruptable.  */
       read_one_sym (cs, &main_sym, &main_aux);
 
+#ifdef SEM
+      temp_sem_val = cs->c_name[0] << 24 | cs->c_name[1] << 16 |
+                     cs->c_name[2] << 8 | cs->c_name[3];
+      if (int_sem_val == temp_sem_val)
+        last_coffsem = (int) strtol (cs->c_name+4, (char **) NULL, 10);
+#endif
+
       if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
        {
-         CORE_ADDR last_file_end = cur_src_end_addr;
-
          if (last_source_file)
            end_symtab ();
 
@@ -913,7 +867,8 @@ read_coff_symtab (desc, nsyms)
        }
 
       /* Special case for file with type declarations only, no text.  */
-      if (!last_source_file && cs->c_type != T_NULL && cs->c_secnum == N_DEBUG)
+      if (!last_source_file && SDB_TYPE (cs->c_type)
+         && cs->c_secnum == N_DEBUG)
        complete_symtab (filestring, 0, 0);
 
       /* Typedefs should not be treated as symbol definitions.  */
@@ -960,34 +915,48 @@ read_coff_symtab (desc, nsyms)
                end_symtab ();
                start_symtab ();
              }
-           num_object_files++;
+           in_source_file = 1;
            break;
 
           case C_STAT:
            if (cs->c_name[0] == '.') {
                    if (strcmp (cs->c_name, _TEXT) == 0) {
-                           if (num_object_files == 1) {
+                           if (++num_object_files == 1) {
                                    /* last address of startup file */
                                    first_object_file_end = cs->c_value +
                                            main_aux.x_scn.x_scnlen;
                            }
-                           /* for some reason the old code didn't do
-                            * this if this section entry had
-                            * main_aux.x_scn.x_nlinno equal to 0
-                            */
-                           complete_symtab (filestring, cs->c_value,
-                                            main_aux.x_scn.x_scnlen);
+                           /* Check for in_source_file deals with case of
+                              a file with debugging symbols
+                              followed by a later file with no symbols.  */
+                           if (in_source_file)
+                             complete_symtab (filestring, cs->c_value,
+                                              main_aux.x_scn.x_scnlen);
+                           in_source_file = 0;
                    }
                    /* flush rest of '.' symbols */
                    break;
            }
+           else if (!SDB_TYPE (cs->c_type)
+                    && cs->c_name[0] == 'L'
+                    && (strncmp (cs->c_name, "LI%", 3) == 0
+                        || strncmp (cs->c_name, "LF%", 3) == 0
+                        || strncmp (cs->c_name,"LC%",3) == 0
+                        || strncmp (cs->c_name,"LP%",3) == 0
+                        || strncmp (cs->c_name,"LPB%",4) == 0
+                        || strncmp (cs->c_name,"LBB%",4) == 0
+                        || strncmp (cs->c_name,"LBE%",4) == 0
+                        || strncmp (cs->c_name,"LPBX%",5) == 0))
+             /* At least on a 3b1, gcc generates swbeg and string labels
+                that look like this.  Ignore them.  */
+             break;
            /* fall in for static symbols that don't start with '.' */
          case C_EXT:
            if (cs->c_sclass == C_EXT &&
                cs->c_secnum == N_ABS &&
                strcmp (cs->c_name, _ETEXT) == 0)
                    end_of_text_addr = cs->c_value;
-           if (cs->c_type == T_NULL) {
+           if (!SDB_TYPE (cs->c_type)) {
                    if (cs->c_secnum <= 1) {    /* text or abs */
                            record_misc_function (cs->c_name, cs->c_value);
                            break;
@@ -1001,12 +970,6 @@ read_coff_symtab (desc, nsyms)
          case C_FCN:
            if (strcmp (cs->c_name, ".bf") == 0)
              {
-#if 0
-               /* Don't do this; we want all functions to be on the
-                  mfl now.  */
-               unrecord_misc_function ();
-#endif
-
                within_function = 1;
 
                /* value contains address of first non-init type code */
@@ -1033,18 +996,32 @@ read_coff_symtab (desc, nsyms)
                       */
                /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
                            contains number of lines to '}' */
+               new = context_stack;
+               if (new == 0)
+                 {
+                   complain (&ef_complaint, cs->c_symnum);
+                   within_function = 0;
+                   break;
+                 }
                fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
                enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line);
-               new = context_stack;
 
-               if (new == 0)
-                 error ("Invalid symbol data; .bf/.ef/.bb/.eb symbol mismatch, at symbol %d.",
-                        symnum);
-               
                finish_block (new->name, &local_symbols, new->old_blocks,
                              new->start_addr,
+#if defined (FUNCTION_EPILOGUE_SIZE)
+                             /* This macro should be defined only on
+                                machines where the
+                                fcn_aux_saved.x_sym.x_misc.x_fsize
+                                field is always zero.
+                                So use the .bf record information that
+                                points to the epilogue and add the size
+                                of the epilogue.  */
+                             cs->c_value + FUNCTION_EPILOGUE_SIZE
+#else
                              fcn_cs_saved.c_value +
-                                 fcn_aux_saved.x_sym.x_misc.x_fsize);
+                                 fcn_aux_saved.x_sym.x_misc.x_fsize
+#endif
+                             );
                context_stack = 0;
                within_function = 0;
                free (new);
@@ -1084,8 +1061,27 @@ read_coff_symtab (desc, nsyms)
                free (new);
              }
            break;
+#ifdef TDESC
+          case C_VERSION:
+#if 0
+           /* This isn't used currently.  */
+            if (strcmp (cs->c_name, ".coffsyn") == 0)
+               last_coffsyn = cs->c_value;
+           else
+#endif /* 0 */
+             if ((strcmp (cs->c_name, ".coffsem") == 0) &&
+                     (cs->c_value != 0))
+               last_coffsem = cs->c_value;
+            break;
+#endif /* TDESC */
 
          default:
+#ifdef TDESC
+           if ((strcmp (cs->c_name, ".coffsem") == 0) &&
+               (cs->c_value != 0))
+             last_coffsem = cs->c_value;
+            else
+#endif
            (void) process_coff_symbol (cs, &main_aux);
            break;
        }
@@ -1099,6 +1095,9 @@ read_coff_symtab (desc, nsyms)
 \f
 /* Routines for reading headers and symbols from executable.  */
 
+#ifdef FIXME
+/* Move these XXXMAGIC symbol defns into BFD!  */
+
 /* Read COFF file header, check magic number,
    and return number of symbols. */
 read_file_hdr (chan, file_hdr)
@@ -1123,7 +1122,27 @@ read_file_hdr (chan, file_hdr)
 #endif
 #ifdef CLIPPERMAGIC
     case CLIPPERMAGIC:
+#endif
+#if defined (MC68KWRMAGIC) \
+  && (!defined (MC68MAGIC) || MC68KWRMAGIC != MC68MAGIC)
+    case MC68KWRMAGIC:
+#endif
+#ifdef MC68KROMAGIC
+    case MC68KROMAGIC:
+    case MC68KPGMAGIC:
+#endif
+#ifdef MC88DGMAGIC
+    case MC88DGMAGIC:
+#endif      
+#ifdef MC88MAGIC
+    case MC88MAGIC:
 #endif      
+#ifdef I960ROMAGIC
+    case I960ROMAGIC:          /* Intel 960 */
+#endif
+#ifdef I960RWMAGIC
+    case I960RWMAGIC:          /* Intel 960 */
+#endif
        return file_hdr->f_nsyms;
 
       default:
@@ -1137,62 +1156,42 @@ read_file_hdr (chan, file_hdr)
 #endif
     }
 }
+#endif
 
-read_aout_hdr (chan, aout_hdr, size)
-    int chan;
-    AOUTHDR *aout_hdr;
-    int size;
-{
-  lseek (chan, (long)FILHSZ, 0);
-  if (size != sizeof (AOUTHDR))
-    return -1;
-  if (myread (chan, (char *)aout_hdr, size) != size)
-    return -1;
-  return 0;
-}
-
-read_section_hdr (chan, section_name, section_hdr, nsects)
-    register int chan;
-    register char *section_name;
-    SCNHDR *section_hdr;
-    register int nsects;
-{
-  register int i;
-
-  if (lseek (chan, FILHSZ + sizeof (AOUTHDR), 0) < 0)
-    return -1;
-
-  for (i = 0; i < nsects; i++)
-    {
-      if (myread (chan, (char *)section_hdr, SCNHSZ) < 0)
-       return -1;
-      if (strncmp (section_hdr->s_name, section_name, 8) == 0)
-       return 0;
-    }
-    return -1;
-}
+/* Read the next symbol, swap it, and return it in both internal_syment
+   form, and coff_symbol form.  Also return its first auxent, if any,
+   in internal_auxent form, and skip any other auxents.  */
 
+static void
 read_one_sym (cs, sym, aux)
     register struct coff_symbol *cs;
-    register SYMENT *sym;
-    register AUXENT *aux;
+    register struct internal_syment *sym;
+    register union internal_auxent *aux;
 {
+  struct external_syment temp_sym[1];
+  union external_auxent temp_aux[1];
+  int i;
+
   cs->c_symnum = symnum;
-  fread ((char *)sym, SYMESZ, 1, nlist_stream_global);
+  fread ((char *)temp_sym, SYMESZ, 1, nlist_stream_global);
+  bfd_coff_swap_sym_in (symfile_bfd, temp_sym, sym);
   cs->c_nsyms = (sym->n_numaux & 0xff) + 1;
-  if (cs->c_nsyms == 2)
+  if (cs->c_nsyms >= 2)
     {
-      /* doc for coff says there is either no aux entry or just one */
-      fread ((char *)aux, AUXESZ, 1, nlist_stream_global);
+    fread ((char *)temp_aux, AUXESZ, 1, nlist_stream_global);
+    bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass, aux);
+    /* If more than one aux entry, read past it (only the first aux
+       is important). */
+    for (i = 2; i < cs->c_nsyms; i++)
+      fread ((char *)temp_aux, AUXESZ, 1, nlist_stream_global);
     }
-  else if (cs->c_nsyms > 2)
-    error ("more than one aux symbol table entry at symnum=%d\n", symnum);
-
   cs->c_name = getsymname (sym);
   cs->c_value = sym->n_value;
   cs->c_sclass = (sym->n_sclass & 0xff);
   cs->c_secnum = sym->n_scnum;
   cs->c_type = (unsigned) sym->n_type;
+  if (!SDB_TYPE (cs->c_type))
+    cs->c_type = 0;
 
   symnum += cs->c_nsyms;
 }
@@ -1206,8 +1205,9 @@ init_stringtab (chan, offset)
     int chan;
     long offset;
 {
-  long buffer;
+  long length;
   int val;
+  unsigned char lengthbuf[4];
 
   if (stringtab)
     {
@@ -1218,21 +1218,24 @@ init_stringtab (chan, offset)
   if (lseek (chan, offset, 0) < 0)
     return -1;
 
-  val = myread (chan, (char *)&buffer, sizeof buffer);
+  val = myread (chan, (char *)lengthbuf, sizeof lengthbuf);
+  length = bfd_h_get_32 (symfile_bfd, lengthbuf);
 
   /* If no string table is needed, then the file may end immediately
      after the symbols.  Just return with `stringtab' set to null. */
-  if (val != sizeof buffer || buffer == 0)
+  if (val != sizeof length || length < sizeof length)
     return 0;
 
-  stringtab = (char *) xmalloc (buffer);
+  stringtab = (char *) xmalloc (length);
   if (stringtab == NULL)
     return -1;
 
-  bcopy (&buffer, stringtab, sizeof buffer);
+  bcopy (&length, stringtab, sizeof length);
+  if (length == sizeof length)         /* Empty table -- just the count */
+    return 0;
 
-  val = myread (chan, stringtab + sizeof buffer, buffer - sizeof buffer);
-  if (val != buffer - sizeof buffer || stringtab[buffer - 1] != '\0')
+  val = myread (chan, stringtab + sizeof length, length - sizeof length);
+  if (val != length - sizeof length || stringtab[length - 1] != '\0')
     return -1;
 
   return 0;
@@ -1248,18 +1251,18 @@ free_stringtab ()
 
 static char *
 getsymname (symbol_entry)
-    SYMENT *symbol_entry;
+    struct internal_syment *symbol_entry;
 {
   static char buffer[SYMNMLEN+1];
   char *result;
 
-  if (symbol_entry->n_zeroes == 0)
+  if (symbol_entry->_n._n_n._n_zeroes == 0)
     {
-      result = stringtab + symbol_entry->n_offset;
+      result = stringtab + symbol_entry->_n._n_n._n_offset;
     }
   else
     {
-      strncpy (buffer, symbol_entry->n_name, SYMNMLEN);
+      strncpy (buffer, symbol_entry->_n._n_name, SYMNMLEN);
       buffer[SYMNMLEN] = '\0';
       result = buffer;
     }
@@ -1268,7 +1271,7 @@ getsymname (symbol_entry)
 
 static char *
 getfilename (aux_entry)
-    AUXENT *aux_entry;
+    union internal_auxent *aux_entry;
 {
   static char buffer[BUFSIZ];
   register char *temp;
@@ -1276,12 +1279,23 @@ getfilename (aux_entry)
   extern char *rindex ();
 
 #ifndef COFF_NO_LONG_FILE_NAMES
-  if (aux_entry->x_file.x_foff != 0)
-    strcpy (buffer, stringtab + aux_entry->x_file.x_foff);
+#if defined (x_zeroes)
+  /* Data General.  */
+  if (aux_entry->x_zeroes == 0)
+    strcpy (buffer, stringtab + aux_entry->x_offset);
+#else /* no x_zeroes */
+  if (aux_entry->x_file.x_n.x_zeroes == 0)
+    strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
+#endif /* no x_zeroes */
   else
-#endif
+#endif /* COFF_NO_LONG_FILE_NAMES */
     {
+#if defined (x_name)
+      /* Data General.  */
+      strncpy (buffer, aux_entry->x_name, FILNMLEN);
+#else
       strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
+#endif
       buffer[FILNMLEN] = '\0';
     }
   result = buffer;
@@ -1289,58 +1303,79 @@ getfilename (aux_entry)
     result = temp + 1;
   return (result);
 }
-
+\f
 /* Support for line number handling */
 static char *linetab = NULL;
 static long linetab_offset;
-static int linetab_count;
+static unsigned long linetab_size;
 
+/* Read in all the line numbers for fast lookups later.  Leave them in
+   external (unswapped) format in memory; we'll swap them as we enter
+   them into GDB's data structures.  */
 static int
-init_lineno (chan, offset, count)
+init_lineno (chan, offset, size)
     int chan;
     long offset;
-    int count;
+    int size;
 {
   int val;
 
+  linetab_offset = offset;
+  linetab_size = size;
+
+  if (size == 0)
+    return 0;
+
   if (lseek (chan, offset, 0) < 0)
     return -1;
   
-  if (linetab)
-    free (linetab);
-  linetab = (char *) xmalloc (count * LINESZ);
+  linetab = (char *) xmalloc (size);
 
-  val = myread (chan, linetab, count * LINESZ);
-  if (val != count * LINESZ)
+  val = myread (chan, linetab, size);
+  if (val != size)
     return -1;
 
-  linetab_offset = offset;
-  linetab_count = count;
+  make_cleanup (free, linetab);                /* Be sure it gets de-allocated. */
   return 0;
 }
 
+#if !defined (L_LNNO32)
+#define L_LNNO32(lp) ((lp)->l_lnno)
+#endif
+
 static void
 enter_linenos (file_offset, first_line, last_line)
     long file_offset;
     register int first_line;
     register int last_line;
 {
-  register char *rawptr = &linetab[file_offset - linetab_offset];
-  struct lineno lptr;
+  register char *rawptr;
+  struct internal_lineno lptr;
+
+  if (file_offset < linetab_offset)
+    {
+      complain (&lineno_complaint, file_offset);
+      if (file_offset > linetab_size)  /* Too big to be an offset? */
+       return;
+      file_offset += linetab_offset;  /* Try reading at that linetab offset */
+    }
+  
+  rawptr = &linetab[file_offset - linetab_offset];
 
   /* skip first line entry for each function */
   rawptr += LINESZ;
   /* line numbers start at one for the first line of the function */
   first_line--;
 
-  /* Bcopy since occaisionally rawptr isn't pointing at long
-     boundaries.  */
-  for (bcopy (rawptr, &lptr, LINESZ);
-       lptr.l_lnno && lptr.l_lnno <= last_line;
-       rawptr += LINESZ, bcopy (rawptr, &lptr, LINESZ))
-    {
-      record_line (first_line + lptr.l_lnno, lptr.l_addr.l_paddr);
-    }
+  for (;;) {
+    bfd_coff_swap_lineno_in (symfile_bfd, (LINENO *)rawptr, &lptr);
+    rawptr += LINESZ;
+    if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
+      record_line (first_line + L_LNNO32 (&lptr), lptr.l_addr.l_paddr);
+    else
+      break;
+  } 
 }
 \f
 static int
@@ -1403,7 +1438,7 @@ patch_opaque_types ()
       register int i;
 
       /* Go through the per-file symbols only */
-      b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1);
+      b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
       for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
        {
          register struct symbol *real_sym;
@@ -1429,22 +1464,21 @@ patch_opaque_types ()
                      !strcmp (name + 1, SYMBOL_NAME (sym) + 1))
                    {
                      if (prev)
-                       SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym);
+                       SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
                      else
-                       opaque_type_chain[hash]
-                         = (struct symbol *) SYMBOL_VALUE (sym);
+                       opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
 
                      patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym));
 
                      if (prev)
-                       sym = (struct symbol *) SYMBOL_VALUE (prev);
+                       sym = SYMBOL_VALUE_CHAIN (prev);
                      else
                        sym = opaque_type_chain[hash];
                    }
                  else
                    {
                      prev = sym;
-                     sym = (struct symbol *) SYMBOL_VALUE (sym);
+                     sym = SYMBOL_VALUE_CHAIN (sym);
                    }
                }
            }
@@ -1452,15 +1486,18 @@ patch_opaque_types ()
     }
 }
 \f
+#if defined (clipper)
+#define BELIEVE_PCC_PROMOTION 1
+#endif
+
 static struct symbol *
 process_coff_symbol (cs, aux)
      register struct coff_symbol *cs;
-     register AUXENT *aux;
+     register union internal_auxent *aux;
 {
   register struct symbol *sym
     = (struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol));
   char *name;
-  char *dot;
 #ifdef NAMES_HAVE_UNDERSCORE
   int offset = 1;
 #else
@@ -1501,11 +1538,13 @@ process_coff_symbol (cs, aux)
 
          case C_EXT:
            SYMBOL_CLASS (sym) = LOC_STATIC;
+           SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
            add_symbol_to_list (sym, &global_symbols);
            break;
 
          case C_STAT:
            SYMBOL_CLASS (sym) = LOC_STATIC;
+           SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
            if (within_function) {
              /* Static symbol of local scope */
              add_symbol_to_list (sym, &local_symbols);
@@ -1527,7 +1566,7 @@ process_coff_symbol (cs, aux)
          case C_ARG:
            SYMBOL_CLASS (sym) = LOC_ARG;
            add_symbol_to_list (sym, &local_symbols);
-#ifndef clipper           
+#if !defined (BELIEVE_PCC_PROMOTION)
            /* If PCC says a parameter is a short or a char,
               it is really an int.  */
            if (SYMBOL_TYPE (sym) == builtin_type_char
@@ -1542,7 +1581,7 @@ process_coff_symbol (cs, aux)
          case C_REGPARM:
            SYMBOL_CLASS (sym) = LOC_REGPARM;
            add_symbol_to_list (sym, &local_symbols);
-#ifndef clipper
+#if !defined (BELIEVE_PCC_PROMOTION)
            /* If PCC says a parameter is a short or a char,
               it is really an int.  */
            if (SYMBOL_TYPE (sym) == builtin_type_char
@@ -1571,7 +1610,7 @@ process_coff_symbol (cs, aux)
              {
                register int i = hashname (SYMBOL_NAME (sym));
 
-               SYMBOL_VALUE (sym) = (int) opaque_type_chain[i];
+               SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
                opaque_type_chain[i] = sym;
              }
            add_symbol_to_list (sym, &file_symbols);
@@ -1609,10 +1648,9 @@ struct type *
 decode_type (cs, c_type, aux)
      register struct coff_symbol *cs;
      unsigned int c_type;
-     register AUXENT *aux;
+     register union internal_auxent *aux;
 {
   register struct type *type = 0;
-  register int n;
   unsigned int new_c_type;
 
   if (c_type & ~N_BTMASK)
@@ -1636,7 +1674,7 @@ decode_type (cs, c_type, aux)
 
          /* Define an array type.  */
          /* auxent refers to array, not base type */
-         if (aux->x_sym.x_tagndx == 0)
+         if (aux->x_sym.x_tagndx.l == 0)
            cs->c_nsyms = 1;
 
          /* shift the indices down */
@@ -1661,9 +1699,9 @@ decode_type (cs, c_type, aux)
     }
 
   /* Reference to existing type */
-  if (cs->c_nsyms > 1 && aux->x_sym.x_tagndx != 0)
+  if (cs->c_nsyms > 1 && aux->x_sym.x_tagndx.l != 0)
     {
-      type = coff_alloc_type (aux->x_sym.x_tagndx);
+      type = coff_alloc_type (aux->x_sym.x_tagndx.l);
       return type;
     }
 
@@ -1678,12 +1716,12 @@ struct type *
 decode_function_type (cs, c_type, aux)
      register struct coff_symbol *cs;
      unsigned int c_type;
-     register AUXENT *aux;
+     register union internal_auxent *aux;
 {
-  if (aux->x_sym.x_tagndx == 0)
+  if (aux->x_sym.x_tagndx.l == 0)
     cs->c_nsyms = 1;   /* auxent refers to function, not base type */
 
-  return decode_type (cs, DECREF (cs->c_type), aux);
+  return decode_type (cs, DECREF (c_type), aux);
 }
 \f
 /* basic C types */
@@ -1693,7 +1731,7 @@ struct type *
 decode_base_type (cs, c_type, aux)
      register struct coff_symbol *cs;
      unsigned int c_type;
-     register AUXENT *aux;
+     register union internal_auxent *aux;
 {
   struct type *type;
 
@@ -1703,9 +1741,20 @@ decode_base_type (cs, c_type, aux)
         /* shows up with "void (*foo)();" structure members */
        return builtin_type_void;
 
+#if 0
+/* DGUX actually defines both T_ARG and T_VOID to the same value.  */
+#ifdef T_ARG
       case T_ARG:
-       /* shouldn't show up here */
-       break;
+       /* Shows up in DGUX, I think.  Not sure where.  */
+       return builtin_type_void;       /* shouldn't show up here */
+#endif
+#endif /* 0 */
+
+#ifdef T_VOID
+      case T_VOID:
+       /* Intel 960 COFF has this symbol and meaning.  */
+       return builtin_type_void;
+#endif
 
       case T_CHAR:
        return builtin_type_char;
@@ -1818,8 +1867,8 @@ read_struct_type (index, length, lastsym)
 #endif
   struct coff_symbol member_sym;
   register struct coff_symbol *ms = &member_sym;
-  SYMENT sub_sym;
-  AUXENT sub_aux;
+  struct internal_syment sub_sym;
+  union internal_auxent sub_aux;
   int done = 0;
 
   type = coff_alloc_type (index);
@@ -1887,7 +1936,9 @@ read_struct_type (index, length, lastsym)
 /* Read a definition of an enumeration type,
    and create and return a suitable type object.
    Also defines the symbols that represent the values of the type.  */
+/* Currently assumes it's sizeof (int) and doesn't use length.  */
 
+/* ARGSUSED */
 static struct type *
 read_enum_type (index, length, lastsym)
      int index;
@@ -1897,11 +1948,12 @@ read_enum_type (index, length, lastsym)
   register struct symbol *sym;
   register struct type *type;
   int nsyms = 0;
+  int done = 0;
   struct pending **symlist;
   struct coff_symbol member_sym;
   register struct coff_symbol *ms = &member_sym;
-  SYMENT sub_sym;
-  AUXENT sub_aux;
+  struct internal_syment sub_sym;
+  union internal_auxent sub_aux;
   struct pending *osyms, *syms;
   register int n;
   char *name;
@@ -1918,7 +1970,7 @@ read_enum_type (index, length, lastsym)
     symlist = &file_symbols;
   osyms = *symlist;
 
-  while (symnum < lastsym && symnum < nlist_nsyms_global)
+  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
     {
       read_one_sym (ms, &sub_sym, &sub_aux);
       name = ms->c_name;
@@ -1939,12 +1991,17 @@ read_enum_type (index, length, lastsym)
            break;
 
          case C_EOS:
+           /* Sometimes the linker (on 386/ix 2.0.2 at least) screws
+              up the count of how many symbols to read.  So stop
+              on .eos.  */
+           done = 1;
            break;
        }
     }
 
   /* Now fill in the fields of the type-structure.  */
 
+  /* FIXME: Should be sizeof (int) on target, not host.  */
   TYPE_LENGTH (type) = sizeof (int);
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   TYPE_NFIELDS (type) = nsyms;
@@ -1967,42 +2024,24 @@ read_enum_type (index, length, lastsym)
   return type;
 }
 
-/* This function is really horrible, but to avoid it, there would need
-   to be more filling in of forward references.  THIS SHOULD BE MOVED
-   OUT OF COFFREAD.C AND DBXREAD.C TO SOME PLACE WHERE IT CAN BE SHARED. */
-int
-fill_in_vptr_fieldno (type)
-     struct type *type;
-{
-  if (TYPE_VPTR_FIELDNO (type) < 0)
-    TYPE_VPTR_FIELDNO (type) =
-      fill_in_vptr_fieldno (TYPE_BASECLASS (type, 1));
-  return TYPE_VPTR_FIELDNO (type);
-}
-
-/* partial symbol tables are not implemented in coff, therefore
-   block_for_pc() (and others) will never decide to call this. */
+/* Register our ability to parse symbols for coff BFD files */
 
-extern struct symtab *
-psymtab_to_symtab ()
+static struct sym_fns coff_sym_fns =
 {
-  fatal ("error: Someone called psymtab_to_symtab\n");
-}
-
-/* These will stay zero all the time */
-struct psymbol_allocation_list global_psymbols, static_psymbols;
+    /* This assumes that 88kbcs implies TDESC and TDESC implies 88kbcs.
+       If that's not true, this can be relaxed, but if it is true,
+       it will just cause users grief if we try to read the wrong kind
+       of symbol file.  */
+#if defined (TDESC)
+    "m88kbcs", 8,
+#else /* not TDESC */
+    "coff", 4,
+#endif /* not TDESC */
+    coff_new_init, coff_symfile_init, coff_symfile_read,
+};
 
-_initialize_coff ()
+void
+_initialize_coffread ()
 {
-  symfile = 0;
-
-  bzero (&global_psymbols, sizeof (global_psymbols));
-  bzero (&static_psymbols, sizeof (static_psymbols));
-
-  add_com ("symbol-file", class_files, symbol_file_command,
-          "Load symbol table (in coff format) from executable file FILE.");
+  add_symtab_fns(&coff_sym_fns);
 }
-
-
-#endif /* COFF_FORMAT */
-
This page took 0.040374 seconds and 4 git commands to generate.