* configure.in: i386lynx_coff_vec requires coff-i386lynx.o.
authorStan Shebs <shebs@codesourcery.com>
Fri, 1 Oct 1993 21:42:59 +0000 (21:42 +0000)
committerStan Shebs <shebs@codesourcery.com>
Fri, 1 Oct 1993 21:42:59 +0000 (21:42 +0000)
* coff-i386lynx.c: New file, defines Lynx target vector and name,
includes coff-i386.c.
* coff-i386.c (i386coff_vec): Allow redefinition of target vector
symbol and name, if TARGET_SYM and/or TARGET_NAME are defined.
* i386lynx.c: Remove coff vector definition entirely.
(lynx_32_swap_ext_reloc_in): Define.
(lynx_32_swap_std_reloc_in): Define, get reloc bits in i386
Lynx-specific way.
(lynx_32_swap_ext_reloc_out): Define.
(lynx_32_swap_std_reloc_out): Define.
(lynx_32_slurp_reloc_table): Define, call Lynx swapping fns.
(lynx_32_squirt_out_relocs): Define, call Lynx swapping fns.
(lynx_32_canonicalize_reloc): Define, call Lynx swapping fns.
(WRITE_HEADERS): Define, call Lynx swapping fns.

* config/i386-lynx.mt (SELECT_VECS): Remove redundant vector.

bfd/.Sanitize
bfd/ChangeLog
bfd/coff-i386.c
bfd/coff-i386lynx.c [new file with mode: 0644]
bfd/configure.in
bfd/i386lynx.c [new file with mode: 0644]

index a06603b3314594088c6f35d4f710bb4ba18cca87..72abad6e7186120d6c3e454e08034ac0a53bc0a1 100644 (file)
@@ -54,6 +54,7 @@ coff-alpha.c
 coff-h8300.c
 coff-h8500.c
 coff-i386.c
+coff-i386lynx.c
 coff-i960.c
 coff-m68k.c
 coff-m88k.c
index 54a879dd8f752a132c147afe2ef68971fc709a62..a38176bcf2b13542aef2b29b14058018d337e899 100644 (file)
@@ -1,9 +1,38 @@
+Fri Oct  1 13:14:17 1993  Stan Shebs  (shebs@rtl.cygnus.com)
+
+       * configure.in: i386lynx_coff_vec requires coff-i386lynx.o.
+       * coff-i386lynx.c: New file, defines Lynx target vector and name,
+       includes coff-i386.c.
+       * coff-i386.c (i386coff_vec): Allow redefinition of target vector
+       symbol and name, if TARGET_SYM and/or TARGET_NAME are defined.
+       * i386lynx.c: Remove coff vector definition entirely.
+       (lynx_32_swap_ext_reloc_in): Define.
+       (lynx_32_swap_std_reloc_in): Define, get reloc bits in i386
+       Lynx-specific way.
+       (lynx_32_swap_ext_reloc_out): Define.
+       (lynx_32_swap_std_reloc_out): Define.
+       (lynx_32_slurp_reloc_table): Define, call Lynx swapping fns.
+       (lynx_32_squirt_out_relocs): Define, call Lynx swapping fns.
+       (lynx_32_canonicalize_reloc): Define, call Lynx swapping fns.
+       (WRITE_HEADERS): Define, call Lynx swapping fns.
+
+       * config/i386-lynx.mt (SELECT_VECS): Remove redundant vector.
+
 Thu Sep 30 17:50:52 1993  Ken Raeburn  (raeburn@cambridge.cygnus.com)
 
        * reloc.c (bfd_reloc_code_type): Add linkage-table relative
        relocations of size 8, 16, 32.  Sort generic relocs by type rather
        than size.  Added a little documentation too.
 
+       * aoutx.h (howto_table_std): Add BASE16 and BASE32 relocs.
+       (TABLE_SIZE): New macro.
+       (reloc_type_lookup): Handle BFD_RELOC_{16,32}_BASEREL for std
+       relocs.
+       (swap_std_reloc_out): Write baserel relocs correctly.
+       (swap_std_reloc_in): Handle r_baserel field.  Assert that
+       r_jmptable and r_relative fields are clear, and that the computed
+       index does refer to a defined entry of the howto table.
+
 Tue Sep 28 14:47:46 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
        * section.c (bfd_make_section_anyway): New function.
index dd208ceb516c38a353bff86550cde85b6b236870..f76332dc417bde9e2a51f1a92bfb2b9771b01bd5 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for Intel 386 COFF files.
-   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -26,30 +26,210 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "coff/internal.h"
 #include "libcoff.h"
 
+static bfd_reloc_status_type coff_i386_reloc PARAMS ((bfd *abfd,
+                                                     arelent *reloc_entry,
+                                                     asymbol *symbol,
+                                                     PTR data,
+                                                     asection *input_section,
+                                                     bfd *output_bfd));
+
+/* For some reason when using i386 COFF the value stored in the .text
+   section for a reference to a common symbol is the value itself plus
+   any desired offset.  Ian Taylor, Cygnus Support.  */
+
+/* If we are producing relocateable output, we need to do some
+   adjustments to the object file that are not done by the
+   bfd_perform_relocation function.  This function is called by every
+   reloc type to make any required adjustments.  */
+
+static bfd_reloc_status_type
+coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd)
+     bfd *abfd;
+     arelent *reloc_entry;
+     asymbol *symbol;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+{
+  symvalue diff;
+
+  if (output_bfd == (bfd *) NULL)
+    return bfd_reloc_continue;
+
+  if (bfd_is_com_section (symbol->section))
+    {
+      /* We are relocating a common symbol.  The current value in the
+        object file is ORIG + OFFSET, where ORIG is the value of the
+        common symbol as seen by the object file when it was compiled
+        (this may be zero if the symbol was undefined) and OFFSET is
+        the offset into the common symbol (normally zero, but may be
+        non-zero when referring to a field in a common structure).
+        ORIG is the negative of reloc_entry->addend, which is set by
+        the CALC_ADDEND macro below.  We want to replace the value in
+        the object file with NEW + OFFSET, where NEW is the value of
+        the common symbol which we are going to put in the final
+        object file.  NEW is symbol->value.  */
+      diff = symbol->value + reloc_entry->addend;
+    }
+  else
+    {
+      /* For some reason bfd_perform_relocation always effectively
+        ignores the addend for a COFF target when producing
+        relocateable output.  This seems to be always wrong for 386
+        COFF, so we handle the addend here instead.  */
+      diff = reloc_entry->addend;
+    }
+
+#define DOIT(x) \
+  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
+
+  if (diff != 0)
+    {
+      reloc_howto_type *howto = reloc_entry->howto;
+      unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+
+      switch (howto->size)
+       {
+       case 0:
+         {
+           char x = bfd_get_8 (abfd, addr);
+           DOIT (x);
+           bfd_put_8 (abfd, x, addr);
+         }
+         break;
+
+       case 1:
+         {
+           short x = bfd_get_16 (abfd, addr);
+           DOIT (x);
+           bfd_put_16 (abfd, x, addr);
+         }
+         break;
+
+       case 2:
+         {
+           long x = bfd_get_32 (abfd, addr);
+           DOIT (x);
+           bfd_put_32 (abfd, x, addr);
+         }
+         break;
+
+       default:
+         abort ();
+       }
+    }
+
+  /* Now let bfd_perform_relocation finish everything up.  */
+  return bfd_reloc_continue;
+}
 
 static reloc_howto_type howto_table[] = 
 {
-    {0},
-    {1},
-    {2},
-    {3},
-    {4},
-    {5},
-  HOWTO(R_DIR32,              0,  2,   32, false, 0, true,true,0,"dir32",      true, 0xffffffff,0xffffffff, false),
-    {7},
-    {010},
-    {011},
-    {012},
-    {013},
-    {014},
-    {015},
-    {016},
-  HOWTO(R_RELBYTE,            0,  0,   8,  false, 0, true,  true,0,"8",        true, 0x000000ff,0x000000ff, false),
-  HOWTO(R_RELWORD,            0,  1,   16, false, 0, true,  true,0,"16",       true, 0x0000ffff,0x0000ffff, false),
-  HOWTO(R_RELLONG,            0,  2,   32, false, 0, true,  true,0,"32",       true, 0xffffffff,0xffffffff, false),
-  HOWTO(R_PCRBYTE,            0,  0,   8,  true,  0, false, true,0,"DISP8",    true, 0x000000ff,0x000000ff, false),
-  HOWTO(R_PCRWORD,            0,  1,   16, true,  0, false, true,0,"DISP16",   true, 0x0000ffff,0x0000ffff, false),
-  HOWTO(R_PCRLONG,            0,  2,   32, true,  0, false, true,0,"DISP32",   true, 0xffffffff,0xffffffff, false),
+  {0},
+  {1},
+  {2},
+  {3},
+  {4},
+  {5},
+  HOWTO (R_DIR32,               /* type */                                 
+        0,                     /* rightshift */                           
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
+        32,                    /* bitsize */                   
+        false,                 /* pc_relative */                          
+        0,                     /* bitpos */                               
+        complain_overflow_bitfield, /* complain_on_overflow */
+        coff_i386_reloc,       /* special_function */                     
+        "dir32",               /* name */                                 
+        true,                  /* partial_inplace */                      
+        0xffffffff,            /* src_mask */                             
+        0xffffffff,            /* dst_mask */                             
+        false),                /* pcrel_offset */
+  {7},
+  {010},
+  {011},
+  {012},
+  {013},
+  {014},
+  {015},
+  {016},
+  HOWTO (R_RELBYTE,            /* type */                                 
+        0,                     /* rightshift */                           
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */ 
+        8,                     /* bitsize */                   
+        false,                 /* pc_relative */                          
+        0,                     /* bitpos */                               
+        complain_overflow_bitfield, /* complain_on_overflow */
+        coff_i386_reloc,       /* special_function */                     
+        "8",                   /* name */                                 
+        true,                  /* partial_inplace */                      
+        0x000000ff,            /* src_mask */                             
+        0x000000ff,            /* dst_mask */                             
+        false),                /* pcrel_offset */
+  HOWTO (R_RELWORD,            /* type */                                 
+        0,                     /* rightshift */                           
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
+        16,                    /* bitsize */                   
+        false,                 /* pc_relative */                          
+        0,                     /* bitpos */                               
+        complain_overflow_bitfield, /* complain_on_overflow */
+        coff_i386_reloc,       /* special_function */                     
+        "16",                  /* name */                                 
+        true,                  /* partial_inplace */                      
+        0x0000ffff,            /* src_mask */                             
+        0x0000ffff,            /* dst_mask */                             
+        false),                /* pcrel_offset */
+  HOWTO (R_RELLONG,            /* type */                                 
+        0,                     /* rightshift */                           
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
+        32,                    /* bitsize */                   
+        false,                 /* pc_relative */                          
+        0,                     /* bitpos */                               
+        complain_overflow_bitfield, /* complain_on_overflow */
+        coff_i386_reloc,       /* special_function */                     
+        "32",                  /* name */                                 
+        true,                  /* partial_inplace */                      
+        0xffffffff,            /* src_mask */                             
+        0xffffffff,            /* dst_mask */                             
+        false),                /* pcrel_offset */
+  HOWTO (R_PCRBYTE,            /* type */                                 
+        0,                     /* rightshift */                           
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */ 
+        8,                     /* bitsize */                   
+        true,                  /* pc_relative */                          
+        0,                     /* bitpos */                               
+        complain_overflow_signed, /* complain_on_overflow */
+        coff_i386_reloc,       /* special_function */                     
+        "DISP8",               /* name */                                 
+        true,                  /* partial_inplace */                      
+        0x000000ff,            /* src_mask */                             
+        0x000000ff,            /* dst_mask */                             
+        false),                /* pcrel_offset */
+  HOWTO (R_PCRWORD,            /* type */                                 
+        0,                     /* rightshift */                           
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */ 
+        16,                    /* bitsize */                   
+        true,                  /* pc_relative */                          
+        0,                     /* bitpos */                               
+        complain_overflow_signed, /* complain_on_overflow */
+        coff_i386_reloc,       /* special_function */                     
+        "DISP16",              /* name */                                 
+        true,                  /* partial_inplace */                      
+        0x0000ffff,            /* src_mask */                             
+        0x0000ffff,            /* dst_mask */                             
+        false),                /* pcrel_offset */
+  HOWTO (R_PCRLONG,            /* type */                                 
+        0,                     /* rightshift */                           
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
+        32,                    /* bitsize */                   
+        true,                  /* pc_relative */                          
+        0,                     /* bitpos */                               
+        complain_overflow_signed, /* complain_on_overflow */
+        coff_i386_reloc,       /* special_function */                     
+        "DISP32",              /* name */                                 
+        true,                  /* partial_inplace */                      
+        0xffffffff,            /* src_mask */                             
+        0xffffffff,            /* dst_mask */                             
+        false)                 /* pcrel_offset */
 };
 
 /* Turn a howto into a reloc  nunmber */
@@ -61,17 +241,67 @@ static reloc_howto_type howto_table[] =
 #define RTYPE2HOWTO(cache_ptr, dst) \
            cache_ptr->howto = howto_table + (dst)->r_type;
 
-#include "coffcode.h"
+/* On SCO Unix 3.2.2 the native assembler generates two .data
+   sections.  We handle that by renaming the second one to .data2.  It
+   does no harm to do this for any 386 COFF target.  */
+#define TWO_DATA_SECS
+
+/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
+   library.  On some other COFF targets STYP_BSS is normally
+   STYP_NOLOAD.  */
+#define BSS_NOLOAD_IS_SHARED_LIBRARY
 
-#define coff_write_armap bsd_write_armap
+/* Compute the addend of a reloc.  If the reloc is to a common symbol,
+   the object file contains the value of the common symbol.  By the
+   time this is called, the linker may be using a different symbol
+   from a different object file with a different value.  Therefore, we
+   hack wildly to locate the original symbol from this file so that we
+   can make the correct adjustment.  This macro sets coffsym to the
+   symbol from the original file, and uses it to set the addend value
+   correctly.  If this is not a common symbol, the usual addend
+   calculation is done, except that an additional tweak is needed for
+   PC relative relocs.
+   FIXME: This macro refers to symbols and asect; these are from the
+   calling function, not the macro arguments.  */
+
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)               \
+  {                                                            \
+    coff_symbol_type *coffsym = (coff_symbol_type *) NULL;     \
+    if (ptr && bfd_asymbol_bfd (ptr) != abfd)                  \
+      coffsym = (obj_symbols (abfd)                            \
+                + (cache_ptr->sym_ptr_ptr - symbols));         \
+    else if (ptr)                                              \
+      coffsym = coff_symbol_from (abfd, ptr);                  \
+    if (coffsym != (coff_symbol_type *) NULL                   \
+       && coffsym->native->u.syment.n_scnum == 0)              \
+      cache_ptr->addend = - coffsym->native->u.syment.n_value; \
+    else if (ptr && bfd_asymbol_bfd (ptr) == abfd              \
+            && ptr->section != (asection *) NULL)              \
+      cache_ptr->addend = - (ptr->section->vma + ptr->value);  \
+    else                                                       \
+      cache_ptr->addend = 0;                                   \
+    if (ptr && howto_table[reloc.r_type].pc_relative)          \
+      cache_ptr->addend += asect->vma;                         \
+  }
+
+#include "coffcode.h"
 
 bfd_target *i3coff_object_p(a)
 bfd *a ;
 { return coff_object_p(a); }
 
-bfd_target i386coff_vec =
+bfd_target
+#ifdef TARGET_SYM
+  TARGET_SYM =
+#else
+  i386coff_vec =
+#endif
 {
+#ifdef TARGET_NAME
+  TARGET_NAME,
+#else
   "coff-i386",                 /* name */
+#endif
   bfd_target_coff_flavour,
   false,                       /* data byte order is little */
   false,                       /* header byte order is little */
@@ -86,8 +316,12 @@ bfd_target i386coff_vec =
   15,                          /* ar_max_namelen */
 
   2,                           /* minimum alignment power */
-  _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_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
 
 /* Note that we allow an object file to be treated as a core file as well. */
     {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
@@ -98,5 +332,5 @@ bfd_target i386coff_vec =
        _bfd_write_archive_contents, bfd_false},
 
   JUMP_TABLE(coff),
-  COFF_SWAP_TABLE
-  };
+  COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-i386lynx.c b/bfd/coff-i386lynx.c
new file mode 100644 (file)
index 0000000..541f59e
--- /dev/null
@@ -0,0 +1,24 @@
+/* BFD back-end for Intel 386 COFF LynxOS files.
+   Copyright 1993 Free Software Foundation, Inc.
+   Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_SYM     i386lynx_coff_vec
+#define TARGET_NAME    "coff-i386-lynx"
+
+#include "coff-i386.c"
index 8755716b55dfc14718e47b95c9e51c6b975b0cb6..84d4b1d80ea5227bbf10c98e921970c2834ca2d7 100644 (file)
@@ -51,10 +51,6 @@ for targ in $target $canon_targets
 do
     bfd_target=`$srcdir/config.bfd $targ`
 
-    case "$targ" in
-       netbsd386)      bfd_target=i386-netbsd ;;
-    esac
-
     if [ "x$bfd_target" = "xall" ]; then
         all_targets=true
     else
@@ -179,12 +175,15 @@ do
     netbsd386_vec)             tb="$tb netbsd386.o aout32.o stab-syms.o" ;;
     i386coff_vec)              tb="$tb coff-i386.o" ;;
     i386linux_vec)             tb="$tb i386linux.o aout32.o stab-syms.o" ;;
-    i386lynx_vec)              tb="$tb i386lynx.o aout32.o stab-syms.o" ;;
+    i386lynx_aout_vec)         tb="$tb i386lynx.o lynx-core.o aout32.o stab-syms.o" ;;
+    i386lynx_coff_vec)         tb="$tb coff-i386lynx.o lynx-core.o stab-syms.o" ;;
     icoff_big_vec)             tb="$tb coff-i960.o" ;;
     icoff_little_vec)          tb="$tb coff-i960.o" ;;
     ieee_vec)                  tb="$tb ieee.o" ;;
     m68kcoff_vec)              tb="$tb coff-m68k.o" ;;
     m68kcoffun_vec)            tb="$tb coff-u68k.o coff-m68k.o" ;;
+    m68klynx_aout_vec)         tb="$tb m68klynx.o lynx-core.o aout32.o stab-syms.o" ;;
+    m68klynx_coff_vec)         tb="$tb m68klynx.o lynx-core.o aout32.o stab-syms.o" ;;
     m88kbcs_vec)               tb="$tb coff-m88k.o" ;;
     newsos3_vec)               tb="$tb newsos3.o aout32.o stab-syms.o" ;;
     nlm32_big_generic_vec)     tb="$tb nlm32-gen.o nlm32.o nlm.o" ;;
diff --git a/bfd/i386lynx.c b/bfd/i386lynx.c
new file mode 100644 (file)
index 0000000..04af2b7
--- /dev/null
@@ -0,0 +1,549 @@
+/* BFD back-end for i386 a.out binaries under Lynx.
+   Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define BYTES_IN_WORD 4
+#define ARCH 32
+#define N_SHARED_LIB(x) 0
+
+#define TEXT_START_ADDR 0
+#define PAGE_SIZE 4096
+#define SEGMENT_SIZE PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_i386
+
+#define MY(OP) CAT(i386lynx_aout_,OP)
+#define TARGETNAME "a.out-i386-lynx"
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#ifndef WRITE_HEADERS
+#define WRITE_HEADERS(abfd, execp)                                           \
+      {                                                                              \
+       bfd_size_type text_size; /* dummy vars */                             \
+       file_ptr text_end;                                                    \
+       if (adata(abfd).magic == undecided_magic)                             \
+         NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);     \
+                                                                             \
+       execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;        \
+       execp->a_entry = bfd_get_start_address (abfd);                        \
+                                                                             \
+       execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *                \
+                          obj_reloc_entry_size (abfd));                      \
+       execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *                \
+                          obj_reloc_entry_size (abfd));                      \
+       NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);           \
+                                                                             \
+       bfd_seek (abfd, (file_ptr) 0, SEEK_SET);                              \
+       bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd);              \
+       /* Now write out reloc info, followed by syms and strings */          \
+                                                                             \
+       if (bfd_get_symcount (abfd) != 0)                                     \
+           {                                                                 \
+             bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET);        \
+                                                                             \
+             NAME(aout,write_syms)(abfd);                                    \
+                                                                             \
+             bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET);       \
+                                                                             \
+             if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) return false; \
+             bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET);       \
+                                                                             \
+             if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \
+           }                                                                 \
+      }                                                                              
+#endif
+
+#include "libaout.h"
+#include "aout/aout64.h"
+
+#ifdef HOST_LYNX
+
+char *lynx_core_file_failing_command();
+int lynx_core_file_failing_signal();
+boolean lynx_core_file_matches_executable_p();
+bfd_target *lynx_core_file_p();
+
+#define        MY_core_file_failing_command lynx_core_file_failing_command
+#define        MY_core_file_failing_signal lynx_core_file_failing_signal
+#define        MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
+#define        MY_core_file_p lynx_core_file_p
+
+#endif /* HOST_LYNX */
+
+\f
+#define KEEPIT flags
+
+extern reloc_howto_type aout_32_ext_howto_table[];
+extern reloc_howto_type aout_32_std_howto_table[];
+
+/* Standard reloc stuff */
+/* Output standard relocation information to a file in target byte order. */
+
+void
+DEFUN(NAME(lynx,swap_std_reloc_out),(abfd, g, natptr),
+      bfd *abfd AND
+      arelent *g AND
+      struct reloc_std_external *natptr)
+{
+  int r_index;
+  asymbol *sym = *(g->sym_ptr_ptr);
+  int r_extern;
+  unsigned int r_length;
+  int r_pcrel;
+  int r_baserel, r_jmptable, r_relative;
+  unsigned int r_addend;
+  asection *output_section = sym->section->output_section;
+
+  PUT_WORD(abfd, g->address, natptr->r_address);
+
+  r_length = g->howto->size ;  /* Size as a power of two */
+  r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
+  /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
+  r_baserel = 0;
+  r_jmptable = 0;
+  r_relative = 0;
+    
+  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+    
+  /* name was clobbered by aout_write_syms to be symbol index */
+
+  /* If this relocation is relative to a symbol then set the 
+     r_index to the symbols index, and the r_extern bit.
+
+     Absolute symbols can come in in two ways, either as an offset
+     from the abs section, or as a symbol which has an abs value.
+     check for that here
+     */
+     
+
+  if (bfd_is_com_section (output_section)
+      || output_section == &bfd_abs_section
+      || output_section == &bfd_und_section) 
+    {
+      if (bfd_abs_section.symbol == sym)
+      {
+       /* Whoops, looked like an abs symbol, but is really an offset
+          from the abs section */
+       r_index = 0;
+       r_extern = 0;
+       }
+      else 
+      {
+       /* Fill in symbol */
+       r_extern = 1;
+       r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
+     
+      }
+    }
+  else 
+    {
+      /* Just an ordinary section */
+      r_extern = 0;
+      r_index  = output_section->target_index;      
+    }
+
+  /* now the fun stuff */
+  if (abfd->xvec->header_byteorder_big_p != false) {
+      natptr->r_index[0] = r_index >> 16;
+      natptr->r_index[1] = r_index >> 8;
+      natptr->r_index[2] = r_index;
+      natptr->r_type[0] =
+       (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
+       | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
+        | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
+         | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
+          | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
+           | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
+    } else {
+       natptr->r_index[2] = r_index >> 16;
+       natptr->r_index[1] = r_index >> 8;
+       natptr->r_index[0] = r_index;
+       natptr->r_type[0] =
+        (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
+         | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
+          | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
+           | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
+            | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
+             | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
+      }
+}
+
+
+/* Extended stuff */
+/* Output extended relocation information to a file in target byte order. */
+
+void
+DEFUN(NAME(lynx,swap_ext_reloc_out),(abfd, g, natptr),
+      bfd *abfd AND
+      arelent *g AND
+      register struct reloc_ext_external *natptr)
+{
+  int r_index;
+  int r_extern;
+  unsigned int r_type;
+  unsigned int r_addend;
+  asymbol *sym = *(g->sym_ptr_ptr);    
+  asection *output_section = sym->section->output_section;
+  
+  PUT_WORD (abfd, g->address, natptr->r_address);
+    
+  r_type = (unsigned int) g->howto->type;
+    
+  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+
+
+  /* If this relocation is relative to a symbol then set the 
+     r_index to the symbols index, and the r_extern bit.
+
+     Absolute symbols can come in in two ways, either as an offset
+     from the abs section, or as a symbol which has an abs value.
+     check for that here
+     */
+     
+  if (bfd_is_com_section (output_section)
+      || output_section == &bfd_abs_section
+      || output_section == &bfd_und_section)
+  {
+    if (bfd_abs_section.symbol == sym)
+    {
+      /* Whoops, looked like an abs symbol, but is really an offset
+        from the abs section */
+      r_index = 0;
+      r_extern = 0;
+     }
+    else 
+    {
+      r_extern = 1;
+      r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
+    }
+  }
+  else 
+  {
+    /* Just an ordinary section */
+    r_extern = 0;
+    r_index  = output_section->target_index;      
+  }
+        
+        
+  /* now the fun stuff */
+  if (abfd->xvec->header_byteorder_big_p != false) {
+    natptr->r_index[0] = r_index >> 16;
+    natptr->r_index[1] = r_index >> 8;
+    natptr->r_index[2] = r_index;
+    natptr->r_type[0] =
+     (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
+      | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
+  } else {
+    natptr->r_index[2] = r_index >> 16;
+    natptr->r_index[1] = r_index >> 8;
+    natptr->r_index[0] = r_index;
+    natptr->r_type[0] =
+     (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
+      | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
+  }
+
+  PUT_WORD (abfd, r_addend, natptr->r_addend);
+}
+
+/* BFD deals internally with all things based from the section they're
+   in. so, something in 10 bytes into a text section  with a base of
+   50 would have a symbol (.text+10) and know .text vma was 50. 
+
+   Aout keeps all it's symbols based from zero, so the symbol would
+   contain 60. This macro subs the base of each section from the value
+   to give the true offset from the section */
+
+
+#define MOVE_ADDRESS(ad)                                                       \
+  if (r_extern) {                                                      \
+   /* undefined symbol */                                              \
+     cache_ptr->sym_ptr_ptr = symbols + r_index;                       \
+     cache_ptr->addend = ad;                                           \
+     } else {                                                          \
+    /* defined, section relative. replace symbol with pointer to       \
+       symbol which points to section  */                              \
+    switch (r_index) {                                                 \
+    case N_TEXT:                                                       \
+    case N_TEXT | N_EXT:                                               \
+      cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;     \
+      cache_ptr->addend = ad  - su->textsec->vma;                      \
+      break;                                                           \
+    case N_DATA:                                                       \
+    case N_DATA | N_EXT:                                               \
+      cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;     \
+      cache_ptr->addend = ad - su->datasec->vma;                       \
+      break;                                                           \
+    case N_BSS:                                                                \
+    case N_BSS | N_EXT:                                                        \
+      cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;      \
+      cache_ptr->addend = ad - su->bsssec->vma;                                \
+      break;                                                           \
+    default:                                                           \
+    case N_ABS:                                                                \
+    case N_ABS | N_EXT:                                                        \
+     cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;  \
+      cache_ptr->addend = ad;                                          \
+      break;                                                           \
+    }                                                                  \
+  }                                                                    \
+
+void
+DEFUN(NAME(lynx,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
+      bfd *abfd AND
+      struct reloc_ext_external *bytes AND
+      arelent *cache_ptr AND
+      asymbol **symbols)
+{
+  int r_index;
+  int r_extern;
+  unsigned int r_type;
+  struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+  cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
+
+  /* now the fun stuff */
+  if (1 /* abfd->xvec->header_byteorder_big_p != false */) {
+    r_index =  (bytes->r_index[0] << 16)
+            | (bytes->r_index[1] << 8)
+            |  bytes->r_index[2];
+    r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
+    r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
+                                     >> RELOC_EXT_BITS_TYPE_SH_BIG;
+  } else {
+    r_index =  (bytes->r_index[2] << 16)
+            | (bytes->r_index[1] << 8)
+            |  bytes->r_index[0];
+    r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
+    r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
+                                     >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
+  }
+
+  cache_ptr->howto =  aout_32_ext_howto_table + r_type;
+  MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
+}
+
+void
+DEFUN(NAME(lynx,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
+  bfd *abfd AND
+  struct reloc_std_external *bytes AND
+  arelent *cache_ptr AND
+  asymbol **symbols)
+{
+  char tmp;
+  int r_index;
+  int r_extern;
+  unsigned int r_length;
+  int r_pcrel;
+  int r_baserel, r_jmptable, r_relative;
+  struct aoutdata  *su = &(abfd->tdata.aout_data->a);
+
+  cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
+
+  r_index = (bytes->r_type[0] << 16)
+    | (bytes->r_index[2] << 8)
+      |  bytes->r_index[1];
+  r_extern  = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
+  r_pcrel   = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
+  r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
+  r_jmptable= (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
+  r_relative= (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
+  r_length  =       (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG) 
+    >> RELOC_STD_BITS_LENGTH_SH_BIG;
+
+  cache_ptr->howto =  aout_32_std_howto_table + r_length + 4 * r_pcrel;
+  /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
+
+  MOVE_ADDRESS(0);
+}
+
+/* Reloc hackery */
+
+boolean
+DEFUN(NAME(lynx,slurp_reloc_table),(abfd, asect, symbols),
+      bfd *abfd AND
+      sec_ptr asect AND
+      asymbol **symbols)
+{
+  unsigned int count;
+  bfd_size_type reloc_size;
+  PTR relocs;
+  arelent *reloc_cache;
+  size_t each_size;
+
+  if (asect->relocation) return true;
+
+  if (asect->flags & SEC_CONSTRUCTOR) return true;
+
+  if (asect == obj_datasec (abfd)) {
+    reloc_size = exec_hdr(abfd)->a_drsize;
+    goto doit;
+  }
+
+  if (asect == obj_textsec (abfd)) {
+    reloc_size = exec_hdr(abfd)->a_trsize;
+    goto doit;
+  }
+
+  bfd_error = invalid_operation;
+  return false;
+
+ doit:
+  bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
+  each_size = obj_reloc_entry_size (abfd);
+
+  count = reloc_size / each_size;
+
+
+  reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
+                                                      (arelent)));
+  if (!reloc_cache) {
+nomem:
+    bfd_error = no_memory;
+    return false;
+  }
+
+  relocs = (PTR) bfd_alloc (abfd, reloc_size);
+  if (!relocs) {
+    bfd_release (abfd, reloc_cache);
+    goto nomem;
+  }
+
+  if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
+    bfd_release (abfd, relocs);
+    bfd_release (abfd, reloc_cache);
+    bfd_error = system_call_error;
+    return false;
+  }
+
+  if (each_size == RELOC_EXT_SIZE) {
+    register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
+    unsigned int counter = 0;
+    arelent *cache_ptr = reloc_cache;
+
+    for (; counter < count; counter++, rptr++, cache_ptr++) {
+      NAME(lynx,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
+    }
+  } else {
+    register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
+    unsigned int counter = 0;
+    arelent *cache_ptr = reloc_cache;
+
+    for (; counter < count; counter++, rptr++, cache_ptr++) {
+       NAME(lynx,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
+    }
+
+  }
+
+  bfd_release (abfd,relocs);
+  asect->relocation = reloc_cache;
+  asect->reloc_count = count;
+  return true;
+}
+
+
+
+/* Write out a relocation section into an object file.  */
+
+boolean
+DEFUN(NAME(lynx,squirt_out_relocs),(abfd, section),
+      bfd *abfd AND
+      asection *section)
+{
+  arelent **generic;
+  unsigned char *native, *natptr;
+  size_t each_size;
+
+  unsigned int count = section->reloc_count;
+  size_t natsize;
+
+  if (count == 0) return true;
+
+  each_size = obj_reloc_entry_size (abfd);
+  natsize = each_size * count;
+  native = (unsigned char *) bfd_zalloc (abfd, natsize);
+  if (!native) {
+    bfd_error = no_memory;
+    return false;
+  }
+
+  generic = section->orelocation;
+
+  if (each_size == RELOC_EXT_SIZE) 
+    {
+      for (natptr = native;
+          count != 0;
+          --count, natptr += each_size, ++generic)
+       NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
+    }
+  else 
+    {
+      for (natptr = native;
+          count != 0;
+          --count, natptr += each_size, ++generic)
+       NAME(lynx,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
+    }
+
+  if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
+    bfd_release(abfd, native);
+    return false;
+  }
+  bfd_release (abfd, native);
+
+  return true;
+}
+
+/* This is stupid.  This function should be a boolean predicate */
+unsigned int
+DEFUN(NAME(lynx,canonicalize_reloc),(abfd, section, relptr, symbols),
+      bfd *abfd AND
+      sec_ptr section AND
+      arelent **relptr AND
+      asymbol **symbols)
+{
+  arelent *tblptr = section->relocation;
+  unsigned int count;
+
+  if (!(tblptr || NAME(lynx,slurp_reloc_table)(abfd, section, symbols)))
+    return 0;
+
+  if (section->flags & SEC_CONSTRUCTOR) {
+    arelent_chain *chain = section->constructor_chain;
+    for (count = 0; count < section->reloc_count; count ++) {
+      *relptr ++ = &chain->relent;
+      chain = chain->next;
+    }
+  }
+  else {
+    tblptr = section->relocation;
+    if (!tblptr) return 0;
+
+    for (count = 0; count++ < section->reloc_count;) 
+      {
+       *relptr++ = tblptr++;
+      }
+  }
+  *relptr = 0;
+
+  return section->reloc_count;
+}
+
+#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
+
+#include "aout-target.h"