diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
new file mode 100644
index 00000000000..c27e8c3b627
--- /dev/null
+++ b/bfd/coff-mips.c
@@ -0,0 +1,1093 @@
+/* MIPS Extended-Coff handler for Binary File Diddling.
+   Written by Per Bothner.
+
+   FIXME, Needs Copyleft here.  */
+
+/* This does not compile on anything but a MIPS yet (and I haven't been
+   able to test it there either since the latest merge!).  So it stays
+   out by default.  */
+#ifdef ECOFF_BFD
+
+#define MIPS 1
+#include "libbfd.h"
+#include "sysdep.h"
+#include "libcoff.h"		/* to allow easier abstraction-breaking */
+
+#include "intel-coff.h"
+
+
+
+
+static reloc_howto_type howto_table[] = 
+{
+  {0},
+  {1},
+  {2},
+  {3},
+  {4},
+  {5},
+  {6},
+  {7},
+  {8},
+  {9},
+  {10},
+  {11},
+  {12},
+  {13},
+  {14},
+  {15},
+  {16},
+  {  R_RELLONG, 0, 2, 32, 0, 0, true, true},
+  {18},
+  {19},
+  {20},
+  {21},
+  {22},
+  {23},
+  {24},
+  {  R_IPRMED, 2, 2,22,1,0, true, true},
+  {26},
+/* What do we do with this - ? */
+#if 1
+  {  R_OPTCALL, 0,2,32,0,0, true, true},
+#else
+  {  R_OPTCALL, 0,3,32,0,0, true, true},
+#endif
+};
+
+
+#define ALIGN(this, boundary) \
+  ((( (this) + ((boundary) -1)) & (~((boundary)-1))))
+
+
+/* Support for Motorola 88k bcs coff as well as Intel 960 coff */
+
+
+#include <stdio.h>
+#include <string.h>
+
+
+/* Align an address by rounding it up to a power of two.  It leaves the
+   address unchanged if align == 0 (2^0 = alignment of 1 byte) */
+#define	i960_align(addr, align)	\
+	( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
+
+#define TAG_SECTION_NAME ".tagbits"
+
+/* Libraries shouldn't be doing this stuff anyway! */
+void fatal();
+/* void warning(); */
+
+
+/* initialize a section structure with information
+ * peculiar to this particular implementation of coff 
+ */
+
+static void
+ecoff_new_section_hook(abfd, section)
+bfd *abfd;
+asection *section;
+{
+
+  section->output_file_alignment = DEFAULT_SECTION_ALIGNMENT;
+  section->subsection_alignment = section->output_file_alignment;
+  if (abfd->flags & D_PAGED)
+    {
+      /**
+	If the output object file is demand paged then the
+	text section starts at the filehdr, with the first 
+	usefull bit of data at the end of the filehdr+opthdr+
+	scnhdrs. Since we don't know how many sections will
+	be put into the output file, we have to recalculate
+	the section pads after each additional section has
+	been created
+	**/
+      asection *ptr = abfd->sections;
+      unsigned int padding = FILHSZ + AOUTSZ +SCNHSZ * abfd->section_count;
+
+      padding = ALIGN(padding, ptr->output_file_alignment);
+      while (ptr) 
+	{
+	  ptr->start_pad = padding;
+	  /* Only the first section is padded  */
+	  padding = 0;
+	  ptr = ptr->next;
+	}
+    }
+  else 
+    {
+
+      /* If the object is not demand paged, then all the sections
+	 have no padding 
+	 */
+      section->start_pad = 0;
+    }
+
+
+
+}
+/* actually it makes itself and its children from the file headers */
+static boolean
+make_a_section_from_file (abfd, hdr)
+bfd *abfd;
+     struct scnhdr *hdr;
+
+{
+  asection *return_section ;
+
+  { char *name = (char *)xmalloc(9); 
+
+    strncpy(name, (char *)&hdr->s_name[0], 8);
+
+    return_section = bfd_make_section(abfd,  name);
+    (return_section->name)[8] = 0;
+  }
+
+  /* s_paddr is presumed to be = to s_vaddr */
+  /* FIXME -- needs to call swapping routines */
+#define assign(to, from) return_section->to = hdr->from
+  assign (vma, s_vaddr);
+  assign (original_vma, s_vaddr);
+  assign (size, s_size);
+  assign (filepos, s_scnptr);
+  assign (rel_filepos, s_relptr);
+  assign (reloc_count, s_nreloc);
+#ifdef I960
+  assign (alignment, s_align);
+#endif
+  assign (line_filepos, s_lnnoptr);
+/*  return_section->linesize =   hdr->s_nlnno * sizeof (struct lineno);*/
+
+#undef assign
+  return_section->lineno_count = hdr->s_nlnno;
+  return_section->userdata = (void *)NULL;
+  return_section->next = (asection *)NULL;
+  if ((hdr->s_flags & STYP_TEXT) || (hdr->s_flags & STYP_DATA))
+    return_section->flags = (SEC_LOAD | SEC_ALLOC);
+  else if (hdr->s_flags & STYP_BSS)
+    return_section->flags = SEC_ALLOC;
+
+  if (hdr->s_nreloc != 0) return_section->flags |= SEC_RELOC;
+
+  return true;
+}
+
+bfd_target *
+ecoff_real_object_p (abfd, nscns, opthdr)
+     bfd *abfd;
+     unsigned short nscns, opthdr;
+{
+  struct icofdata *tdata;
+  char *file_info;		/* buffer for all the headers */
+  long readsize;		/* length of file_info */
+  struct filehdr* filehdr;	/* points into file_info */
+  struct scnhdr *sections;	/* points into file_info */
+
+  /* OK, now we know the format, read in the filehdr, soi-disant
+     "optional header", and all the sections.*/
+  readsize = sizeof(struct filehdr) + opthdr + (nscns * sizeof (struct scnhdr));
+  file_info = xmalloc (readsize);
+  if (file_info == NULL) {
+    bfd_error = no_memory;
+    return 0;
+  }
+  if (bfd_seek (abfd, 0, false) < 0) return 0;
+  if (bfd_read (file_info, 1, readsize, abfd) != readsize) return 0;
+  filehdr = (struct filehdr *) file_info;
+  sections = (struct scnhdr *) (file_info + sizeof (struct filehdr) + opthdr);
+
+  /* Now copy data as required; construct all asections etc */
+  tdata = (struct icofdata *) xmalloc (sizeof (struct icofdata) +
+				      sizeof (AOUTHDR));
+  if (tdata == NULL) {
+    bfd_error = no_memory;
+    return 0;
+  }
+
+  if (nscns != 0) 
+  {
+    unsigned int i;
+    for (i = 0; i < nscns; i++) 
+      {
+	make_a_section_from_file (abfd, sections + i);
+      }
+  }
+
+#ifdef I960
+  /* OK, now make a section for the tagbits if there were any */
+#if 0
+  {
+    AOUTHDR *aouthdr;		/* points into tdata! */
+    aouthdr = (AOUTHDR *) (((char *) tdata) + sizeof (struct icofdata));
+    if (aouthdr->tagentries != 0) {
+      asection *tag_section = (asection *) xmalloc (sizeof (asection));
+      if (tag_section == NULL) {
+	free (tdata);
+	return 0;
+      }
+      tag_section->size = aouthdr->tagentries * sizeof (TAGBITS);
+      tag_section->name = TAG_SECTION_NAME;
+      tag_section->filepos = readsize; /* not surprisingly */
+      /* Put this one first */
+      tag_section->next = abfd->sections;
+      abfd->sections = tag_section;
+    }
+  }
+#endif
+#endif
+abfd->flags |= HAS_RELOC | HAS_LINENO | HAS_LOCALS;
+
+
+  /* FIXME, the guess should be set by OR-ing info from the sections */
+  if ((filehdr->f_flags & F_RELFLG) != F_RELFLG) abfd->flags &= ~HAS_RELOC;
+  if ((filehdr->f_flags & F_EXEC) == F_EXEC)     abfd->flags |= EXEC_P;
+  if ((filehdr->f_flags & F_LNNO) != F_LNNO)     abfd->flags &= ~HAS_LINENO;
+  if ((filehdr->f_flags & F_LSYMS) != F_LSYMS)   abfd->flags &= ~HAS_LOCALS;
+  abfd->tdata = tdata;
+  bfd_get_symcount (abfd) = filehdr->f_nsyms;
+  if (filehdr->f_nsyms) abfd->flags |= HAS_SYMS;
+   
+  tdata->sym_filepos = filehdr->f_symptr;
+  tdata->hdr = (struct aouthdr *)(file_info + sizeof (struct filehdr));
+  tdata->symbols = (esymbol *)NULL;
+  bfd_get_start_address (abfd) = exec_hdr (abfd)->entry;
+  return abfd->xvec;
+}
+
+bfd_target *
+ecoff_object_p (abfd)
+     bfd *abfd;
+{
+  unsigned short magic, nscns, opthdr;
+
+  bfd_error = no_error;
+
+  /* figure out how much to read */
+  if (bfd_read (&magic, 1, sizeof (magic), abfd) != sizeof (magic))
+    return 0;
+
+  magic = bfd_h_getshort (abfd, (unsigned char *)&magic);
+  if (magic != (abfd->xvec->byteorder_big_p ? 0x160 :  0x162)) {
+    bfd_error = wrong_format;
+    return 0;
+  }
+  if (bfd_read (&nscns, 1, sizeof (nscns), abfd) != sizeof (nscns))
+    return 0;
+  nscns = bfd_h_getshort (abfd, (unsigned char *)&nscns);
+
+  if (bfd_seek (abfd, ((sizeof (long)) * 3), true) < 0) return false;
+  if (bfd_read (&opthdr, 1, sizeof (opthdr), abfd) != sizeof (opthdr))
+    return 0;
+  opthdr = bfd_h_getshort (abfd, (unsigned char *)&opthdr);
+
+  return ecoff_real_object_p (abfd, nscns, opthdr);
+}
+
+static boolean
+ecoff_mkobject (abfd)
+     bfd *abfd;
+{
+  char *rawptr;
+
+
+  bfd_error = no_error;
+
+  /* Use an intermediate variable for clarity */
+  rawptr =  xmalloc (sizeof (struct icofdata) + sizeof (AOUTHDR));
+  if (rawptr == NULL) {
+    bfd_error = no_memory;
+    return false;
+  }
+
+  abfd->tdata = (struct icofdata *) rawptr;
+  exec_hdr (abfd) = (AOUTHDR *) (rawptr + sizeof (struct icofdata));
+
+  return true;
+}
+
+static void
+ecoff_count_linenumbers(abfd)
+bfd *abfd;
+{
+  unsigned int limit = bfd_get_symcount(abfd);
+  unsigned int i = 0;
+  esymbol **p = (esymbol **)(abfd->outsymbols);
+  {
+    asection *s = abfd->sections;
+    while (s) {
+      if (s->lineno_count != 0) {
+	fatal("Bad initial state");
+      }
+      s = s->next;
+    }
+  }
+
+  while (i < limit) 
+    {
+      esymbol *q = *p;
+      if (q->c.lineno) 
+	{
+	  /* This symbol has a linenumber, increment the
+	   * owning section's linenumber count */
+	  alent *l = q->c.lineno;
+	  q->c.section->lineno_count++;
+	  l++;
+	  while (l->line_number) {
+	    q->c.section->lineno_count++;
+	    l++;
+	  }
+	}
+      p++;
+      i++;
+    }
+}
+
+/*
+ run through the internal symbol table and make all the
+ pointers and things within the table point to the right places
+ */
+
+static void
+ecoff_mangle_symbols(abfd)
+bfd *abfd;
+{
+  esymbol **p = (esymbol **)(abfd->outsymbols);
+  unsigned int native_index = 0;
+  unsigned int last_file_index = 0;
+  unsigned int limit = bfd_get_symcount(abfd);
+  struct syment *last_file_symbol = (struct syment *)NULL;
+  while (limit--) {
+    esymbol *q = *p;
+    struct syment *native = q->native;
+    if(native) {
+      /* Alter the native representation */
+
+      native->n_value = q->c.value;
+      if (q->c.flags & BSF_FORT_COMM) {
+	native->n_scnum = 0;
+      }
+      else if (q->c.flags & BSF_DEBUGGING) {
+	native->n_scnum = -2;
+      }
+      else if (q->c.flags & BSF_UNDEFINED) {
+	native->n_scnum = 0;
+      }
+      else if (q->c.flags & BSF_ABSOLUTE) {
+	native->n_scnum = -1;
+      }
+      else {
+	native->n_scnum = q->c.section->index + 1;
+      }
+      if (native->n_numaux) 
+	{
+	  union auxent *a = (union auxent *)(native+1);
+	  /* Relocate symbol indexes */
+	  if (ISFCN(native->n_type))
+	    {
+	      a->x_sym.x_fcnary.x_fcn.x_endndx += last_file_index;
+	    }
+	  else if(native->n_sclass == C_BLOCK && q->c.name[1] == 'b')
+	    {
+	      a->x_sym.x_fcnary.x_fcn.x_endndx += last_file_index;
+	    }
+
+	  else if (native->n_sclass == C_STRTAG) 
+	    {
+	      a->x_sym.x_fcnary.x_fcn.x_endndx += last_file_index;
+	    }
+	  else       if (native->n_sclass == C_MOS || native->n_sclass == C_EOS || native->n_sclass == C_MOE) 
+	    {
+	      a->x_sym.x_tagndx += last_file_index;
+	    }
+	}
+
+
+      switch (native->n_sclass) {
+      case C_MOS:
+      case C_EOS:
+      case C_REGPARM:
+      case C_REG:
+      case 19:			/*C_REGARG:FIXME */
+	/* Fix so that they have an absolute section */
+	native->n_scnum= -1;
+	break;
+
+      case C_FILE:
+	/* Chain all the .file symbols together */
+	if(last_file_symbol) {
+	  last_file_symbol->n_value = native_index;
+	}
+	last_file_symbol = native;
+	last_file_index = native_index;
+	break;
+      case C_NULL:
+      case C_AUTO:
+      case C_EXT:
+      case C_EXTDEF:
+      case C_LABEL:
+      case C_ULABEL:
+      case C_USTATIC:
+      case C_STRTAG:
+      case C_FCN:
+      case C_BLOCK:
+      case C_STAT:
+      case C_LEAFPROC:
+	break;
+      default:
+	/* Bogus: This should be returning an error code, not printing
+	   something out! */
+	/* warning("Unrecognised sclass %d", native->n_sclass); */
+	break;
+      }
+      native_index += 1 + native->n_numaux;
+    }
+    else {
+      native_index++;
+    }
+    p++;
+  }
+}
+static void
+ecoff_write_symbols(abfd)
+bfd *abfd;
+{
+}
+
+
+void
+ecoff_write_linenumbers(abfd)
+bfd *abfd;
+{
+}
+
+
+asymbol *
+ecoff_make_empty_symbol(abfd, n)
+bfd *abfd;
+unsigned int n;
+{
+  unsigned int j;
+  esymbol *new = (esymbol *)xmalloc(sizeof(esymbol) * n);
+  for (j= 0; j < n; j++) {
+    new[j].native = 0;
+    new[j].c.lineno = (alent *)NULL;
+  }
+  return (asymbol *)new;
+}
+
+/*SUPPRESS 558*/
+/*SUPPRESS 529*/
+boolean
+ecoff_write_object_contents (abfd)
+     bfd *abfd;
+{
+  return false;
+}
+
+/* Calculate the file position for each section. */
+
+static void
+ecoff_compute_section_file_positions (abfd)
+     bfd *abfd;
+{
+  file_ptr sofar = sizeof (struct filehdr) + sizeof (AOUTHDR);
+  asection *current;
+
+  sofar += abfd->section_count * sizeof (struct scnhdr);
+  for (current = abfd->sections; current != NULL; current = current->next) {
+    sofar = ALIGN(sofar, current->output_file_alignment);
+    current->filepos = sofar;
+    /* Only add sections which are loadable */
+    if (current->flags & SEC_LOAD) sofar += current->size;
+#if 0
+    if(current->filepos & (current->alignment-1)) {
+      sofar += current->alignment - (current->filepos &(current->alignment-1));
+      current->filepos = (current->filepos + current->alignment) & -current->alignment;
+    }
+#endif
+  }
+  obj_relocbase (abfd) = sofar;
+}
+
+boolean
+ecoff_set_section_contents (abfd, section, location, offset, count)
+     bfd *abfd;
+     sec_ptr section;
+     unsigned char *location;
+     file_ptr offset;
+      int count;
+{
+    return false;
+}
+
+boolean
+ecoff_set_section_linenos (abfd, section, location, offset, count)
+     bfd *abfd;
+     sec_ptr section;
+     unsigned char *location;
+     file_ptr offset;
+      int count;
+{
+   return 0;
+}
+
+
+boolean
+ecoff_close_and_cleanup (abfd)
+     bfd *abfd;
+{
+  return false;
+}
+
+
+
+
+
+static void *
+buy_and_read(abfd, where, relative, size)
+bfd *abfd;
+int where;
+boolean relative;
+unsigned int size;
+{
+  void *area = (void *)xmalloc(size);
+  if (!area) {
+    bfd_error = no_memory;
+    return 0;
+  }
+  bfd_seek(abfd, where, relative);
+  if (bfd_read(area, 1, size, abfd) != size){
+    bfd_error = system_call_error;
+    free(area);
+    return 0;
+  }
+  return area;
+}
+
+static
+struct sec_struct *section_from_bfd_index(abfd, index)
+bfd *abfd;
+int index;
+{
+if (index > 0) {
+  struct sec_struct *answer = abfd->sections;
+
+  while (--index) {
+    answer = answer->next;
+  }
+  return answer;
+}
+return 0;
+}
+
+static int
+ecoff_get_symcount_upper_bound (abfd)
+     bfd *abfd;
+{
+fatal("call to ecoff_get_symcount_upper_bound");
+return 0;
+}
+
+static symindex
+ecoff_get_first_symbol (abfd)
+     bfd * abfd;
+{
+  return 0;
+}
+
+static symindex
+ecoff_get_next_symbol (abfd, oidx)
+     bfd *abfd;
+     symindex oidx;
+{
+  if (oidx == BFD_NO_MORE_SYMBOLS) return BFD_NO_MORE_SYMBOLS;
+  return ++oidx >= bfd_get_symcount (abfd) ? BFD_NO_MORE_SYMBOLS : oidx;
+}
+
+static char *
+ecoff_symbol_name (abfd, idx)
+     bfd *abfd;
+     symindex idx;
+{
+  return (obj_symbols (abfd) + idx)->c.name;
+}
+
+static long
+ecoff_symbol_value (abfd, idx)
+     bfd *abfd;
+     symindex idx;
+{
+  return (obj_symbols (abfd) + idx)->c.value;
+}
+
+static symclass
+ecoff_classify_symbol (abfd, idx)
+     bfd *abfd;
+     symindex idx;
+{
+  esymbol *sym = obj_symbols (abfd) + idx;
+
+  if ((sym->c.flags & BSF_FORT_COMM) != 0)   return bfd_symclass_fcommon;
+  if ((sym->c.flags & BSF_GLOBAL) != 0)    return bfd_symclass_global;
+  if ((sym->c.flags & BSF_DEBUGGING) != 0)  return bfd_symclass_debugger;
+  if ((sym->c.flags & BSF_UNDEFINED) != 0) return bfd_symclass_undefined;
+
+  return bfd_symclass_unknown;
+}
+
+static boolean
+ecoff_symbol_hasclass (abfd, idx, class)
+     bfd *abfd;
+     symindex idx;
+     symclass class;
+{
+
+  esymbol *sym = obj_symbols (abfd) + idx;
+
+  switch (class) {
+
+  case bfd_symclass_fcommon:   return (sym->c.flags & BSF_FORT_COMM) != 0;
+  case bfd_symclass_global:    return (sym->c.flags & BSF_GLOBAL) != 0;
+  case bfd_symclass_debugger:  return (sym->c.flags & BSF_DEBUGGING) != 0;
+  case bfd_symclass_undefined: return (sym->c.flags & BSF_UNDEFINED) != 0;
+
+  default: return false;
+  }
+}
+
+
+
+
+static
+boolean
+ecoff_slurp_line_table (abfd, asect)
+  bfd *abfd;
+  asection *asect;
+{
+  return true;
+}
+
+static boolean
+ecoff_slurp_symbol_table(abfd)
+     bfd *abfd;
+{
+  struct syment *native_symbols;
+  esymbol *cached_area;
+  char *string_table = (char *)NULL;
+  unsigned int string_table_size;
+  unsigned int number_of_symbols = 0;
+  if (obj_symbols (abfd)) return true;
+  bfd_seek(abfd, obj_sym_filepos(abfd), false);
+  /* Read in the symbol table */
+  native_symbols =
+    (struct syment *)buy_and_read(abfd,
+				  obj_sym_filepos(abfd),
+				  false,
+				  bfd_get_symcount(abfd) * sizeof(struct syment));
+  if (!native_symbols) {
+    return false;
+  }
+
+
+  /* Allocate enough room for all the symbols in cached form */
+  cached_area = (esymbol *)xmalloc(bfd_get_symcount(abfd) * sizeof(esymbol));
+
+
+  {
+
+    esymbol *dst = cached_area;
+    unsigned int last_native_index = bfd_get_symcount(abfd);
+    unsigned int this_index = 0;
+    while (this_index < last_native_index) 
+      {
+	struct syment *src = native_symbols + this_index;
+	if (src->n_zeroes == 0) {
+	  /* This symbol has a name in the string table */
+	  /* Which means that we'll have to read it in */
+
+	  /* Fetch the size of the string table which is straight after the
+	   * symbol table
+	   */
+	  if (string_table == (char *)NULL) {
+	    if (bfd_read(&string_table_size, sizeof(string_table_size), 1, abfd) !=
+		sizeof(string_table_size)) {
+	      fatal("Corrupt coff format");
+	    }
+	    else {
+	      /* Read the string table */
+	      string_table = 
+		(char *)buy_and_read(abfd,0, true,
+				     string_table_size - sizeof(string_table_size)) ;
+
+	    }
+	  }
+
+
+	dst->c.name = string_table + src->n_offset - 4;
+	}
+	else {
+	  /* Otherwise we have to buy somewhere for this name */
+	  dst->c.name = xmalloc (SYMNMLEN+1);
+	  strncpy(dst->c.name, src->n_name, SYMNMLEN);
+	  dst->c.name[SYMNMLEN+1] = '\0';	/* Be sure to terminate it */
+	}  
+
+	/* We use the native name field to point to the cached field */
+	src->n_zeroes = (long)dst;
+	dst->c.section = section_from_bfd_index(abfd, src->n_scnum);
+	switch (src->n_sclass) 
+	  {
+#ifdef I960
+	  case C_LEAFPROC:
+	    dst->c.value = src->n_value - dst->c.section->vma;
+	    dst->c.flags = BSF_EXPORT | BSF_GLOBAL;
+	    dst->c.flags |= BSF_NOT_AT_END;
+	    break;
+
+#endif
+
+	  case C_EXT:
+	    if (src->n_scnum == 0) {
+	      if (src->n_value == 0) 
+		{
+		  dst->c.flags =  BSF_UNDEFINED;
+		}
+	      else {
+		dst->c.flags = BSF_FORT_COMM;
+		dst->c.value = src->n_value;
+	      }
+	    }
+	    else {
+
+	      /* Base the value as an index from the base of the section */
+	      if (dst->c.section == (asection *)NULL)  
+		{
+	      dst->c.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
+		  dst->c.value = src->n_value;
+		}
+	      else 
+		{
+	      dst->c.flags = BSF_EXPORT | BSF_GLOBAL;
+		  dst->c.value = src->n_value - dst->c.section->vma;	
+		}
+	      if (ISFCN(src->n_type)) {
+		/* A function ext does not go at the end of a file*/
+		dst->c.flags |= BSF_NOT_AT_END;
+	      }
+
+	    }
+
+	    break;
+	  case C_STAT	:	/* static			*/
+	  case C_LABEL	:	/* label			*/
+	    dst->c.flags = BSF_LOCAL;
+	    /* Base the value as an index from the base of the section */
+	    dst->c.value = src->n_value - dst->c.section->vma;	
+	    break;
+
+	  case C_MOS	:	/* member of structure	*/
+	  case C_EOS	:	/* end of structure		*/
+	  case C_REGPARM	: /* register parameter		*/
+	  case C_REG	:	/* register variable		*/
+	  case 19           :	/* Intel specific REGARG FIXME */
+	  case C_TPDEF	:	/* type definition		*/
+
+ 	  case C_ARG:
+          case C_AUTO:		/* automatic variable */
+	  case C_FIELD:		/* bit field */
+	  case C_ENTAG	:	/* enumeration tag		*/
+	  case C_MOE	:	/* member of enumeration	*/
+	  case C_MOU	:	/* member of union		*/
+	  case C_UNTAG	:	/* union tag			*/
+
+	    dst->c.flags = BSF_DEBUGGING;
+	    dst->c.value = src->n_value;
+	    break;
+
+	  case C_FILE	:	/* file name			*/
+	  case C_STRTAG	:	/* structure tag		*/
+	    dst->c.flags = BSF_DEBUGGING;
+	    dst->c.value = src->n_value ;
+
+	    break;
+	  case C_BLOCK	:	/* ".bb" or ".eb"		*/
+	  case C_FCN	:	/* ".bf" or ".ef"		*/
+	    dst->c.flags = BSF_LOCAL;
+	    /* Base the value as an index from the base of the section */
+	    dst->c.value = src->n_value - dst->c.section->vma;	
+
+	    break;
+	  case C_EFCN	:	/* physical end of function	*/
+	  case C_NULL:
+	  case C_EXTDEF	:	/* external definition		*/
+	  case C_ULABEL	:	/* undefined label		*/
+	  case C_USTATIC	: /* undefined static		*/
+	  case C_LINE	:	/* line # reformatted as symbol table entry */
+	  case C_ALIAS	:	/* duplicate tag		*/
+	  case C_HIDDEN	:	/* ext symbol in dmert public lib */
+
+	  default:
+
+	    printf("SICK%d\n",src->n_sclass);
+	    dst->c.flags = BSF_DEBUGGING;
+	    dst->c.value = src->n_value ;
+
+	    break;
+	  }
+
+
+
+
+	if (dst->c.flags == 0) fatal("OOOO dear");
+
+	dst->native = src;
+	dst->c.udata = 0;
+	dst->c.lineno = (alent *)NULL;
+	this_index += src->n_numaux + 1;
+	dst++;
+	number_of_symbols++;
+      }
+
+  }
+  obj_symbols(abfd) = cached_area;
+  obj_raw_syments(abfd) = native_symbols;
+  bfd_get_symcount(abfd) = number_of_symbols;
+
+  /* Slurp the line tables for each section too */
+  {
+    asection *p;
+    p = abfd->sections;
+    while (p) {
+      ecoff_slurp_line_table(abfd, p);
+      p =p->next;
+    }
+  }
+  return true;
+}
+
+unsigned int
+ecoff_get_symtab_upper_bound (abfd)
+     bfd *abfd;
+{
+  if (!ecoff_slurp_symbol_table (abfd)) return 0;
+
+  return (bfd_get_symcount (abfd)+1) * (sizeof (esymbol *));
+}
+
+
+unsigned int
+ecoff_get_symtab(abfd, alocation)
+bfd *abfd;
+asymbol **alocation;
+{
+  unsigned int counter = 0;
+  esymbol *symbase;
+  esymbol **location = (esymbol **)(alocation);
+
+  if (!ecoff_slurp_symbol_table (abfd)) return 0;
+
+  for (symbase = obj_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
+    *(location++) = symbase++;
+  *location++ =0;
+  return counter;
+}
+
+unsigned int
+ecoff_get_reloc_upper_bound (abfd, asect)
+     bfd *abfd;
+     sec_ptr asect;
+{
+  if (bfd_get_format (abfd) != bfd_object) {
+    bfd_error = invalid_operation;
+    return 0;
+  }
+
+  return   (asect->reloc_count + 1) * sizeof(arelent *);
+}
+
+
+
+
+boolean
+ecoff_slurp_reloc_table (abfd, asect)
+     bfd *abfd;
+     sec_ptr asect;
+{
+  struct reloc *native_relocs;
+  arelent *reloc_cache;
+
+  if (asect->relocation) return true;
+  if (asect->reloc_count ==0) return true;
+  if (!ecoff_slurp_symbol_table (abfd)) return false;
+
+  native_relocs = (struct reloc *)buy_and_read(abfd,
+					       asect->rel_filepos,
+					       false,
+					       sizeof(struct reloc) * asect->reloc_count);
+  reloc_cache = (arelent *)xmalloc(asect->reloc_count * sizeof(arelent ));
+
+  {
+
+    unsigned int counter = 0;
+    arelent *cache_ptr = reloc_cache;
+    struct reloc *src = native_relocs;
+    while (counter < asect->reloc_count) 
+      {
+	cache_ptr->address = src->r_vaddr  - asect->original_vma;
+	cache_ptr->sym = (asymbol *)(src->r_symndx +
+				     obj_raw_syments (abfd))->n_zeroes;
+	/* The symbols that we have read in have been relocated as if their
+	 * sections started at 0. But the offsets refering to the symbols
+	 * in the raw data have not been modified, so we have to have
+	 * a negative addend to compensate
+	 */
+	if (cache_ptr->sym->section) {
+	  cache_ptr->addend = - cache_ptr->sym->section->original_vma;
+	}
+	else {
+	  /* If the symbol doesn't have a section then it hasn't been relocated,
+	   * so we don't have to fix it 
+	   */
+	  cache_ptr->addend = 0;
+	}
+
+	cache_ptr->section = 0;
+#if I960
+	cache_ptr->howto = howto_table + src->r_type;
+#endif
+#if M88
+	if (src->r_type >= R_PCR16L && src->r_type <= R_VRT32) 
+	  {
+	    cache_ptr->howto = howto_table + src->r_type - R_PCR16L;
+	  }
+	else 
+	  {
+	    fatal("unrecognised reloc type %d\n", src->r_type);
+	  }
+#endif
+	cache_ptr++;
+	src++;
+	counter++;
+      }
+
+  }
+
+  free (native_relocs);
+  asect->relocation = reloc_cache;
+  return true;
+}
+
+
+/* This is stupid.  This function should be a boolean predicate */
+unsigned int
+ecoff_canonicalize_reloc (abfd, section, relptr)
+     bfd *abfd;
+     sec_ptr section;
+     arelent **relptr;
+{
+    return 0;
+}
+
+bfd_target ecoff_little_vec =
+    {"ecoff-littlemips",      /* name */
+       false,			/* data byte order is little */
+       false,			/* header byte order is little */
+
+       (HAS_RELOC | EXEC_P |	/* object flags */
+	HAS_LINENO | HAS_DEBUG |
+	HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+
+       (SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+       0,			/* valid reloc types */
+       '/',			/* ar_pad_char */
+       15,			/* ar_max_namelen */
+       ecoff_close_and_cleanup,	/* _close_and_cleanup */
+       ecoff_set_section_contents, /* bfd_set_section_contents */
+       ecoff_new_section_hook,	/* new_section_hook */
+       _bfd_dummy_core_file_failing_command, /* _core_file_failing_command */
+       _bfd_dummy_core_file_failing_signal, /* _core_file_failing_signal */
+       _bfd_dummy_core_file_matches_executable_p, /* _core_file_matches_ex...p */
+
+       bfd_slurp_coff_armap,	/* bfd_slurp_armap */
+       _bfd_slurp_extended_name_table, /* bfd_slurp_extended_name_table*/
+       bfd_dont_truncate_arname, /* bfd_truncate_arname */
+
+       ecoff_get_symtab_upper_bound, /* get_symtab_upper_bound */
+       ecoff_get_symtab,		/* canonicalize_symtab */
+       (void (*)())bfd_false,		/* bfd_reclaim_symbol_table */
+       ecoff_get_reloc_upper_bound, /* get_reloc_upper_bound */
+       ecoff_canonicalize_reloc,	/* bfd_canonicalize_reloc */
+       (void (*)())bfd_false,		/* bfd_reclaim_reloc */
+
+       ecoff_get_symcount_upper_bound,	/* bfd_get_symcount_upper_bound */
+       ecoff_get_first_symbol,		/* bfd_get_first_symbol */
+       ecoff_get_next_symbol,		/* bfd_get_next_symbol */
+       ecoff_classify_symbol,		/* bfd_classify_symbol */
+       ecoff_symbol_hasclass,		/* bfd_symbol_hasclass */
+       ecoff_symbol_name,	        /* bfd_symbol_name */
+       ecoff_symbol_value,		/* bfd_symbol_value */
+
+       _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
+       _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
+
+       {_bfd_dummy_target, ecoff_object_p, /* bfd_check_format */
+	  bfd_generic_archive_p, _bfd_dummy_target},
+       {bfd_false, ecoff_mkobject, bfd_false, /* bfd_set_format */
+	  bfd_false},
+       ecoff_make_empty_symbol,
+
+
+     };
+
+bfd_target ecoff_big_vec =
+    {"ecoff-bigmips",      /* name */
+       true,			/* data byte order is big */
+       true,			/* header byte order is big */
+
+       (HAS_RELOC | EXEC_P |	/* object flags */
+	HAS_LINENO | HAS_DEBUG |
+	HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+
+       (SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+       0,			/* valid reloc types */
+       '/',			/* ar_pad_char */
+       15,			/* ar_max_namelen */
+       ecoff_close_and_cleanup,	/* _close_and_cleanup */
+       ecoff_set_section_contents, /* bfd_set_section_contents */
+       ecoff_new_section_hook,	/* new_section_hook */
+       _bfd_dummy_core_file_failing_command, /* _core_file_failing_command */
+       _bfd_dummy_core_file_failing_signal, /* _core_file_failing_signal */
+       _bfd_dummy_core_file_matches_executable_p, /* _core_file_matches_ex...p */
+
+       bfd_slurp_coff_armap,	/* bfd_slurp_armap */
+       _bfd_slurp_extended_name_table, /* bfd_slurp_extended_name_table*/
+       bfd_dont_truncate_arname, /* bfd_truncate_arname */
+
+       ecoff_get_symtab_upper_bound, /* get_symtab_upper_bound */
+       ecoff_get_symtab,		/* canonicalize_symtab */
+       (void (*)())bfd_false,		/* bfd_reclaim_symbol_table */
+       ecoff_get_reloc_upper_bound, /* get_reloc_upper_bound */
+       ecoff_canonicalize_reloc,	/* bfd_canonicalize_reloc */
+       (void (*)())bfd_false,		/* bfd_reclaim_reloc */
+
+       ecoff_get_symcount_upper_bound,	/* bfd_get_symcount_upper_bound */
+       ecoff_get_first_symbol,		/* bfd_get_first_symbol */
+       ecoff_get_next_symbol,		/* bfd_get_next_symbol */
+       ecoff_classify_symbol,		/* bfd_classify_symbol */
+       ecoff_symbol_hasclass,		/* bfd_symbol_hasclass */
+       ecoff_symbol_name,	        /* bfd_symbol_name */
+       ecoff_symbol_value,		/* bfd_symbol_value */
+
+       _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
+       _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
+
+       {_bfd_dummy_target, ecoff_object_p, /* bfd_check_format */
+	  bfd_generic_archive_p, _bfd_dummy_target},
+       {bfd_false, ecoff_mkobject, bfd_false, /* bfd_set_format */
+	  bfd_false},
+       ecoff_make_empty_symbol,
+
+
+     };
+
+#endif /* ECOFF_BFD */
diff --git a/ld/ld-gldm88kbcs-Ur.script b/ld/ld-gldm88kbcs-Ur.script
new file mode 100755
index 00000000000..8d3f12b89ed
--- /dev/null
+++ b/ld/ld-gldm88kbcs-Ur.script
@@ -0,0 +1,31 @@
+SCRIPT 
+SEARCH_DIR(/lib) 			
+SEARCH_DIR(/usr/lib) 			
+SEARCH_DIR(/usr/local/lib) 		
+SECTIONS 				
+{ 					
+  .text 0: 				
+  { 					
+   CREATE_OBJECT_SYMBOLS                
+    *(.text) 				
+    } 					
+  .data SIZEOF(.text) + ADDR(.text) :	
+  { 					
+    *(.data) 				
+    ___DTOR_LIST__ = . ;               	
+    LONG((___CTOR_LIST__ - .) / 4 -2)  	
+    *(___DTOR_LIST__)                   
+    LONG(0)                             
+    ___CTOR_LIST__ = . ;               	
+    LONG((___end_list__  - .) / 4 -2)     
+    *(___CTOR_LIST__)                   
+    LONG(0)                             
+    ___end_list__  =  . ;			
+    } 					
+  .bss SIZEOF(.data) + ADDR(.data) :	
+  {					
+    *(.bss)				
+   [COMMON]				
+    } 					
+} 					
+ENDSCRIPT 
diff --git a/ld/ld-gldm88kbcs-r.script b/ld/ld-gldm88kbcs-r.script
new file mode 100755
index 00000000000..a3b39fe8573
--- /dev/null
+++ b/ld/ld-gldm88kbcs-r.script
@@ -0,0 +1,20 @@
+SEARCH_DIR(/lib) 			
+SEARCH_DIR(/usr/lib) 			
+SEARCH_DIR(/usr/local/lib) 		
+SECTIONS 				
+{ 					
+  .text 0: 				
+  { 					
+   CREATE_OBJECT_SYMBOLS                
+    *(.text) 				
+    } 					
+  .data SIZEOF(.text) + ADDR(.text) :	
+  { 					
+    *(.data) 				
+    } 					
+  .bss SIZEOF(.data) + ADDR(.data) :	
+  {					
+    *(.bss)				
+   [COMMON]				
+    } 					
+} 					
diff --git a/ld/ld-gldm88kbcs.c b/ld/ld-gldm88kbcs.c
new file mode 100755
index 00000000000..bfb539f2858
--- /dev/null
+++ b/ld/ld-gldm88kbcs.c
@@ -0,0 +1,141 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GLD is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GLD; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ *  $Id$
+ *
+*/
+
+/* 
+ *  Written by Steve Chamberlain steve@cygnus.com
+ */
+
+
+#include "sysdep.h"
+#include "bfd.h"
+
+
+#include "ld.h"
+#include "config.h"
+#include "ld-emul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+extern  boolean lang_float_flag;
+
+
+extern enum bfd_architecture ldfile_output_architecture;
+extern unsigned long ldfile_output_machine;
+extern char *ldfile_output_machine_name;
+
+extern bfd *output_bfd;
+
+
+
+static void gldm88kbcs_before_parse()
+{
+
+}
+
+
+static void 
+gldm88kbcs_after_parse()
+{
+
+}
+
+static void
+gldm88kbcs_after_allocation()
+{
+
+}
+
+static void
+gldm88kbcs_before_allocation()
+{
+
+}
+
+
+static void
+gldm88kbcs_set_output_arch()
+{
+  /* Set the output architecture and machine if possible */
+  bfd_set_arch_mach(output_bfd, ldfile_output_architecture, ldfile_output_machine);
+}
+
+static char *
+gldm88kbcs_choose_target()
+{
+  char *from_outside = getenv(TARGET_ENVIRON);
+  if (from_outside != (char *)NULL)
+    return from_outside;
+  return GLDM88KBCS_TARGET;
+}
+
+static void
+gldm88kbcs_syslib()
+{
+  info("%S SYSLIB ignored\n");
+}
+
+static void
+gldm88kbcs_hll(ignore)
+char  *ignore;
+{
+  info("%S HLL ignored\n");
+}
+
+static char *gldm88kbcs_script = 
+#include "ld-gldm88kbcs.x"
+;
+
+static char *gldm88kbcs_script_option_Ur  =  
+#include "ld-gldm88kbcs-Ur.x"
+;
+
+static char *gldm88kbcs_script_option_r  =  
+#include "ld-gldm88kbcs-r.x"
+;	     
+			     
+static char *gldm88kbcs_get_script()
+{			     
+  extern ld_config_type config;
+  if (config.relocateable_output == true &&
+      config.build_constructors == true) {
+    return gldm88kbcs_script_option_Ur;
+  }
+  if (config.relocateable_output) {
+    return gldm88kbcs_script_option_r;
+  }
+	
+  return gldm88kbcs_script;
+}
+struct ld_emulation_xfer_struct ld_gldm88kbcs_emulation = 
+{
+  gldm88kbcs_before_parse,
+  gldm88kbcs_syslib,
+  gldm88kbcs_hll,
+  gldm88kbcs_after_parse,
+  gldm88kbcs_after_allocation,
+  gldm88kbcs_set_output_arch,
+  gldm88kbcs_choose_target,
+  gldm88kbcs_before_allocation,
+  gldm88kbcs_get_script,
+};
+
diff --git a/ld/ld-gldm88kbcs.script b/ld/ld-gldm88kbcs.script
new file mode 100755
index 00000000000..ae7cb85009e
--- /dev/null
+++ b/ld/ld-gldm88kbcs.script
@@ -0,0 +1,36 @@
+OUTPUT_FORMAT(m88kbcs)
+OUTPUT_ARCH(m88k)
+SEARCH_DIR(/lib) 			
+SEARCH_DIR(/usr/lib) 			
+SEARCH_DIR(/usr/local/lib) 		
+__DYNAMIC = 0; 				
+SECTIONS 				
+{ 					
+  .text 0x2020 BLOCK(0x2000): 		
+  { 					
+   CREATE_OBJECT_SYMBOLS 		
+    *(.text) 				
+    _etext = ALIGN( 0x2000);       	
+    }  					
+  .data  ALIGN(0x2000)  :		
+  { 					
+    *(.data) 				
+    ___DTOR_LIST__ = . ;               	
+    LONG((___CTOR_LIST__ - .) / 4 -2)  	
+    *(___DTOR_LIST__)                   
+    LONG(0)                             
+    ___CTOR_LIST__ = . ;               	
+    LONG((_edata  - .) / 4 -2)            
+    *(___CTOR_LIST__)                   
+    LONG(0)                             
+      _edata  =  .; 			
+  }  					
+  .bss   SIZEOF(.data) + ADDR(.data) :	
+  { 					
+   *(.bss)	 			
+   [COMMON] 				
+     _end = .;				
+    } 					
+}
+
+