* ns32k.h: New file.
authorIan Lance Taylor <ian@airs.com>
Wed, 27 Mar 1996 19:57:34 +0000 (19:57 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 27 Mar 1996 19:57:34 +0000 (19:57 +0000)
* cpu-ns32k.h: Include ns32k.h.  Rename externally visible
functions to start with _bfd_.
* aout-ns32k.c: Include ns32k.h.  Change references to renamed
functions in cpu-ns32k.h.
* Makefile.in: Rebuild dependencies.
(HFILES): Add ns32k.h.

bfd/.Sanitize
bfd/ChangeLog
bfd/Makefile.in
bfd/aout-ns32k.c
bfd/cpu-ns32k.c [new file with mode: 0644]

index 262ae7a..03e138d 100644 (file)
@@ -216,6 +216,7 @@ nlm32.c
 nlm64.c
 nlmcode.h
 nlmswap.h
+ns32k.h
 ns32knetbsd.c
 oasys.c
 opncls.c
index 9406f6a..71c05ab 100644 (file)
@@ -1,5 +1,13 @@
 Wed Mar 27 10:43:34 1996  Ian Lance Taylor  <ian@cygnus.com>
 
+       * ns32k.h: New file.
+       * cpu-ns32k.h: Include ns32k.h.  Rename externally visible
+       functions to start with _bfd_.
+       * aout-ns32k.c: Include ns32k.h.  Change references to renamed
+       functions in cpu-ns32k.h.
+       * Makefile.in: Rebuild dependencies.
+       (HFILES): Add ns32k.h.
+
        * section.c (SEC_LINKER_MARK): Define.
        * bfd-in2.h: Rebuild.
        * aoutx.h (NAME(aout,final_link)): Mark sections included in the
index f37b97f..cd84b94 100644 (file)
@@ -54,7 +54,7 @@ INSTALL_DATA = @INSTALL_DATA@
 AR = @AR@
 AR_FLAGS = rc
 CC = @CC@
-CFLAGS = -g
+CFLAGS = @CFLAGS@
 MAKEINFO = makeinfo
 RANLIB = @RANLIB@
 
@@ -99,13 +99,13 @@ BFD_LIBS = \
        archive.o archures.o bfd.o cache.o coffgen.o corefile.o \
        format.o init.o libbfd.o opncls.o reloc.o \
        section.o syms.o targets.o hash.o linker.o \
-       elf.o srec.o binary.o tekhex.o ihex.o
+       elf.o srec.o binary.o tekhex.o ihex.o stab-syms.o
 
 BFD_LIBS_CFILES = \
        archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
        format.c init.c libbfd.c opncls.c reloc.c \
        section.c syms.c targets.c hash.c linker.c \
-       elf.c srec.c binary.c tekhex.c ihex.c
+       elf.c srec.c binary.c tekhex.c ihex.c stab-syms.c
 
 # This list is alphabetized to make it easier to keep in sync
 # with the decls and initializer in archures.c.
@@ -225,6 +225,7 @@ BFD32_BACKENDS = \
        i386mach3.o \
        i386os9k.o \
        ieee.o \
+       m68klinux.o \
        m68klynx.o \
        m68knetbsd.o \
        m88kmach3.o \
@@ -247,7 +248,6 @@ BFD32_BACKENDS = \
        reloc16.o \
        sparclynx.o \
        sparcnetbsd.o \
-       stab-syms.o \
        sunos.o \
        tekhex.o \
        versados.o \
@@ -309,6 +309,7 @@ BFD32_BACKENDS_CFILES = \
        i386mach3.c \
        i386os9k.c \
        ieee.c \
+       m68klinux.c \
        m68klynx.c \
        m68knetbsd.c \
        m88kmach3.c \
@@ -331,7 +332,6 @@ BFD32_BACKENDS_CFILES = \
        reloc16.c \
        sparclynx.c \
        sparcnetbsd.c \
-       stab-syms.c \
        sunos.c \
        tekhex.c \
        versados.c \
@@ -428,7 +428,7 @@ HFILES = aout-target.h aoutf1.h aoutx.h coffcode.h \
         coffswap.h ecoffswap.h elf32-hppa.h elf32-target.h elf64-target.h \
         elfcode.h hppa_stubs.h libaout.h libbfd.h \
         libcoff.h libecoff.h elf-bfd.h libhppa.h libieee.h libnlm.h \
-        liboasys.h nlm-target.h nlmcode.h som.h genlink.h netbsd.h
+        liboasys.h nlm-target.h nlmcode.h som.h genlink.h netbsd.h ns32k.h
 
 all: Makefile $(ALLLIBS) @PICLIST@
        @$(MAKE) subdir_do DO=all "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS)
@@ -825,6 +825,8 @@ srec.o: srec.c $(INCDIR)/libiberty.h
 binary.o: binary.c
 tekhex.o: tekhex.c $(INCDIR)/libiberty.h
 ihex.o: ihex.c $(INCDIR)/libiberty.h
+stab-syms.o: stab-syms.c libaout.h $(INCDIR)/bfdlink.h \
+  $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab.def
 cpu-a29k.o: cpu-a29k.c
 cpu-alpha.o: cpu-alpha.c
 cpu-arm.o: cpu-arm.c
@@ -837,7 +839,7 @@ cpu-i960.o: cpu-i960.c
 cpu-m68k.o: cpu-m68k.c
 cpu-m88k.o: cpu-m88k.c
 cpu-mips.o: cpu-mips.c
-cpu-ns32k.o: cpu-ns32k.c
+cpu-ns32k.o: cpu-ns32k.c ns32k.h
 cpu-powerpc.o: cpu-powerpc.c
 cpu-rs6000.o: cpu-rs6000.c
 cpu-sh.o: cpu-sh.c
@@ -849,7 +851,7 @@ cpu-z8k.o: cpu-z8k.c
 aout-adobe.o: aout-adobe.c $(INCDIR)/aout/adobe.h $(INCDIR)/aout/stab_gnu.h \
   $(INCDIR)/aout/stab.def libaout.h $(INCDIR)/bfdlink.h
 aout-ns32k.o: aout-ns32k.c $(INCDIR)/aout/aout64.h \
-  libaout.h $(INCDIR)/bfdlink.h
+  ns32k.h libaout.h $(INCDIR)/bfdlink.h
 aout0.o: aout0.c aoutf1.h $(INCDIR)/aout/sun4.h libaout.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
   $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
@@ -877,8 +879,9 @@ coff-arm.o: coff-arm.c $(INCDIR)/coff/arm.h $(INCDIR)/coff/internal.h \
 coff-aux.o: coff-aux.c $(INCDIR)/coff/aux-coff.h $(INCDIR)/coff/internal.h \
   $(INCDIR)/coff/m68k.h coff-m68k.c libcoff.h $(INCDIR)/bfdlink.h \
   coffcode.h coffswap.h
-coff-h8300.o: coff-h8300.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/h8300.h \
-  $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-h8300.o: coff-h8300.c $(INCDIR)/bfdlink.h genlink.h \
+  $(INCDIR)/coff/h8300.h $(INCDIR)/coff/internal.h libcoff.h \
+  coffcode.h coffswap.h
 coff-h8500.o: coff-h8500.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/h8500.h \
   $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
 coff-i386.o: coff-i386.c $(INCDIR)/coff/i386.h $(INCDIR)/coff/internal.h \
@@ -993,6 +996,9 @@ i386mach3.o: i386mach3.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
 i386os9k.o: i386os9k.c $(INCDIR)/bfdlink.h libaout.h \
   $(INCDIR)/os9k.h
 ieee.o: ieee.c $(INCDIR)/ieee.h libieee.h
+m68klinux.o: m68klinux.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+  $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+  $(INCDIR)/bfdlink.h aout-target.h
 m68klynx.o: m68klynx.c libaout.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
   $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
@@ -1054,8 +1060,6 @@ sparclynx.o: sparclynx.c $(INCDIR)/aout/sun4.h libaout.h \
 sparcnetbsd.o: sparcnetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
   aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
   $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
-stab-syms.o: stab-syms.c libaout.h $(INCDIR)/bfdlink.h \
-  $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab.def
 sunos.o: sunos.c $(INCDIR)/bfdlink.h libaout.h aoutf1.h \
   $(INCDIR)/aout/sun4.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
   $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
index dcba191..89b09ef 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for ns32k a.out-ish binaries.
-   Copyright (C) 1990, 1991, 1992, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1990, 1991, 1992, 1994, 1995 Free Software Foundation, Inc.
    Contributed by Ian Dall (idall@eleceng.adelaide.edu.au).
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -16,15 +16,16 @@ 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.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #define BYTES_IN_WORD 4
 
 #include "bfd.h"
 #include "aout/aout64.h"
+#include "ns32k.h"
 
 #define MYNS(OP) CAT(ns32kaout_,OP)
-CONST struct reloc_howto_struct *
+reloc_howto_type *
 MYNS(bfd_reloc_type_lookup)
   PARAMS((bfd *abfd AND
          bfd_reloc_code_real_type code));
@@ -39,38 +40,6 @@ MYNS(write_object_contents)
 #define NAME(x,y) CAT3(ns32kaout,_32_,y)
 
 void bfd_ns32k_arch PARAMS ((void));
-long ns32k_get_displacement PARAMS ((bfd_byte *buffer, long offset, long size));
-int ns32k_put_displacement PARAMS ((long value, bfd_byte *buffer, long offset, long size));
-long ns32k_get_immediate PARAMS ((bfd_byte *buffer, long offset, long size));
-int ns32k_put_immediate  PARAMS ((long value, bfd_byte *buffer, long offset, long size));
-bfd_reloc_status_type
-  ns32k_reloc_disp PARAMS ((bfd *abfd, arelent *reloc_entry,
-                  struct symbol_cache_entry *symbol,
-                  PTR data,
-                  asection *input_section,
-                  bfd *output_bfd,
-                  char **error_message));
-bfd_reloc_status_type
-  ns32k_reloc_imm  PARAMS ((bfd *abfd,
-                  arelent *reloc_entry,
-                  struct symbol_cache_entry *symbol,
-                  PTR data,
-                  asection *input_section,
-                  bfd *output_bfd,
-                  char **error_message));
-bfd_reloc_status_type
-  ns32k_final_link_relocate  PARAMS ((reloc_howto_type *howto,
-                            bfd *input_bfd,
-                            asection *input_section,
-                            bfd_byte *contents,
-                            bfd_vma address,
-                            bfd_vma value,
-                            bfd_vma addend ));
-bfd_reloc_status_type
-  ns32k_relocate_contents  PARAMS ((reloc_howto_type *howto,
-                          bfd *input_bfd,
-                          bfd_vma relocation,
-                          bfd_byte *location));
 
 #include "libaout.h"
 
@@ -81,7 +50,8 @@ bfd_reloc_status_type
 
 static void
 MY_swap_std_reloc_in PARAMS ((bfd *abfd, struct reloc_std_external *bytes,
-                             arelent *cache_ptr, asymbol **symbols));
+                             arelent *cache_ptr, asymbol **symbols,
+                             bfd_size_type symcount));
 
 static void
 MY_swap_std_reloc_out PARAMS ((bfd *abfd, arelent *g,
@@ -121,61 +91,64 @@ MY_swap_std_reloc_out PARAMS ((bfd *abfd, arelent *g,
 
 reloc_howto_type MY(howto_table)[] = 
 {
-/* ns32k immediate operands */
-HOWTO(BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, true,
-       ns32k_reloc_imm, "NS32K_IMM_8",
-       true, 0x000000ff,0x000000ff, false),
-HOWTO(BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, true,
-       ns32k_reloc_imm,  "NS32K_IMM_16",
-       true, 0x0000ffff,0x0000ffff, false),
-HOWTO(BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, true,
-       ns32k_reloc_imm, "NS32K_IMM_32",
-       true, 0xffffffff,0xffffffff, false),
-HOWTO(BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, false,
-       ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
-       true, 0x000000ff, 0x000000ff, false),
-HOWTO(BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, false,
-       ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
-       true, 0x0000ffff,0x0000ffff, false),
-HOWTO(BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, false,
-       ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
-       true, 0xffffffff,0xffffffff, false),
-
-/* ns32k displacements */
-HOWTO(BFD_RELOC_NS32K_DISP_8, 0, 0, 8, false, 0, true,
-       ns32k_reloc_disp, "NS32K_DISP_8",
-       true, 0x000000ff,0x000000ff, false),
-HOWTO(BFD_RELOC_NS32K_DISP_16, 0, 1, 16, false, 0, true,
-       ns32k_reloc_disp, "NS32K_DISP_16",
-       true, 0x0000ffff, 0x0000ffff, false),
-HOWTO(BFD_RELOC_NS32K_DISP_32, 0, 2, 32, false, 0, true,
-       ns32k_reloc_disp, "NS32K_DISP_32",
-       true, 0xffffffff, 0xffffffff, false),
-HOWTO(BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 8, true, 0, false,
-       ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
-       true, 0x000000ff,0x000000ff, false),
-HOWTO(BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 16, true, 0, false,
-       ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
-       true, 0x0000ffff,0x0000ffff, false),
-HOWTO(BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 32, true, 0, false,
-       ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
-       true, 0xffffffff,0xffffffff, false),
-
-/* Normal 2's complement */
-HOWTO(BFD_RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,
-      "8", true, 0x000000ff,0x000000ff, false),
-HOWTO(BFD_RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,
-      "16", true, 0x0000ffff,0x0000ffff, false),
-HOWTO(BFD_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,
-      "32", true, 0xffffffff,0xffffffff, false),
-HOWTO(BFD_RELOC_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed, 0,
-      "PCREL_8", true, 0x000000ff,0x000000ff, false),
-HOWTO(BFD_RELOC_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed, 0,
-      "PCREL_16", true, 0x0000ffff,0x0000ffff, false),
-HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed, 0,
-      "PCREL_32", true, 0xffffffff,0xffffffff, false),
+  /* ns32k immediate operands */
+  HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, true,
+        _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
+        true, 0x000000ff,0x000000ff, false),
+  HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, true,
+        _bfd_ns32k_reloc_imm,  "NS32K_IMM_16",
+        true, 0x0000ffff,0x0000ffff, false),
+  HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, true,
+        _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
+        true, 0xffffffff,0xffffffff, false),
+  HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, false,
+        _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
+        true, 0x000000ff, 0x000000ff, false),
+  HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, false,
+        _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
+        true, 0x0000ffff,0x0000ffff, false),
+  HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, false,
+        _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
+        true, 0xffffffff,0xffffffff, false),
+
+  /* ns32k displacements */
+  HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 8, false, 0, true,
+        _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
+        true, 0x000000ff,0x000000ff, false),
+  HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 16, false, 0, true,
+        _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
+        true, 0x0000ffff, 0x0000ffff, false),
+  HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 32, false, 0, true,
+        _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
+        true, 0xffffffff, 0xffffffff, false),
+  HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 8, true, 0, false,
+        _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
+        true, 0x000000ff,0x000000ff, false),
+  HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 16, true, 0, false,
+        _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
+        true, 0x0000ffff,0x0000ffff, false),
+  HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 32, true, 0, false,
+        _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
+        true, 0xffffffff,0xffffffff, false),
+
+  /* Normal 2's complement */
+  HOWTO (BFD_RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,
+        "8", true, 0x000000ff,0x000000ff, false),
+  HOWTO (BFD_RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,
+        "16", true, 0x0000ffff,0x0000ffff, false),
+  HOWTO (BFD_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,
+        "32", true, 0xffffffff,0xffffffff, false),
+  HOWTO (BFD_RELOC_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed, 0,
+        "PCREL_8", true, 0x000000ff,0x000000ff, false),
+  HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed, 0,
+        "PCREL_16", true, 0x0000ffff,0x0000ffff, false),
+  HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed, 0,
+        "PCREL_32", true, 0xffffffff,0xffffffff, false),
 };
 
+
+#define CTOR_TABLE_RELOC_HOWTO(BFD) (MY(howto_table) + 14)
+
 #define RELOC_STD_BITS_NS32K_TYPE_BIG 0x06
 #define RELOC_STD_BITS_NS32K_TYPE_LITTLE 0x60
 #define RELOC_STD_BITS_NS32K_TYPE_SH_BIG 1
@@ -191,7 +164,7 @@ MY(reloc_howto)(abfd, rel, r_index, r_extern, r_pcrel)
 {
   unsigned int r_length;
   int r_ns32k_type;
-/*  BFD_ASSERT(abfd->xvec->header_byteorder_big_p == false); */
+/*  BFD_ASSERT(bfd_header_little_endian (abfd)); */
   *r_index =  ((rel->r_index[2] << 16)
               | (rel->r_index[1] << 8)
               |  rel->r_index[0] );
@@ -222,7 +195,7 @@ MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc)
   r_length = howto->size ;     /* Size as a power of two */
   r_pcrel  = (int) howto->pc_relative; /* Relative to PC? */
   r_ns32k_type = (howto - MY(howto_table) )/6;
-/*  BFD_ASSERT (abfd->xvec->header_byteorder_big_p == false); */
+/*  BFD_ASSERT (bfd_header_little_endian (abfd)); */
   reloc->r_index[2] = r_index >> 16;
   reloc->r_index[1] = r_index >> 8;
   reloc->r_index[0] = r_index;
@@ -238,15 +211,15 @@ MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc)
 
 #define STAT_FOR_EXEC
 
-#define MY_final_link_relocate ns32k_final_link_relocate
-#define MY_relocate_contents ns32k_relocate_contents
+#define MY_final_link_relocate _bfd_ns32k_final_link_relocate
+#define MY_relocate_contents _bfd_ns32k_relocate_contents
 
 #include <aoutx.h>
 
-CONST struct reloc_howto_struct *
-  MY(bfd_reloc_type_lookup)(abfd,code)
-      bfd *abfd;
-      bfd_reloc_code_real_type code;
+reloc_howto_type *
+MY(bfd_reloc_type_lookup)(abfd,code)
+     bfd *abfd;
+     bfd_reloc_code_real_type code;
 {
 
 #define ENTRY(i,j)     case i: return &MY(howto_table)[j]
@@ -281,24 +254,23 @@ CONST struct reloc_howto_struct *
       ENTRY(BFD_RELOC_8_PCREL, 15);
       ENTRY(BFD_RELOC_16_PCREL, 16);
       ENTRY(BFD_RELOC_32_PCREL, 17);
-    default: return (CONST struct reloc_howto_struct *) 0;
+    default: return (reloc_howto_type *) NULL;
     }
 #undef ENTRY
 }
 
 
 static void
-MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
+MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
      bfd *abfd;
      struct reloc_std_external *bytes;
      arelent *cache_ptr;
      asymbol **symbols;
+     bfd_size_type symcount;
 {
   int r_index;
   int r_extern;
-  unsigned int r_length;
   int r_pcrel;
-  int r_ns32k_type;
   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
 
   cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
@@ -319,9 +291,6 @@ MY_swap_std_reloc_out (abfd, g, natptr)
   int r_index;
   asymbol *sym = *(g->sym_ptr_ptr);
   int r_extern;
-  unsigned int r_length;
-  int r_pcrel;
-  int r_ns32k_type;
   unsigned int r_addend;
   asection *output_section = sym->section->output_section;
 
@@ -351,8 +320,9 @@ MY_swap_std_reloc_out (abfd, g, natptr)
        {
          /* Fill in symbol */
          r_extern = 1;
-#define KEEPIT flags
-         r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
+#undef KEEPIT
+#define KEEPIT udata.i
+         r_index =  (*(g->sym_ptr_ptr))->KEEPIT;
 #undef KEEPIT     
        }
     }
@@ -367,7 +337,7 @@ MY_swap_std_reloc_out (abfd, g, natptr)
 }
 
 bfd_reloc_status_type
-ns32k_relocate_contents (howto, input_bfd, relocation, location)
+_bfd_ns32k_relocate_contents (howto, input_bfd, relocation, location)
      reloc_howto_type *howto;
      bfd *input_bfd;
      bfd_vma relocation;
@@ -380,12 +350,12 @@ ns32k_relocate_contents (howto, input_bfd, relocation, location)
   switch (r_ns32k_type)
     {
     case 0:
-      get_data = ns32k_get_immediate;
-      put_data = ns32k_put_immediate;
+      get_data = _bfd_ns32k_get_immediate;
+      put_data = _bfd_ns32k_put_immediate;
       break;
     case 1:
-      get_data = ns32k_get_displacement;
-      put_data = ns32k_put_displacement;
+      get_data = _bfd_ns32k_get_displacement;
+      put_data = _bfd_ns32k_put_displacement;
       break;
     case 2:
       return _bfd_relocate_contents (howto, input_bfd, relocation,
@@ -393,6 +363,6 @@ ns32k_relocate_contents (howto, input_bfd, relocation, location)
       /* NOT REACHED */
       break;
     }
-  return do_ns32k_reloc_contents (howto, input_bfd, relocation,
-                                location, get_data, put_data);
+  return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
+                                      location, get_data, put_data);
 }
diff --git a/bfd/cpu-ns32k.c b/bfd/cpu-ns32k.c
new file mode 100644 (file)
index 0000000..be31d88
--- /dev/null
@@ -0,0 +1,843 @@
+/* BFD support for the ns32k architecture.
+   Copyright (C) 1990, 1991, 1994, 1995 Free Software Foundation, Inc.
+   Almost totally rewritten by Ian Dall from initial work
+   by Andrew Cagney.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "ns32k.h"
+
+#define N(machine, printable, d, next)  \
+{  32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, }
+
+static const bfd_arch_info_type arch_info_struct[] =
+{ 
+  N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
+};
+
+const bfd_arch_info_type bfd_ns32k_arch =
+  N(32032,"ns32k:32032",false, &arch_info_struct[0]);
+
+static long
+ns32k_sign_extend(value, bits)
+     int value;
+     int bits;
+{
+  value = value & ((1 << bits) - 1);
+  return (value & (1 << (bits-1))
+         ? value | (~((1 << bits) - 1))
+         : value);
+}
+
+long
+_bfd_ns32k_get_displacement(buffer, offset, size)
+     bfd_byte *buffer;
+     long offset;
+     long size;
+{
+  long value;
+  buffer += offset;
+  switch (size)
+    {
+    case 1:
+      value = ns32k_sign_extend (*buffer, 7);
+      break;
+    case 2:
+      value = ns32k_sign_extend(*buffer++, 6);
+      value = (value << 8) | (0xff & *buffer);
+      break;
+    case 4:
+      value = ns32k_sign_extend(*buffer++, 6);
+      value = (value << 8) | (0xff & *buffer++);
+      value = (value << 8) | (0xff & *buffer++);
+      value = (value << 8) | (0xff & *buffer);
+      break;
+    }
+  return value;
+}
+
+int
+_bfd_ns32k_put_displacement(value, buffer, offset, size)
+     long value;
+     bfd_byte *buffer;
+     long offset;
+     long size;
+{
+  buffer += offset;
+  switch (size)
+    {
+    case 1:
+      if (value < -64 || value > 63)
+       return -1;
+      value&=0x7f;
+      *buffer++=value;
+      break;
+    case 2:
+      if (value < -8192 || value > 8191)
+       return -1;
+      value&=0x3fff;
+      value|=0x8000;
+      *buffer++=(value>>8);
+      *buffer++=value;
+      break;
+    case 4:
+      if (value < -0x1f000000 || value >= 0x20000000)
+       return -1;
+      value|=0xc0000000;
+      *buffer++=(value>>24);
+      *buffer++=(value>>16);
+      *buffer++=(value>>8);
+      *buffer++=value;
+      break;
+    default:
+      return -1;
+  }
+  return 0;
+}
+
+long
+_bfd_ns32k_get_immediate (buffer, offset, size)
+     bfd_byte *buffer;
+     long offset;
+     long size;
+{
+  long value = 0;
+  buffer += offset;
+  switch (size)
+    {
+    case 4:
+      value = (value << 8) | (*buffer++ & 0xff);
+    case 3:
+      value = (value << 8) | (*buffer++ & 0xff);
+    case 2:
+      value = (value << 8) | (*buffer++ & 0xff);
+    case 1:
+      value = (value << 8) | (*buffer++ & 0xff);
+    }
+  return value;
+}
+
+int
+_bfd_ns32k_put_immediate (value, buffer, offset, size)
+     long value;
+     bfd_byte *buffer;
+     long offset;
+     long size;
+{
+  buffer += offset + size - 1;
+  switch (size)
+    {
+    case 4:
+      *buffer-- = (value & 0xff); value >>= 8;
+    case 3:
+      *buffer-- = (value & 0xff); value >>= 8;
+    case 2:
+      *buffer-- = (value & 0xff); value >>= 8;
+    case 1:
+      *buffer-- = (value & 0xff); value >>= 8;
+    }
+  return 0;
+}
+
+/* This is just like the standard perform_relocation except we
+ * use get_data and put_data which know about the ns32k
+ * storage methods.
+ * This is probably a lot more complicated than it needs to be!
+ */
+static bfd_reloc_status_type
+do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
+               error_message, get_data, put_data)
+     bfd *abfd;
+     arelent *reloc_entry;
+     struct symbol_cache_entry *symbol;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message;
+     long (*get_data)();
+     int (*put_data)();
+{
+  int overflow = 0;
+  bfd_vma relocation;
+  bfd_reloc_status_type flag = bfd_reloc_ok;
+  bfd_size_type addr = reloc_entry->address;
+  bfd_vma output_base = 0;
+  reloc_howto_type *howto = reloc_entry->howto;
+  asection *reloc_target_output_section;
+
+  if ((symbol->section == &bfd_abs_section)
+      && output_bfd != (bfd *) NULL)
+    {
+      reloc_entry->address += input_section->output_offset;
+      return bfd_reloc_ok;
+    }
+
+  /* If we are not producing relocateable output, return an error if
+     the symbol is not defined.  An undefined weak symbol is
+     considered to have a value of zero (SVR4 ABI, p. 4-27).  */
+  if (symbol->section == &bfd_und_section
+      && (symbol->flags & BSF_WEAK) == 0
+      && output_bfd == (bfd *) NULL)
+    flag = bfd_reloc_undefined;
+
+
+  /* Is the address of the relocation really within the section?  */
+  if (reloc_entry->address > input_section->_cooked_size)
+    return bfd_reloc_outofrange;
+
+  /* Work out which section the relocation is targetted at and the
+     initial relocation command value.  */
+
+  /* Get symbol value.  (Common symbols are special.)  */
+  if (bfd_is_com_section (symbol->section))
+    relocation = 0;
+  else
+    relocation = symbol->value;
+
+
+  reloc_target_output_section = symbol->section->output_section;
+
+  /* Convert input-section-relative symbol value to absolute.  */
+  if (output_bfd && howto->partial_inplace == false)
+    output_base = 0;
+  else
+    output_base = reloc_target_output_section->vma;
+
+  relocation += output_base + symbol->section->output_offset;
+
+  /* Add in supplied addend.  */
+  relocation += reloc_entry->addend;
+
+  /* Here the variable relocation holds the final address of the
+     symbol we are relocating against, plus any addend.  */
+
+  if (howto->pc_relative == true)
+    {
+      /* This is a PC relative relocation.  We want to set RELOCATION
+        to the distance between the address of the symbol and the
+        location.  RELOCATION is already the address of the symbol.
+
+        We start by subtracting the address of the section containing
+        the location.
+
+        If pcrel_offset is set, we must further subtract the position
+        of the location within the section.  Some targets arrange for
+        the addend to be the negative of the position of the location
+        within the section; for example, i386-aout does this.  For
+        i386-aout, pcrel_offset is false.  Some other targets do not
+        include the position of the location; for example, m88kbcs,
+        or ELF.  For those targets, pcrel_offset is true.
+
+        If we are producing relocateable output, then we must ensure
+        that this reloc will be correctly computed when the final
+        relocation is done.  If pcrel_offset is false we want to wind
+        up with the negative of the location within the section,
+        which means we must adjust the existing addend by the change
+        in the location within the section.  If pcrel_offset is true
+        we do not want to adjust the existing addend at all.
+
+        FIXME: This seems logical to me, but for the case of
+        producing relocateable output it is not what the code
+        actually does.  I don't want to change it, because it seems
+        far too likely that something will break.  */
+
+      relocation -=
+       input_section->output_section->vma + input_section->output_offset;
+
+      if (howto->pcrel_offset == true)
+       relocation -= reloc_entry->address;
+    }
+
+  if (output_bfd != (bfd *) NULL)
+    {
+      if (howto->partial_inplace == false)
+       {
+         /* This is a partial relocation, and we want to apply the relocation
+            to the reloc entry rather than the raw data. Modify the reloc
+            inplace to reflect what we now know.  */
+         reloc_entry->addend = relocation;
+         reloc_entry->address += input_section->output_offset;
+         return flag;
+       }
+      else
+       {
+         /* This is a partial relocation, but inplace, so modify the
+            reloc record a bit.
+
+            If we've relocated with a symbol with a section, change
+            into a ref to the section belonging to the symbol.  */
+
+         reloc_entry->address += input_section->output_offset;
+
+         /* WTF?? */
+         if (abfd->xvec->flavour == bfd_target_coff_flavour
+             && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0)
+           {
+#if 1
+             /* For m68k-coff, the addend was being subtracted twice during
+                relocation with -r.  Removing the line below this comment
+                fixes that problem; see PR 2953.
+
+However, Ian wrote the following, regarding removing the line below,
+which explains why it is still enabled:  --djm
+
+If you put a patch like that into BFD you need to check all the COFF
+linkers.  I am fairly certain that patch will break coff-i386 (e.g.,
+SCO); see coff_i386_reloc in coff-i386.c where I worked around the
+problem in a different way.  There may very well be a reason that the
+code works as it does.
+
+Hmmm.  The first obvious point is that bfd_perform_relocation should
+not have any tests that depend upon the flavour.  It's seem like
+entirely the wrong place for such a thing.  The second obvious point
+is that the current code ignores the reloc addend when producing
+relocateable output for COFF.  That's peculiar.  In fact, I really
+have no idea what the point of the line you want to remove is.
+
+A typical COFF reloc subtracts the old value of the symbol and adds in
+the new value to the location in the object file (if it's a pc
+relative reloc it adds the difference between the symbol value and the
+location).  When relocating we need to preserve that property.
+
+BFD handles this by setting the addend to the negative of the old
+value of the symbol.  Unfortunately it handles common symbols in a
+non-standard way (it doesn't subtract the old value) but that's a
+different story (we can't change it without losing backward
+compatibility with old object files) (coff-i386 does subtract the old
+value, to be compatible with existing coff-i386 targets, like SCO).
+
+So everything works fine when not producing relocateable output.  When
+we are producing relocateable output, logically we should do exactly
+what we do when not producing relocateable output.  Therefore, your
+patch is correct.  In fact, it should probably always just set
+reloc_entry->addend to 0 for all cases, since it is, in fact, going to
+add the value into the object file.  This won't hurt the COFF code,
+which doesn't use the addend; I'm not sure what it will do to other
+formats (the thing to check for would be whether any formats both use
+the addend and set partial_inplace).
+
+When I wanted to make coff-i386 produce relocateable output, I ran
+into the problem that you are running into: I wanted to remove that
+line.  Rather than risk it, I made the coff-i386 relocs use a special
+function; it's coff_i386_reloc in coff-i386.c.  The function
+specifically adds the addend field into the object file, knowing that
+bfd_perform_relocation is not going to.  If you remove that line, then
+coff-i386.c will wind up adding the addend field in twice.  It's
+trivial to fix; it just needs to be done.
+
+The problem with removing the line is just that it may break some
+working code.  With BFD it's hard to be sure of anything.  The right
+way to deal with this is simply to build and test at least all the
+supported COFF targets.  It should be straightforward if time and disk
+space consuming.  For each target:
+    1) build the linker
+    2) generate some executable, and link it using -r (I would
+       probably use paranoia.o and link against newlib/libc.a, which
+       for all the supported targets would be available in
+       /usr/cygnus/progressive/H-host/target/lib/libc.a).
+    3) make the change to reloc.c
+    4) rebuild the linker
+    5) repeat step 2
+    6) if the resulting object files are the same, you have at least
+       made it no worse
+    7) if they are different you have to figure out which version is
+       right
+*/
+             relocation -= reloc_entry->addend;
+#endif
+             reloc_entry->addend = 0;
+           }
+         else
+           {
+             reloc_entry->addend = relocation;
+           }
+       }
+    }
+  else
+    {
+      reloc_entry->addend = 0;
+    }
+
+  /* FIXME: This overflow checking is incomplete, because the value
+     might have overflowed before we get here.  For a correct check we
+     need to compute the value in a size larger than bitsize, but we
+     can't reasonably do that for a reloc the same size as a host
+     machine word.
+     FIXME: We should also do overflow checking on the result after
+     adding in the value contained in the object file.  */
+  if (howto->complain_on_overflow != complain_overflow_dont)
+    {
+      bfd_vma check;
+
+      /* Get the value that will be used for the relocation, but
+        starting at bit position zero.  */
+      if (howto->rightshift > howto->bitpos)
+       check = relocation >> (howto->rightshift - howto->bitpos);
+      else
+       check = relocation << (howto->bitpos - howto->rightshift);
+      switch (howto->complain_on_overflow)
+       {
+       case complain_overflow_signed:
+         {
+           /* Assumes two's complement.  */
+           bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+           bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
+
+           /* The above right shift is incorrect for a signed value.
+              Fix it up by forcing on the upper bits.  */
+           if (howto->rightshift > howto->bitpos
+               && (bfd_signed_vma) relocation < 0)
+             check |= ((bfd_vma) - 1
+                       & ~((bfd_vma) - 1
+                           >> (howto->rightshift - howto->bitpos)));
+           if ((bfd_signed_vma) check > reloc_signed_max
+               || (bfd_signed_vma) check < reloc_signed_min)
+             flag = bfd_reloc_overflow;
+         }
+         break;
+       case complain_overflow_unsigned:
+         {
+           /* Assumes two's complement.  This expression avoids
+              overflow if howto->bitsize is the number of bits in
+              bfd_vma.  */
+           bfd_vma reloc_unsigned_max =
+           (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+           if ((bfd_vma) check > reloc_unsigned_max)
+             flag = bfd_reloc_overflow;
+         }
+         break;
+       case complain_overflow_bitfield:
+         {
+           /* Assumes two's complement.  This expression avoids
+              overflow if howto->bitsize is the number of bits in
+              bfd_vma.  */
+           bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+           if (((bfd_vma) check & ~reloc_bits) != 0
+               && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+             {
+               /* The above right shift is incorrect for a signed
+                  value.  See if turning on the upper bits fixes the
+                  overflow.  */
+               if (howto->rightshift > howto->bitpos
+                   && (bfd_signed_vma) relocation < 0)
+                 {
+                   check |= ((bfd_vma) - 1
+                             & ~((bfd_vma) - 1
+                                 >> (howto->rightshift - howto->bitpos)));
+                   if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+                     flag = bfd_reloc_overflow;
+                 }
+               else
+                 flag = bfd_reloc_overflow;
+             }
+         }
+         break;
+       default:
+         abort ();
+       }
+    }
+
+  /*
+    Either we are relocating all the way, or we don't want to apply
+    the relocation to the reloc entry (probably because there isn't
+    any room in the output format to describe addends to relocs)
+    */
+
+  /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
+     (OSF version 1.3, compiler version 3.11).  It miscompiles the
+     following program:
+
+     struct str
+     {
+       unsigned int i0;
+     } s = { 0 };
+
+     int
+     main ()
+     {
+       unsigned long x;
+
+       x = 0x100000000;
+       x <<= (unsigned long) s.i0;
+       if (x == 0)
+        printf ("failed\n");
+       else
+        printf ("succeeded (%lx)\n", x);
+     }
+     */
+
+  relocation >>= (bfd_vma) howto->rightshift;
+
+  /* Shift everything up to where it's going to be used */
+
+  relocation <<= (bfd_vma) howto->bitpos;
+
+  /* Wait for the day when all have the mask in them */
+
+  /* What we do:
+     i instruction to be left alone
+     o offset within instruction
+     r relocation offset to apply
+     S src mask
+     D dst mask
+     N ~dst mask
+     A part 1
+     B part 2
+     R result
+
+     Do this:
+     i i i i i o o o o o        from bfd_get<size>
+     and           S S S S S    to get the size offset we want
+     +   r r r r r r r r r r  to get the final value to place
+     and           D D D D D  to chop to right size
+     -----------------------
+     A A A A A
+     And this:
+     ...   i i i i i o o o o o  from bfd_get<size>
+     and   N N N N N            get instruction
+     -----------------------
+     ...   B B B B B
+
+     And then:
+     B B B B B
+     or              A A A A A
+     -----------------------
+     R R R R R R R R R R        put into bfd_put<size>
+     */
+
+#define DOIT(x) \
+  x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
+
+  switch (howto->size)
+    {
+    case 0:
+      {
+       char x = get_data (data, addr, 1);
+       DOIT (x);
+       overflow = put_data(x, data, addr, 1);
+      }
+      break;
+
+    case 1:
+      if (relocation)
+       {
+         short x = get_data (data, addr, 2);
+         DOIT (x);
+         overflow = put_data(x, (unsigned char *) data, addr, 2);
+       }
+      break;
+    case 2:
+      if (relocation)
+       {
+         long x = get_data (data, addr, 4);
+         DOIT (x);
+         overflow = put_data(x, data, addr, 4);
+       }
+      break;
+    case -2:
+      {
+       long  x = get_data(data, addr, 4);
+       relocation = -relocation;
+       DOIT(x);
+       overflow = put_data(x, data , addr, 4);
+      }
+      break;
+
+    case 3:
+      /* Do nothing */
+      break;
+
+    case 4:
+#ifdef BFD64
+      if (relocation)
+       {
+         bfd_vma x = get_data (data, addr, 8);
+         DOIT (x);
+         overflow = put_data(x, data, addr, 8);
+       }
+#else
+      abort ();
+#endif
+      break;
+    default:
+      return bfd_reloc_other;
+    }
+  if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
+    return bfd_reloc_overflow;
+
+  return flag;
+}
+
+/* Relocate a given location using a given value and howto.  */
+
+bfd_reloc_status_type
+_bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
+                             get_data, put_data)
+     reloc_howto_type *howto;
+     bfd *input_bfd;
+     bfd_vma relocation;
+     bfd_byte *location;
+     long (*get_data)();
+     int (*put_data)();
+{
+  int size;
+  bfd_vma x;
+  boolean overflow;
+
+  /* If the size is negative, negate RELOCATION.  This isn't very
+     general.  */
+  if (howto->size < 0)
+    relocation = -relocation;
+
+  /* Get the value we are going to relocate.  */
+  size = bfd_get_reloc_size (howto);
+  switch (size)
+    {
+    default:
+    case 0:
+      abort ();
+    case 1:
+    case 2:
+    case 4:
+#ifdef BFD64
+    case 8:
+#endif
+      x = get_data (location, 0, size);
+      break;
+    }
+
+  /* Check for overflow.  FIXME: We may drop bits during the addition
+     which we don't check for.  We must either check at every single
+     operation, which would be tedious, or we must do the computations
+     in a type larger than bfd_vma, which would be inefficient.  */
+  overflow = false;
+  if (howto->complain_on_overflow != complain_overflow_dont)
+    {
+      bfd_vma check;
+      bfd_signed_vma signed_check;
+      bfd_vma add;
+      bfd_signed_vma signed_add;
+
+      if (howto->rightshift == 0)
+       {
+         check = relocation;
+         signed_check = (bfd_signed_vma) relocation;
+       }
+      else
+       {
+         /* Drop unwanted bits from the value we are relocating to.  */
+         check = relocation >> howto->rightshift;
+
+         /* If this is a signed value, the rightshift just dropped
+            leading 1 bits (assuming twos complement).  */
+         if ((bfd_signed_vma) relocation >= 0)
+           signed_check = check;
+         else
+           signed_check = (check
+                           | ((bfd_vma) - 1
+                              & ~((bfd_vma) - 1 >> howto->rightshift)));
+       }
+
+      /* Get the value from the object file.  */
+      add = x & howto->src_mask;
+
+      /* Get the value from the object file with an appropriate sign.
+        The expression involving howto->src_mask isolates the upper
+        bit of src_mask.  If that bit is set in the value we are
+        adding, it is negative, and we subtract out that number times
+        two.  If src_mask includes the highest possible bit, then we
+        can not get the upper bit, but that does not matter since
+        signed_add needs no adjustment to become negative in that
+        case.  */
+      signed_add = add;
+      if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
+       signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
+
+      /* Add the value from the object file, shifted so that it is a
+        straight number.  */
+      if (howto->bitpos == 0)
+       {
+         check += add;
+         signed_check += signed_add;
+       }
+      else
+       {
+         check += add >> howto->bitpos;
+
+         /* For the signed case we use ADD, rather than SIGNED_ADD,
+            to avoid warnings from SVR4 cc.  This is OK since we
+            explictly handle the sign bits.  */
+         if (signed_add >= 0)
+           signed_check += add >> howto->bitpos;
+         else
+           signed_check += ((add >> howto->bitpos)
+                            | ((bfd_vma) - 1
+                               & ~((bfd_vma) - 1 >> howto->bitpos)));
+       }
+
+      switch (howto->complain_on_overflow)
+       {
+       case complain_overflow_signed:
+         {
+           /* Assumes two's complement.  */
+           bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+           bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
+
+           if (signed_check > reloc_signed_max
+               || signed_check < reloc_signed_min)
+             overflow = true;
+         }
+         break;
+       case complain_overflow_unsigned:
+         {
+           /* Assumes two's complement.  This expression avoids
+              overflow if howto->bitsize is the number of bits in
+              bfd_vma.  */
+           bfd_vma reloc_unsigned_max =
+           (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+           if (check > reloc_unsigned_max)
+             overflow = true;
+         }
+         break;
+       case complain_overflow_bitfield:
+         {
+           /* Assumes two's complement.  This expression avoids
+              overflow if howto->bitsize is the number of bits in
+              bfd_vma.  */
+           bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+           if ((check & ~reloc_bits) != 0
+               && (((bfd_vma) signed_check & ~reloc_bits)
+                   != (-1 & ~reloc_bits)))
+             overflow = true;
+         }
+         break;
+       default:
+         abort ();
+       }
+    }
+
+  /* Put RELOCATION in the right bits.  */
+  relocation >>= (bfd_vma) howto->rightshift;
+  relocation <<= (bfd_vma) howto->bitpos;
+
+  /* Add RELOCATION to the right bits of X.  */
+  x = ((x & ~howto->dst_mask)
+       | (((x & howto->src_mask) + relocation) & howto->dst_mask));
+
+  /* Put the relocated value back in the object file.  */
+  switch (size)
+    {
+    default:
+    case 0:
+      abort ();
+    case 1:
+    case 2:
+    case 4:
+#ifdef BFD64
+    case 8:
+#endif
+      put_data(x, location, 0, size);
+      break;
+    }
+
+  return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
+}
+
+bfd_reloc_status_type
+_bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
+                      output_bfd, error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     struct symbol_cache_entry *symbol;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message;
+{
+  return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
+                        output_bfd, error_message,
+                        _bfd_ns32k_get_displacement,
+                        _bfd_ns32k_put_displacement);
+}
+
+bfd_reloc_status_type
+_bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
+                     output_bfd, error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     struct symbol_cache_entry *symbol;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message;
+{
+  return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
+                        output_bfd, error_message, _bfd_ns32k_get_immediate,
+                        _bfd_ns32k_put_immediate);
+}
+
+bfd_reloc_status_type
+_bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
+                               address, value, addend)
+     reloc_howto_type *howto;
+     bfd *input_bfd;
+     asection *input_section;
+     bfd_byte *contents;
+     bfd_vma address;
+     bfd_vma value;
+     bfd_vma addend;
+{
+  bfd_vma relocation;
+
+  /* Sanity check the address.  */
+  if (address > input_section->_cooked_size)
+    return bfd_reloc_outofrange;
+
+  /* This function assumes that we are dealing with a basic relocation
+     against a symbol.  We want to compute the value of the symbol to
+     relocate to.  This is just VALUE, the value of the symbol, plus
+     ADDEND, any addend associated with the reloc.  */
+  relocation = value + addend;
+
+  /* If the relocation is PC relative, we want to set RELOCATION to
+     the distance between the symbol (currently in RELOCATION) and the
+     location we are relocating.  Some targets (e.g., i386-aout)
+     arrange for the contents of the section to be the negative of the
+     offset of the location within the section; for such targets
+     pcrel_offset is false.  Other targets (e.g., m88kbcs or ELF)
+     simply leave the contents of the section as zero; for such
+     targets pcrel_offset is true.  If pcrel_offset is false we do not
+     need to subtract out the offset of the location within the
+     section (which is just ADDRESS).  */
+  if (howto->pc_relative)
+    {
+      relocation -= (input_section->output_section->vma
+                    + input_section->output_offset);
+      if (howto->pcrel_offset)
+       relocation -= address;
+    }
+
+  return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
+                                      contents + address);
+}