From bd23b552efa04f218036a941d9e1d0f6de81b17f Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor <ian@airs.com>
Date: Fri, 9 Sep 1994 15:54:45 +0000
Subject: [PATCH] 	Convert m68k COFF to use new COFF backend linker. 
 * coff-m68k.c (coff_relocate_section): Define. 	* cf-m68klynx.c
 (coff_rtype_to_howto): Define. 	(coff_m68k_lynx_rtype_to_howto): New
 static function. 	* configure.in (m68kcoff_vec): Build cofflink.o. 
 (m68kcoffun_vec, m68klynx_coff_vec): Likewise.

---
 bfd/ChangeLog     | 13 +++++++--
 bfd/cf-m68klynx.c | 71 ++++++++++++++++++++++++++++++++++++++++-------
 bfd/configure.in  | 10 +++----
 3 files changed, 77 insertions(+), 17 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e679984956f..1f6c369a9b0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,7 +1,16 @@
+Fri Sep  9 11:51:49 1994  Ian Lance Taylor  (ian@sanguine.cygnus.com)
+
+	Convert m68k COFF to use new COFF backend linker.
+	* coff-m68k.c (coff_relocate_section): Define.
+	* cf-m68klynx.c (coff_rtype_to_howto): Define.
+	(coff_m68k_lynx_rtype_to_howto): New static function.
+	* configure.in (m68kcoff_vec): Build cofflink.o.
+	(m68kcoffun_vec, m68klynx_coff_vec): Likewise.
+
 Thu Sep  8 16:20:38 1994  Steve Chamberlain  (sac@jonny.cygnus.com)
 
-	* coff-h8300.c (h8300_reloc16_extra_cases, case RELBYTE):  Flag overflows
-	correctly.
+	* coff-h8300.c (h8300_reloc16_extra_cases, case RELBYTE): Flag
+	overflows correctly.
 
 Wed Sep  7 19:01:42 1994  Ian Lance Taylor  (ian@sanguine.cygnus.com)
 
diff --git a/bfd/cf-m68klynx.c b/bfd/cf-m68klynx.c
index c244b492be3..15c9915b888 100644
--- a/bfd/cf-m68klynx.c
+++ b/bfd/cf-m68klynx.c
@@ -1,5 +1,5 @@
 /* BFD back-end for Motorola M68K COFF LynxOS files.
-   Copyright 1993 Free Software Foundation, Inc.
+   Copyright 1993, 1994 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -35,13 +35,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "bfd.h"
 #include "sysdep.h"
 
-static bfd_reloc_status_type _bfd_m68klynx_special_fn PARAMS ((bfd *abfd,
-						      arelent *reloc_entry,
-						      asymbol *symbol,
-						      PTR data,
-						      asection *input_section,
-						      bfd *output_bfd,
-						      char **error_message));
+#ifdef ANSI_PROTOTYPES
+struct internal_reloc;
+struct coff_link_hash_entry;
+struct internal_syment;
+#endif
+
+static bfd_reloc_status_type _bfd_m68klynx_special_fn
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static const struct reloc_howto_struct *coff_m68k_lynx_rtype_to_howto
+  PARAMS ((bfd *, asection *, struct internal_reloc *,
+	   struct coff_link_hash_entry *, struct internal_syment *,
+	   bfd_vma *));
 
 /* For some reason when using m68k COFF the value stored in the .text
    section for a reference to a common symbol is the value itself plus
@@ -54,8 +59,8 @@ static bfd_reloc_status_type _bfd_m68klynx_special_fn PARAMS ((bfd *abfd,
    reloc type to make any required adjustments.  */
 
 static bfd_reloc_status_type
-_bfd_m68klynx_special_fn (abfd, reloc_entry, symbol, data, input_section, output_bfd,
-			  error_message)
+_bfd_m68klynx_special_fn (abfd, reloc_entry, symbol, data, input_section,
+			  output_bfd, error_message)
      bfd *abfd;
      arelent *reloc_entry;
      asymbol *symbol;
@@ -170,5 +175,51 @@ _bfd_m68klynx_special_fn (abfd, reloc_entry, symbol, data, input_section, output
       cache_ptr->addend += asect->vma;				\
   }
 
+#define coff_rtype_to_howto coff_m68k_lynx_rtype_to_howto
 
 #include "coff-m68k.c"
+
+/* coff-m68k.c uses the special COFF backend linker.  We need to
+   adjust common symbols.  FIXME: We may able to get rid of
+   CALC_ADDEND and _bfd_m68klynx_special_fn.  However, they may still
+   be used by gas.
+
+   We can't define this function until after we have included
+   coff-m68k.c, because it uses RTYPE2HOWTO.  */
+
+/*ARGSUSED*/
+static const struct reloc_howto_struct *
+coff_m68k_lynx_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+     bfd *abfd;
+     asection *sec;
+     struct internal_reloc *rel;
+     struct coff_link_hash_entry *h;
+     struct internal_syment *sym;
+     bfd_vma *addendp;
+{
+  arelent relent;
+  const struct reloc_howto_struct *howto;
+
+  RTYPE2HOWTO (&relent, rel);
+
+  howto = relent.howto;
+
+  if (sym->n_scnum == 0 && sym->n_value != 0)
+    {
+      /* This is a common symbol.  The section contents include the
+	 size (sym->n_value) as an addend.  The relocate_section
+	 function will be adding in the final value of the symbol.  We
+	 need to subtract out the current size in order to get the
+	 correct result.  */
+      BFD_ASSERT (h != NULL);
+      *addendp -= sym->n_value;
+    }
+
+  /* If the output symbol is common (in which case this must be a
+     relocateable link), we need to add in the final size of the
+     common symbol.  */
+  if (h != NULL && h->root.type == bfd_link_hash_common)
+    *addendp += h->root.u.c.size;
+
+  return howto;
+}
diff --git a/bfd/configure.in b/bfd/configure.in
index e8c50de8521..db687722a4c 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -175,19 +175,19 @@ do
     i386aout_vec)		tb="$tb i386aout.o aout32.o stab-syms.o" ;;
     i386bsd_vec)		tb="$tb i386bsd.o aout32.o stab-syms.o" ;;
     i386dynix_vec)		tb="$tb i386dynix.o aout32.o stab-syms.o" ;;
-    i386coff_vec)		tb="$tb coff-i386.o" ;;
+    i386coff_vec)		tb="$tb coff-i386.o cofflink.o" ;;
     i386linux_vec)		tb="$tb i386linux.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 cf-i386lynx.o lynx-core.o stab-syms.o" ;;
+    i386lynx_coff_vec)		tb="$tb cf-i386lynx.o cofflink.o lynx-core.o stab-syms.o" ;;
     i386mach3_vec)		tb="$tb i386mach3.o aout32.o stab-syms.o" ;;
     i386os9k_vec)		tb="$tb i386os9k.o aout32.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" ;;
+    m68kcoff_vec)		tb="$tb coff-m68k.o cofflink.o" ;;
+    m68kcoffun_vec)		tb="$tb coff-u68k.o coff-m68k.o cofflink.o" ;;
     m68klynx_aout_vec)		tb="$tb m68klynx.o lynx-core.o aout32.o stab-syms.o" ;;
-    m68klynx_coff_vec)		tb="$tb cf-m68klynx.o coff-m68k.o lynx-core.o stab-syms.o" ;;
+    m68klynx_coff_vec)		tb="$tb cf-m68klynx.o coff-m68k.o cofflink.o lynx-core.o stab-syms.o" ;;
     m88kbcs_vec)		tb="$tb coff-m88k.o" ;;
     netbsd386_vec)		tb="$tb netbsd386.o aout32.o stab-syms.o" ;;
     netbsd532_vec)		tb="$tb netbsd532.o aout-ns32k.o stab-syms.o" ;;