]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/coffread.c
run copyright.sh for 2011.
[thirdparty/binutils-gdb.git] / gdb / coffread.c
index ebbe6db59977358a549dcdcd5044341600c563b6..63a553882a0f2172b8836c45a49feded572a329c 100644 (file)
@@ -1,14 +1,14 @@
 /* Read coff symbol tables and convert to internal format, for GDB.
-   Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009,
+   2010, 2011 Free Software Foundation, Inc.
    Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
 
    This file is part of GDB.
 
    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 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "symtab.h"
 
 #include "coff-pe-read.h"
 
+#include "psymtab.h"
+
 extern void _initialize_coffread (void);
 
 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 */
+    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 */
 
-    CORE_ADDR textaddr;                /* Addr of .text section. */
-    unsigned int textsize;     /* Size of .text section. */
+    CORE_ADDR textaddr;                /* Addr of .text section.  */
+    unsigned int textsize;     /* Size of .text section.  */
     struct stab_section_list *stabsects;       /* .stab sections.  */
-    asection *stabstrsect;     /* Section pointer for .stab section */
+    asection *stabstrsect;     /* Section pointer for .stab section */
     char *stabstrdata;
   };
 
 /* Translate an external name string into a user-visible name.  */
 #define        EXTERNAL_NAME(string, abfd) \
-       (string[0] == bfd_get_symbol_leading_char(abfd)? string+1: string)
+       (string[0] == bfd_get_symbol_leading_char (abfd) \
+       ? string + 1 : string)
 
 /* 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
@@ -85,7 +86,8 @@ static bfd *nlist_bfd_global;
 static int nlist_nsyms_global;
 
 
-/* Pointers to scratch storage, used for reading raw symbols and auxents.  */
+/* Pointers to scratch storage, used for reading raw symbols and
+   auxents.  */
 
 static char *temp_sym;
 static char *temp_aux;
@@ -106,10 +108,10 @@ static unsigned local_n_tshift;
 #define        N_TMASK         local_n_tmask
 #define        N_TSHIFT        local_n_tshift
 
-/* Local variables that hold the sizes in the file of various COFF structures.
-   (We only need to know this to read them from the file -- BFD will then
-   translate the data in them, into `internal_xxx' structs in the right
-   byte order, alignment, etc.)  */
+/* Local variables that hold the sizes in the file of various COFF
+   structures.  (We only need to know this to read them from the file
+   -- BFD will then translate the data in them, into `internal_xxx'
+   structs in the right byte order, alignment, etc.)  */
 
 static unsigned local_linesz;
 static unsigned local_symesz;
@@ -124,14 +126,15 @@ static int pe_file;
 
 static struct symbol *opaque_type_chain[HASHSIZE];
 
-/* Simplified internal version of coff symbol table information */
+/* Simplified internal version of coff symbol table information */
 
 struct coff_symbol
   {
     char *c_name;
-    int c_symnum;              /* symbol number of this entry */
-    int c_naux;                        /* 0 if syment only, 1 if syment + auxent, etc */
-    long c_value;
+    int c_symnum;              /* Symbol number of this entry.  */
+    int c_naux;                        /* 0 if syment only, 1 if syment +
+                                  auxent, etc.  */
+    CORE_ADDR c_value;
     int c_sclass;
     int c_secnum;
     unsigned int c_type;
@@ -139,19 +142,25 @@ struct coff_symbol
 
 extern void stabsread_clear_cache (void);
 
-static struct type *coff_read_struct_type (int, int, int);
+static struct type *coff_read_struct_type (int, int, int,
+                                          struct objfile *);
 
 static struct type *decode_base_type (struct coff_symbol *,
-                                     unsigned int, union internal_auxent *);
+                                     unsigned int,
+                                     union internal_auxent *,
+                                     struct objfile *);
 
 static struct type *decode_type (struct coff_symbol *, unsigned int,
-                                union internal_auxent *);
+                                union internal_auxent *,
+                                struct objfile *);
 
 static struct type *decode_function_type (struct coff_symbol *,
                                          unsigned int,
-                                         union internal_auxent *);
+                                         union internal_auxent *,
+                                         struct objfile *);
 
-static struct type *coff_read_enum_type (int, int, int);
+static struct type *coff_read_enum_type (int, int, int,
+                                        struct objfile *);
 
 static struct symbol *process_coff_symbol (struct coff_symbol *,
                                           union internal_auxent *,
@@ -178,7 +187,8 @@ static void free_stringtab_cleanup (void *ignore);
 static int init_stringtab (bfd *, long);
 
 static void read_one_sym (struct coff_symbol *,
-                         struct internal_syment *, union internal_auxent *);
+                         struct internal_syment *,
+                         union internal_auxent *);
 
 static void coff_symtab_read (long, unsigned int, struct objfile *);
 \f
@@ -200,7 +210,7 @@ coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
 
   csi = (struct coff_symfile_info *) csip;
   name = bfd_get_section_name (abfd, sectp);
-  if (DEPRECATED_STREQ (name, ".text"))
+  if (strcmp (name, ".text") == 0)
     {
       csi->textaddr = bfd_section_vma (abfd, sectp);
       csi->textsize += bfd_section_size (abfd, sectp);
@@ -209,7 +219,7 @@ coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
     {
       csi->textsize += bfd_section_size (abfd, sectp);
     }
-  else if (DEPRECATED_STREQ (name, ".stabstr"))
+  else if (strcmp (name, ".stabstr") == 0)
     {
       csi->stabstrsect = sectp;
     }
@@ -255,33 +265,33 @@ static void
 find_targ_sec (bfd *abfd, asection *sect, void *obj)
 {
   struct find_targ_sec_arg *args = (struct find_targ_sec_arg *) obj;
+
   if (sect->target_index == args->targ_index)
     *args->resultp = sect;
 }
 
-/* Return the section number (SECT_OFF_*) that CS points to.  */
-static int
-cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
+/* Return the bfd_section that CS points to.  */
+static struct bfd_section*
+cs_to_bfd_section (struct coff_symbol *cs, struct objfile *objfile)
 {
   asection *sect = NULL;
   struct find_targ_sec_arg args;
-  int off = SECT_OFF_TEXT (objfile);
 
   args.targ_index = cs->c_secnum;
   args.resultp = &sect;
   bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
-  if (sect != NULL)
-    {
-      /* This is the section.  Figure out what SECT_OFF_* code it is.  */
-      if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
-       off = SECT_OFF_TEXT (objfile);
-      else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
-       off = SECT_OFF_DATA (objfile);
-      else
-       /* Just return the bfd section index. */
-       off = sect->index;
-    }
-  return off;
+  return sect;
+}
+
+/* Return the section number (SECT_OFF_*) that CS points to.  */
+static int
+cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
+{
+  asection *sect = cs_to_bfd_section (cs, objfile);
+
+  if (sect == NULL)
+    return SECT_OFF_TEXT (objfile);
+  return sect->index;
 }
 
 /* Return the address of the section of a COFF symbol.  */
@@ -359,11 +369,10 @@ static void
 coff_start_symtab (char *name)
 {
   start_symtab (
-  /* We fill in the filename later.  start_symtab puts
-     this pointer into last_source_file and we put it in
-     subfiles->name, which end_symtab frees; that's why
-     it must be malloc'd.  */
-                savestring (name, strlen (name)),
+  /* We fill in the filename later.  start_symtab puts this pointer
+     into last_source_file and we put it in subfiles->name, which
+     end_symtab frees; that's why it must be malloc'd.  */
+                xstrdup (name),
   /* We never know the directory name for COFF.  */
                 NULL,
   /* The start address is irrelevant, since we set
@@ -374,23 +383,24 @@ coff_start_symtab (char *name)
 
 /* 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.  */
+   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.  */
 
 static void
 complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
 {
   if (last_source_file != NULL)
     xfree (last_source_file);
-  last_source_file = savestring (name, strlen (name));
+  last_source_file = xstrdup (name);
   current_source_start_addr = start_addr;
   current_source_end_addr = start_addr + size;
 }
 
-/* Finish the symbol definitions for one main source file,
-   close off all the lexical contexts for that file
-   (creating struct block's for them), then make the
-   struct symtab for that file and put it in the list of all such. */
+/* Finish the symbol definitions for one main source file, close off
+   all the lexical contexts for that file (creating struct block's for
+   them), then make the struct symtab for that file and put it in the
+   list of all such.  */
 
 static void
 coff_end_symtab (struct objfile *objfile)
@@ -399,24 +409,28 @@ coff_end_symtab (struct objfile *objfile)
 
   last_source_start_addr = current_source_start_addr;
 
-  symtab = end_symtab (current_source_end_addr, objfile, SECT_OFF_TEXT (objfile));
-
-  if (symtab != NULL)
-    free_named_symtabs (symtab->filename);
+  symtab = end_symtab (current_source_end_addr, objfile,
+                      SECT_OFF_TEXT (objfile));
 
-  /* Reinitialize for beginning of new file. */
+  /* Reinitialize for beginning of new file.  */
   last_source_file = NULL;
 }
 \f
-static void
-record_minimal_symbol (char *name, CORE_ADDR address,
-                      enum minimal_symbol_type type, struct objfile *objfile)
+static struct minimal_symbol *
+record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
+                      enum minimal_symbol_type type, int section, 
+                      struct objfile *objfile)
 {
-  /* We don't want TDESC entry points in the minimal symbol table */
-  if (name[0] == '@')
-    return;
+  struct bfd_section *bfd_section;
+
+  /* We don't want TDESC entry points in the minimal symbol table.  */
+  if (cs->c_name[0] == '@')
+    return NULL;
 
-  prim_record_minimal_symbol (name, address, type, objfile);
+  bfd_section = cs_to_bfd_section (cs, objfile);
+  return prim_record_minimal_symbol_and_info (cs->c_name, address,
+                                             type, section,
+                                             bfd_section, objfile);
 }
 \f
 /* coff_symfile_init ()
@@ -426,26 +440,29 @@ record_minimal_symbol (char *name, CORE_ADDR address,
    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
+   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).  */
+   The ultimate result is a new symtab (or, FIXME, eventually a
+   psymtab).  */
 
 static void
 coff_symfile_init (struct objfile *objfile)
 {
-  /* Allocate struct to keep track of stab reading. */
+  /* Allocate struct to keep track of stab reading.  */
   objfile->deprecated_sym_stab_info = (struct dbx_symfile_info *)
     xmalloc (sizeof (struct dbx_symfile_info));
 
   memset (objfile->deprecated_sym_stab_info, 0,
          sizeof (struct dbx_symfile_info));
 
-  /* Allocate struct to keep track of the symfile */
-  objfile->deprecated_sym_private = xmalloc (sizeof (struct coff_symfile_info));
+  /* Allocate struct to keep track of the symfile.  */
+  objfile->deprecated_sym_private
+    = xmalloc (sizeof (struct coff_symfile_info));
 
-  memset (objfile->deprecated_sym_private, 0, sizeof (struct coff_symfile_info));
+  memset (objfile->deprecated_sym_private, 0,
+         sizeof (struct coff_symfile_info));
 
   /* COFF objects may be reordered, so set OBJF_REORDERED.  If we
      find this causes a significant slowdown in gdb then we could
@@ -455,9 +472,9 @@ coff_symfile_init (struct objfile *objfile)
   init_entry_point_info (objfile);
 }
 
-/* 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.  */
+/* 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.  */
 
 static void
 find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
@@ -466,18 +483,18 @@ find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
   int size, count;
   file_ptr offset, maxoff;
 
-/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+  /* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
   count = asect->lineno_count;
-/* End of warning */
+  /* End of warning.  */
 
   if (count == 0)
     return;
   size = count * local_linesz;
 
   info = (struct coff_symfile_info *) vpinfo;
-/* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
+  /* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
   offset = asect->line_filepos;
-/* End of warning */
+  /* End of warning.  */
 
   if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
     info->min_lineno_offset = offset;
@@ -496,7 +513,7 @@ static bfd *symfile_bfd;
 /* Read a symbol file, after initialization by coff_symfile_init.  */
 
 static void
-coff_symfile_read (struct objfile *objfile, int mainline)
+coff_symfile_read (struct objfile *objfile, int symfile_flags)
 {
   struct coff_symfile_info *info;
   struct dbx_symfile_info *dbxinfo;
@@ -509,12 +526,10 @@ coff_symfile_read (struct objfile *objfile, int mainline)
   int stringtab_offset;
   struct cleanup *back_to, *cleanup_minimal_symbols;
   int stabstrsize;
-  int len;
-  char * target;
   
   info = (struct coff_symfile_info *) objfile->deprecated_sym_private;
   dbxinfo = objfile->deprecated_sym_stab_info;
-  symfile_bfd = abfd;          /* Kludge for swap routines */
+  symfile_bfd = abfd;          /* Kludge for swap routines */
 
 /* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
   num_symbols = bfd_get_symcount (abfd);       /* How many syms */
@@ -548,7 +563,7 @@ coff_symfile_read (struct objfile *objfile, int mainline)
     strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0
     || strncmp (bfd_get_target (objfile->obfd), "epoc-pe", 7) == 0;
 
-/* End of warning */
+  /* End of warning.  */
 
   info->min_lineno_offset = 0;
   info->max_lineno_offset = 0;
@@ -576,7 +591,7 @@ coff_symfile_read (struct objfile *objfile, int mainline)
       val = init_lineno (abfd, info->min_lineno_offset,
                          info->max_lineno_offset - info->min_lineno_offset);
       if (val < 0)
-        error ("\"%s\": error reading line numbers\n", name);
+        error (_("\"%s\": error reading line numbers."), name);
     }
 
   /* Now read the string table, all at once.  */
@@ -584,7 +599,7 @@ coff_symfile_read (struct objfile *objfile, int mainline)
   make_cleanup (free_stringtab_cleanup, 0 /*ignore*/);
   val = init_stringtab (abfd, stringtab_offset);
   if (val < 0)
-    error ("\"%s\": can't get string table", name);
+    error (_("\"%s\": can't get string table"), name);
 
   init_minimal_symbol_collection ();
   cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols ();
@@ -594,32 +609,22 @@ coff_symfile_read (struct objfile *objfile, int mainline)
 
   coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
 
-  /* Install any minimal symbols that have been collected as the current
-     minimal symbols for this objfile.  */
+  /* Install any minimal symbols that have been collected as the
+     current minimal symbols for this objfile.  */
 
   install_minimal_symbols (objfile);
 
   /* Free the installed minimal symbol data.  */
   do_cleanups (cleanup_minimal_symbols);
 
-  /* If we are reinitializing, or if we have not loaded syms yet,
-     empty the psymtab.  "mainline" is cleared so the *_read_psymtab
-     functions do not all re-initialize it.  */
-  if (mainline)
-    {
-      init_psymbol_list (objfile, 0);
-      mainline = 0;
-    }
-
   bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
 
   if (info->stabsects)
     {
       if (!info->stabstrsect)
        {
-         error (("The debugging information in `%s' is corrupted.\n"
-                 "The file has a `.stabs' section, but no `.stabstr' "
-                 "section."),
+         error (_("The debugging information in `%s' is corrupted.\n"
+                  "The file has a `.stabs' section, but no `.stabstr' section."),
                 name);
        }
 
@@ -630,7 +635,6 @@ coff_symfile_read (struct objfile *objfile, int mainline)
       stabstrsize = bfd_section_size (abfd, info->stabstrsect);
 
       coffstab_build_psymtabs (objfile,
-                              mainline,
                               info->textaddr, info->textsize,
                               info->stabsects,
                               info->stabstrsect->filepos, stabstrsize);
@@ -638,11 +642,27 @@ coff_symfile_read (struct objfile *objfile, int mainline)
   if (dwarf2_has_info (objfile))
     {
       /* DWARF2 sections.  */
-      dwarf2_build_psymtabs (objfile, mainline);
+      dwarf2_build_psymtabs (objfile);
     }
 
   dwarf2_build_frame_info (objfile);
 
+  /* Try to add separate debug file if no symbols table found.   */
+  if (!objfile_has_partial_symbols (objfile))
+    {
+      char *debugfile;
+
+      debugfile = find_separate_debug_file_by_debuglink (objfile);
+
+      if (debugfile)
+       {
+         bfd *abfd = symfile_bfd_open (debugfile);
+
+         symbol_file_add_separate (abfd, symfile_flags, objfile);
+         xfree (debugfile);
+       }
+    }
+
   do_cleanups (back_to);
 }
 
@@ -651,10 +671,11 @@ coff_new_init (struct objfile *ignore)
 {
 }
 
-/* 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. */
+/* 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
 coff_symfile_finish (struct objfile *objfile)
@@ -664,8 +685,10 @@ coff_symfile_finish (struct objfile *objfile)
       xfree (objfile->deprecated_sym_private);
     }
 
-  /* Let stabs reader clean up */
+  /* Let stabs reader clean up */
   stabsread_clear_cache ();
+
+  dwarf2_free_objfile (objfile);
 }
 \f
 
@@ -678,6 +701,7 @@ static void
 coff_symtab_read (long symtab_offset, unsigned int nsyms,
                  struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct context_stack *new;
   struct coff_symbol coff_symbol;
   struct coff_symbol *cs = &coff_symbol;
@@ -700,10 +724,11 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
   long fcn_line_ptr = 0;
   int val;
   CORE_ADDR tmpaddr;
+  struct minimal_symbol *msym;
 
   /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
-     it's hard to know I've really worked around it.  The fix should be
-     harmless, anyway).  The symptom of the bug is that the first
+     it's hard to know I've really worked around it.  The fix should
+     be harmless, anyway).  The symptom of the bug is that the first
      fread (in read_one_sym), will (in my example) actually get data
      from file offset 268, when the fseek was to 264 (and ftell shows
      264).  This causes all hell to break loose.  I was unable to
@@ -717,7 +742,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 
   bfd_seek (objfile->obfd, 0, 0);
 
-  /* Position to read the symbol table. */
+  /* Position to read the symbol table.  */
   val = bfd_seek (objfile->obfd, (long) symtab_offset, 0);
   if (val < 0)
     perror_with_name (objfile->name);
@@ -728,7 +753,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
   last_source_file = NULL;
   memset (opaque_type_chain, 0, sizeof opaque_type_chain);
 
-  if (type_vector)             /* Get rid of previous one */
+  if (type_vector)             /* Get rid of previous one */
     xfree (type_vector);
   type_vector_length = 160;
   type_vector = (struct type **)
@@ -750,11 +775,18 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
            coff_end_symtab (objfile);
 
          coff_start_symtab ("_globals_");
+         /* coff_start_symtab will set the language of this symtab to
+            language_unknown, since such a ``file name'' is not
+            recognized.  Override that with the minimal language to
+            allow printing values in this symtab.  */
+         current_subfile->language = language_minimal;
          complete_symtab ("_globals_", 0, 0);
-         /* done with all files, everything from here on out is globals */
+         /* Done with all files, everything from here on out is
+            globals.  */
        }
 
-      /* Special case for file with type declarations only, no text.  */
+      /* Special case for file with type declarations only, no
+        text.  */
       if (!last_source_file && SDB_TYPE (cs->c_type)
          && cs->c_secnum == N_DEBUG)
        complete_symtab (filestring, 0, 0);
@@ -762,9 +794,14 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
       /* Typedefs should not be treated as symbol definitions.  */
       if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
        {
-         /* Record all functions -- external and static -- in minsyms. */
-         tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-         record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile);
+         /* Record all functions -- external and static -- in
+            minsyms.  */
+         int section = cs_to_section (cs, objfile);
+
+         tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets,
+                                           SECT_OFF_TEXT (objfile));
+         record_minimal_symbol (cs, tmpaddr, mst_text,
+                                section, objfile);
 
          fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
          fcn_start_addr = tmpaddr;
@@ -783,13 +820,14 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
        case C_LINE:
        case C_ALIAS:
        case C_HIDDEN:
-         complaint (&symfile_complaints, "Bad n_sclass for symbol %s",
+         complaint (&symfile_complaints,
+                    _("Bad n_sclass for symbol %s"),
                     cs->c_name);
          break;
 
        case C_FILE:
-         /* c_value field contains symnum of next .file entry in table
-            or symnum of first global after last .file.  */
+         /* c_value field contains symnum of next .file entry in
+            table or symnum of first global after last .file.  */
          next_file_symnum = cs->c_value;
          if (cs->c_naux > 0)
            filestring = coff_getfilename (&main_aux);
@@ -806,12 +844,12 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
          in_source_file = 1;
          break;
 
-         /* C_LABEL is used for labels and static functions.  Including
-            it here allows gdb to see static functions when no debug
-            info is available.  */
+         /* C_LABEL is used for labels and static functions.
+            Including it here allows gdb to see static functions when
+            no debug info is available.  */
        case C_LABEL:
-         /* However, labels within a function can make weird backtraces,
-            so filter them out (from phdm@macqel.be). */
+         /* However, labels within a function can make weird
+            backtraces, so filter them out (from phdm@macqel.be).  */
          if (within_function)
            break;
        case C_STAT:
@@ -820,20 +858,21 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
        case C_THUMBSTATFUNC:
          if (cs->c_name[0] == '.')
            {
-             if (DEPRECATED_STREQ (cs->c_name, ".text"))
+             if (strcmp (cs->c_name, ".text") == 0)
                {
-                 /* FIXME:  don't wire in ".text" as section name
-                    or symbol name! */
-                 /* Check for in_source_file deals with case of
-                    a file with debugging symbols
-                    followed by a later file with no symbols.  */
+                 /* FIXME: don't wire in ".text" as section name or
+                    symbol name!  */
+                 /* 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 + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+                   cs->c_value + ANOFFSET (objfile->section_offsets,
+                                           SECT_OFF_TEXT (objfile)),
                                     main_aux.x_scn.x_scnlen);
                  in_source_file = 0;
                }
-             /* flush rest of '.' symbols */
+             /* Flush rest of '.' symbols.  */
              break;
            }
          else if (!SDB_TYPE (cs->c_type)
@@ -849,7 +888,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
            /* 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 '.' */
+         /* Fall in for static symbols that don't start with '.'  */
        case C_THUMBEXT:
        case C_THUMBEXTFUNC:
        case C_EXT:
@@ -868,6 +907,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
                /* This is a common symbol.  See if the target
                   environment knows where it has been relocated to.  */
                CORE_ADDR reladdr;
+
                if (target_lookup_symbol (cs->c_name, &reladdr))
                  {
                    /* Error in lookup; ignore symbol.  */
@@ -884,58 +924,59 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
            else if (cs->c_secnum == N_ABS)
              {
                /* Use the correct minimal symbol type (and don't
-                  relocate) for absolute values. */
+                  relocate) for absolute values.  */
                ms_type = mst_abs;
                sec = cs_to_section (cs, objfile);
                tmpaddr = cs->c_value;
              }
            else
              {
+               asection *bfd_section = cs_to_bfd_section (cs, objfile);
+
                sec = cs_to_section (cs, objfile);
                tmpaddr = cs->c_value;
-               /* Statics in a PE file also get relocated */
+               /* Statics in a PE file also get relocated */
                if (cs->c_sclass == C_EXT
                    || cs->c_sclass == C_THUMBEXTFUNC
                    || cs->c_sclass == C_THUMBEXT
                    || (pe_file && (cs->c_sclass == C_STAT)))
                  tmpaddr += ANOFFSET (objfile->section_offsets, sec);
 
-               if (sec == SECT_OFF_TEXT (objfile))
+               if (bfd_section->flags & SEC_CODE)
                  {
                    ms_type =
                      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
                      || cs->c_sclass == C_THUMBEXT ?
                      mst_text : mst_file_text;
-                   tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr);
+                   tmpaddr = gdbarch_smash_text_address (gdbarch, tmpaddr);
                  }
-               else if (sec == SECT_OFF_DATA (objfile))
+               else if (bfd_section->flags & SEC_ALLOC
+                        && bfd_section->flags & SEC_LOAD)
                  {
                    ms_type =
-                     cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
-                     mst_data : mst_file_data;
+                     cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
+                     mst_data : mst_file_data;
                  }
-               else if (sec == SECT_OFF_BSS (objfile))
+               else if (bfd_section->flags & SEC_ALLOC)
                  {
                    ms_type =
-                     cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
-                     mst_data : mst_file_data;
+                     cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
+                     ? mst_bss : mst_file_bss;
                  }
                else
                  ms_type = mst_unknown;
              }
 
-           if (cs->c_name[0] != '@' /* Skip tdesc symbols */ )
-             {
-               struct minimal_symbol *msym;
-               msym = prim_record_minimal_symbol_and_info
-                 (cs->c_name, tmpaddr, ms_type, NULL,
-                  sec, NULL, objfile);
-               if (msym)
-                 COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
-             }
+           msym = record_minimal_symbol (cs, tmpaddr, ms_type,
+                                         sec, objfile);
+           if (msym)
+             gdbarch_coff_make_msymbol_special (gdbarch,
+                                                cs->c_sclass, msym);
+
            if (SDB_TYPE (cs->c_type))
              {
                struct symbol *sym;
+
                sym = process_coff_symbol
                  (cs, &main_aux, objfile);
                SYMBOL_VALUE (sym) = tmpaddr;
@@ -945,16 +986,18 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
          break;
 
        case C_FCN:
-         if (DEPRECATED_STREQ (cs->c_name, ".bf"))
+         if (strcmp (cs->c_name, ".bf") == 0)
            {
              within_function = 1;
 
-             /* value contains address of first non-init type code */
+             /* Value contains address of first non-init type
+                code.  */
              /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
-                contains line number of '{' } */
+                contains line number of '{' } */
              if (cs->c_naux != 1)
                complaint (&symfile_complaints,
-                          "`.bf' symbol %d has no aux entry", cs->c_symnum);
+                          _("`.bf' symbol %d has no aux entry"),
+                          cs->c_symnum);
              fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
              fcn_first_line_addr = cs->c_value;
 
@@ -965,21 +1008,22 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
              new = push_context (depth, fcn_start_addr);
              fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
              new->name =
-               process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
+               process_coff_symbol (&fcn_cs_saved, 
+                                    &fcn_aux_saved, objfile);
            }
-         else if (DEPRECATED_STREQ (cs->c_name, ".ef"))
+         else if (strcmp (cs->c_name, ".ef") == 0)
            {
              if (!within_function)
-               error ("Bad coff function information\n");
-             /* the value of .ef is the address of epilogue code;
+               error (_("Bad coff function information."));
+             /* The value of .ef is the address of epilogue code;
                 not useful for gdb.  */
              /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
                 contains number of lines to '}' */
 
              if (context_stack_depth <= 0)
-               {               /* We attempted to pop an empty context stack */
+               {       /* We attempted to pop an empty context stack.  */
                  complaint (&symfile_complaints,
-                            "`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d",
+                            _("`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d"),
                             cs->c_symnum);
                  within_function = 0;
                  break;
@@ -990,7 +1034,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
              if (context_stack_depth > 0 || new == NULL)
                {
                  complaint (&symfile_complaints,
-                            "Unmatched .ef symbol(s) ignored starting at symnum %d",
+                            _("Unmatched .ef symbol(s) ignored starting at symnum %d"),
                             cs->c_symnum);
                  within_function = 0;
                  break;
@@ -998,7 +1042,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
              if (cs->c_naux != 1)
                {
                  complaint (&symfile_complaints,
-                            "`.ef' symbol %d has no aux entry", cs->c_symnum);
+                            _("`.ef' symbol %d has no aux entry"),
+                            cs->c_symnum);
                  fcn_last_line = 0x7FFFFFFF;
                }
              else
@@ -1007,35 +1052,25 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
                }
              /* fcn_first_line is the line number of the opening '{'.
                 Do not record it - because it would affect gdb's idea
-                of the line number of the first statement of the function -
-                except for one-line functions, for which it is also the line
-                number of all the statements and of the closing '}', and
-                for which we do not have any other statement-line-number. */
+                of the line number of the first statement of the
+                function - except for one-line functions, for which
+                it is also the line number of all the statements and
+                of the closing '}', and for which we do not have any
+                other statement-line-number.  */
              if (fcn_last_line == 1)
                record_line (current_subfile, fcn_first_line,
-                            fcn_first_line_addr);
+                            gdbarch_addr_bits_remove (gdbarch,
+                                                      fcn_first_line_addr));
              else
-               enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line,
-                              objfile);
-
-             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
-                           + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
-#else
+               enter_linenos (fcn_line_ptr, fcn_first_line,
+                              fcn_last_line, objfile);
+
+             finish_block (new->name, &local_symbols,
+                           new->old_blocks, new->start_addr,
                            fcn_cs_saved.c_value
                            + fcn_aux_saved.x_sym.x_misc.x_fsize
-                           + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
-#endif
+                           + ANOFFSET (objfile->section_offsets,
+                                       SECT_OFF_TEXT (objfile)),
                            objfile
                );
              within_function = 0;
@@ -1043,18 +1078,19 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
          break;
 
        case C_BLOCK:
-         if (DEPRECATED_STREQ (cs->c_name, ".bb"))
+         if (strcmp (cs->c_name, ".bb") == 0)
            {
              tmpaddr = cs->c_value;
-             tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+             tmpaddr += ANOFFSET (objfile->section_offsets,
+                                  SECT_OFF_TEXT (objfile));
              push_context (++depth, tmpaddr);
            }
-         else if (DEPRECATED_STREQ (cs->c_name, ".eb"))
+         else if (strcmp (cs->c_name, ".eb") == 0)
            {
              if (context_stack_depth <= 0)
-               {               /* We attempted to pop an empty context stack */
+               {       /* We attempted to pop an empty context stack. */
                  complaint (&symfile_complaints,
-                            "`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d",
+                            _("`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d"),
                             cs->c_symnum);
                  break;
                }
@@ -1062,15 +1098,16 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
              new = pop_context ();
              if (depth-- != new->depth)
                {
-                 complaint (&symfile_complaints,
-                            "Mismatched .eb symbol ignored starting at symnum %d",
+                 complaint (&symfile_complaints, 
+                            _("Mismatched .eb symbol ignored starting at symnum %d"),
                             symnum);
                  break;
                }
              if (local_symbols && context_stack_depth > 0)
                {
                  tmpaddr =
-                   cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+                   cs->c_value + ANOFFSET (objfile->section_offsets,
+                                           SECT_OFF_TEXT (objfile));
                  /* Make a block for the local symbols within.  */
                  finish_block (0, &local_symbols, new->old_blocks,
                                new->start_addr, tmpaddr, objfile);
@@ -1088,8 +1125,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 
   if ((nsyms == 0) && (pe_file))
     {
-      /* We've got no debugging symbols, but it's is a portable
-        executable, so try to read the export table */
+      /* We've got no debugging symbols, but it's a portable
+        executable, so try to read the export table */
       read_pe_exported_syms (objfile);
     }
 
@@ -1106,9 +1143,10 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 \f
 /* Routines for reading headers and symbols from executable.  */
 
-/* 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.  */
+/* 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 (struct coff_symbol *cs,
@@ -1116,20 +1154,30 @@ read_one_sym (struct coff_symbol *cs,
              union internal_auxent *aux)
 {
   int i;
+  bfd_size_type bytes;
 
   cs->c_symnum = symnum;
-  bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
+  bytes = bfd_bread (temp_sym, local_symesz, nlist_bfd_global);
+  if (bytes != local_symesz)
+    error ("%s: error reading symbols", current_objfile->name);
   bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym);
   cs->c_naux = sym->n_numaux & 0xff;
   if (cs->c_naux >= 1)
     {
-      bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
-      bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,
+      bytes  = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+      if (bytes != local_auxesz)
+       error ("%s: error reading symbols", current_objfile->name);
+      bfd_coff_swap_aux_in (symfile_bfd, temp_aux,
+                           sym->n_type, sym->n_sclass,
                            0, cs->c_naux, (char *) aux);
       /* If more than one aux entry, read past it (only the first aux
-         is important). */
+         is important).  */
       for (i = 1; i < cs->c_naux; i++)
-       bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+       {
+         bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+         if (bytes != local_auxesz)
+           error ("%s: error reading symbols", current_objfile->name);
+       }
     }
   cs->c_name = getsymname (sym);
   cs->c_value = sym->n_value;
@@ -1141,7 +1189,7 @@ read_one_sym (struct coff_symbol *cs,
 
 #if 0
   if (cs->c_sclass & 128)
-    printf ("thumb symbol %s, class 0x%x\n", cs->c_name, cs->c_sclass);
+    printf (_("thumb symbol %s, class 0x%x\n"), cs->c_name, cs->c_sclass);
 #endif
 
   symnum += 1 + cs->c_naux;
@@ -1175,7 +1223,7 @@ read_one_sym (struct coff_symbol *cs,
     }
 }
 \f
-/* Support for string table handling */
+/* Support for string table handling */
 
 static char *stringtab = NULL;
 
@@ -1189,7 +1237,7 @@ init_stringtab (bfd *abfd, long offset)
   free_stringtab ();
 
   /* If the file is stripped, the offset might be zero, indicating no
-     string table.  Just return with `stringtab' set to null. */
+     string table.  Just return with `stringtab' set to null.  */
   if (offset == 0)
     return 0;
 
@@ -1200,19 +1248,19 @@ init_stringtab (bfd *abfd, long offset)
   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. */
+     after the symbols.  Just return with `stringtab' set to null.  */
   if (val != sizeof lengthbuf || length < sizeof lengthbuf)
     return 0;
 
   stringtab = (char *) xmalloc (length);
-  /* This is in target format (probably not very useful, and not currently
-     used), not host format.  */
+  /* This is in target format (probably not very useful, and not
+     currently used), not host format.  */
   memcpy (stringtab, lengthbuf, sizeof lengthbuf);
-  if (length == sizeof length) /* Empty table -- just the count */
+  if (length == sizeof length) /* Empty table -- just the count */
     return 0;
 
-  val = bfd_bread (stringtab + sizeof lengthbuf, length - sizeof lengthbuf,
-                  abfd);
+  val = bfd_bread (stringtab + sizeof lengthbuf, 
+                  length - sizeof lengthbuf, abfd);
   if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
     return -1;
 
@@ -1254,9 +1302,9 @@ getsymname (struct internal_syment *symbol_entry)
   return result;
 }
 
-/* Extract the file name from the aux entry of a C_FILE symbol.  Return
-   only the last component of the name.  Result is in static storage and
-   is only good for temporary use.  */
+/* Extract the file name from the aux entry of a C_FILE symbol.
+   Return only the last component of the name.  Result is in static
+   storage and is only good for temporary use.  */
 
 static char *
 coff_getfilename (union internal_auxent *aux_entry)
@@ -1308,14 +1356,14 @@ init_lineno (bfd *abfd, long offset, int size)
   if (bfd_seek (abfd, offset, 0) < 0)
     return -1;
 
-  /* Allocate the desired table, plus a sentinel */
+  /* Allocate the desired table, plus a sentinel */
   linetab = (char *) xmalloc (size + local_linesz);
 
   val = bfd_bread (linetab, size, abfd);
   if (val != size)
     return -1;
 
-  /* Terminate it with an all-zero sentinel record */
+  /* Terminate it with an all-zero sentinel record */
   memset (linetab + size, 0, local_linesz);
 
   return 0;
@@ -1343,6 +1391,7 @@ static void
 enter_linenos (long file_offset, int first_line,
               int last_line, struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   char *rawptr;
   struct internal_lineno lptr;
 
@@ -1351,18 +1400,19 @@ enter_linenos (long file_offset, int first_line,
   if (file_offset < linetab_offset)
     {
       complaint (&symfile_complaints,
-                "Line number pointer %ld lower than start of line numbers",
+                _("Line number pointer %ld lower than start of line numbers"),
                 file_offset);
-      if (file_offset > linetab_size)  /* Too big to be an offset? */
+      if (file_offset > linetab_size)  /* Too big to be an offset?  */
        return;
-      file_offset += linetab_offset;   /* Try reading at that linetab offset */
+      file_offset += linetab_offset;   /* Try reading at that linetab
+                                          offset.  */
     }
 
   rawptr = &linetab[file_offset - linetab_offset];
 
-  /* skip first line entry for each function */
+  /* Skip first line entry for each function.  */
   rawptr += local_linesz;
-  /* line numbers start at one for the first line of the function */
+  /* Line numbers start at one for the first line of the function.  */
   first_line--;
 
   /* If the line number table is full (e.g. 64K lines in COFF debug
@@ -1373,11 +1423,16 @@ enter_linenos (long file_offset, int first_line,
       bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
       rawptr += local_linesz;
       /* The next function, or the sentinel, will have L_LNNO32 zero;
-        we exit. */
+        we exit.  */
       if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
-       record_line (current_subfile, first_line + L_LNNO32 (&lptr),
-                    lptr.l_addr.l_paddr
-                    + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)));
+       {
+         CORE_ADDR addr = lptr.l_addr.l_paddr;
+         addr += ANOFFSET (objfile->section_offsets,
+                           SECT_OFF_TEXT (objfile));
+         record_line (current_subfile,
+                      first_line + L_LNNO32 (&lptr),
+                      gdbarch_addr_bits_remove (gdbarch, addr));
+       }
       else
        break;
     }
@@ -1392,20 +1447,25 @@ patch_type (struct type *type, struct type *real_type)
 
   TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
   TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
-  TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size);
+  TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target,
+                                                     field_size);
 
-  memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size);
+  memcpy (TYPE_FIELDS (target), 
+         TYPE_FIELDS (real_target), 
+         field_size);
 
   if (TYPE_NAME (real_target))
     {
       if (TYPE_NAME (target))
        xfree (TYPE_NAME (target));
-      TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL);
+      TYPE_NAME (target) = concat (TYPE_NAME (real_target), 
+                                  (char *) NULL);
     }
 }
 
 /* Patch up all appropriate typedef symbols in the opaque_type_chains
-   so that they can be used to print out opaque data structures properly.  */
+   so that they can be used to print out opaque data structures
+   properly.  */
 
 static void
 patch_opaque_types (struct symtab *s)
@@ -1414,7 +1474,7 @@ patch_opaque_types (struct symtab *s)
   struct dict_iterator iter;
   struct symbol *real_sym;
 
-  /* Go through the per-file symbols only */
+  /* Go through the per-file symbols only */
   b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
   ALL_BLOCK_SYMBOLS (b, iter, real_sym)
     {
@@ -1422,20 +1482,20 @@ patch_opaque_types (struct symtab *s)
          Remove syms from the chain when their types are stored,
          but search the whole chain, as there may be several syms
          from different files with the same name.  */
-      if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
-         SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN &&
-         TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
-         TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
+      if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF
+         && SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN
+         && TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR
+         && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
        {
-         char *name = DEPRECATED_SYMBOL_NAME (real_sym);
+         char *name = SYMBOL_LINKAGE_NAME (real_sym);
          int hash = hashname (name);
          struct symbol *sym, *prev;
 
          prev = 0;
          for (sym = opaque_type_chain[hash]; sym;)
            {
-             if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
-                 strcmp (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0)
+             if (name[0] == SYMBOL_LINKAGE_NAME (sym)[0]
+                 && strcmp (name + 1, SYMBOL_LINKAGE_NAME (sym) + 1) == 0)
                {
                  if (prev)
                    {
@@ -1467,21 +1527,31 @@ patch_opaque_types (struct symtab *s)
     }
 }
 \f
+static int
+coff_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+  return gdbarch_sdb_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+}
+
+static const struct symbol_register_ops coff_register_funcs = {
+  coff_reg_to_regnum
+};
+
 static struct symbol *
 process_coff_symbol (struct coff_symbol *cs,
                     union internal_auxent *aux,
                     struct objfile *objfile)
 {
   struct symbol *sym
-  = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
-                                    sizeof (struct symbol));
+    = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
+                                      sizeof (struct symbol));
   char *name;
 
   memset (sym, 0, sizeof (struct symbol));
   name = cs->c_name;
   name = EXTERNAL_NAME (name, objfile->obfd);
-  SYMBOL_LANGUAGE (sym) = language_auto;
-  SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
+  SYMBOL_SET_LANGUAGE (sym, current_subfile->language);
+  SYMBOL_SET_NAMES (sym, name, strlen (name), 1, objfile);
 
   /* default assumptions */
   SYMBOL_VALUE (sym) = cs->c_value;
@@ -1490,9 +1560,11 @@ process_coff_symbol (struct coff_symbol *cs,
 
   if (ISFCN (cs->c_type))
     {
-      SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+      SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets,
+                                     SECT_OFF_TEXT (objfile));
       SYMBOL_TYPE (sym) =
-       lookup_function_type (decode_function_type (cs, cs->c_type, aux));
+       lookup_function_type (decode_function_type (cs, cs->c_type,
+                                                   aux, objfile));
 
       SYMBOL_CLASS (sym) = LOC_BLOCK;
       if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
@@ -1504,7 +1576,7 @@ process_coff_symbol (struct coff_symbol *cs,
     }
   else
     {
-      SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);
+      SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux, objfile);
       switch (cs->c_sclass)
        {
        case C_NULL:
@@ -1520,7 +1592,8 @@ process_coff_symbol (struct coff_symbol *cs,
        case C_EXT:
          SYMBOL_CLASS (sym) = LOC_STATIC;
          SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
-         SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
+                                                 SECT_OFF_TEXT (objfile));
          add_symbol_to_list (sym, &global_symbols);
          break;
 
@@ -1529,15 +1602,16 @@ process_coff_symbol (struct coff_symbol *cs,
        case C_STAT:
          SYMBOL_CLASS (sym) = LOC_STATIC;
          SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
-         SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+         SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
+                                                 SECT_OFF_TEXT (objfile));
          if (within_function)
            {
-             /* Static symbol of local scope */
+             /* Static symbol of local scope */
              add_symbol_to_list (sym, &local_symbols);
            }
          else
            {
-             /* Static symbol at top level of file */
+             /* Static symbol at top level of file */
              add_symbol_to_list (sym, &file_symbols);
            }
          break;
@@ -1547,7 +1621,8 @@ process_coff_symbol (struct coff_symbol *cs,
 #endif
        case C_REG:
          SYMBOL_CLASS (sym) = LOC_REGISTER;
-         SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
+         SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+         SYMBOL_VALUE (sym) = cs->c_value;
          add_symbol_to_list (sym, &local_symbols);
          break;
 
@@ -1557,52 +1632,16 @@ process_coff_symbol (struct coff_symbol *cs,
 
        case C_ARG:
          SYMBOL_CLASS (sym) = LOC_ARG;
+         SYMBOL_IS_ARGUMENT (sym) = 1;
          add_symbol_to_list (sym, &local_symbols);
-#if !defined (BELIEVE_PCC_PROMOTION)
-         if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-           {
-             /* If PCC says a parameter is a short or a char,
-                aligned on an int boundary, realign it to the
-                "little end" of the int.  */
-             struct type *temptype;
-             temptype = lookup_fundamental_type (current_objfile,
-                                                 FT_INTEGER);
-             if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
-                 && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
-                 && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
-               {
-                 SYMBOL_VALUE (sym) +=
-                   TYPE_LENGTH (temptype)
-                   - TYPE_LENGTH (SYMBOL_TYPE (sym));
-               }
-           }
-#endif
          break;
 
        case C_REGPARM:
-         SYMBOL_CLASS (sym) = LOC_REGPARM;
-         SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM (cs->c_value);
+         SYMBOL_CLASS (sym) = LOC_REGISTER;
+         SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+         SYMBOL_IS_ARGUMENT (sym) = 1;
+         SYMBOL_VALUE (sym) = cs->c_value;
          add_symbol_to_list (sym, &local_symbols);
-#if !defined (BELIEVE_PCC_PROMOTION)
-         /* FIXME:  This should retain the current type, since it's just
-            a register value.  gnu@adobe, 26Feb93 */
-         {
-           /* If PCC says a parameter is a short or a char,
-              it is really an int.  */
-           struct type *temptype;
-           temptype =
-             lookup_fundamental_type (current_objfile, FT_INTEGER);
-           if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
-               && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
-             {
-               SYMBOL_TYPE (sym) =
-                 (TYPE_UNSIGNED (SYMBOL_TYPE (sym))
-                  ? lookup_fundamental_type (current_objfile,
-                                             FT_UNSIGNED_INTEGER)
-                  : temptype);
-             }
-         }
-#endif
          break;
 
        case C_TPDEF:
@@ -1615,19 +1654,19 @@ process_coff_symbol (struct coff_symbol *cs,
              if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
                  || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
                {
-                 /* If we are giving a name to a type such as "pointer to
-                    foo" or "function returning foo", we better not set
-                    the TYPE_NAME.  If the program contains "typedef char
-                    *caddr_t;", we don't want all variables of type char
-                    * to print as caddr_t.  This is not just a
-                    consequence of GDB's type management; CC and GCC (at
-                    least through version 2.4) both output variables of
-                    either type char * or caddr_t with the type
-                    refering to the C_TPDEF symbol for caddr_t.  If a future
-                    compiler cleans this up it GDB is not ready for it
-                    yet, but if it becomes ready we somehow need to
-                    disable this check (without breaking the PCC/GCC2.4
-                    case).
+                 /* If we are giving a name to a type such as
+                    "pointer to foo" or "function returning foo", we
+                    better not set the TYPE_NAME.  If the program
+                    contains "typedef char *caddr_t;", we don't want 
+                    all variables of type char * to print as caddr_t.
+                    This is not just a consequence of GDB's type
+                    management; CC and GCC (at least through version
+                    2.4) both output variables of either type char *
+                    or caddr_t with the type refering to the C_TPDEF
+                    symbol for caddr_t.  If a future compiler cleans
+                    this up it GDB is not ready for it yet, but if it
+                    becomes ready we somehow need to disable this
+                    check (without breaking the PCC/GCC2.4 case).
 
                     Sigh.
 
@@ -1637,20 +1676,21 @@ process_coff_symbol (struct coff_symbol *cs,
                }
              else
                TYPE_NAME (SYMBOL_TYPE (sym)) =
-                 concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
+                 concat (SYMBOL_LINKAGE_NAME (sym), (char *) NULL);
            }
 
-         /* Keep track of any type which points to empty structured type,
-            so it can be filled from a definition from another file.  A
-            simple forward reference (TYPE_CODE_UNDEF) is not an
-            empty structured type, though; the forward references
-            work themselves out via the magic of coff_lookup_type.  */
-         if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
-             TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
-             TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
-             TYPE_CODE_UNDEF)
+         /* Keep track of any type which points to empty structured
+            type, so it can be filled from a definition from another
+            file.  A simple forward reference (TYPE_CODE_UNDEF) is
+            not an empty structured type, though; the forward
+            references work themselves out via the magic of
+            coff_lookup_type.  */
+         if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+             && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0
+             && TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym)))
+                != TYPE_CODE_UNDEF)
            {
-             int i = hashname (DEPRECATED_SYMBOL_NAME (sym));
+             int i = hashname (SYMBOL_LINKAGE_NAME (sym));
 
              SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
              opaque_type_chain[i] = sym;
@@ -1666,13 +1706,13 @@ process_coff_symbol (struct coff_symbol *cs,
 
          /* Some compilers try to be helpful by inventing "fake"
             names for anonymous enums, structures, and unions, like
-            "~0fake" or ".0fake".  Thanks, but no thanks... */
+            "~0fake" or ".0fake".  Thanks, but no thanks...  */
          if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
-           if (DEPRECATED_SYMBOL_NAME (sym) != NULL
-               && *DEPRECATED_SYMBOL_NAME (sym) != '~'
-               && *DEPRECATED_SYMBOL_NAME (sym) != '.')
+           if (SYMBOL_LINKAGE_NAME (sym) != NULL
+               && *SYMBOL_LINKAGE_NAME (sym) != '~'
+               && *SYMBOL_LINKAGE_NAME (sym) != '.')
              TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
-               concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
+               concat (SYMBOL_LINKAGE_NAME (sym), (char *)NULL);
 
          add_symbol_to_list (sym, &file_symbols);
          break;
@@ -1688,7 +1728,7 @@ process_coff_symbol (struct coff_symbol *cs,
 
 static struct type *
 decode_type (struct coff_symbol *cs, unsigned int c_type,
-            union internal_auxent *aux)
+            union internal_auxent *aux, struct objfile *objfile)
 {
   struct type *type = 0;
   unsigned int new_c_type;
@@ -1698,12 +1738,12 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
       new_c_type = DECREF (c_type);
       if (ISPTR (c_type))
        {
-         type = decode_type (cs, new_c_type, aux);
+         type = decode_type (cs, new_c_type, aux, objfile);
          type = lookup_pointer_type (type);
        }
       else if (ISFCN (c_type))
        {
-         type = decode_type (cs, new_c_type, aux);
+         type = decode_type (cs, new_c_type, aux, objfile);
          type = lookup_function_type (type);
        }
       else if (ISARY (c_type))
@@ -1713,11 +1753,11 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
          struct type *base_type, *index_type, *range_type;
 
          /* Define an array type.  */
-         /* auxent refers to array, not base type */
+         /* auxent refers to array, not base type */
          if (aux->x_sym.x_tagndx.l == 0)
            cs->c_naux = 0;
 
-         /* shift the indices down */
+         /* Shift the indices down.  */
          dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
          i = 1;
          n = dim[0];
@@ -1725,23 +1765,24 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
            *dim = *(dim + 1);
          *dim = 0;
 
-         base_type = decode_type (cs, new_c_type, aux);
-         index_type = lookup_fundamental_type (current_objfile, FT_INTEGER);
+         base_type = decode_type (cs, new_c_type, aux, objfile);
+         index_type = objfile_type (objfile)->builtin_int;
          range_type =
-           create_range_type ((struct type *) NULL, index_type, 0, n - 1);
+           create_range_type ((struct type *) NULL, 
+                              index_type, 0, n - 1);
          type =
-           create_array_type ((struct type *) NULL, base_type, range_type);
+           create_array_type ((struct type *) NULL, 
+                              base_type, range_type);
        }
       return type;
     }
 
-  /* Reference to existing type.  This only occurs with the
-     struct, union, and enum types.  EPI a29k coff
-     fakes us out by producing aux entries with a nonzero
-     x_tagndx for definitions of structs, unions, and enums, so we
-     have to check the c_sclass field.  SCO 3.2v4 cc gets confused
-     with pointers to pointers to defined structs, and generates
-     negative x_tagndx fields.  */
+  /* Reference to existing type.  This only occurs with the struct,
+     union, and enum types.  EPI a29k coff fakes us out by producing
+     aux entries with a nonzero x_tagndx for definitions of structs,
+     unions, and enums, so we have to check the c_sclass field.  SCO
+     3.2v4 cc gets confused with pointers to pointers to defined
+     structs, and generates negative x_tagndx fields.  */
   if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
     {
       if (cs->c_sclass != C_STRTAG
@@ -1755,83 +1796,90 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
       else
        {
          complaint (&symfile_complaints,
-                    "Symbol table entry for %s has bad tagndx value",
+                    _("Symbol table entry for %s has bad tagndx value"),
                     cs->c_name);
-         /* And fall through to decode_base_type... */
+         /* And fall through to decode_base_type...  */
        }
     }
 
-  return decode_base_type (cs, BTYPE (c_type), aux);
+  return decode_base_type (cs, BTYPE (c_type), aux, objfile);
 }
 
 /* Decode a coff type specifier for function definition;
    return the type that the function returns.  */
 
 static struct type *
-decode_function_type (struct coff_symbol *cs, unsigned int c_type,
-                     union internal_auxent *aux)
+decode_function_type (struct coff_symbol *cs, 
+                     unsigned int c_type,
+                     union internal_auxent *aux, 
+                     struct objfile *objfile)
 {
   if (aux->x_sym.x_tagndx.l == 0)
-    cs->c_naux = 0;            /* auxent refers to function, not base type */
+    cs->c_naux = 0;    /* auxent refers to function, not base
+                          type.  */
 
-  return decode_type (cs, DECREF (c_type), aux);
+  return decode_type (cs, DECREF (c_type), aux, objfile);
 }
 \f
-/* basic C types */
+/* Basic C types.  */
 
 static struct type *
-decode_base_type (struct coff_symbol *cs, unsigned int c_type,
-                 union internal_auxent *aux)
+decode_base_type (struct coff_symbol *cs, 
+                 unsigned int c_type,
+                 union internal_auxent *aux, 
+                 struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct type *type;
 
   switch (c_type)
     {
     case T_NULL:
-      /* shows up with "void (*foo)();" structure members */
-      return lookup_fundamental_type (current_objfile, FT_VOID);
+      /* Shows up with "void (*foo)();" structure members.  */
+      return objfile_type (objfile)->builtin_void;
 
 #ifdef T_VOID
     case T_VOID:
       /* Intel 960 COFF has this symbol and meaning.  */
-      return lookup_fundamental_type (current_objfile, FT_VOID);
+      return objfile_type (objfile)->builtin_void;
 #endif
 
     case T_CHAR:
-      return lookup_fundamental_type (current_objfile, FT_CHAR);
+      return objfile_type (objfile)->builtin_char;
 
     case T_SHORT:
-      return lookup_fundamental_type (current_objfile, FT_SHORT);
+      return objfile_type (objfile)->builtin_short;
 
     case T_INT:
-      return lookup_fundamental_type (current_objfile, FT_INTEGER);
+      return objfile_type (objfile)->builtin_int;
 
     case T_LONG:
       if (cs->c_sclass == C_FIELD
-         && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
-       return lookup_fundamental_type (current_objfile, FT_LONG_LONG);
+         && aux->x_sym.x_misc.x_lnsz.x_size
+            > gdbarch_long_bit (gdbarch))
+       return objfile_type (objfile)->builtin_long_long;
       else
-       return lookup_fundamental_type (current_objfile, FT_LONG);
+       return objfile_type (objfile)->builtin_long;
 
     case T_FLOAT:
-      return lookup_fundamental_type (current_objfile, FT_FLOAT);
+      return objfile_type (objfile)->builtin_float;
 
     case T_DOUBLE:
-      return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+      return objfile_type (objfile)->builtin_double;
 
     case T_LNGDBL:
-      return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+      return objfile_type (objfile)->builtin_long_double;
 
     case T_STRUCT:
       if (cs->c_naux != 1)
        {
-         /* anonymous structure type */
+         /* Anonymous structure type.  */
          type = coff_alloc_type (cs->c_symnum);
          TYPE_CODE (type) = TYPE_CODE_STRUCT;
          TYPE_NAME (type) = NULL;
-         /* This used to set the tag to "<opaque>".  But I think setting it
-            to NULL is right, and the printing code can print it as
-            "struct {...}".  */
+         /* This used to set the tag to "<opaque>".  But I think
+            setting it to NULL is right, and the printing code can
+            print it as "struct {...}".  */
          TYPE_TAG_NAME (type) = NULL;
          INIT_CPLUS_SPECIFIC (type);
          TYPE_LENGTH (type) = 0;
@@ -1842,19 +1890,20 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
        {
          type = coff_read_struct_type (cs->c_symnum,
                                        aux->x_sym.x_misc.x_lnsz.x_size,
-                                     aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+                                       aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+                                       objfile);
        }
       return type;
 
     case T_UNION:
       if (cs->c_naux != 1)
        {
-         /* anonymous union type */
+         /* Anonymous union type.  */
          type = coff_alloc_type (cs->c_symnum);
          TYPE_NAME (type) = NULL;
-         /* This used to set the tag to "<opaque>".  But I think setting it
-            to NULL is right, and the printing code can print it as
-            "union {...}".  */
+         /* This used to set the tag to "<opaque>".  But I think
+            setting it to NULL is right, and the printing code can
+            print it as "union {...}".  */
          TYPE_TAG_NAME (type) = NULL;
          INIT_CPLUS_SPECIFIC (type);
          TYPE_LENGTH (type) = 0;
@@ -1865,7 +1914,8 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
        {
          type = coff_read_struct_type (cs->c_symnum,
                                        aux->x_sym.x_misc.x_lnsz.x_size,
-                                     aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+                                       aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+                                       objfile);
        }
       TYPE_CODE (type) = TYPE_CODE_UNION;
       return type;
@@ -1873,13 +1923,13 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
     case T_ENUM:
       if (cs->c_naux != 1)
        {
-         /* anonymous enum type */
+         /* Anonymous enum type.  */
          type = coff_alloc_type (cs->c_symnum);
          TYPE_CODE (type) = TYPE_CODE_ENUM;
          TYPE_NAME (type) = NULL;
-         /* This used to set the tag to "<opaque>".  But I think setting it
-            to NULL is right, and the printing code can print it as
-            "enum {...}".  */
+         /* This used to set the tag to "<opaque>".  But I think
+            setting it to NULL is right, and the printing code can
+            print it as "enum {...}".  */
          TYPE_TAG_NAME (type) = NULL;
          TYPE_LENGTH (type) = 0;
          TYPE_FIELDS (type) = 0;
@@ -1889,32 +1939,35 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
        {
          type = coff_read_enum_type (cs->c_symnum,
                                      aux->x_sym.x_misc.x_lnsz.x_size,
-                                     aux->x_sym.x_fcnary.x_fcn.x_endndx.l);
+                                     aux->x_sym.x_fcnary.x_fcn.x_endndx.l,
+                                     objfile);
        }
       return type;
 
     case T_MOE:
-      /* shouldn't show up here */
+      /* Shouldn't show up here.  */
       break;
 
     case T_UCHAR:
-      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+      return objfile_type (objfile)->builtin_unsigned_char;
 
     case T_USHORT:
-      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+      return objfile_type (objfile)->builtin_unsigned_short;
 
     case T_UINT:
-      return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+      return objfile_type (objfile)->builtin_unsigned_int;
 
     case T_ULONG:
       if (cs->c_sclass == C_FIELD
-         && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
-       return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+         && aux->x_sym.x_misc.x_lnsz.x_size
+            > gdbarch_long_bit (gdbarch))
+       return objfile_type (objfile)->builtin_unsigned_long_long;
       else
-       return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+       return objfile_type (objfile)->builtin_unsigned_long;
     }
-  complaint (&symfile_complaints, "Unexpected type for symbol %s", cs->c_name);
-  return lookup_fundamental_type (current_objfile, FT_VOID);
+  complaint (&symfile_complaints, 
+            _("Unexpected type for symbol %s"), cs->c_name);
+  return objfile_type (objfile)->builtin_void;
 }
 \f
 /* This page contains subroutines of read_type.  */
@@ -1923,7 +1976,8 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
    object describing the type.  */
 
 static struct type *
-coff_read_struct_type (int index, int length, int lastsym)
+coff_read_struct_type (int index, int length, int lastsym,
+                      struct objfile *objfile)
 {
   struct nextfield
     {
@@ -1952,7 +2006,7 @@ coff_read_struct_type (int index, int length, int lastsym)
     {
       read_one_sym (ms, &sub_sym, &sub_aux);
       name = ms->c_name;
-      name = EXTERNAL_NAME (name, current_objfile->obfd);
+      name = EXTERNAL_NAME (name, objfile->obfd);
 
       switch (ms->c_sclass)
        {
@@ -1965,14 +2019,12 @@ coff_read_struct_type (int index, int length, int lastsym)
          list = new;
 
          /* Save the data.  */
-         list->field.name =
-           obsavestring (name,
-                         strlen (name),
-                         &current_objfile->objfile_obstack);
-         FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
-         FIELD_BITPOS (list->field) = 8 * ms->c_value;
+         list->field.name = obsavestring (name, strlen (name), 
+                                          &objfile->objfile_obstack);
+         FIELD_TYPE (list->field) = decode_type (ms, ms->c_type,
+                                                 &sub_aux, objfile);
+         SET_FIELD_BITPOS (list->field, 8 * ms->c_value);
          FIELD_BITSIZE (list->field) = 0;
-         FIELD_STATIC_KIND (list->field) = 0;
          nfields++;
          break;
 
@@ -1984,14 +2036,12 @@ coff_read_struct_type (int index, int length, int lastsym)
          list = new;
 
          /* Save the data.  */
-         list->field.name =
-           obsavestring (name,
-                         strlen (name),
-                         &current_objfile->objfile_obstack);
-         FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
-         FIELD_BITPOS (list->field) = ms->c_value;
+         list->field.name = obsavestring (name, strlen (name), 
+                                          &objfile->objfile_obstack);
+         FIELD_TYPE (list->field) = decode_type (ms, ms->c_type,
+                                                 &sub_aux, objfile);
+         SET_FIELD_BITPOS (list->field, ms->c_value);
          FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
-         FIELD_STATIC_KIND (list->field) = 0;
          nfields++;
          break;
 
@@ -2019,8 +2069,10 @@ coff_read_struct_type (int index, int length, int lastsym)
    Also defines the symbols that represent the values of the type.  */
 
 static struct type *
-coff_read_enum_type (int index, int length, int lastsym)
+coff_read_enum_type (int index, int length, int lastsym,
+                    struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct symbol *sym;
   struct type *type;
   int nsyms = 0;
@@ -2048,19 +2100,18 @@ coff_read_enum_type (int index, int length, int lastsym)
     {
       read_one_sym (ms, &sub_sym, &sub_aux);
       name = ms->c_name;
-      name = EXTERNAL_NAME (name, current_objfile->obfd);
+      name = EXTERNAL_NAME (name, objfile->obfd);
 
       switch (ms->c_sclass)
        {
        case C_MOE:
          sym = (struct symbol *) obstack_alloc
-           (&current_objfile->objfile_obstack,
-            sizeof (struct symbol));
+           (&objfile->objfile_obstack, sizeof (struct symbol));
          memset (sym, 0, sizeof (struct symbol));
 
-         DEPRECATED_SYMBOL_NAME (sym) =
-           obsavestring (name, strlen (name),
-                         &current_objfile->objfile_obstack);
+         SYMBOL_SET_LINKAGE_NAME (sym,
+                                  obsavestring (name, strlen (name),
+                                                &objfile->objfile_obstack));
          SYMBOL_CLASS (sym) = LOC_CONST;
          SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
          SYMBOL_VALUE (sym) = ms->c_value;
@@ -2081,8 +2132,8 @@ coff_read_enum_type (int index, int length, int lastsym)
 
   if (length > 0)
     TYPE_LENGTH (type) = length;
-  else
-    TYPE_LENGTH (type) = TARGET_INT_BIT / TARGET_CHAR_BIT;     /* Assume ints */
+  else /* Assume ints.  */
+    TYPE_LENGTH (type) = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   TYPE_NFIELDS (type) = nsyms;
   TYPE_FIELDS (type) = (struct field *)
@@ -2105,35 +2156,46 @@ coff_read_enum_type (int index, int length, int lastsym)
       for (; j < syms->nsyms; j++, n++)
        {
          struct symbol *xsym = syms->symbol[j];
+
          SYMBOL_TYPE (xsym) = type;
-         TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
-         TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+         TYPE_FIELD_NAME (type, n) = SYMBOL_LINKAGE_NAME (xsym);
+         SET_FIELD_BITPOS (TYPE_FIELD (type, n), SYMBOL_VALUE (xsym));
          if (SYMBOL_VALUE (xsym) < 0)
            unsigned_enum = 0;
          TYPE_FIELD_BITSIZE (type, n) = 0;
-         TYPE_FIELD_STATIC_KIND (type, n) = 0;
        }
       if (syms == osyms)
        break;
     }
 
   if (unsigned_enum)
-    TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+    TYPE_UNSIGNED (type) = 1;
 
   return type;
 }
 
-/* Register our ability to parse symbols for coff BFD files. */
+/* Register our ability to parse symbols for coff BFD files.  */
 
-static struct sym_fns coff_sym_fns =
+static const struct sym_fns coff_sym_fns =
 {
   bfd_target_coff_flavour,
-  coff_new_init,               /* sym_new_init: init anything gbl to entire symtab */
-  coff_symfile_init,           /* sym_init: read initial info, setup for sym_read() */
-  coff_symfile_read,           /* sym_read: read a symbol file into symtab */
-  coff_symfile_finish,         /* sym_finish: finished with file, cleanup */
-  default_symfile_offsets,     /* sym_offsets:  xlate external to internal form */
-  NULL                         /* next: pointer to next struct sym_fns */
+  coff_new_init,               /* sym_new_init: init anything gbl to
+                                  entire symtab */
+  coff_symfile_init,           /* sym_init: read initial info, setup
+                                  for sym_read() */
+  coff_symfile_read,           /* sym_read: read a symbol file into
+                                  symtab */
+  coff_symfile_finish,         /* sym_finish: finished with file,
+                                  cleanup */
+  default_symfile_offsets,     /* sym_offsets: xlate external to
+                                  internal form */
+  default_symfile_segments,    /* sym_segments: Get segment
+                                  information from a file */
+  NULL,                         /* sym_read_linetable  */
+
+  default_symfile_relocate,    /* sym_relocate: Relocate a debug
+                                  section.  */
+  &psym_functions
 };
 
 void