diff --git a/bfd/.Sanitize b/bfd/.Sanitize index 262ae7adf9..03e138d85e 100644 --- a/bfd/.Sanitize +++ b/bfd/.Sanitize @@ -216,6 +216,7 @@ nlm32.c nlm64.c nlmcode.h nlmswap.h +ns32k.h ns32knetbsd.c oasys.c opncls.c diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9406f6ae8e..71c05ab143 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,13 @@ Wed Mar 27 10:43:34 1996 Ian Lance Taylor + * 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 diff --git a/bfd/Makefile.in b/bfd/Makefile.in index f37b97fb3c..cd84b94c19 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -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 diff --git a/bfd/aout-ns32k.c b/bfd/aout-ns32k.c index dcba191e2e..89b09ef8c2 100644 --- a/bfd/aout-ns32k.c +++ b/bfd/aout-ns32k.c @@ -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 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, - 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), + /* 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), + /* 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 -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 index 0000000000..be31d88bd3 --- /dev/null +++ b/bfd/cpu-ns32k.c @@ -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 + 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 + 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 + */ + +#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); +}