diff --git a/contrib/binutils/bfd/freebsd.h b/contrib/binutils/bfd/freebsd.h index ccd201f1af79..8e42124ea84d 100644 --- a/contrib/binutils/bfd/freebsd.h +++ b/contrib/binutils/bfd/freebsd.h @@ -1,4 +1,4 @@ -/* BFD back-end definitions used by all FreeBSD targets. +/* BFD back-end definitions used by all FreeBSD a.out targets. Copyright (C) 1990, 1991, 1992, 1996 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -18,26 +18,33 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* FreeBSD ZMAGIC files never have the header in the text. */ -#define N_HEADER_IN_TEXT(x) 0 +/* FreeBSD QMAGIC files have the header in the text. */ +#define N_HEADER_IN_TEXT(x) 1 +#define MY_text_includes_header 1 -/* ZMAGIC files start at offset 0. Does not apply to QMAGIC files. */ -#define TEXT_START_ADDR 0 +#define TEXT_START_ADDR (TARGET_PAGE_SIZE + 0x20) -#define N_GETMAGIC_NET(exec) \ - ((exec).a_info & 0xffff) -#define N_GETMID_NET(exec) \ - (((exec).a_info >> 16) & 0x3ff) -#define N_GETFLAG_NET(ex) \ - (((exec).a_info >> 26) & 0x3f) +/* + * FreeBSD uses a weird mix of byte orderings for its a_info field. + * Its assembler emits NetBSD style object files, with a big-endian + * a_info. Its linker seems to accept either byte ordering, but + * emits a little-endian a_info. + * + * Here, we accept either byte ordering, but always produce + * little-endian. + * + * FIXME - Probably we should always produce the _native_ byte + * ordering. I.e., it should be in the architecture-specific + * file, not here. But in reality, there is almost zero chance + * that FreeBSD will ever use a.out in a new port. + */ #define N_MACHTYPE(exec) \ ((enum machine_type) \ - ((N_GETMAGIC_NET (exec) == ZMAGIC) ? N_GETMID_NET (exec) : \ - ((exec).a_info >> 16) & 0x3ff)) + ((freebsd_swap_magic(&(exec).a_info) >> 16) & 0x3ff)) #define N_FLAGS(exec) \ - ((N_GETMAGIC_NET (exec) == ZMAGIC) ? N_GETFLAG_NET (exec) : \ - ((exec).a_info >> 26) & 0x3f) + ((enum machine_type) \ + ((freebsd_swap_magic(&(exec).a_info) >> 26) & 0x3f)) #define N_SET_INFO(exec, magic, type, flags) \ ((exec).a_info = ((magic) & 0xffff) \ @@ -55,22 +62,50 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "libbfd.h" #include "libaout.h" -/* On FreeBSD, the magic number is always in ntohl's "network" (big-endian) - format. I think. */ -#define SWAP_MAGIC(ext) bfd_getb32 (ext) +#define SWAP_MAGIC(ext) (freebsd_swap_magic(ext)) +#define MY_bfd_final_link freebsd_bfd_final_link +#define MY_write_object_contents freebsd_write_object_contents -#define MY_write_object_contents MY(write_object_contents) -static boolean MY(write_object_contents) PARAMS ((bfd *abfd)); +static boolean freebsd_bfd_final_link PARAMS ((bfd *, struct bfd_link_info *)); +static long freebsd_swap_magic PARAMS ((void *ext)); +static boolean freebsd_write_object_contents PARAMS ((bfd *abfd)); #include "aout-target.h" +static boolean +freebsd_bfd_final_link(abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + obj_aout_subformat (abfd) = q_magic_format; + return NAME(aout,final_link) (abfd, info, MY_final_link_callback); +} + +/* Swap a magic number. We accept either endian, whichever looks valid. */ + +static long +freebsd_swap_magic(ext) + void *ext; +{ + long linfo = bfd_getl32(ext); + long binfo = bfd_getb32(ext); + int lmagic = linfo & 0xffff; + int bmagic = binfo & 0xffff; + int lmagic_ok = lmagic == OMAGIC || lmagic == NMAGIC || + lmagic == ZMAGIC || lmagic == QMAGIC; + int bmagic_ok = bmagic == OMAGIC || bmagic == NMAGIC || + bmagic == ZMAGIC || bmagic == QMAGIC; + + return bmagic_ok && !lmagic_ok ? binfo : linfo; +} + /* Write an object file. Section contents have already been written. We write the file header, symbols, and relocation. */ static boolean -MY(write_object_contents) (abfd) +freebsd_write_object_contents(abfd) bfd *abfd; { struct external_exec exec_bytes; diff --git a/contrib/binutils/gas/config/tc-i386.h b/contrib/binutils/gas/config/tc-i386.h index 8205f532054e..139ccc744943 100644 --- a/contrib/binutils/gas/config/tc-i386.h +++ b/contrib/binutils/gas/config/tc-i386.h @@ -69,6 +69,9 @@ extern int tc_i386_fix_adjustable PARAMS ((struct fix *)); #define TARGET_ARCH bfd_arch_i386 #ifdef OBJ_AOUT +#ifdef TE_FreeBSD +#define TARGET_FORMAT "a.out-i386-freebsd" +#endif #ifdef TE_NetBSD #define TARGET_FORMAT "a.out-i386-netbsd" #endif diff --git a/contrib/binutils/gas/config/te-freebsd.h b/contrib/binutils/gas/config/te-freebsd.h new file mode 100644 index 000000000000..13142359dcd7 --- /dev/null +++ b/contrib/binutils/gas/config/te-freebsd.h @@ -0,0 +1,8 @@ +/* + * Target environment for FreeBSD. It is the same as the generic + * target, except it arranges to suppress the use of "/" as a comment + * character. Some code in the FreeBSD kernel uses "/" to mean + * division. (What a concept.) + */ +#define TE_FreeBSD 1 +#include "te-generic.h" diff --git a/contrib/binutils/gas/configure b/contrib/binutils/gas/configure index b188f4f9d443..661cea9f6da3 100755 --- a/contrib/binutils/gas/configure +++ b/contrib/binutils/gas/configure @@ -817,8 +817,10 @@ for this_target in $target $canon_targets ; do i386-*-linux*) fmt=elf em=linux ;; i386-*-lynxos*) fmt=coff targ=i386coff em=lynx ;; - i386-*-sysv4* | i386-*-solaris* | i386-*-elf | i386-*-freebsdelf*) + i386-*-sysv4* | i386-*-solaris* | i386-*-elf) fmt=elf ;; + i386-*-freebsdelf*) fmt=elf em=freebsd ;; + i386-*-freebsd*) fmt=aout em=freebsd bfd_gas=yes ;; i386-*-sco*elf*) fmt=elf targ=sco5 ;; i386-*-coff | i386-*-sysv* | i386-*-sco* | i386-*-isc*) fmt=coff targ=i386coff ;; diff --git a/contrib/binutils/gas/configure.in b/contrib/binutils/gas/configure.in index 81e12092cbbb..9431028aa536 100644 --- a/contrib/binutils/gas/configure.in +++ b/contrib/binutils/gas/configure.in @@ -160,8 +160,10 @@ changequote([,])dnl i386-*-linux*) fmt=elf em=linux ;; i386-*-lynxos*) fmt=coff targ=i386coff em=lynx ;; - i386-*-sysv4* | i386-*-solaris* | i386-*-elf | i386-*-freebsdelf*) + i386-*-sysv4* | i386-*-solaris* | i386-*-elf) fmt=elf ;; + i386-*-freebsdelf*) fmt=elf em=freebsd ;; + i386-*-freebsd*) fmt=aout em=freebsd bfd_gas=yes ;; i386-*-sco*elf*) fmt=elf targ=sco5 ;; i386-*-coff | i386-*-sysv* | i386-*-sco* | i386-*-isc*) fmt=coff targ=i386coff ;; diff --git a/contrib/binutils/ld/Makefile.in b/contrib/binutils/ld/Makefile.in index d32720664b7b..f6f2b2c5d595 100644 --- a/contrib/binutils/ld/Makefile.in +++ b/contrib/binutils/ld/Makefile.in @@ -235,6 +235,7 @@ ALL_EMULATIONS = \ ei386aout.o \ ei386bsd.o \ ei386coff.o \ + ei386freebsd.o \ ei386go32.o \ ei386linux.o \ ei386lynx.o \ @@ -480,6 +481,9 @@ ei386bsd.c: $(srcdir)/emulparams/i386bsd.sh \ ei386coff.c: $(srcdir)/emulparams/i386coff.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386coff.sc ${GEN_DEPENDS} ${GENSCRIPTS} i386coff "$(tdir_i386coff)" +ei386freebsd.c: $(srcdir)/emulparams/i386freebsd.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} + ${GENSCRIPTS} i386freebsd "$(tdir_i386freebsd)" ei386go32.c: $(srcdir)/emulparams/i386go32.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386go32.sc ${GEN_DEPENDS} ${GENSCRIPTS} i386go32 "$(tdir_i386go32)" diff --git a/contrib/binutils/ld/configure.tgt b/contrib/binutils/ld/configure.tgt index 9539e1feb6e0..3ea65fa3c377 100644 --- a/contrib/binutils/ld/configure.tgt +++ b/contrib/binutils/ld/configure.tgt @@ -77,6 +77,7 @@ i[3456]86-*-netbsd*) targ_emul=i386nbsd ;; i[3456]86-*-netware) targ_emul=i386nw ;; i[3456]86-*-elf*) targ_emul=elf_i386 ;; i[3456]86-*-freebsdelf*) targ_emul=elf_i386 ;; +i[3456]86-*-freebsd*) targ_emul=i386freebsd ;; i[3456]86-*-sysv*) targ_emul=i386coff ;; i[3456]86-*-ptx*) targ_emul=i386coff ;; i[3456]86-*-mach*) targ_emul=i386mach ;; diff --git a/contrib/binutils/ld/emulparams/i386freebsd.sh b/contrib/binutils/ld/emulparams/i386freebsd.sh new file mode 100644 index 000000000000..0d5e9ff9bd4d --- /dev/null +++ b/contrib/binutils/ld/emulparams/i386freebsd.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=aout +TEXT_START_ADDR=0x1020 +OUTPUT_FORMAT="a.out-i386-freebsd" +TARGET_PAGE_SIZE=0x1000 +ARCH=i386 +EXECUTABLE_SYMBOLS='__DYNAMIC = 0;'