Initial revision
authorSteve Chamberlain <steve@cygnus>
Tue, 23 Apr 1991 15:59:23 +0000 (15:59 +0000)
committerSteve Chamberlain <steve@cygnus>
Tue, 23 Apr 1991 15:59:23 +0000 (15:59 +0000)
bfd/coff-mips.c [new file with mode: 0644]
ld/ld-gldm88kbcs-Ur.script [new file with mode: 0755]
ld/ld-gldm88kbcs-r.script [new file with mode: 0755]
ld/ld-gldm88kbcs.c [new file with mode: 0755]
ld/ld-gldm88kbcs.script [new file with mode: 0755]

diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
new file mode 100644 (file)
index 0000000..c27e8c3
--- /dev/null
@@ -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(); */
+\f
+
+/* 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;
+}
+\f
+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;
+}
+\f
+/* 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;
+}
+\f
+
+boolean
+ecoff_close_and_cleanup (abfd)
+     bfd *abfd;
+{
+  return false;
+}
+\f
+
+
+
+
+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 (executable)
index 0000000..8d3f12b
--- /dev/null
@@ -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 (executable)
index 0000000..a3b39fe
--- /dev/null
@@ -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 (executable)
index 0000000..bfb539f
--- /dev/null
@@ -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 (executable)
index 0000000..ae7cb85
--- /dev/null
@@ -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 = .;                         
+    }                                  
+}
+
+