Basically a checkpoint.
authorIan Lance Taylor <ian@airs.com>
Fri, 8 Jan 1993 21:46:36 +0000 (21:46 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 8 Jan 1993 21:46:36 +0000 (21:46 +0000)
Fri Jan  8 15:47:53 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)

* bfd.c (struct _bfd): Added ecoff_tdata to tdata union.
* targets.c (enum target_flavour): Added bfd_target_ecoff_flavour.
* coff-msym.c: Use DEFUN for function definitons.
* coff-mips.c: Added code to read and print symbols, and to find
line numbers.

bfd/ChangeLog
bfd/bfd.c
bfd/coff-mips.c
bfd/coff-msym.c
bfd/targets.c

index ebbd433..33e1a0a 100644 (file)
@@ -1,5 +1,11 @@
 Fri Jan  8 15:47:53 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
+       * bfd.c (struct _bfd): Added ecoff_tdata to tdata union.
+       * targets.c (enum target_flavour): Added bfd_target_ecoff_flavour.
+       * coff-msym.c: Use DEFUN for function definitons.
+       * coff-mips.c: Added code to read and print symbols, and to find
+       line numbers.
+
        * coffcode.h: Moved many generic functions into coffgen.c.  Moved
        swapping functions into coffswap.h for ECOFF use.  Moved
        relocation functions, only used by h8300 and z8k, into reloc16.c.
index 0820c3f..8910ca8 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -146,6 +146,7 @@ CODE_FRAGMENT
 .      struct _oasys_data *oasys_obj_data;
 .      struct _oasys_ar_data *oasys_ar_data;
 .      struct coff_tdata *coff_obj_data;
+.      struct ecoff_tdata *ecoff_obj_data;
 .      struct ieee_data_struct *ieee_data;
 .      struct ieee_ar_data_struct *ieee_ar_data;
 .      struct srec_data_struct *srec_data;
@@ -519,6 +520,53 @@ bfd_get_mtime (abfd)
 
 /*
 FUNCTION
+       The bfd_get_size function
+
+SYNOPSIS
+       long bfd_get_size(bfd *);
+
+DESCRIPTION
+       Return file size (as read from file system) for the file
+       associated with a bfd.
+
+       Note that the initial motivation for, and use of, this routine is not
+       so we can get the exact size of the object the bfd applies to, since
+       that might not be generally possible (archive members for example?).
+       Although it would be ideal if someone could eventually modify
+       it so that such results were guaranteed.
+
+       Instead, we want to ask questions like "is this NNN byte sized
+       object I'm about to try read from file offset YYY reasonable?"
+       As as example of where we might want to do this, some object formats
+       use string tables for which the first sizeof(long) bytes of the table
+       contain the size of the table itself, including the size bytes.
+       If an application tries to read what it thinks is one of these
+       string tables, without some way to validate the size, and for
+       some reason the size is wrong (byte swapping error, wrong location
+       for the string table, etc), the only clue is likely to be a read
+       error when it tries to read the table, or a "virtual memory
+       exhausted" error when it tries to allocated 15 bazillon bytes
+       of space for the 15 bazillon byte table it is about to read.
+       This function at least allows us to answer the quesion, "is the
+       size reasonable?".
+*/
+
+long
+bfd_get_size (abfd)
+     bfd *abfd;
+{
+  FILE *fp;
+  struct stat buf;
+
+  fp = bfd_cache_lookup (abfd);
+  if (0 != fstat (fileno (fp), &buf))
+    return 0;
+
+  return buf.st_size;
+}
+
+/*
+FUNCTION
        stuff
 
 DESCRIPTION
index ee63e07..cddc415 100644 (file)
@@ -1,6 +1,7 @@
 /* BFD back-end for MIPS Extended-Coff files.
    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
    Written by Per Bothner.
+   Symbol and line number support added by Ian Lance Taylor.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -23,42 +24,1289 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "libbfd.h"
 #include "coff/mips.h"
 #include "coff/internal.h"
-#include "libcoff.h"           /* to allow easier abstraction-breaking */
-
-#define BADMAG(x) ECOFFBADMAG(x)
-
-/* Can't read these relocs */
-#define RTYPE2HOWTO(a,b) ;
-/* Define NO_COFF_SYMBOLS and NO_COFF_LINENOS to avoid coffcode.h
-   defining a mess of useless functions.  */
-#define        NO_COFF_SYMBOLS
-#define        NO_COFF_LINENOS
-/* Define MIPS to get MIPS magic numbers and such */
-#define MIPS 1
-/* Define additional MIPS section types */
-#define STYP_OTHER_LOAD        0x98000300
-#include "coffcode.h"
-
-/* We do not implement symbols for ecoff. */
-#define        coff_get_symtab_upper_bound (PROTO(unsigned int, (*),(bfd *)))bfd_false
-#define        coff_get_symtab  (PROTO(unsigned int, (*), (bfd *, asymbol **)))bfd_0
-#define coff_print_symbol \
-    (PROTO(void,(*),(bfd *, PTR, asymbol *, enum bfd_print_symbol))) bfd_void
-#define        coff_swap_sym_in (PROTO(void,(*),(bfd *,PTR,PTR))) bfd_void
-#define        coff_swap_aux_in (PROTO(void,(*),(bfd *,PTR,int,int,PTR))) bfd_void
-#define        coff_swap_sym_out (PROTO(unsigned,(*),(bfd *,PTR,PTR))) bfd_void
-#define        coff_swap_aux_out (PROTO(unsigned,(*),(bfd *,PTR,int,int,PTR))) bfd_void
-
-/* We do not implement linenos for ecoff. */
-#define coff_get_lineno (struct lineno_cache_entry *(*)()) bfd_nullvoidptr
-#define        coff_swap_lineno_in (PROTO(void,(*),(bfd *,PTR,PTR))) bfd_void
-#define coff_find_nearest_line (PROTO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
-#define coff_swap_lineno_out  (PROTO(unsigned,(*),(bfd *,PTR,PTR))) bfd_void
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/ecoff-ext.h"
+#include "libcoff.h"
+
+/* `Tdata' information kept for ECOFF files.  */
+
+#define ecoff_data(abfd) ((abfd)->tdata.ecoff_obj_data)
+
+typedef struct ecoff_tdata
+{
+  /* The symbol table file position.  */
+  file_ptr sym_filepos;
+
+  /* The unswapped ECOFF symbolic information.  */
+  PTR raw_syments;
+
+  /* The swapped ECOFF symbolic header.  */
+  HDRR symbolic_header;
+
+  /* Pointers to the unswapped symbolic information.  */
+  unsigned char *line;
+  struct dnr_ext *external_dnr;
+  struct pdr_ext *external_pdr;
+  struct sym_ext *external_sym;
+  struct opt_ext *external_opt;
+  union aux_ext *external_aux;
+  char *ss;
+  char *ssext;
+  struct fdr_ext *external_fdr;
+  struct rfd_ext *external_rfd;
+  struct ext_ext *external_ext;
+
+  /* The swapped fdr information.  */
+  FDR *fdr;
+
+  /* The canonical BFD symbols.  */
+  struct ecoff_symbol_struct *canonical_symbols;
+
+} ecoff_data_type;
+
+/* Each canonical asymbol really looks like this.  */
+
+typedef struct ecoff_symbol_struct
+{
+  /* The actual symbol which the rest of BFD works with */
+  asymbol symbol;
+
+  /* The fdr for this symbol.  */
+  FDR *fdr;
+
+  /* true if this is a local symbol rather than an external one.  */
+  boolean local;
+
+  /* A pointer to the unswapped hidden information for this symbol */
+  union
+    {
+      struct sym_ext *lnative;
+      struct ext_ext *enative;
+    }
+  native;
+} ecoff_symbol_type;
+
+/* We take the address of the first element of a asymbol to ensure that the
+   macro is only ever applied to an asymbol.  */
+#define ecoffsymbol(asymbol) ((ecoff_symbol_type *) (&((asymbol)->the_bfd)))
+
+/* MIPS ECOFF has COFF sections, but the debugging information is
+   stored in a completely different format.  This files uses the some
+   of the swapping routines from coffswap.h, and some of the generic
+   COFF routines in coffgen.c, but, unlike the real COFF targets, does
+   not use coffcode.h itself.  */
+
+/* Get the generic COFF swapping routines, except for the symbol and
+   lineno ones.  Give them ecoff names.  */
+#define NO_COFF_SYMBOLS
+#define NO_COFF_LINENOS
+#define coff_swap_reloc_in ecoff_swap_reloc_in
+#define coff_swap_reloc_out ecoff_swap_reloc_out
+#define coff_swap_filehdr_in ecoff_swap_filehdr_in
+#define coff_swap_filehdr_out ecoff_swap_filehdr_out
+#define coff_swap_aouthdr_in ecoff_swap_aouthdr_in
+#define coff_swap_aouthdr_out ecoff_swap_aouthdr_out
+#define coff_swap_scnhdr_in ecoff_swap_scnhdr_in
+#define coff_swap_scnhdr_out ecoff_swap_scnhdr_out
+#include "coffswap.h"
+\f
+/* This stuff is somewhat copied from coffcode.h.  */
+
+static asection bfd_debug_section = { "*DEBUG*" };
+
+/* See whether the magic number matches.  */
+
+static boolean
+DEFUN(ecoff_bad_format_hook, (abfd, filehdr),
+      bfd *abfd AND
+      PTR filehdr)
+{
+  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+  if (ECOFFBADMAG (*internal_f))
+    return false;
+
+  return true;
+}
+
+/* This is a hook needed by SCO COFF, but we have nothing to do.  */
+
+static asection *
+DEFUN (ecoff_make_section_hook, (abfd, name),
+       bfd *abfd AND
+       char *name)
+{
+  return (asection *) NULL;
+}
+
+/* Initialize a new section.  */
+
+static boolean
+DEFUN (ecoff_new_section_hook, (abfd, section),
+       bfd *abfd AND
+       asection *section)
+{
+  section->alignment_power = abfd->xvec->align_power_min;
+  return true;
+}
+
+#define ecoff_set_alignment_hook \
+  ((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void)
+
+static boolean
+DEFUN (ecoff_mkobject, (abfd),
+       bfd *abfd)
+{
+  abfd->tdata.ecoff_obj_data = ((struct ecoff_tdata *)
+                               bfd_zalloc (abfd, sizeof(ecoff_data_type)));
+  if (abfd->tdata.ecoff_obj_data == NULL)
+    {
+      bfd_error = no_memory;
+      return false;
+    }
+
+  return true;
+}
+
+/* Create the COFF backend specific information.  */
+
+static          PTR
+DEFUN(ecoff_mkobject_hook,(abfd, filehdr),
+      bfd            *abfd AND
+      PTR           filehdr)
+{
+  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+  ecoff_data_type *ecoff;
+
+  if (ecoff_mkobject (abfd) == false)
+    return NULL;
+
+  ecoff = ecoff_data (abfd);
+  ecoff->sym_filepos = internal_f->f_symptr;
+  return (PTR) ecoff;
+}
+
+/* Determine the machine architecture and type.  */
+static boolean
+DEFUN (ecoff_set_arch_mach_hook, (abfd, filehdr),
+       bfd *abfd AND
+       PTR filehdr)
+{
+  long machine;
+  enum bfd_architecture arch;
+  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+  machine = 0;
+  switch (internal_f->f_magic) {
+  case  MIPS_MAGIC_1:
+  case  MIPS_MAGIC_2:
+  case  MIPS_MAGIC_3:
+    arch = bfd_arch_mips;
+    machine = 0;
+    break;
+
+  default:                     /* Unreadable input file type */
+    arch = bfd_arch_obscure;
+    break;
+  }
+
+  bfd_default_set_arch_mach(abfd, arch, machine);
+  return true;
+}
+
+/* Get the BFD flags to use for a section.  */
+
+static flagword
+DEFUN(styp_to_sec_flags, (abfd, hdr),
+      bfd *abfd AND
+      PTR hdr)
+{
+  struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
+  long styp_flags = internal_s->s_flags;
+  flagword sec_flags=0;
+
+  if (styp_flags & STYP_NOLOAD)
+    sec_flags |= SEC_NEVER_LOAD;
+
+  /* For 386 COFF, at least, an unloadable text or data section is
+     actually a shared library section.  */
+  if (styp_flags & STYP_TEXT)
+    {
+      if (sec_flags & SEC_NEVER_LOAD)
+       sec_flags |= SEC_CODE | SEC_SHARED_LIBRARY;
+      else
+       sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
+    }
+  else if ((styp_flags & STYP_DATA)
+          || (styp_flags & STYP_RDATA)
+          || (styp_flags & STYP_SDATA))
+    {
+      if (sec_flags & SEC_NEVER_LOAD)
+       sec_flags |= SEC_DATA | SEC_SHARED_LIBRARY;
+      else
+       sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
+      if (styp_flags & STYP_RDATA)
+       sec_flags |= SEC_READONLY;
+    }
+  else if ((styp_flags & STYP_BSS)
+          || (styp_flags & STYP_SBSS))
+    {
+      sec_flags |= SEC_ALLOC;
+    }
+  else if (styp_flags & STYP_INFO) 
+    {
+      sec_flags |= SEC_NEVER_LOAD;
+    }
+  else if ((styp_flags & STYP_LIT8)
+          || (styp_flags & STYP_LIT4))
+    {
+      sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
+    }
+  else
+    {
+      sec_flags |= SEC_ALLOC | SEC_LOAD;
+    }
+
+  return sec_flags;
+}
+\f
+/* ECOFF symbol table routines.  The ECOFF symbol table is described
+   in gcc/mips-tfile.c.  */
+
+/* Create an empty symbol.  */
+
+static asymbol *
+DEFUN (ecoff_make_empty_symbol, (abfd),
+       bfd *abfd)
+{
+  ecoff_symbol_type *new;
+
+  new = (ecoff_symbol_type *) bfd_alloc (abfd, sizeof (ecoff_symbol_type));
+  if (new == (ecoff_symbol_type *) NULL)
+    {
+      bfd_error = no_memory;
+      return (asymbol *) NULL;
+    }
+  new->symbol.section = (asection *) NULL;
+  new->fdr = (FDR *) NULL;
+  new->local = false;
+  new->native.lnative = (struct sym_ext *) NULL;
+  new->symbol.the_bfd = abfd;
+  return &new->symbol;
+}
+
+/* Set the BFD flags and section for an ECOFF symbol.  */
+
+static void
+DEFUN (ecoff_set_symbol_info, (abfd, ecoff_sym, asym, ext),
+       bfd *abfd AND
+       SYMR *ecoff_sym AND
+       asymbol *asym AND
+       int ext)
+{
+  asym->the_bfd = abfd;
+  asym->value = ecoff_sym->value;
+  asym->section = &bfd_debug_section;
+  asym->udata = NULL;
+  if (ext)
+    asym->flags = BSF_EXPORT | BSF_GLOBAL;
+  else
+    asym->flags = BSF_LOCAL;
+  switch (ecoff_sym->sc)
+    {
+    case scNil:
+      asym->flags = 0;
+      break;
+    case scText:
+      asym->section = bfd_make_section_old_way (abfd, ".text");
+      asym->value -= asym->section->vma;
+      break;
+    case scData:
+      asym->section = bfd_make_section_old_way (abfd, ".data");
+      asym->value -= asym->section->vma;
+      break;
+    case scBss:
+      asym->section = &bfd_com_section;
+      asym->flags = 0;
+      break;
+    case scRegister:
+      asym->flags = BSF_DEBUGGING;
+      break;
+    case scAbs:
+      asym->section = &bfd_abs_section;
+      asym->flags = 0;
+      break;
+    case scUndefined:
+      asym->section = &bfd_und_section;
+      asym->flags = 0;
+      break;
+    case scCdbLocal:
+    case scBits:
+    case scCdbSystem:
+    case scRegImage:
+    case scInfo:
+    case scUserStruct:
+      asym->flags = BSF_DEBUGGING;
+      break;
+    case scSData:
+      asym->section = bfd_make_section_old_way (abfd, ".sdata");
+      asym->value -= asym->section->vma;
+      break;
+    case scSBss:
+      asym->section = &bfd_com_section;
+      asym->flags = 0;
+      break;
+    case scRData:
+      asym->section = bfd_make_section_old_way (abfd, ".rdata");
+      asym->value -= asym->section->vma;
+      break;
+    case scVar:
+      asym->flags = BSF_DEBUGGING;
+      break;
+    case scCommon:
+    case scSCommon:
+      asym->section = &bfd_com_section;
+      asym->flags = 0;
+      break;
+    case scVarRegister:
+    case scVariant:
+      asym->flags = BSF_DEBUGGING;
+      break;
+    case scSUndefined:
+      asym->section = &bfd_und_section;
+      asym->flags = 0;
+      break;
+    case scInit:
+      asym->section = bfd_make_section_old_way (abfd, ".init");
+      asym->value -= asym->section->vma;
+      break;
+    case scBasedVar:
+    case scXData:
+    case scPData:
+      asym->flags = BSF_DEBUGGING;
+      break;
+    case scFini:
+      asym->section = bfd_make_section_old_way (abfd, ".fini");
+      asym->value -= asym->section->vma;
+      break;
+    default:
+      asym->flags = 0;
+      break;
+    }
+}
+
+/* Read an ECOFF symbol table.  */
+
+static boolean
+DEFUN (ecoff_slurp_symbol_table, (abfd),
+       bfd *abfd)
+{
+  struct hdr_ext external_symhdr;
+  HDRR *internal_symhdr;
+  bfd_size_type raw_base;
+  bfd_size_type raw_size;
+  PTR raw;
+  bfd_size_type internal_size;
+  struct fdr_ext *fraw_src;
+  struct fdr_ext *fraw_end;
+  struct fdr *fdr_ptr;
+  struct fdr *fdr_end;
+  ecoff_symbol_type *internal;
+  ecoff_symbol_type *internal_ptr;
+  struct ext_ext *eraw_src;
+  struct ext_ext *eraw_end;
+
+  /* If we've already read in the symbol table, do nothing.  */
+  if (ecoff_data (abfd)->canonical_symbols != NULL)
+    return true;
+
+  /* At this point bfd_get_symcount (abfd) holds the number of symbols
+     as read from the file header, but on ECOFF this is always the
+     size of the symbolic information header.  It would be cleaner to
+     handle this when we first read the file in coffgen.c.  */
+  if (bfd_get_symcount (abfd) != sizeof (external_symhdr))
+    {
+      bfd_error = bad_value;
+      return false;
+    }
+
+  /* Read the symbolic information header.  */
+  if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) == -1
+      || (bfd_read ((PTR) &external_symhdr, sizeof (external_symhdr), 1, abfd)
+         != sizeof (external_symhdr)))
+    {
+      bfd_error = system_call_error;
+      return false;
+    }
+  internal_symhdr = &ecoff_data (abfd)->symbolic_header;
+  ecoff_swap_hdr_in (abfd, &external_symhdr, internal_symhdr);
+
+  if (internal_symhdr->magic != magicSym)
+    {
+      bfd_error = bad_value;
+      return false;
+    }
+
+  /* Now we can get the correct number of symbols.  */
+  bfd_get_symcount (abfd) = (internal_symhdr->isymMax
+                            + internal_symhdr->iextMax);
+
+  /* Read the entire symbol table at once.  This expression assumes
+     that the external symbols are always the last item.  */
+  raw_base = ecoff_data (abfd)->sym_filepos + sizeof (external_symhdr);
+  raw_size = (internal_symhdr->cbExtOffset - raw_base
+             + internal_symhdr->iextMax * sizeof (struct ext_ext));
+  raw = (PTR) bfd_alloc (abfd, raw_size);
+  if (raw == NULL)
+    {
+      bfd_error = no_memory;
+      return false;
+    }
+  if (bfd_read (raw, raw_size, 1, abfd) != raw_size)
+    {
+      bfd_error = system_call_error;
+      bfd_release (abfd, raw);
+      return false;
+    }
+
+  ecoff_data (abfd)->raw_syments = raw;
+
+  /* Get pointers for the numeric offsets in the HDRR structure.  */
+#define FIX(off1, off2, type) \
+  if (internal_symhdr->off1 == 0) \
+    ecoff_data (abfd)->off2 = (type *) NULL; \
+  else \
+    ecoff_data (abfd)->off2 = (type *) ((char *) raw \
+                                       + internal_symhdr->off1 \
+                                       - raw_base)
+  FIX (cbLineOffset, line, unsigned char);
+  FIX (cbDnOffset, external_dnr, struct dnr_ext);
+  FIX (cbPdOffset, external_pdr, struct pdr_ext);
+  FIX (cbSymOffset, external_sym, struct sym_ext);
+  FIX (cbOptOffset, external_opt, struct opt_ext);
+  FIX (cbAuxOffset, external_aux, union aux_ext);
+  FIX (cbSsOffset, ss, char);
+  FIX (cbSsExtOffset, ssext, char);
+  FIX (cbFdOffset, external_fdr, struct fdr_ext);
+  FIX (cbRfdOffset, external_rfd, struct rfd_ext);
+  FIX (cbExtOffset, external_ext, struct ext_ext);
+#undef FIX
+
+  /* I don't want to always swap all the data, because it will just
+     waste time and most programs will never look at this data.  The
+     only time the linker needs most of the debugging information
+     swapped is when linking big-endian and little-endian MIPS object
+     files together, which is not a common occurrence.
+
+     We need to look at the fdr to deal with a lot of information in
+     the symbols, so we swap them here.  We also canonicalize the
+     symbols.  */
+  ecoff_data (abfd)->fdr = (struct fdr *) bfd_alloc (abfd,
+                                                    (internal_symhdr->ifdMax *
+                                                     sizeof (struct fdr)));
+  if (ecoff_data (abfd)->fdr == NULL)
+    {
+      bfd_error = no_memory;
+      return false;
+    }
+  fdr_ptr = ecoff_data (abfd)->fdr;
+  fraw_src = ecoff_data (abfd)->external_fdr;
+  fraw_end = fraw_src + internal_symhdr->ifdMax;
+  for (; fraw_src < fraw_end; fraw_src++, fdr_ptr++)
+    ecoff_swap_fdr_in (abfd, fraw_src, fdr_ptr);
+
+  internal_size = bfd_get_symcount (abfd) * sizeof (ecoff_symbol_type);
+  internal = (ecoff_symbol_type *) bfd_alloc (abfd, internal_size);
+  if (internal == NULL)
+    {
+      bfd_error = no_memory;
+      return false;
+    }
+
+  internal_ptr = internal;
+  eraw_src = ecoff_data (abfd)->external_ext;
+  eraw_end = eraw_src + internal_symhdr->iextMax;
+  for (; eraw_src < eraw_end; eraw_src++, internal_ptr++)
+    {
+      EXTR internal_esym;
+
+      ecoff_swap_ext_in (abfd, eraw_src, &internal_esym);
+      internal_ptr->symbol.name = (ecoff_data (abfd)->ssext
+                                  + internal_esym.asym.iss);
+      ecoff_set_symbol_info (abfd, &internal_esym.asym,
+                            &internal_ptr->symbol, 1);
+      internal_ptr->fdr = ecoff_data (abfd)->fdr + internal_esym.ifd;
+      internal_ptr->local = false;
+      internal_ptr->native.enative = eraw_src;
+    }
+
+  /* The local symbols must be accessed via the fdr's, because the
+     string and aux indices are relative to the fdr information.  */
+  fdr_ptr = ecoff_data (abfd)->fdr;
+  fdr_end = fdr_ptr + internal_symhdr->ifdMax;
+  for (; fdr_ptr < fdr_end; fdr_ptr++)
+    {
+      struct sym_ext *lraw_src;
+      struct sym_ext *lraw_end;
+
+      lraw_src = ecoff_data (abfd)->external_sym + fdr_ptr->isymBase;
+      lraw_end = lraw_src + fdr_ptr->csym;
+      for (; lraw_src < lraw_end; lraw_src++, internal_ptr++)
+       {
+         SYMR internal_sym;
+
+         ecoff_swap_sym_in (abfd, lraw_src, &internal_sym);
+         internal_ptr->symbol.name = (ecoff_data (abfd)->ss
+                                      + fdr_ptr->issBase
+                                      + internal_sym.iss);
+         ecoff_set_symbol_info (abfd, &internal_sym,
+                                &internal_ptr->symbol, 0);
+         internal_ptr->fdr = fdr_ptr;
+         internal_ptr->local = true;
+         internal_ptr->native.lnative = lraw_src;
+       }
+    }
+
+  ecoff_data (abfd)->canonical_symbols = internal;
+
+  return true;
+}
+
+static unsigned int
+DEFUN (ecoff_get_symtab_upper_bound, (abfd),
+       bfd *abfd)
+{
+  if (! ecoff_slurp_symbol_table (abfd))
+    return 0;
+
+  return (bfd_get_symcount (abfd) + 1) * (sizeof (ecoff_symbol_type *));
+}
+
+static unsigned int
+DEFUN (ecoff_get_symtab, (abfd, alocation),
+       bfd *abfd AND
+       asymbol **alocation)
+{
+  unsigned int counter = 0;
+  ecoff_symbol_type *symbase;
+  ecoff_symbol_type **location = (ecoff_symbol_type **) alocation;
+
+  if (! ecoff_slurp_symbol_table (abfd))
+    return 0;
+
+  symbase = ecoff_data (abfd)->canonical_symbols;
+  while (counter < bfd_get_symcount (abfd))
+    {
+      *(location++) = symbase++;
+      counter++;
+    }
+  *location++ = (ecoff_symbol_type *) NULL;
+  return bfd_get_symcount (abfd);
+}
+
+/* Turn ECOFF type information into a printable string.
+   emit_aggregate and type_to_string are from gcc/mips-tdump.c, with
+   swapping added and used_ptr removed.  */
+
+/* Write aggregate information to a string.  */
+
+static void
+DEFUN (emit_aggregate, (abfd, string, rndx, isym, which),
+       bfd *abfd AND
+       char *string AND
+       RNDXR *rndx AND
+       long isym AND
+       CONST char *which)
+{
+  int ifd = rndx->rfd;
+  int indx = rndx->index;
+  int sym_base, ss_base;
+  CONST char *name;
+  
+  if (ifd == 0xfff)
+    ifd = isym;
+
+  sym_base = ecoff_data (abfd)->fdr[ifd].isymBase;
+  ss_base  = ecoff_data (abfd)->fdr[ifd].issBase;
+  
+  if (indx == indexNil)
+    name = "/* no name */";
+  else
+    {
+      SYMR sym;
+
+      indx += sym_base;
+      ecoff_swap_sym_in (abfd,
+                        ecoff_data (abfd)->external_sym + indx,
+                        &sym);
+      name = ecoff_data (abfd)->ss + ss_base + sym.iss;
+    }
+
+  sprintf (string,
+          "%s %s { ifd = %d, index = %d }",
+          which, name, ifd,
+          indx + ecoff_data (abfd)->symbolic_header.iextMax);
+}
+
+/* Convert the type information to string format.  */
+
+static char *
+DEFUN (type_to_string, (abfd, aux_ptr, indx, bigendian),
+       bfd *abfd AND
+       union aux_ext *aux_ptr AND
+       int indx AND
+       int bigendian)
+{
+  AUXU u;
+  struct qual {
+    unsigned int  type;
+    int  low_bound;
+    int  high_bound;
+    int  stride;
+  } qualifiers[7];
+
+  unsigned int basic_type;
+  int i;
+  static char buffer1[1024];
+  static char buffer2[1024];
+  char *p1 = buffer1;
+  char *p2 = buffer2;
+  RNDXR rndx;
+
+  for (i = 0; i < 7; i++)
+    {
+      qualifiers[i].low_bound = 0;
+      qualifiers[i].high_bound = 0;
+      qualifiers[i].stride = 0;
+    }
+
+  if (AUX_GET_ISYM (bigendian, &aux_ptr[indx]) == -1)
+    return "-1 (no type)";
+  ecoff_swap_tir_in (bigendian, &aux_ptr[indx++].a_ti, &u.ti);
+
+  basic_type = u.ti.bt;
+  qualifiers[0].type = u.ti.tq0;
+  qualifiers[1].type = u.ti.tq1;
+  qualifiers[2].type = u.ti.tq2;
+  qualifiers[3].type = u.ti.tq3;
+  qualifiers[4].type = u.ti.tq4;
+  qualifiers[5].type = u.ti.tq5;
+  qualifiers[6].type = tqNil;
+
+  /*
+   * Go get the basic type.
+   */
+  switch (basic_type)
+    {
+    case btNil:                        /* undefined */
+      strcpy (p1, "nil");
+      break;
+
+    case btAdr:                        /* address - integer same size as pointer */
+      strcpy (p1, "address");
+      break;
+
+    case btChar:               /* character */
+      strcpy (p1, "char");
+      break;
+
+    case btUChar:              /* unsigned character */
+      strcpy (p1, "unsigned char");
+      break;
+
+    case btShort:              /* short */
+      strcpy (p1, "short");
+      break;
+
+    case btUShort:             /* unsigned short */
+      strcpy (p1, "unsigned short");
+      break;
+
+    case btInt:                        /* int */
+      strcpy (p1, "int");
+      break;
+
+    case btUInt:               /* unsigned int */
+      strcpy (p1, "unsigned int");
+      break;
+
+    case btLong:               /* long */
+      strcpy (p1, "long");
+      break;
+
+    case btULong:              /* unsigned long */
+      strcpy (p1, "unsigned long");
+      break;
+
+    case btFloat:              /* float (real) */
+      strcpy (p1, "float");
+      break;
+
+    case btDouble:             /* Double (real) */
+      strcpy (p1, "double");
+      break;
+
+      /* Structures add 1-2 aux words:
+        1st word is [ST_RFDESCAPE, offset] pointer to struct def;
+        2nd word is file index if 1st word rfd is ST_RFDESCAPE.  */
+
+    case btStruct:             /* Structure (Record) */
+      ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
+      emit_aggregate (abfd, p1, &rndx,
+                     AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+                     "struct");
+      indx++;                  /* skip aux words */
+      break;
+
+      /* Unions add 1-2 aux words:
+        1st word is [ST_RFDESCAPE, offset] pointer to union def;
+        2nd word is file index if 1st word rfd is ST_RFDESCAPE.  */
+
+    case btUnion:              /* Union */
+      ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
+      emit_aggregate (abfd, p1, &rndx,
+                     AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+                     "union");
+      indx++;                  /* skip aux words */
+      break;
+
+      /* Enumerations add 1-2 aux words:
+        1st word is [ST_RFDESCAPE, offset] pointer to enum def;
+        2nd word is file index if 1st word rfd is ST_RFDESCAPE.  */
+
+    case btEnum:               /* Enumeration */
+      ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
+      emit_aggregate (abfd, p1, &rndx,
+                     AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+                     "enum");
+      indx++;                  /* skip aux words */
+      break;
+
+    case btTypedef:            /* defined via a typedef, isymRef points */
+      strcpy (p1, "typedef");
+      break;
+
+    case btRange:              /* subrange of int */
+      strcpy (p1, "subrange");
+      break;
+
+    case btSet:                        /* pascal sets */
+      strcpy (p1, "set");
+      break;
+
+    case btComplex:            /* fortran complex */
+      strcpy (p1, "complex");
+      break;
+
+    case btDComplex:           /* fortran double complex */
+      strcpy (p1, "double complex");
+      break;
+
+    case btIndirect:           /* forward or unnamed typedef */
+      strcpy (p1, "forward/unamed typedef");
+      break;
+
+    case btFixedDec:           /* Fixed Decimal */
+      strcpy (p1, "fixed decimal");
+      break;
+
+    case btFloatDec:           /* Float Decimal */
+      strcpy (p1, "float decimal");
+      break;
+
+    case btString:             /* Varying Length Character String */
+      strcpy (p1, "string");
+      break;
+
+    case btBit:                        /* Aligned Bit String */
+      strcpy (p1, "bit");
+      break;
+
+    case btPicture:            /* Picture */
+      strcpy (p1, "picture");
+      break;
+
+    case btVoid:               /* Void */
+      strcpy (p1, "void");
+      break;
+
+    default:
+      sprintf (p1, "Unknown basic type %d", (int) basic_type);
+      break;
+    }
+
+  p1 += strlen (buffer1);
+
+  /*
+   * If this is a bitfield, get the bitsize.
+   */
+  if (u.ti.fBitfield)
+    {
+      int bitsize;
+
+      bitsize = AUX_GET_WIDTH (bigendian, &aux_ptr[indx++]);
+      sprintf (p1, " : %d", bitsize);
+      p1 += strlen (buffer1);
+    }
+
+
+  /*
+   * Deal with any qualifiers.
+   */
+  if (qualifiers[0].type != tqNil)
+    {
+      /*
+       * Snarf up any array bounds in the correct order.  Arrays
+       * store 5 successive words in the aux. table:
+       *       word 0  RNDXR to type of the bounds (ie, int)
+       *       word 1  Current file descriptor index
+       *       word 2  low bound
+       *       word 3  high bound (or -1 if [])
+       *       word 4  stride size in bits
+       */
+      for (i = 0; i < 7; i++)
+       {
+         if (qualifiers[i].type == tqArray)
+           {
+             qualifiers[i].low_bound =
+               AUX_GET_DNLOW (bigendian, &aux_ptr[indx+2]);
+             qualifiers[i].high_bound =
+               AUX_GET_DNHIGH (bigendian, &aux_ptr[indx+3]);
+             qualifiers[i].stride =
+               AUX_GET_WIDTH (bigendian, &aux_ptr[indx+4]);
+             indx += 5;
+           }
+       }
+
+      /*
+       * Now print out the qualifiers.
+       */
+      for (i = 0; i < 6; i++)
+       {
+         switch (qualifiers[i].type)
+           {
+           case tqNil:
+           case tqMax:
+             break;
+
+           case tqPtr:
+             strcpy (p2, "ptr to ");
+             p2 += sizeof ("ptr to ")-1;
+             break;
+
+           case tqVol:
+             strcpy (p2, "volatile ");
+             p2 += sizeof ("volatile ")-1;
+             break;
+
+           case tqFar:
+             strcpy (p2, "far ");
+             p2 += sizeof ("far ")-1;
+             break;
+
+           case tqProc:
+             strcpy (p2, "func. ret. ");
+             p2 += sizeof ("func. ret. ");
+             break;
+
+           case tqArray:
+             {
+               int first_array = i;
+               int j;
+
+               /* Print array bounds reversed (ie, in the order the C
+                  programmer writes them).  C is such a fun language.... */
+
+               while (i < 5 && qualifiers[i+1].type == tqArray)
+                 i++;
+
+               for (j = i; j >= first_array; j--)
+                 {
+                   strcpy (p2, "array [");
+                   p2 += sizeof ("array [")-1;
+                   if (qualifiers[j].low_bound != 0)
+                     sprintf (p2,
+                              "%ld:%ld {%ld bits}",
+                              (long) qualifiers[j].low_bound,
+                              (long) qualifiers[j].high_bound,
+                              (long) qualifiers[j].stride);
+
+                   else if (qualifiers[j].high_bound != -1)
+                     sprintf (p2,
+                              "%ld {%ld bits}",
+                              (long) (qualifiers[j].high_bound + 1),
+                              (long) (qualifiers[j].stride));
+
+                   else
+                     sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
+
+                   p2 += strlen (p2);
+                   strcpy (p2, "] of ");
+                   p2 += sizeof ("] of ")-1;
+                 }
+             }
+             break;
+           }
+       }
+    }
+
+  strcpy (p2, buffer1);
+  return buffer2;
+}
+
+/* Print information about an ECOFF symbol.  */
+
+static void
+DEFUN (ecoff_print_symbol, (abfd, filep, symbol, how),
+       bfd *abfd AND
+       PTR filep AND
+       asymbol *symbol AND
+       bfd_print_symbol_type how)
+{
+  FILE *file = (FILE *)filep;
+
+  switch (how)
+    {
+    case bfd_print_symbol_name:
+      fprintf (file, "%s", symbol->name);
+      break;
+    case bfd_print_symbol_more:
+      if (ecoffsymbol (symbol)->local)
+       {
+         SYMR ecoff_sym;
+       
+         ecoff_swap_sym_in (abfd, ecoffsymbol (symbol)->native.lnative,
+                            &ecoff_sym);
+         fprintf (file, "ecoff local %lx %x %x",
+                  (unsigned long) ecoff_sym.value,
+                  (unsigned) ecoff_sym.st, (unsigned) ecoff_sym.sc);
+       }
+      else
+       {
+         EXTR ecoff_ext;
+
+         ecoff_swap_ext_in (abfd, ecoffsymbol (symbol)->native.enative,
+                            &ecoff_ext);
+         fprintf (file, "ecoff extern %lx %x %x",
+                  (unsigned long) ecoff_ext.asym.value,
+                  (unsigned) ecoff_ext.asym.st,
+                  (unsigned) ecoff_ext.asym.sc);
+       }
+      break;
+    case bfd_print_symbol_nm:
+      {
+       CONST char *section_name = symbol->section->name;
+
+       bfd_print_symbol_vandf ((PTR) file, symbol);
+       fprintf (file, " %-5s %s %s",
+                section_name,
+                ecoffsymbol (symbol)->local ? "l" : "e",
+                symbol->name);
+      }
+      break;
+    case bfd_print_symbol_all:
+      /* Print out the symbols in a reasonable way */
+      {
+       CONST char *section_name = symbol->section->name;
+       char type;
+       int pos;
+       EXTR ecoff_ext;
+       char jmptbl;
+       char cobol_main;
+       char weakext;
+
+       if (ecoffsymbol (symbol)->local)
+         {
+           ecoff_swap_sym_in (abfd, ecoffsymbol (symbol)->native.lnative,
+                              &ecoff_ext.asym);
+           type = 'l';
+           pos = (ecoffsymbol (symbol)->native.lnative
+                  - ecoff_data (abfd)->external_sym
+                  + ecoff_data (abfd)->symbolic_header.iextMax);
+           jmptbl = ' ';
+           cobol_main = ' ';
+           weakext = ' ';
+         }
+       else
+         {
+           ecoff_swap_ext_in (abfd, ecoffsymbol (symbol)->native.enative,
+                              &ecoff_ext);
+           type = 'e';
+           pos = (ecoffsymbol (symbol)->native.enative
+                  - ecoff_data (abfd)->external_ext);
+           jmptbl = ecoff_ext.jmptbl ? 'j' : ' ';
+           cobol_main = ecoff_ext.cobol_main ? 'c' : ' ';
+           weakext = ecoff_ext.weakext ? 'w' : ' ';
+         }
+
+       fprintf (file, "[%3d] %c %lx st %x sc %x indx %x %c%c%c %s",
+                pos, type, (unsigned long) ecoff_ext.asym.value,
+                (unsigned) ecoff_ext.asym.st,
+                (unsigned) ecoff_ext.asym.sc,
+                (unsigned) ecoff_ext.asym.index,
+                jmptbl, cobol_main, weakext,
+                symbol->name);
+
+       if (ecoffsymbol (symbol)->fdr != NULL
+           && ecoff_ext.asym.index != indexNil)
+         {
+           unsigned indx;
+           int bigendian;
+           long sym_base;
+           union aux_ext *aux_base;
+
+           indx = ecoff_ext.asym.index;
+
+           /* sym_base is used to map the fdr relative indices which
+              appear in the file to the position number which we are
+              using.  */
+           sym_base = ecoffsymbol (symbol)->fdr->isymBase;
+           if (ecoffsymbol (symbol)->local)
+             sym_base += ecoff_data (abfd)->symbolic_header.iextMax;
+
+           /* aux_base is the start of the aux entries for this file;
+              asym.index is an offset from this.  */
+           aux_base = (ecoff_data (abfd)->external_aux
+                       + ecoffsymbol (symbol)->fdr->iauxBase);
+
+           /* The aux entries are stored in host byte order; the
+              order is indicated by a bit in the fdr.  */
+           bigendian = ecoffsymbol (symbol)->fdr->fBigendian;
+
+           /* This switch is basically from gcc/mips-tdump.c  */
+           switch (ecoff_ext.asym.st)
+             {
+             case stNil:
+             case stLabel:
+               break;
+
+             case stFile:
+             case stBlock:
+               printf ("\n      End+1 symbol: %ld", indx + sym_base);
+               break;
+
+             case stEnd:
+               if (ecoff_ext.asym.sc == scText
+                   || ecoff_ext.asym.sc == scInfo)
+                 printf ("\n      First symbol: %ld", indx + sym_base);
+               else
+                 printf ("\n      First symbol: %ld", 
+                         (AUX_GET_ISYM (bigendian,
+                                        &aux_base[ecoff_ext.asym.index])
+                          + sym_base));
+               break;
+
+             case stProc:
+             case stStaticProc:
+               if (MIPS_IS_STAB (&ecoff_ext.asym))
+                 ;
+               else if (ecoffsymbol (symbol)->local)
+                 printf ("\n      End+1 symbol: %-7ld   Type:  %s",
+                         (AUX_GET_ISYM (bigendian,
+                                        &aux_base[ecoff_ext.asym.index])
+                          + sym_base),
+                         type_to_string (abfd, aux_base, indx + 1,
+                                         bigendian));
+               else
+                 printf ("\n      Type: %s",
+                         type_to_string (abfd, aux_base, indx, bigendian));
+
+               break;
+
+             default:
+               if (!MIPS_IS_STAB (&ecoff_ext.asym))
+                 printf ("\n      Type: %s",
+                         type_to_string (abfd, aux_base, indx, bigendian));
+               break;
+             }
+         }
+      }
+      break;
+    }
+}
+\f
+/* Provided a BFD, a section and an offset into the section, calculate
+   and return the name of the source file and the line nearest to the
+   wanted location.  */
+
+static boolean
+DEFUN (ecoff_find_nearest_line, (abfd,
+                                section,
+                                ignore_symbols,
+                                offset,
+                                filename_ptr,
+                                functionname_ptr,
+                                retline_ptr),
+       bfd *abfd AND
+       asection *section AND
+       asymbol **ignore_symbols AND
+       bfd_vma offset AND
+       CONST char **filename_ptr AND
+       CONST char **functionname_ptr AND
+       unsigned int *retline_ptr)
+{
+  FDR *fdr_ptr;
+  FDR *fdr_start;
+  FDR *fdr_end;
+  FDR *fdr_hold;
+  struct pdr_ext *pdr_ptr;
+  struct pdr_ext *pdr_end;
+  PDR pdr;
+  unsigned char *line_ptr;
+  unsigned char *line_end;
+  int lineno;
+  SYMR proc_sym;
+
+  /* If we're not in the .text section, we don't have any line
+     numbers.  */
+  if (strcmp (section->name, _TEXT) != 0)
+    return false;
+
+  /* Each file descriptor (FDR) has a memory address.  Here we track
+     down which FDR we want.  The FDR's are stored in increasing
+     memory order.  If speed is ever important, this can become a
+     binary search.  We must ignore FDR's with no PDR entries; they
+     will have the adr of the FDR before or after them.  */
+  fdr_start = ecoff_data (abfd)->fdr;
+  fdr_end = fdr_start + ecoff_data (abfd)->symbolic_header.ifdMax;
+  fdr_hold = (FDR *) NULL;
+  for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
+    {
+      if (offset < fdr_ptr->adr)
+       break;
+      if (fdr_ptr->cpd > 0)
+       fdr_hold = fdr_ptr;
+    }
+  if (fdr_hold == (FDR *) NULL)
+    return false;
+  fdr_ptr = fdr_hold;
+
+  /* Each FDR has a list of procedure descriptors (PDR).  PDR's also
+     have an address, which is relative to the FDR address, and are
+     also stored in increasing memory order.  */
+  offset -= fdr_ptr->adr;
+  pdr_ptr = ecoff_data (abfd)->external_pdr + fdr_ptr->ipdFirst;
+  pdr_end = pdr_ptr + fdr_ptr->cpd;
+  ecoff_swap_pdr_in (abfd, pdr_ptr, &pdr);
+  if (offset < pdr.adr)
+    return false;
+  for (pdr_ptr++; pdr_ptr < pdr_end; pdr_ptr++)
+    {
+      ecoff_swap_pdr_in (abfd, pdr_ptr, &pdr);
+      if (offset < pdr.adr)
+       break;
+    }
+
+  /* Now we can look for the actual line number.  The line numbers are
+     stored in a very funky format, which I won't try to describe.
+     Note that right here pdr_ptr and pdr hold the PDR *after* the one
+     we want; we need this to compute line_end.  */
+  line_end = ecoff_data (abfd)->line;
+  if (pdr_ptr == pdr_end)
+    line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
+  else
+    line_end += fdr_ptr->cbLineOffset + pdr.cbLineOffset;
+
+  /* Now change pdr and pdr_ptr to the one we want.  */
+  pdr_ptr--;
+  ecoff_swap_pdr_in (abfd, pdr_ptr, &pdr);
+
+  offset -= pdr.adr;
+  lineno = pdr.lnLow;
+  line_ptr = (ecoff_data (abfd)->line
+             + fdr_ptr->cbLineOffset
+             + pdr.cbLineOffset);
+  while (line_ptr < line_end)
+    {
+      int delta;
+      int count;
+
+      delta = *line_ptr >> 4;
+      if (delta >= 0x8)
+       delta -= 0x10;
+      count = (*line_ptr & 0xf) + 1;
+      ++line_ptr;
+      if (delta == -8)
+       {
+         delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff);
+         if (delta >= 0x8000)
+           delta -= 0x10000;
+         line_ptr += 2;
+       }
+      lineno += delta;
+      if (offset < count * 4)
+       break;
+      offset -= count * 4;
+    }
+
+  /* If offset is too large, this line is not interesting.  */
+  if (offset > 100)
+    return false;
+
+  *filename_ptr = ecoff_data (abfd)->ss + fdr_ptr->issBase + fdr_ptr->rss;
+  ecoff_swap_sym_in (abfd,
+                    (ecoff_data (abfd)->external_sym
+                     + fdr_ptr->isymBase
+                     + pdr.isym),
+                    &proc_sym);
+  *functionname_ptr = ecoff_data (abfd)->ss + proc_sym.iss;
+  *retline_ptr = lineno;
+  return true;
+}
+\f
+static CONST bfd_coff_backend_data bfd_ecoff_std_swap_table = {
+  (void (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_in */
+  (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
+  (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
+  (unsigned (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_out */
+  (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
+  (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
+  ecoff_swap_reloc_out, ecoff_swap_filehdr_out, ecoff_swap_aouthdr_out,
+  ecoff_swap_scnhdr_out,
+  FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
+  ecoff_swap_filehdr_in, ecoff_swap_aouthdr_in, ecoff_swap_scnhdr_in,
+  ecoff_bad_format_hook, ecoff_set_arch_mach_hook, ecoff_mkobject_hook,
+  styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
+  ecoff_slurp_symbol_table
+};
+
+/* Routines that need to be written.  */
+#define ecoff_write_object_contents (boolean (*) PARAMS ((bfd *))) bfd_false
+#define ecoff_set_section_contents (boolean (*) PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type))) bfd_false
+#define ecoff_get_reloc_upper_bound (unsigned int (*) PARAMS ((bfd *, sec_ptr))) bfd_0
+#define ecoff_canonicalize_reloc (unsigned int (*) PARAMS ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry **))) bfd_0
+#define ecoff_set_arch_mach (boolean (*) PARAMS ((bfd *, enum bfd_architecture, unsigned long))) bfd_false
+#define ecoff_sizeof_headers (int (*) PARAMS ((bfd *, boolean))) bfd_0
+
+/* get_lineno could be written for ECOFF, but it would currently only
+   be useful for linking ECOFF and COFF files together, which doesn't
+   seem too likely.  */
+#define ecoff_get_lineno (struct lineno_cache_entry *(*)()) bfd_nullvoidptr
+
+#define ecoff_core_file_failing_command        _bfd_dummy_core_file_failing_command
+#define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
+#define ecoff_core_file_matches_executable_p   _bfd_dummy_core_file_matches_executable_p
+#define ecoff_slurp_armap              bfd_slurp_coff_armap
+#define ecoff_slurp_extended_name_table        _bfd_slurp_extended_name_table
+#define ecoff_write_armap              coff_write_armap
+#define ecoff_truncate_arname          bfd_dont_truncate_arname
+#define ecoff_openr_next_archived_file bfd_generic_openr_next_archived_file
+#define ecoff_generic_stat_arch_elt    bfd_generic_stat_arch_elt
+#define        ecoff_get_section_contents      bfd_generic_get_section_contents
+#define        ecoff_close_and_cleanup         bfd_generic_close_and_cleanup
+
+#define ecoff_bfd_debug_info_start     bfd_void
+#define ecoff_bfd_debug_info_end               bfd_void
+#define ecoff_bfd_debug_info_accumulate        \
+                       (void (*) PARAMS ((bfd *, struct sec *))) bfd_void
+#define ecoff_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
+#define ecoff_bfd_relax_section                bfd_generic_relax_section
 
 bfd_target ecoff_little_vec =
 {
   "ecoff-littlemips",          /* name */
-  bfd_target_coff_flavour,
+  bfd_target_ecoff_flavour,
   false,                       /* data byte order is little */
   false,                       /* header byte order is little */
 
@@ -75,18 +1323,20 @@ bfd_target ecoff_little_vec =
   _do_getl64, _do_putl64,      _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
   _do_getl64, _do_putl64,      _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
 
- {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
    bfd_generic_archive_p, _bfd_dummy_target},
{bfd_false, coff_mkobject, bfd_false, /* bfd_set_format */
 {bfd_false, ecoff_mkobject, bfd_false, /* bfd_set_format */
    bfd_false},
- {bfd_false, coff_write_object_contents, bfd_false, bfd_false},
-  JUMP_TABLE (coff)
- };
+  {bfd_false, ecoff_write_object_contents, bfd_false, bfd_false},
+  JUMP_TABLE (ecoff),
+  0, 0,
+  (PTR) &bfd_ecoff_std_swap_table
+};
 
 bfd_target ecoff_big_vec =
 {
   "ecoff-bigmips",             /* name */
-  bfd_target_coff_flavour,
+  bfd_target_ecoff_flavour,
   true,                                /* data byte order is big */
   true,                                /* header byte order is big */
 
@@ -103,10 +1353,14 @@ bfd_target ecoff_big_vec =
   _do_getb64, _do_putb64,      _do_getb32, _do_putb32, _do_getb16, _do_putb16,
  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
    bfd_generic_archive_p, _bfd_dummy_target},
- {bfd_false, coff_mkobject, bfd_false, /* bfd_set_format */
+ {bfd_false, ecoff_mkobject, bfd_false, /* bfd_set_format */
    bfd_false},
- {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
    bfd_false, bfd_false},
-  JUMP_TABLE(coff),
-  COFF_SWAP_TABLE
- };
+  JUMP_TABLE(ecoff),
+  0, 0,
+  (PTR) &bfd_ecoff_std_swap_table
+  /* Note that there is another bfd_target just above this one.  If
+     you are adding initializers here, you should be adding them there
+     as well.  */
+};
index 2037f0e..4929cff 100644 (file)
@@ -38,10 +38,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "coff/ecoff-ext.h"    /* ECOFF external struct defns */
 
 void
-ecoff_swap_hdr_in (abfd, ext_copy, intern)
-     bfd *abfd;
-     struct hdr_ext *ext_copy;
-     HDRR *intern;
+DEFUN (ecoff_swap_hdr_in, (abfd, ext_copy, intern),
+       bfd *abfd AND
+       struct hdr_ext *ext_copy AND
+       HDRR *intern)
 {
   struct hdr_ext ext[1];
 
@@ -82,10 +82,10 @@ ecoff_swap_hdr_in (abfd, ext_copy, intern)
 /* Swap in the file descriptor record.  */
 
 void
-ecoff_swap_fdr_in (abfd, ext_copy, intern)
-     bfd *abfd;
-     struct fdr_ext *ext_copy;
-     FDR *intern;
+DEFUN (ecoff_swap_fdr_in, (abfd, ext_copy, intern),
+       bfd *abfd AND
+       struct fdr_ext *ext_copy AND
+       FDR *intern)
 {
   struct fdr_ext ext[1];
 
@@ -143,10 +143,10 @@ ecoff_swap_fdr_in (abfd, ext_copy, intern)
 /* Swap in the procedure descriptor record.  */
 
 void
-ecoff_swap_pdr_in (abfd, ext_copy, intern)
-     bfd *abfd;
-     struct pdr_ext *ext_copy;
-     PDR *intern;
+DEFUN (ecoff_swap_pdr_in, (abfd, ext_copy, intern),
+       bfd *abfd AND
+       struct pdr_ext *ext_copy AND
+       PDR *intern)
 {
   struct pdr_ext ext[1];
 
@@ -177,10 +177,10 @@ ecoff_swap_pdr_in (abfd, ext_copy, intern)
 /* Swap in a symbol record.  */
 
 void
-ecoff_swap_sym_in (abfd, ext_copy, intern)
-     bfd *abfd;
-     struct sym_ext *ext_copy;
-     SYMR *intern;
+DEFUN (ecoff_swap_sym_in, (abfd, ext_copy, intern),
+       bfd *abfd AND
+       struct sym_ext *ext_copy AND
+       SYMR *intern)
 {
   struct sym_ext ext[1];
 
@@ -226,10 +226,10 @@ ecoff_swap_sym_in (abfd, ext_copy, intern)
 /* Swap in an external symbol record.  */
 
 void
-ecoff_swap_ext_in (abfd, ext_copy, intern)
-     bfd *abfd;
-     struct ext_ext *ext_copy;
-     EXTR *intern;
+DEFUN (ecoff_swap_ext_in, (abfd, ext_copy, intern),
+       bfd *abfd AND
+       struct ext_ext *ext_copy AND
+       EXTR *intern)
 {
   struct ext_ext ext[1];
 
@@ -260,10 +260,10 @@ ecoff_swap_ext_in (abfd, ext_copy, intern)
    info comes from the file header record (fh-fBigendian).  */
 
 void
-ecoff_swap_tir_in (bigend, ext_copy, intern)
-     int bigend;
-     struct tir_ext *ext_copy;
-     TIR *intern;
+DEFUN (ecoff_swap_tir_in, (bigend, ext_copy, intern),
+       int bigend AND
+       struct tir_ext *ext_copy AND
+       TIR *intern)
 {
   struct tir_ext ext[1];
 
@@ -316,10 +316,10 @@ ecoff_swap_tir_in (bigend, ext_copy, intern)
    big-endian or little-endian format.*/
 
 void
-ecoff_swap_rndx_in (bigend, ext_copy, intern)
-     int bigend;
-     struct rndx_ext *ext_copy;
-     RNDXR *intern;
+DEFUN (ecoff_swap_rndx_in, (bigend, ext_copy, intern),
+       int bigend AND
+       struct rndx_ext *ext_copy AND
+       RNDXR *intern)
 {
   struct rndx_ext ext[1];
 
@@ -353,10 +353,10 @@ ecoff_swap_rndx_in (bigend, ext_copy, intern)
 /* Swap in a relative file descriptor.  */
 
 void
-ecoff_swap_rfd_in (abfd, ext, intern)
-     bfd *abfd;
-     struct rfd_ext *ext;
-     RFDT *intern;
+DEFUN (ecoff_swap_rfd_in, (abfd, ext, intern),
+       bfd *abfd AND
+       struct rfd_ext *ext AND
+       RFDT *intern)
 {
   
   *intern = bfd_h_get_32 (abfd, (bfd_byte *)ext->rfd);
index 57ff69a..912adb9 100644 (file)
@@ -132,6 +132,7 @@ of a file.
 .    bfd_target_unknown_flavour,
 .    bfd_target_aout_flavour,
 .    bfd_target_coff_flavour,
+.    bfd_target_ecoff_flavour,
 .    bfd_target_elf_flavour,
 .    bfd_target_ieee_flavour,
 .    bfd_target_oasys_flavour,
@@ -357,7 +358,7 @@ extern bfd_target rs6000coff_vec;
 extern bfd_target h8300coff_vec;
 extern bfd_target z8kcoff_vec;
 extern bfd_target we32kcoff_vec;
-#ifdef hp9000s800
+#ifdef HOST_HPPAHPUX
 extern bfd_target hppa_vec;
 #endif
 
@@ -412,7 +413,7 @@ bfd_target *target_vector[] = {
        &m68kcoff_vec,
        &a29kcoff_big_vec,
        &rs6000coff_vec,
-#ifdef hp9000s800
+#ifdef HOST_HPPAHPUX
         &hppa_vec,
 #endif
        &we32kcoff_vec,