--- binutils-2.22.51.0.1/bfd/acinclude.m4.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/acinclude.m4 2012-01-13 20:48:18.063307545 +0100 @@ -5,7 +5,7 @@ AC_DEFUN([BFD_BINARY_FOPEN], [AC_REQUIRE([AC_CANONICAL_TARGET]) case "${host}" in changequote(,)dnl -*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) +*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows* | *-*-mint*) changequote([,])dnl AC_DEFINE(USE_BINARY_FOPEN, 1, [Use b modifier when opening binary files?]) ;; esac])dnl --- binutils-2.22.51.0.1/bfd/aoutx.h.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/aoutx.h 2012-01-13 20:48:18.063307545 +0100 @@ -1841,6 +1841,11 @@ emit_stringtab (bfd *abfd, struct bfd_st bfd_byte buffer[BYTES_IN_WORD]; bfd_size_type amt = BYTES_IN_WORD; + /* The MiNT backend writes past the string table. It therefore has to + know about the table size. */ + obj_aout_external_string_size (abfd) = _bfd_stringtab_size (tab) + + BYTES_IN_WORD; + /* The string table starts with the size. */ PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer); if (bfd_bwrite ((void *) buffer, amt, abfd) != amt) @@ -4221,10 +4226,17 @@ aout_link_input_section_std (struct aout return FALSE; } +#ifdef MY_final_link_relocate_rel + r = MY_final_link_relocate_rel (howto, + input_bfd, input_section, + contents, r_addr, relocation, + (bfd_vma) 0, rel); +#else r = MY_final_link_relocate (howto, input_bfd, input_section, contents, r_addr, relocation, (bfd_vma) 0); +#endif } if (r != bfd_reloc_ok) --- binutils-2.22.51.0.1/bfd/bfd-in2.h.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/bfd-in2.h 2012-01-13 20:48:18.063307545 +0100 @@ -752,6 +752,15 @@ extern bfd_boolean bfd_m68klinux_size_dy extern bfd_boolean bfd_sparclinux_size_dynamic_sections (bfd *, struct bfd_link_info *); +/* MiNT executable support routines for the linker. */ + +extern bfd_boolean bfd_m68kmint_set_extended_flags + (bfd *, flagword); +extern bfd_boolean bfd_m68kmint_set_stack_size + (bfd *, bfd_signed_vma); +extern bfd_boolean bfd_m68kmint_add_tpa_relocation_entry + (bfd *, bfd_vma); + /* mmap hacks */ struct _bfd_window_internal; --- binutils-2.22.51.0.1/bfd/bfd-in.h.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/bfd-in.h 2012-01-13 20:48:18.063307545 +0100 @@ -745,6 +745,15 @@ extern bfd_boolean bfd_m68klinux_size_dy extern bfd_boolean bfd_sparclinux_size_dynamic_sections (bfd *, struct bfd_link_info *); +/* MiNT executable support routines for the linker. */ + +extern bfd_boolean bfd_m68kmint_set_extended_flags + (bfd *, flagword); +extern bfd_boolean bfd_m68kmint_set_stack_size + (bfd *, bfd_signed_vma); +extern bfd_boolean bfd_m68kmint_add_tpa_relocation_entry + (bfd *, bfd_vma); + /* mmap hacks */ struct _bfd_window_internal; --- binutils-2.22.51.0.1/bfd/config.bfd.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/config.bfd 2012-01-13 20:48:18.066640878 +0100 @@ -802,6 +802,11 @@ case "${targ}" in # targ_selvecs=m68kmach3_vec # targ_cflags=-DSTAT_FOR_EXEC ;; + m68*-*-mint*) + targ_defvec=aout0_big_vec + targ_selvecs=m68kmint_prg_vec + targ_underscore=yes + ;; m68*-hp*-netbsd*) targ_defvec=m68k4knetbsd_vec targ_selvecs="m68knetbsd_vec hp300bsd_vec sunos_big_vec" --- binutils-2.22.51.0.1/bfd/configure.in.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/configure.in 2012-01-13 20:48:18.069974212 +0100 @@ -895,6 +895,7 @@ do m68kcoff_vec) tb="$tb coff-m68k.lo cofflink.lo" ;; m68kcoffun_vec) tb="$tb coff-u68k.lo coff-m68k.lo cofflink.lo" ;; m68klinux_vec) tb="$tb m68klinux.lo aout32.lo" ;; + m68kmint_prg_vec) tb="$tb prg-mint.lo aout32.lo" ;; m68knetbsd_vec) tb="$tb m68knetbsd.lo aout32.lo" ;; m68ksysvcoff_vec) tb="$tb coff-svm68k.lo cofflink.lo" ;; m88kbcs_vec) tb="$tb coff-m88k.lo" ;; --- binutils-2.22.51.0.1/bfd/configure.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/configure 2012-01-13 20:48:18.069974212 +0100 @@ -13623,7 +13623,7 @@ _ACEOF case "${host}" in -*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) +*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows* | *-*-mint*) $as_echo "#define USE_BINARY_FOPEN 1" >>confdefs.h ;; @@ -15396,6 +15396,7 @@ do m68kcoff_vec) tb="$tb coff-m68k.lo cofflink.lo" ;; m68kcoffun_vec) tb="$tb coff-u68k.lo coff-m68k.lo cofflink.lo" ;; m68klinux_vec) tb="$tb m68klinux.lo aout32.lo" ;; + m68kmint_prg_vec) tb="$tb prg-mint.lo aout32.lo" ;; m68knetbsd_vec) tb="$tb m68knetbsd.lo aout32.lo" ;; m68ksysvcoff_vec) tb="$tb coff-svm68k.lo cofflink.lo" ;; m88kbcs_vec) tb="$tb coff-m88k.lo" ;; --- binutils-2.22.51.0.1/bfd/libaout.h.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/libaout.h 2012-01-13 20:48:18.069974212 +0100 @@ -422,6 +422,10 @@ struct aoutdata table, used when linking on SunOS. This is indexed by the symbol index. */ bfd_vma *local_got_offsets; + + /* A pointer for data used by aout extensions. (Currently only used + by MiNT executables (see prg-mint.c). */ + void *ext; }; struct aout_data_struct @@ -449,6 +453,7 @@ struct aout_data_struct #define obj_aout_string_window(bfd) (adata (bfd).string_window) #define obj_aout_sym_hashes(bfd) (adata (bfd).sym_hashes) #define obj_aout_dynamic_info(bfd) (adata (bfd).dynamic_info) +#define obj_aout_ext(bfd) (adata (bfd).ext) /* We take the address of the first element of an asymbol to ensure that the macro is only ever applied to an asymbol. */ --- binutils-2.22.51.0.1/bfd/Makefile.am.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/Makefile.am 2012-01-13 20:48:18.059974212 +0100 @@ -394,6 +394,7 @@ BFD32_BACKENDS = \ peigen.lo \ plugin.lo \ ppcboot.lo \ + prg-mint.lo \ reloc16.lo \ riscix.lo \ som.lo \ @@ -579,6 +580,7 @@ BFD32_BACKENDS_CFILES = \ pei-sh.c \ plugin.c \ ppcboot.c \ + prg-mint.c \ reloc16.c \ riscix.c \ som.c \ --- binutils-2.22.51.0.1/bfd/Makefile.in.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/Makefile.in 2012-01-13 20:48:18.063307545 +0100 @@ -694,6 +694,7 @@ BFD32_BACKENDS = \ peigen.lo \ plugin.lo \ ppcboot.lo \ + prg-mint.lo \ reloc16.lo \ riscix.lo \ som.lo \ @@ -879,6 +880,7 @@ BFD32_BACKENDS_CFILES = \ pei-sh.c \ plugin.c \ ppcboot.c \ + prg-mint.c \ reloc16.c \ riscix.c \ som.c \ --- binutils-2.22.51.0.1/bfd/prg-mint.c.mint~ 2012-01-13 20:48:18.073307545 +0100 +++ binutils-2.22.51.0.1/bfd/prg-mint.c 2012-01-13 20:48:18.073307545 +0100 @@ -0,0 +1,1732 @@ +/* BFD backend for traditional MiNT executables. + Copyright 1998, 2007, 2008, 2009 Free Software Foundation, Inc. + Originally written by Guido Flohr (guido@freemint.de). + Modified by Vincent Riviere (vincent.riviere@freesbee.fr). + + 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 3 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., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* The format of executables on Atari is actually not a.out, it is + only chosen as an approach which comes close enough. The layout of a + program image on disk looked like this: + + +-----------------+ + | 28 Bytes Header | + +-----------------+ + | Text segment | + +-----------------+ + | Data segment | + +-----------------+ + | BSS | + +-----------------+ + | Symbol table | + +-----------------+ + | TPA relocation | + +-----------------+ + + The 28 byte exec header used to look like this: + + struct old_exec_header + { + bfd_byte a_magic[2]; + bfd_byte a_text[4]; + bfd_byte a_data[4]; + bfd_byte a_bss[4]; + bfd_byte a_syms[4]; + bfd_byte a_resvd[4]; + bfd_byte a_abs[2]; + }; + + The first two bytes (A_MAGIC) contained an assembler branch + instruction to the beginning of the text segment. Because the + exec header had a fixed size and the text entry point was constant + this assembler instruction also had a constant value (0x601a). + In fact the operating system never really executed the branch + instruction but used this value (0x601a) as a magic value. + + TEXT, DATA and BSS were as one would expect them. The symbol + table wasn't. Several different formats were in use, none of them + very efficient, none of them powerful enough to support source + level debugging. I've changed that and the GNU symbol table will + now be used instead (unless the --traditional-format option was + given to the linker). + + If the last member A_ABS of the exec header is zero the program + image contains an additional table with relocation information + at the end of the image. The kernel can load program images at + virtually any address in the address space. In fact it will load + it at the start of the biggest block of free memory. This block + is then called the Transient Program Area TPA and the image has + to be relocated against the TPA at runtime. The relocation info + itself is in a simply way compressed: It starts with a four-byte + value, the first address within the image to be relocated. Now + following are one-byte offsets to the last address. The special + value of 1 (which is impossible as an offset) signifies that 254 + has to be added to the next offset. The table is finished with + a zero-byte. + + I now simply extended the header from its old 28 bytes to 256 + bytes. The first 28 bytes give home to a standard Atari header, + the rest is for extensions. The extension header starts with + a ``real'' assembler instruction, a far jump to the text entry + point. The extension header gives home to a standard a.out + exec header (currently NMAGIC) plus some extra + more or less useful fields plus space to future extensions. + For the OS the extension header will already belong to the text + segment, for BFD backends the text segment is 228 (or 0xe4) + bytes smaller than for the OS. This explains for example the + funny TEXT_START_ADDR 0xe4. + + The TARGET_PAGE_SIZE is 2 which is only fake. There is currently + no such thing as memory paging on the Atari (and this is why + ZMAGICs are disabled for now to allow for future enhancements). + + If you think that this whole file looks quite like a big hack + you're probably right. But the results (mainly the output of + the linker) seem to work and they allow to use up-to-date + binutils on the Atari until a better executable format (maybe + ELF) has been established for this machine. */ + +#include "sysdep.h" +#include "bfd.h" + +#define N_HEADER_IN_TEXT(x) 0 +#define BYTES_IN_WORD 4 +#define ENTRY_CAN_BE_ZERO +#define N_SHARED_LIB(x) 0 +#define TEXT_START_ADDR 0xe4 +#define TARGET_PAGE_SIZE 2 +#define TARGET_IS_BIG_ENDIAN_P +#define DEFAULT_ARCH bfd_arch_m68k +#define N_TXTADDR(x) TEXT_START_ADDR + +/* Do not "beautify" the CONCAT* macro args. Traditional C will not + remove whitespace added here, and thus will fail to concatenate + the tokens. */ +#define MY(OP) CONCAT2 (m68kmint_prg_,OP) +#define TARGETNAME "a.out-mintprg" +#define NAME(x,y) CONCAT3 (mintprg,_32_,y) + +/* We have to do quite a lot of magic to make the Atari format + for GEMDOS executables fit into the standard a.out format. + We start with the original header. */ +#define external_exec mint_external_exec +struct mint_external_exec +{ + bfd_byte g_branch[2]; /* 0x601a. */ + bfd_byte g_text[4]; /* Length of text section. */ + bfd_byte g_data[4]; /* Length of data section. */ + bfd_byte g_bss[4]; /* Length of bss section. */ + bfd_byte g_syms[4]; /* Length of symbol table. */ + bfd_byte g_extmagic[4]; /* Always 0x4d694e54 + (in ASCII: ``MiNT''). */ + bfd_byte g_flags[4]; /* Atari special flags. */ + bfd_byte g_abs[2]; /* Non-zero if absolute (no relocation + info. */ + + /* We extend this header now to provide the information that the + binutils want to see. Everything following will actually be part + of the text segment (from MiNT's point of view). As a + consequence the text section has 228 bytes of redundancy. + + The following eight bytes should be treated as opaque. + If the word ``opaque'' always attracts your curiosity in + typedefs and structs, here's the explanation: These eight bytes + are really two assembler instructions. The first one moves + the contents of e_entry into register d0, the second one + jumps (pc-relative) to the entry point. See swap_exec_header_out + for details. */ + bfd_byte g_jump_entry[8]; + + /* Now following a standard a.out header. Note that the values + may differ from the one given on top. The traditional header + contains the values that the OS wants to see, the values below + are the values that make the binutils work. */ + bfd_byte e_info[4]; /* Magic number and stuff. */ + bfd_byte e_text[4]; /* Length of text section in bytes. */ + bfd_byte e_data[4]; /* Length of data section. */ + bfd_byte e_bss[4]; /* Length of standard symbol + table. */ + bfd_byte e_syms[4]; /* Length of symbol table. */ + bfd_byte e_entry[4]; /* Start address. */ + bfd_byte e_trsize[4]; /* Length of text relocation + info. */ + bfd_byte e_drsize[4]; /* Length of data relocation + info. */ + + bfd_byte g_tparel_pos[4]; /* File position of TPA relative + relocation info. */ + bfd_byte g_tparel_size[4]; /* Length of TPA relative relocation + info. */ + + /* This is for extensions. */ + bfd_byte g_stkpos[4]; /* If stacksize is hardcoded into + the executable you will find it + at file offset g_stkpos. If + not this is NULL. */ + + bfd_byte g_symbol_format[4]; /* Format of the symbol table. See + definitions for _MINT_SYMBOL_FORMAT* + above. */ + + /* Pad with zeros. */ + bfd_byte g_pad0[172]; +}; +#define EXEC_BYTES_SIZE 256 +#define GEMDOS_HEADER_SIZE 28 + +/* The following defines are required by aoutx.h. + They are not automatically defined in aout/aout64.h + if external_exec is defined. */ + +#define OMAGIC 0407 /* Object file or impure executable. */ +#define NMAGIC 0410 /* Code indicating pure executable. */ +#define ZMAGIC 0413 /* Code indicating demand-paged executable. */ +#define BMAGIC 0415 /* Used by a b.out object. */ +#define QMAGIC 0314 /* Like ZMAGIC but with N_HEADER_IN_TEXT true. */ + +/* Files using the following magic flags will not be loaded. */ +#define N_BADMAG(x) (N_MAGIC(x) != NMAGIC) + +/* For DRI symbol table format. */ +struct dri_symbol +{ + bfd_byte a_name[8]; /* Symbol name */ + bfd_byte a_type[2]; /* Type flag, i.e. A_TEXT etc; see below. */ + bfd_byte a_value[4]; /* value of this symbol (or sdb offset). */ +}; +#define DRI_SYMBOL_SIZE 14 + +/* Simple values for a_type. */ +#define A_UNDF 0 +#define A_BSS 0x0100 +#define A_TEXT 0x0200 +#define A_DATA 0x0400 +#define A_EXT 0x0800 /* External. */ +#define A_EQREG 0x1000 /* Equated register. */ +#define A_GLOBL 0x2000 /* Global. */ +#define A_EQU 0x4000 /* Equated. */ +#define A_DEF 0x8000 /* Defined. */ +#define A_LNAM 0x0048 /* GST compatible long name. */ + /* File symbols ala aln. */ +#define A_TFILE 0x0280 /* Text file corresponding to object module. */ +#define A_TFARC 0x02C0 /* Text file archive. Unfortunately this + conflicts with the bits in A_LNAM. */ + +/* The following include contains the definitions for internal a.out structures + as well as the prototypes for the NAME(...) functions defined in aoutx.h. */ + +#include "libaout.h" + +/* The following function is similar to _bfd_final_link_relocate, except it + adds the reloc structure as an additional parameter. + It will be used int aoutx.h. */ + +static bfd_reloc_status_type +m68kmint_prg_final_link_relocate_rel (reloc_howto_type *howto, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + bfd_vma address, + bfd_vma value, + bfd_vma addend, + struct reloc_std_external *rel); + +#define MY_final_link_relocate_rel m68kmint_prg_final_link_relocate_rel + +/* The following include contains the definitions for the NAME(...) functions. */ + +#include "aoutx.h" + +/* Data structure that holds some private information for us. */ +struct mint_internal_info +{ + struct bfd_link_info *linkinfo; /* Remembered from final_link. */ + bfd_boolean traditional_format; /* Saved from link info. */ + int symbol_format; /* Format of the symbol table. */ + void *tparel; /* Data for TPA relative relocation + information. */ + file_ptr tparel_pos; /* File position of TPA relative + relocation information. */ + bfd_size_type tparel_size; /* Size of TPA relative relocation + information. */ + bfd_size_type dri_symtab_size; /* Size of traditional symbol table. */ + +#define MINT_RELOC_CHUNKSIZE 0x1000 + bfd_vma *relocs; /* Array of address relocations. */ + unsigned long relocs_used; /* Number of relocation entries + already used up. */ + unsigned long relocs_allocated; /* Number of relocation entries + allocated. */ + + bfd_vma stkpos; /* File offset to value of _stksize. */ + + flagword prg_flags; /* Standard GEMDOS flags. */ + + bfd_boolean override_stack_size; /* TRUE if the executable stack size + must be overriden with stack_size. */ + bfd_signed_vma stack_size; + + bfd_boolean reloc_error; /* TRUE if an unhandled error during + relocation occured. */ +}; + +/* If --traditional-format was given to the linker an old-style DRI + symbol table is written into the executable. This is with respect + to many old debugging tools or disassemblers which expect this format. + Although created by the linker, these symbols will be ignored from + input files. */ +#define _MINT_SYMBOL_FORMAT_GNU 0 +#define _MINT_SYMBOL_FORMAT_DRI 1 + +/* Declarations for the variables and functions + defined later in aout-target.h. */ + +static const bfd_target * +m68kmint_prg_callback (bfd *abfd); + +static void +MY_final_link_callback (bfd *abfd, + file_ptr *ptreloff, + file_ptr *pdreloff, + file_ptr *psymoff); + +extern const bfd_target m68kmint_prg_vec; + +/* Initialize a new BFD using our file format. */ + +#define MY_mkobject m68kmint_prg_mkobject + +static bfd_boolean +m68kmint_prg_mkobject (bfd *abfd) +{ + struct mint_internal_info *myinfo; + + if (!NAME (aout, mkobject (abfd))) + return FALSE; + + /* Allocate our private BFD data. */ + myinfo = bfd_zalloc (abfd, sizeof (*myinfo)); + if (myinfo == NULL) + return FALSE; + obj_aout_ext (abfd) = myinfo; + + return TRUE; +} + +/* Finish up the reading of an a.out file header. */ + +#define MY_object_p m68kmint_prg_object_p + +static const bfd_target * +m68kmint_prg_object_p (bfd *abfd) +{ + struct external_exec exec_bytes; /* Raw exec header from file. */ + struct internal_exec exec; /* Cleaned-up exec header. */ + const bfd_target *target; + bfd_size_type amt = EXEC_BYTES_SIZE; + struct mint_internal_info *myinfo; + + /* Read the exec bytesd from the file. */ + if (bfd_bread (&exec_bytes, amt, abfd) != amt) + { + if (bfd_get_error () != bfd_error_system_call) + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + /* Instead of byte-swapping we compare bytes. */ + if (exec_bytes.g_branch[0] != 0x60 + || exec_bytes.g_branch[1] != 0x1a + || exec_bytes.g_extmagic[0] != 'M' + || exec_bytes.g_extmagic[1] != 'i' + || exec_bytes.g_extmagic[2] != 'N' + || exec_bytes.g_extmagic[3] != 'T') + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + /* Swap the standard a.out fields. */ + NAME (aout, swap_exec_header_in) (abfd, &exec_bytes, &exec); + + /* Check a.out magic value. */ + if (N_BADMAG (exec)) + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + /* Initialize this BFD with the exec values. */ + target = NAME (aout, some_aout_object_p) (abfd, &exec, m68kmint_prg_callback); + + /* Allocate our private BFD data. */ + myinfo = bfd_zalloc (abfd, sizeof (*myinfo)); + if (myinfo == NULL) + return NULL; + obj_aout_ext (abfd) = myinfo; + + /* Now get the missing information. */ + myinfo->prg_flags = bfd_h_get_32 (abfd, exec_bytes.g_flags); + myinfo->stkpos = bfd_h_get_32 (abfd, exec_bytes.g_stkpos); + myinfo->symbol_format = bfd_h_get_32 (abfd, exec_bytes.g_symbol_format); + + /* TPA relocation information. */ + myinfo->tparel_pos = bfd_h_get_32 (abfd, exec_bytes.g_tparel_pos); + myinfo->tparel_size = bfd_h_get_32 (abfd, exec_bytes.g_tparel_size); + + /* FIXME: Currently we always read the TPA relative relocation + information. This is suboptimal because often times there + is no need for it. Read it only if need be! Maybe this should + also depend on abfd->cacheable? */ + if (myinfo->tparel_size == 0) + myinfo->tparel = bfd_zalloc (abfd, 4); + else + myinfo->tparel = bfd_alloc (abfd, myinfo->tparel_size); + + if (myinfo->tparel == NULL) + return NULL; + + if (myinfo->tparel_size == 0) + { + myinfo->tparel_size = 4; + } + else + { + /* Read the information from the bfd. */ + if (bfd_seek (abfd, myinfo->tparel_pos, SEEK_SET) != 0 + || (bfd_bread (myinfo->tparel, myinfo->tparel_size, abfd) + != myinfo->tparel_size)) + return NULL; + } + + return target; +} + +/* Free all information we have cached for this BFD. We can always + read it again later if we need it. */ + +#define MY_bfd_free_cached_info m68kmint_prg_bfd_free_cached_info + +static bfd_boolean +m68kmint_prg_bfd_free_cached_info (bfd *abfd) +{ + struct mint_internal_info *myinfo = obj_aout_ext (abfd); + + if (myinfo != NULL && myinfo->relocs != NULL) + { + free (myinfo->relocs); + myinfo->relocs = NULL; + } + + /* myinfo itself has been allocated by bfd_zalloc() + so will be automatically freed along with the BFD. + Same for myinfo->tparel. */ + + return NAME (aout, bfd_free_cached_info) (abfd); +} + +/* Write a DRI symbol with TYPE and VALUE. If the NAME of the + symbol exceeds 8 characters write a long symbol. If it + exceeds 22 characters truncate the name. */ + +static int +write_dri_symbol (bfd *abfd, const char *name, int type, bfd_vma value) +{ + int written_bytes = 0; + struct dri_symbol sym; + int is_long_name = strlen (name) > sizeof (sym.a_name); + + if (is_long_name) + type |= A_LNAM; + + strncpy ((char*)sym.a_name, name, sizeof (sym.a_name)); + bfd_put_16 (abfd, type, sym.a_type); + bfd_put_32 (abfd, value, sym.a_value); + + if (bfd_bwrite (&sym, DRI_SYMBOL_SIZE, abfd) != DRI_SYMBOL_SIZE) + return -1; + written_bytes += DRI_SYMBOL_SIZE; + + if (is_long_name) + { + char more_name[DRI_SYMBOL_SIZE]; + + strncpy (more_name, name + sizeof (sym.a_name), DRI_SYMBOL_SIZE); + + if (bfd_bwrite (more_name, DRI_SYMBOL_SIZE, abfd) != DRI_SYMBOL_SIZE) + return -1; + written_bytes += DRI_SYMBOL_SIZE; + } + + return written_bytes; +} + +/* Emit a traditional DRI symbol table while linking. + Most of this code comes from aout_link_write_symbols() in aoutx.h. */ + +static bfd_boolean +link_write_traditional_syms (bfd *abfd, struct bfd_link_info *info) +{ + bfd *input_bfd; + enum bfd_link_strip strip = info->strip; + enum bfd_link_discard discard = info->discard; + struct mint_internal_info *myinfo = obj_aout_ext (abfd); + bfd *last_archive = NULL; + + /* Position file pointer. */ + if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) + return FALSE; + + myinfo->dri_symtab_size = 0; + + for (input_bfd = info->input_bfds; input_bfd != NULL; input_bfd = input_bfd->link_next) + { + bfd_size_type sym_count = obj_aout_external_sym_count (input_bfd); + char *strings = obj_aout_external_strings (input_bfd); + struct external_nlist *sym = obj_aout_external_syms (input_bfd); + struct external_nlist *sym_end = sym + sym_count; + struct aout_link_hash_entry **sym_hash = obj_aout_sym_hashes (input_bfd); + bfd_boolean pass = FALSE; + bfd_boolean skip = FALSE; + bfd_boolean skip_next = FALSE; + int written_bytes; + int a_type; + bfd_boolean write_archive_name = FALSE; + bfd_vma val = 0; + + /* First write out a symbol for the archive if we do not + strip these symbols and if it differs from the last + one. */ + if (input_bfd->my_archive != last_archive + && input_bfd->my_archive != NULL) + { + write_archive_name = TRUE; + last_archive = input_bfd->my_archive; + } + + if (write_archive_name + && strip != strip_all + && (strip != strip_some + || bfd_hash_lookup (info->keep_hash, + input_bfd->my_archive->filename, + FALSE, FALSE) != NULL) + && discard != discard_all) + { + val = bfd_get_section_vma (abfd, + obj_textsec (input_bfd)->output_section) + + obj_textsec (input_bfd)->output_offset; + + written_bytes = write_dri_symbol (abfd, + input_bfd->my_archive->filename, + A_TFILE, val); + + if (written_bytes < 0) + return FALSE; + else + myinfo->dri_symtab_size += written_bytes; + } + + /* Now write out a symbol for the object file if we do not + strip these symbols. */ + if (strip != strip_all + && (strip != strip_some + || bfd_hash_lookup (info->keep_hash, input_bfd->filename, + FALSE, FALSE) != NULL) + && discard != discard_all) + { + val = bfd_get_section_vma (abfd, + obj_textsec (input_bfd)->output_section) + + obj_textsec (input_bfd)->output_offset; + + written_bytes = write_dri_symbol (abfd, input_bfd->filename, + A_TFILE, val); + if (written_bytes < 0) + return FALSE; + else + myinfo->dri_symtab_size += written_bytes; + } + + /* Now we have a problem. All symbols that we see have already + been marked written (because we write them a second time + here. If we would do it the clean way we would have + to traverse the entire symbol map and reset the written + flag. We hack here instead... */ +#define mark_written(h) (* (int *) &h->written = (int) TRUE + 1) +#define is_written(h) ((int) h->written == (int) TRUE + 1) + for (; sym < sym_end; sym++, sym_hash++) + { + const char *name; + int type; + struct aout_link_hash_entry *h; + asection *symsec; + val = 0; + + type = H_GET_8 (input_bfd, sym->e_type); + name = strings + GET_WORD (input_bfd, sym->e_strx); + + h = NULL; + + if (pass) + { + /* Pass this symbol through. It is the target of an + indirect or warning symbol. */ + val = GET_WORD (input_bfd, sym->e_value); + pass = FALSE; + } + else if (skip_next) + { + /* Skip this symbol, which is the target of an indirect + symbol that we have changed to no longer be an indirect + symbol. */ + skip_next = FALSE; + continue; + } + else + { + struct aout_link_hash_entry *hresolve = *sym_hash; + + /* We have saved the hash table entry for this symbol, if + there is one. Note that we could just look it up again + in the hash table, provided we first check that it is an + external symbol. */ + h = *sym_hash; + + /* Use the name from the hash table, in case the symbol was + wrapped. */ + if (h != NULL + && h->root.type != bfd_link_hash_warning) + name = h->root.root.string; + + /* If this is an indirect or warning symbol, then change + hresolve to the base symbol. */ + hresolve = h; + if (h != (struct aout_link_hash_entry *) NULL + && (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning)) + { + hresolve = (struct aout_link_hash_entry*) h->root.u.i.link; + while (hresolve->root.type == bfd_link_hash_indirect + || hresolve->root.type == bfd_link_hash_warning) + hresolve = ((struct aout_link_hash_entry*) + hresolve->root.u.i.link); + } + + /* If the symbol has already been written out skip it. */ + if (h != NULL + && is_written (h)) + { + if ((type & N_TYPE) == N_INDR + || type == N_WARNING) + skip_next = TRUE; + continue; + } + + /* See if we are stripping this symbol. */ + skip = FALSE; + + /* Skip all debugger symbols. No way to output them in + DRI format. This will also reduce a lot of headaches. */ + if ((type & N_STAB) != 0) + skip = TRUE; + + switch (strip) + { + case strip_none: + case strip_debugger: + break; + case strip_some: + if (bfd_hash_lookup (info->keep_hash, name, FALSE, FALSE) + == NULL) + skip = TRUE; + break; + case strip_all: + skip = TRUE; + break; + } + + if (skip) + { + if (h != NULL) + mark_written (h); + continue; + } + + /* Get the value of the symbol. */ + if ((type & N_TYPE) == N_TEXT + || type == N_WEAKT) + symsec = obj_textsec (input_bfd); + else if ((type & N_TYPE) == N_DATA + || type == N_WEAKD) + symsec = obj_datasec (input_bfd); + else if ((type & N_TYPE) == N_BSS + || type == N_WEAKB) + symsec = obj_bsssec (input_bfd); + else if ((type & N_TYPE) == N_ABS + || type == N_WEAKA) + symsec = bfd_abs_section_ptr; + else if (((type & N_TYPE) == N_INDR + && (hresolve == NULL + || (hresolve->root.type != bfd_link_hash_defined + && hresolve->root.type != bfd_link_hash_defweak + && hresolve->root.type != bfd_link_hash_common))) + || type == N_WARNING) + { + /* Pass the next symbol through unchanged. The + condition above for indirect symbols is so that if + the indirect symbol was defined, we output it with + the correct definition so the debugger will + understand it. */ + pass = TRUE; + val = GET_WORD (input_bfd, sym->e_value); + symsec = NULL; + } + else + { + /* If we get here with an indirect symbol, it means that + we are outputting it with a real definition. In such + a case we do not want to output the next symbol, + which is the target of the indirection. */ + if ((type & N_TYPE) == N_INDR) + skip_next = TRUE; + + symsec = NULL; + + /* We need to get the value from the hash table. We use + hresolve so that if we have defined an indirect + symbol we output the final definition. */ + if (h == NULL) + { + switch (type & N_TYPE) + { + case N_SETT: + symsec = obj_textsec (input_bfd); + break; + case N_SETD: + symsec = obj_datasec (input_bfd); + break; + case N_SETB: + symsec = obj_bsssec (input_bfd); + break; + case N_SETA: + symsec = bfd_abs_section_ptr; + break; + default: + val = 0; + break; + } + } + else if (hresolve->root.type == bfd_link_hash_defined + || hresolve->root.type == bfd_link_hash_defweak) + { + asection *input_section; + asection *output_section; + + /* This case usually means a common symbol which was + turned into a defined symbol. */ + input_section = hresolve->root.u.def.section; + output_section = input_section->output_section; + BFD_ASSERT (bfd_is_abs_section (output_section) + || output_section->owner == abfd); + + /* The following reference to the output section VMA + is commented out because DRI symbols are relative + to the beginning of the section. */ + val = (hresolve->root.u.def.value + /*+ bfd_get_section_vma (abfd, output_section)*/ + + input_section->output_offset); + + /* TEXT symbols values must be adjusted + by adding the size of the extended header. */ + if (output_section == obj_textsec (abfd)) + val += TEXT_START_ADDR; + + /* Get the correct type based on the section. If + this is a constructed set, force it to be + globally visible. */ + if (type == N_SETT + || type == N_SETD + || type == N_SETB + || type == N_SETA) + type |= N_EXT; + + type &=~ N_TYPE; + + if (output_section == obj_textsec (abfd)) + type |= N_TEXT; + else if (output_section == obj_datasec (abfd)) + type |= N_DATA; + else if (output_section == obj_bsssec (abfd)) + type |= N_BSS; + else + type |= N_ABS; + } + else if (hresolve->root.type == bfd_link_hash_common) + val = hresolve->root.u.c.size; + else if (hresolve->root.type == bfd_link_hash_undefweak) + { + val = 0; + type = N_UNDF; + } + else + val = 0; + } + if (symsec != NULL) + { + /* The following reference to the output section VMA + is commented out because DRI symbols are relative + to the beginning of the section. */ + val = (/*symsec->output_section->vma + +*/ symsec->output_offset + + (GET_WORD (input_bfd, sym->e_value) + - symsec->vma)); + + /* TEXT symbols values must be adjusted + by adding the size of the extended header. */ + if (symsec == obj_textsec (input_bfd)) + val += TEXT_START_ADDR; + } + + /* If this is a global symbol set the written flag, and if + it is a local symbol see if we should discard it. */ + if (h != NULL) + { + mark_written (h); + } + else if ((type & N_TYPE) != N_SETT + && (type & N_TYPE) != N_SETD + && (type & N_TYPE) != N_SETB + && (type & N_TYPE) != N_SETA) + { + switch (discard) + { + case discard_none: + case discard_sec_merge: + break; + case discard_l: + if (bfd_is_local_label_name (input_bfd, name)) + skip = TRUE; + break; + default: + case discard_all: + skip = TRUE; + break; + } + if (skip) + { + pass = FALSE; + continue; + } + } + } + + /* Now find the nearest type in DRI format. */ + switch (type) + { + case N_ABS: + case N_ABS | N_EXT: + case N_SETA: + case N_SETA | N_EXT: + case N_WEAKA: + a_type = A_EQU | A_DEF | A_GLOBL; + break; + case N_TEXT: + case N_TEXT | N_EXT: + case N_SETT: + case N_SETT | N_EXT: + case N_WEAKT: + a_type = A_TEXT | A_DEF | A_GLOBL; + break; + case N_DATA: + case N_DATA | N_EXT: + case N_SETD: + case N_SETD | N_EXT: + case N_WEAKD: + a_type = A_DATA | A_DEF | A_GLOBL; + break; + case N_BSS: + case N_BSS | N_EXT: + case N_SETB: + case N_SETB | N_EXT: + case N_WEAKB: + a_type = A_BSS | A_DEF | A_GLOBL; + break; + default: + continue; + } + + written_bytes = write_dri_symbol (abfd, name, a_type, val); + if (written_bytes < 0) + return FALSE; + + myinfo->dri_symtab_size += written_bytes; + } + } + + obj_aout_external_string_size (abfd) = 0; + return TRUE; +} + +/* This is used for qsort() to sort addresses + for the TPA relocation table. */ + +static int +vma_cmp (const void *v1, const void *v2) +{ + return (int) ((*((bfd_vma *) v1)) - (*((bfd_vma *) v2))); +} + +/* Alloc and fill the TPA relocation table. */ + +static bfd_boolean +fill_tparel (bfd *abfd) +{ + struct mint_internal_info *myinfo = obj_aout_ext (abfd); + unsigned long i; + bfd_size_type bytes; + unsigned char *ptr; + + /* Sort the relocation info. */ + if (myinfo->relocs != NULL) + qsort (myinfo->relocs, myinfo->relocs_used, sizeof (bfd_vma), + vma_cmp); + + /* Now calculate the number of bytes we need. The relocation info + is encoded as follows: The first entry is a 32-bit value + denoting the first offset to relocate. All following entries + are relative to the preceding one. For relative offsets of + more than 254 bytes a value of 1 is used. The OS will then + add 254 bytes to the current offset. The list is then terminated + with the byte 0. */ + bytes = 4; /* First entry is a long. */ + for (i = 1; i < myinfo->relocs_used; i++) + { + unsigned long diff = myinfo->relocs[i] - myinfo->relocs[i - 1]; + BFD_ASSERT(diff > 0); + bytes += (diff + 253) / 254; + } + /* Last entry is (bfd_byte) 0 if there are some relocations. */ + if (myinfo->relocs_used > 0) + bytes++; + + myinfo->tparel_size = bytes; + myinfo->tparel = bfd_alloc (abfd, bytes); + if (myinfo->tparel == NULL) + return FALSE; + + /* Now fill the array. */ + ptr = (bfd_byte*) myinfo->tparel; + if (myinfo->relocs != NULL) + bfd_put_32 (abfd, myinfo->relocs[0], ptr); + else + bfd_put_32 (abfd, 0, ptr); + ptr += 4; + + for (i = 1; i < myinfo->relocs_used; i++) + { + unsigned long diff = myinfo->relocs[i] - myinfo->relocs[i - 1]; + while (diff > 254) + { + *ptr++ = 1; + diff -= 254; + } + *ptr++ = (bfd_byte) diff; + } + + if (myinfo->relocs_used > 0) + *ptr = 0; + + return TRUE; +} + +/* Final link routine. We need to use a call back to get the correct + offsets in the output file. And we need to malloc some internal + buffers. */ + +#define MY_bfd_final_link m68kmint_prg_bfd_final_link + +static bfd_boolean +m68kmint_prg_bfd_final_link (bfd *abfd, struct bfd_link_info *info) +{ + struct mint_internal_info *myinfo = obj_aout_ext (abfd); + struct bfd_link_hash_table *hash = info->hash; + enum bfd_link_strip original_strip = info->strip; + + if (info->relocatable) + { + _bfd_error_handler ("%B: relocatable output is not supported by format %s", + abfd, bfd_get_target (abfd)); + bfd_set_error (bfd_error_invalid_operation); + return FALSE; + } + + myinfo->linkinfo = info; + + /* Make sure that for now we never write zmagics. */ + abfd->flags &= ~D_PAGED; + + /* Find the __stksize symbol. This symbol is used for a MiNT + special kludge. The libc defines this symbol in an object file + initialized to a default value to make sure it is defined in + every output file. The start-up code in crtinit() then simply + sets the stacksize accordingly. In your programs (if they need + an unusual stacksize) you can then simply code: + + long _stksize = 0x2000; + + This will create a program stack of 2k. Since MiNT cannot detect + a stack overflow this is the only way to prevent program crashes + caused by a stack that is too small. + + The ancient linker ignored this feature, the ancient strip + program paid heed to it. By default, strip never stripped this + special symbol from the binary. + + Another program called ``printstk'' and its colleague ``fixstk'' + could be used to either print the current value of the stacksize + or to modify it without recompiling and rebuilding. These + programs traversed the symbol table and then took the appropriate + measures if the symbol was found. + + Here we do a different approach. Since we already expanded the + standard executable header we now hardcode the address (as a file + offset) that the __stksize symbol points to into the header. We + can now let strip safely remove the entry from the symbol table + and we're not dependent on a special format of the symbol table. + Because the address is kept in the header we will always be able + to manipulate the stacksize value later. */ + if (hash != NULL) + { + struct aout_link_hash_entry *h = + aout_link_hash_lookup (aout_hash_table (info), "__stksize", + FALSE, FALSE, FALSE); + asection *sec; + + if (h != NULL) + { + switch (h->root.type) + { + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + sec = h->root.u.def.section->output_section; + BFD_ASSERT (sec->owner == abfd); + + myinfo->stkpos = (h->root.u.def.value + sec->vma + + h->root.u.def.section->output_offset + + GEMDOS_HEADER_SIZE); + break; + default: /* Ignore other types. */ + break; + } + } + } + + if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0) + { + myinfo->traditional_format = TRUE; + myinfo->symbol_format = _MINT_SYMBOL_FORMAT_DRI; + } + + /* Unconditionally unset the traditional flag. The only effect in + the a.out code is to disable string hashing (with respect to + SunOS gdx). This is not necessary for us. */ + + abfd->flags &= ~BFD_TRADITIONAL_FORMAT; + + /* Do not write GNU symbols in traditional format. */ + if (myinfo->traditional_format) + info->strip = strip_all; + + if (NAME(aout,final_link) (abfd, info, MY_final_link_callback) + != TRUE) + return FALSE; + + if (myinfo->reloc_error) + return FALSE; + + /* Restore the strip status for the traditional symbols. */ + info->strip = original_strip; + + if (myinfo->traditional_format + && link_write_traditional_syms (abfd, info) != TRUE) + return FALSE; + + if (fill_tparel (abfd) != TRUE) + return FALSE; + + return TRUE; +} + +/* Copy private BFD header information from the input BFD. */ + +#define MY_bfd_copy_private_header_data m68kmint_prg_bfd_copy_private_header_data + +static bfd_boolean +m68kmint_prg_bfd_copy_private_header_data (bfd *ibfd, bfd *obfd) +{ + (void)obfd; /* Unused. */ + + /* We can only copy BFD files using our own file format. */ + if (ibfd->xvec != &m68kmint_prg_vec) + { + _bfd_error_handler ("%B: cannot convert from format %s to format %s", + ibfd, bfd_get_target (ibfd), bfd_get_target (obfd)); + bfd_set_error (bfd_error_invalid_operation); + return FALSE; + } + + return TRUE; +} + +/* Copy backend specific data from one object module to another. + This function is used by objcopy and strip. */ + +#define MY_bfd_copy_private_bfd_data m68kmint_prg_bfd_copy_private_bfd_data + +static bfd_boolean +m68kmint_prg_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) +{ + struct mint_internal_info *myinfo_in; + struct mint_internal_info *myinfo_out; + + /* obfd uses our file format, ibfd may be foreign. */ + if (ibfd->xvec != &m68kmint_prg_vec) + return TRUE; + + myinfo_in = obj_aout_ext (ibfd); + BFD_ASSERT (myinfo_in != NULL); + + myinfo_out = obj_aout_ext (obfd); + BFD_ASSERT (myinfo_out != NULL); + + /* Copy myinfo. */ + memcpy (myinfo_out, myinfo_in, sizeof (*myinfo_out)); + + /* Copy tparel. */ + myinfo_out->tparel = bfd_alloc (obfd, myinfo_out->tparel_size); + if (myinfo_out->tparel == NULL) + return FALSE; + memcpy (myinfo_out->tparel, myinfo_in->tparel, myinfo_out->tparel_size); + + /* Normalize the type of empty symbols. */ + if (bfd_get_symcount (obfd) == 0) + myinfo_out->symbol_format = _MINT_SYMBOL_FORMAT_GNU; + + return TRUE; /* _bfd_generic_bfd_copy_private_bfd_data (ibfd, obfd); */ +} + +/* Merge private BFD information from an input BFD to the output BFD when linking. */ + +#define MY_bfd_merge_private_bfd_data m68kmint_prg_merge_private_bfd_data + +static bfd_boolean +m68kmint_prg_merge_private_bfd_data (bfd *ibfd, bfd *obfd) +{ + (void)obfd; /* Unused. */ + + /* Our file format cannot be used as linker input. */ + if (ibfd->xvec == &m68kmint_prg_vec) + { + _bfd_error_handler ("%B: file format %s cannot be used as linker input", + ibfd, bfd_get_target (ibfd)); + bfd_set_error (bfd_error_invalid_operation); + return FALSE; + } + + return TRUE; /* _bfd_generic_bfd_merge_private_bfd_data (ibfd, obfd); */ +} + +/* Find out the symbol name. */ + +static const char * +find_symbol_name (reloc_howto_type *howto, bfd *input_bfd, + bfd_byte *location, struct reloc_std_external *rel) +{ + struct external_nlist *syms = obj_aout_external_syms (input_bfd); + char *strings = obj_aout_external_strings (input_bfd); + struct aout_link_hash_entry **sym_hashes + = obj_aout_sym_hashes (input_bfd); + struct aout_link_hash_entry *h = NULL; + const char *name; + bfd_size_type r_index; + int r_extern; + + if (bfd_get_reloc_size (howto) != 4) + return "(not a symbol)"; + + /* The input bfd is always big-endian. There is no need to + call bfd_header_big_endian (input_bfd). */ + r_index = ((rel->r_index[0] << 16) + | (rel->r_index[1] << 8) + | (rel->r_index[2])); + r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); + + if (sym_hashes != NULL) + h = sym_hashes[r_index]; + + if (!r_extern) + { + bfd_size_type i; + bfd_vma wanted_value = bfd_get_32 (input_bfd, location); + + name = NULL; + for (i = 0; i < obj_aout_external_sym_count (input_bfd); i++) + { + bfd_vma this_value = bfd_get_32 (input_bfd, syms[i].e_value); + + if (this_value == wanted_value) + { + bfd_byte symtype = bfd_get_8 (input_bfd, syms[i].e_type); + + /* Skip debug symbols and the like. */ + if ((symtype & N_STAB) != 0) + continue; + + /* This is dirty but preferable to a plethoria of + single comparisons. */ + if (symtype <= (N_BSS | N_EXT) + || (symtype >= N_WEAKU && symtype <= N_COMM)) + { + name = strings + GET_WORD (input_bfd, syms[i].e_strx); + break; + } + } + } + + /* FIXME: If the relocation is against a section there is + probably a symbol for that section floating around somewhere + in the bfd jungle. */ + if (name == NULL) + { + switch ((r_index & N_TYPE) & ~N_EXT) + { + case N_TEXT: + name = "text section"; + break; + case N_DATA: + name = "data section"; + break; + case N_BSS: + name = "bss section"; + break; + case N_ABS: + name = "absolute section"; + break; + default: + name = "unknown section"; + break; + } + } + } + else if (h != NULL) + name = h->root.root.string; + else if (r_index >= obj_aout_external_sym_count (input_bfd)) + name = "(unknown symbol)"; /* Shouldn't happen. */ + else + name = strings + GET_WORD (input_bfd, syms[r_index].e_strx); + + return name; +} + +/* This relocation routine is used by some of the backend linkers. + They do not construct asymbol or arelent structures, so there is no + reason for them to use bfd_perform_relocation. Also, + bfd_perform_relocation is so hacked up it is easier to write a new + function than to try to deal with it. + + This routine does a final relocation. Whether it is useful for a + relocatable link depends upon how the object format defines + relocations. + + FIXME: This routine ignores any special_function in the HOWTO, + since the existing special_function values have been written for + bfd_perform_relocation. + + HOWTO is the reloc howto information. + INPUT_BFD is the BFD which the reloc applies to. + INPUT_SECTION is the section which the reloc applies to. + CONTENTS is the contents of the section. + ADDRESS is the address of the reloc within INPUT_SECTION. + VALUE is the value of the symbol the reloc refers to. + ADDEND is the addend of the reloc. */ + +/* The additional parameter REL is specific to this backend. + This function is derived from _bfd_final_link_relocate() + found in reloc.c. It adds additional checking for dangerous + relocations in MiNT sharable text sections, then it records + the relocated offset in myinfo->relocs[] for further processing. */ + +static bfd_reloc_status_type +m68kmint_prg_final_link_relocate_rel (reloc_howto_type *howto, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + bfd_vma address, + bfd_vma value, + bfd_vma addend, + struct reloc_std_external *rel) +{ + bfd_vma relocation; + bfd *output_bfd = input_section->output_section->owner; + struct mint_internal_info *myinfo = obj_aout_ext (output_bfd); + bfd_reloc_status_type retval; + int r_index; + int r_extern; + bfd_boolean need_tpa_relocation; + + /* The input bfd is always big-endian. There is no need to + call bfd_header_big_endian (input_bfd). */ + r_index = ((rel->r_index[0] << 16) + | (rel->r_index[1] << 8) + | (rel->r_index[2])); + r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); + +#define _MINT_F_SHTEXT 0x800 + + /* Sanity check the address. */ + if (address > bfd_get_section_limit (input_bfd, input_section)) + 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; + + /* Check for dangerous relocations in images with a sharable + text section. */ + if ((myinfo->prg_flags & _MINT_F_SHTEXT) != 0 + && bfd_get_reloc_size (howto) == 4) + { + bfd_boolean error_found = FALSE; + const char *name = NULL; + + if (input_section == obj_textsec (input_bfd)) + { + if (!r_extern) + { + /* This is a relocation against another section. Only + relocations against the text section are allowed. */ + if (r_index != N_TEXT && r_index != (N_TEXT | N_EXT)) + error_found = TRUE; + } + else if (relocation > (input_section->output_section->vma + + input_section->output_section->size)) + { + error_found = TRUE; + } + else if (relocation == (input_section->output_section->vma + + input_section->output_section->size)) + { + name = find_symbol_name (howto, input_bfd, + contents + address, + rel); + if (strcmp (name, "_etext") == 0) + error_found = FALSE; + } + } + + if (error_found) + { + const struct bfd_link_callbacks *callbacks + = myinfo->linkinfo->callbacks; + + myinfo->reloc_error = TRUE; + + if (callbacks->reloc_dangerous != NULL) + { + if (name == NULL) + name = find_symbol_name (howto, input_bfd, + contents + address, + rel); + + callbacks->reloc_dangerous (myinfo->linkinfo, name, + input_bfd, + input_section, address); + } + } + } + + /* 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; + } + + retval = _bfd_relocate_contents (howto, input_bfd, relocation, + contents + address); + + /* The symbol has to be relocated again iff the length of the relocation + is 2 words and it is not pc relative. */ + need_tpa_relocation = FALSE; + if (!howto->pc_relative && bfd_get_reloc_size (howto) == 4) + { + if (r_extern) + { + struct aout_link_hash_entry **sym_hashes = obj_aout_sym_hashes (input_bfd); + struct aout_link_hash_entry *h = sym_hashes[r_index]; + asection *output_section = h->root.u.def.section->output_section; + + /* Do not relocate absolute symbols. */ + if (output_section == obj_textsec (output_bfd) + || output_section == obj_datasec (output_bfd) + || output_section == obj_bsssec (output_bfd)) + { + need_tpa_relocation = TRUE; + } + } + else + { + need_tpa_relocation = TRUE; + } + } + + /* Here we add the TPA relocation entries for the address references + located inside the input sections. Note that if some references + to addresses are generated using data statements in the linker + script, they will not be relocated here because they do not + belong to any input section. */ + if (need_tpa_relocation) + { + bfd_vma tpa_address = input_section->output_section->vma + + input_section->output_offset + address; + + if (!bfd_m68kmint_add_tpa_relocation_entry(output_bfd, tpa_address)) + return bfd_reloc_other; + } + + return retval; +} + +/* Write out the TPA relocation table. */ + +static bfd_boolean +write_tparel (bfd *abfd, struct internal_exec *execp) +{ + struct mint_internal_info* myinfo = obj_aout_ext (abfd); + + if (myinfo->dri_symtab_size == 0) + myinfo->tparel_pos = N_STROFF (*execp) + + obj_aout_external_string_size (abfd); + else + myinfo->tparel_pos = N_SYMOFF (*execp) + + myinfo->dri_symtab_size; + + if (bfd_seek (abfd, myinfo->tparel_pos, SEEK_SET) != 0) + return FALSE; + + if (bfd_bwrite (myinfo->tparel, myinfo->tparel_size, abfd) + != myinfo->tparel_size) + return FALSE; + + return TRUE; +} + +/* Write the full exec header. + This function must be called last to ensure that we have all the + information needed to fill the MiNT-specific header fields. */ + +static bfd_boolean +write_exec_header (bfd *abfd, struct internal_exec *execp, struct external_exec *exec_bytes) +{ + struct mint_internal_info *myinfo = obj_aout_ext (abfd); + bfd_size_type symtab_size; + + bfd_h_put_16 (abfd, 0x601a, exec_bytes->g_branch); + + /* The OS will load our extension header fields into the text segment. */ + bfd_h_put_32 (abfd, execp->a_text + (EXEC_BYTES_SIZE - GEMDOS_HEADER_SIZE), + exec_bytes->g_text); + bfd_h_put_32 (abfd, execp->a_data, exec_bytes->g_data); + bfd_h_put_32 (abfd, execp->a_bss, exec_bytes->g_bss); + + /* The OS' notion of the size of the symbol table is another than + the bfd library's. We have to fill in the size of the table + itself plus the size of the string table but only if we have not written + a traditional symbol table. If we have written a traditional symbol + table we know the size. */ + if (myinfo->dri_symtab_size != 0) + symtab_size = myinfo->dri_symtab_size; + else + symtab_size = myinfo->tparel_pos - N_SYMOFF (*execp); + + bfd_h_put_32 (abfd, symtab_size, exec_bytes->g_syms); + + bfd_h_put_32 (abfd, 0x4d694e54, exec_bytes->g_extmagic); + bfd_h_put_32 (abfd, myinfo->prg_flags, exec_bytes->g_flags); + bfd_h_put_16 (abfd, 0, exec_bytes->g_abs); + + /* Generate the jump instruction to the entry point. In m68k + assembler mnemnonics it looks more or less like this: + + move.l exec_bytes->e_entry(pc),d0 + jmp -6(pc,d0.l) + + Sorry for the wrong syntax. As a real assembler addict I + never actually use an assembler. I edit my binaries manually + with a hex editor, looks much cooler and it strengthens your + abstraction abilities. */ + + exec_bytes->g_jump_entry[0] = 0x20; + exec_bytes->g_jump_entry[1] = 0x3a; + exec_bytes->g_jump_entry[2] = 0x00; + exec_bytes->g_jump_entry[3] = 0x1a; + exec_bytes->g_jump_entry[4] = 0x4e; + exec_bytes->g_jump_entry[5] = 0xfb; + exec_bytes->g_jump_entry[6] = 0x08; + exec_bytes->g_jump_entry[7] = 0xfa; + + bfd_h_put_32 (abfd, myinfo->tparel_pos, exec_bytes->g_tparel_pos); + bfd_h_put_32 (abfd, myinfo->tparel_size, exec_bytes->g_tparel_size); + bfd_h_put_32 (abfd, myinfo->stkpos, exec_bytes->g_stkpos); + + /* If there are no symbols, pretend they are in GNU format. */ + if (symtab_size == 0) + myinfo->symbol_format = _MINT_SYMBOL_FORMAT_GNU; + + bfd_h_put_32 (abfd, myinfo->symbol_format, exec_bytes->g_symbol_format); + + memset (&exec_bytes->g_pad0, 0, sizeof (exec_bytes->g_pad0)); + + /* The standard stuff. */ + NAME(aout, swap_exec_header_out) (abfd, execp, exec_bytes); + if (myinfo->symbol_format != _MINT_SYMBOL_FORMAT_GNU) + PUT_WORD (abfd, 0, exec_bytes->e_syms); + + if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) + return FALSE; + + if (bfd_bwrite (exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd) + != EXEC_BYTES_SIZE) + return FALSE; + + /* Override the stack size. */ + if (myinfo->override_stack_size && myinfo->stkpos) + { + bfd_byte big_endian_stack_size[4]; + + bfd_put_32 (abfd, myinfo->stack_size, &big_endian_stack_size); + + if (bfd_seek (abfd, (file_ptr) myinfo->stkpos, SEEK_SET) != 0) + return FALSE; + + if (bfd_bwrite (big_endian_stack_size, 4, abfd) != 4) + return FALSE; + } + + return TRUE; +} + +/* Write an object file. + Section contents have already been written. We write the + file header, symbols, and relocation. */ + +#define MY_write_object_contents m68kmint_prg_write_object_contents + +static bfd_boolean +m68kmint_prg_write_object_contents (bfd *abfd) +{ + struct external_exec exec_bytes; + struct internal_exec *execp = exec_hdr (abfd); + bfd_size_type text_size; + file_ptr text_end; + + BFD_ASSERT (obj_aout_ext (abfd) != NULL); + + obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; + + /* Most of the following code come from the WRITE_HEADERS macro + found in libaout.h. */ + + if (adata(abfd).magic == undecided_magic) + NAME (aout, adjust_sizes_and_vmas) (abfd, & text_size, & text_end); + + execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; + execp->a_entry = bfd_get_start_address (abfd); + + execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * + obj_reloc_entry_size (abfd)); + execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * + obj_reloc_entry_size (abfd)); + + /* Now write out reloc info, followed by syms and strings. */ + + if (bfd_get_outsymbols (abfd) != NULL + && bfd_get_symcount (abfd) != 0) + { + if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0) + return FALSE; + + if (! NAME (aout, write_syms) (abfd)) + return FALSE; + } + + if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 0) + return FALSE; + if (!NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))) + return FALSE; + + if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp)), SEEK_SET) != 0) + return FALSE; + if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd))) + return FALSE; + + if (write_tparel (abfd, execp) != TRUE) + return FALSE; + + if (write_exec_header (abfd, execp, &exec_bytes) != TRUE) + return FALSE; + + return TRUE; +} + +/* Print private BFD data. Used by objdump -p. */ + +#define MY_bfd_print_private_bfd_data m68kmint_prg_print_private_bfd_data + +static bfd_boolean +m68kmint_prg_print_private_bfd_data (bfd *abfd, void *ptr) +{ + FILE *file = (FILE *) ptr; + struct mint_internal_info *myinfo = obj_aout_ext (abfd); + const char* symbol_format; + long stksize = 0; + + fprintf (file, "\n"); + + fprintf (file, " GEMDOS flags: 0x%08lx\n", (unsigned long) myinfo->prg_flags); + fprintf (file, "Start address: 0x%08lx\n", bfd_get_start_address (abfd)); + + /* Stack size. */ + if (myinfo->stkpos != 0) + { + if (bfd_seek (abfd, myinfo->stkpos, SEEK_SET) != 0 + || (bfd_bread (&stksize, sizeof(long), abfd) != sizeof(long))) + return FALSE; + + stksize = bfd_get_signed_32 (abfd, &stksize); + } + fprintf (file, " Stack size: %ld\n", stksize); + + /* Symbol format. */ + switch (myinfo->symbol_format) + { + case _MINT_SYMBOL_FORMAT_GNU: symbol_format = "stabs"; break; + case _MINT_SYMBOL_FORMAT_DRI: symbol_format = "DRI"; break; + default: symbol_format = "?"; break; + } + fprintf (file, "Symbol format: %s\n", symbol_format); + + return TRUE; +} + +/* Special case for NAME (aout, get_section_contents) + It is not declared in libaout.h, neither implemented in aoutx.h. + Instead, a macro named aout_32_get_section_contents is defined in libaout.h. + So the default value of MY_get_section_contents provided by aout-target.h + is not correct, it has to be defined here with the right value. */ + +#define MY_get_section_contents aout_32_get_section_contents + +/* The following include will define m68kmint_prg_vec + and a default implementation for all the MY_ functions + not overriden here. */ + +#include "aout-target.h" + +/* Set the GEMDOS executable flags. + It is called by the linker emulation script. */ + +bfd_boolean +bfd_m68kmint_set_extended_flags (bfd *abfd, flagword prg_flags) +{ + struct mint_internal_info *myinfo; + + BFD_ASSERT(abfd->xvec == &m68kmint_prg_vec); + myinfo = obj_aout_ext (abfd); + BFD_ASSERT(myinfo != NULL); + + myinfo->prg_flags = prg_flags; + + return TRUE; +} + +/* Override the stack size. + It is called by the linker emulation script. */ + +bfd_boolean +bfd_m68kmint_set_stack_size (bfd *abfd, bfd_signed_vma stack_size) +{ + struct mint_internal_info *myinfo; + + BFD_ASSERT(abfd->xvec == &m68kmint_prg_vec); + myinfo = obj_aout_ext (abfd); + BFD_ASSERT(myinfo != NULL); + + myinfo->stack_size = stack_size; + myinfo->override_stack_size = TRUE; + + return TRUE; +} + +/* Add a TPA relocation entry. + It is called by BFD when linking the input sections, and by the + linker when it generates a reference to an address (in particular, + when building the constructors list). */ + +bfd_boolean +bfd_m68kmint_add_tpa_relocation_entry (bfd *abfd, bfd_vma address) +{ + struct mint_internal_info *myinfo; + + BFD_ASSERT(abfd->xvec == &m68kmint_prg_vec); + myinfo = obj_aout_ext (abfd); + BFD_ASSERT(myinfo != NULL); + + /* Enlarge the buffer if necessary. */ + if (myinfo->relocs_used * sizeof (bfd_vma) >= myinfo->relocs_allocated) + { + bfd_vma *newbuf; + myinfo->relocs_allocated += MINT_RELOC_CHUNKSIZE; + newbuf = bfd_realloc (myinfo->relocs, myinfo->relocs_allocated); + if (newbuf == NULL) + return FALSE; + + myinfo->relocs = newbuf; + } + + /* The TPA relative relocation actually just adds the address of + the text segment (i. e. beginning of the executable in memory) + to the addresses at the specified locations. This allows an + executable to be loaded everywhere in the address space without + memory management. */ + myinfo->relocs[myinfo->relocs_used++] = address; + + return TRUE; +} --- binutils-2.22.51.0.1/bfd/targets.c.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/bfd/targets.c 2012-01-13 20:48:18.073307545 +0100 @@ -795,6 +795,7 @@ extern const bfd_target m68kaux_coff_vec extern const bfd_target m68kcoff_vec; extern const bfd_target m68kcoffun_vec; extern const bfd_target m68klinux_vec; +extern const bfd_target m68kmint_prg_vec; extern const bfd_target m68knetbsd_vec; extern const bfd_target m68ksysvcoff_vec; extern const bfd_target m88kbcs_vec; --- binutils-2.22.51.0.1/binutils/configure.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/binutils/configure 2012-01-13 20:48:18.076640878 +0100 @@ -13042,7 +13042,7 @@ fi case "${host}" in -*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) +*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows* | *-*-mint*) $as_echo "#define USE_BINARY_FOPEN 1" >>confdefs.h ;; --- binutils-2.22.51.0.1/binutils/dlltool.c.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/binutils/dlltool.c 2012-01-13 20:48:18.076640878 +0100 @@ -4360,7 +4360,7 @@ deduce_name (const char *prog_name) if (*cp == '-') dash = cp; if ( -#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__) +#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__) || defined(__MINT__) *cp == ':' || *cp == '\\' || #endif *cp == '/') --- binutils-2.22.51.0.1/binutils/dllwrap.c.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/binutils/dllwrap.c 2012-01-13 20:48:18.076640878 +0100 @@ -263,7 +263,7 @@ deduce_name (const char * name) dash = cp; if ( -#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__) +#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__) || defined(__MINT__) *cp == ':' || *cp == '\\' || #endif *cp == '/') --- binutils-2.22.51.0.1/binutils/readelf.c.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/binutils/readelf.c 2012-01-13 20:48:18.076640878 +0100 @@ -10324,7 +10324,11 @@ dump_section_as_strings (Elf_Internal_Sh #ifndef __MSVCRT__ /* PR 11128: Use two separate invocations in order to work around bugs in the Solaris 8 implementation of printf. */ +#if GCC_VERSION < 3000 + printf (" [%6lx] ", (unsigned long) (data - start)); +#else printf (" [%6tx] ", data - start); +#endif printf ("%s\n", data); #else printf (" [%6Ix] %s\n", (size_t) (data - start), data); --- binutils-2.22.51.0.1/binutils/resrc.c.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/binutils/resrc.c 2012-01-13 20:48:18.079974211 +0100 @@ -396,7 +396,7 @@ look_for_default (char *cmd, const char *space = 0; if ( -#if defined (__DJGPP__) || defined (__CYGWIN__) || defined (_WIN32) +#if defined (__DJGPP__) || defined (__CYGWIN__) || defined (_WIN32) || defined (__MINT__) strchr (cmd, '\\') || #endif strchr (cmd, '/')) @@ -514,7 +514,7 @@ read_rc_file (const char *filename, cons if (*cp == '-') dash = cp; if ( -#if defined (__DJGPP__) || defined (__CYGWIN__) || defined(_WIN32) +#if defined (__DJGPP__) || defined (__CYGWIN__) || defined(_WIN32) || defined (__MINT__) *cp == ':' || *cp == '\\' || #endif *cp == '/') --- binutils-2.22.51.0.1/config.guess.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/config.guess 2012-01-13 20:52:38.313298115 +0100 @@ -398,22 +398,22 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} --- binutils-2.22.51.0.1/gas/config/te-mint.h.mint~ 2012-01-13 20:48:18.079974211 +0100 +++ binutils-2.22.51.0.1/gas/config/te-mint.h 2012-01-13 20:48:18.079974211 +0100 @@ -0,0 +1,30 @@ +/* Copyright 2008 Free Software Foundation, Inc. + + This file is part of GAS, the GNU Assembler. + + GAS 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 3, + or (at your option) any later version. + + GAS 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 GAS; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#define TE_MINT + +#define LOCAL_LABELS_DOLLAR 1 +#define LOCAL_LABELS_FB 1 + +/* These define interfaces. */ +#ifdef OBJ_HEADER +#include OBJ_HEADER +#else +#include "obj-format.h" +#endif --- binutils-2.22.51.0.1/gas/configure.tgt.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/gas/configure.tgt 2012-01-13 20:48:18.079974211 +0100 @@ -272,6 +272,7 @@ case ${generic_target} in m68k-*-linux-*) fmt=elf em=linux ;; m68k-*-uclinux*) fmt=elf em=uclinux ;; m68k-*-gnu*) fmt=elf ;; + m68k-*-mint*) fmt=aout em=mint bfd_gas=yes ;; m68k-*-netbsdelf*) fmt=elf em=nbsd ;; m68k-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes ;; m68k-*-openbsd*) fmt=aout em=nbsd bfd_gas=yes ;; --- binutils-2.22.51.0.1/gas/testsuite/gas/all/weakref1u.d.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/gas/testsuite/gas/all/weakref1u.d 2012-01-13 20:48:18.079974211 +0100 @@ -3,7 +3,7 @@ #source: weakref1.s # aout turns undefined into *ABS* symbols. # see weakref1.d for comments on the other not-targets -#not-target: *-*-*aout m68k-*-netbsd m68k-*-openbsd* ns32k-*-netbsd alpha*-*-osf* *-*-ecoff +#not-target: *-*-*aout m68k-*-netbsd m68k-*-openbsd* m68k-*-mint* ns32k-*-netbsd alpha*-*-osf* *-*-ecoff # the rest of this file is generated with the following script: # # script begin --- binutils-2.22.51.0.1/gas/testsuite/gas/m68k/all.exp.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/gas/testsuite/gas/m68k/all.exp 2012-01-13 20:48:18.079974211 +0100 @@ -74,7 +74,7 @@ if { [istarget m68*-*-*] || [istarget fi gas_test_error "p11673.s" "-march=isab" "movel immediate with offset unsupported on isab" - if { [istarget *-*-*aout] || [istarget *-*-netbsd] || [istarget *-*-openbsd*] } then { + if { [istarget *-*-*aout] || [istarget *-*-netbsd] || [istarget *-*-openbsd*] || [istarget *-*-mint*] } then { run_dump_test p3041 run_dump_test p3041data run_dump_test p3041pcrel --- binutils-2.22.51.0.1/gas/testsuite/gas/m68k/br-isaa.d.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/gas/testsuite/gas/m68k/br-isaa.d 2012-01-13 20:48:18.079974211 +0100 @@ -1,7 +1,7 @@ #name: br-isaa.d #objdump: -dr #as: -march=isaa -pcrel -#not-target: *-*-*aout m68k-*-netbsd m68k-*-openbsd* +#not-target: *-*-*aout m68k-*-netbsd m68k-*-openbsd* m68k-*-mint* .*: file format .* --- binutils-2.22.51.0.1/gas/testsuite/gas/m68k/br-isab.d.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/gas/testsuite/gas/m68k/br-isab.d 2012-01-13 20:48:18.079974211 +0100 @@ -1,7 +1,7 @@ #name: br-isab.d #objdump: -dr #as: -march=isab -pcrel -#not-target: *-*-*aout m68k-*-netbsd m68k-*-openbsd* +#not-target: *-*-*aout m68k-*-netbsd m68k-*-openbsd* m68k-*-mint* .*: file format .* --- binutils-2.22.51.0.1/gas/testsuite/gas/m68k/br-isac.d.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/gas/testsuite/gas/m68k/br-isac.d 2012-01-13 20:48:18.079974211 +0100 @@ -1,7 +1,7 @@ #name: br-isac.d #objdump: -dr #as: -march=isac -pcrel -#not-target: *-*-*aout m68k-*-netbsd m68k-*-openbsd* +#not-target: *-*-*aout m68k-*-netbsd m68k-*-openbsd* m68k-*-mint* .*: file format .* --- binutils-2.22.51.0.1/include/filenames.h.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/include/filenames.h 2012-01-13 20:48:18.079974211 +0100 @@ -30,7 +30,7 @@ Foundation, Inc., 51 Franklin Street - F extern "C" { #endif -#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) +#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) || defined (__MINT__) # ifndef HAVE_DOS_BASED_FILE_SYSTEM # define HAVE_DOS_BASED_FILE_SYSTEM 1 # endif --- binutils-2.22.51.0.1/include/getopt.h.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/include/getopt.h 2012-01-13 20:48:18.143307542 +0100 @@ -106,7 +106,7 @@ struct option to find the declaration so provide a fully prototyped one. If it is 1, we found it so don't provide any declaration at all. */ #if !HAVE_DECL_GETOPT -#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT) +#if defined (__GNU_LIBRARY__) || defined (__MINT__) || defined (HAVE_DECL_GETOPT) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in unistd.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ --- binutils-2.22.51.0.1/ld/configure.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/ld/configure 2012-01-13 20:48:18.149974209 +0100 @@ -16557,7 +16557,7 @@ fi case "${host}" in -*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) +*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows* | *-*-mint*) $as_echo "#define USE_BINARY_FOPEN 1" >>confdefs.h ;; --- binutils-2.22.51.0.1/ld/configure.tgt.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/ld/configure.tgt 2012-01-13 20:48:18.149974209 +0100 @@ -345,6 +345,7 @@ m68k-*-linux-*) targ_emul=m68kelf tdir_m68klinux=`echo ${targ_alias} | sed -e 's/linux/linuxaout/'` ;; m68k-*-uclinux*) targ_emul=m68kelf ;; m68*-*-gnu*) targ_emul=m68kelf ;; +m68*-*-mint*) targ_emul=m68kmint ;; m68*-*-netbsd*4k*) targ_emul=m68k4knbsd targ_extra_emuls="m68knbsd m68kelfnbsd" ;; m68*-*-netbsdelf*) targ_emul=m68kelfnbsd --- binutils-2.22.51.0.1/ld/emulparams/m68kmint.sh.mint~ 2012-01-13 20:48:18.149974209 +0100 +++ binutils-2.22.51.0.1/ld/emulparams/m68kmint.sh 2012-01-13 20:48:18.149974209 +0100 @@ -0,0 +1,6 @@ +SCRIPT_NAME=m68kmint +OUTPUT_FORMAT="a.out-mintprg" +RELOCATEABLE_OUTPUT_FORMAT="a.out-zero-big" +TEXT_START_ADDR=0xe4 +ARCH=m68k +EXTRA_EM_FILE=mint --- binutils-2.22.51.0.1/ld/emultempl/mint.em.mint~ 2012-01-13 20:50:30.353302751 +0100 +++ binutils-2.22.51.0.1/ld/emultempl/mint.em 2012-01-13 20:50:30.353302751 +0100 @@ -0,0 +1,330 @@ +# This shell script emits a C file. -*- C -*- +# Copyright 2006, 2007 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# 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 3 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., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +# This file is sourced from generic.em +# +fragment <<EOF + +#include "getopt.h" +#include "ldgram.h" + +/* Standard GEMDOS program flags. */ +#define _MINT_F_FASTLOAD 0x01 /* Don't clear heap. */ +#define _MINT_F_ALTLOAD 0x02 /* OK to load in alternate RAM. */ +#define _MINT_F_ALTALLOC 0x04 /* OK to malloc from alt. RAM. */ +#define _MINT_F_BESTFIT 0x08 /* Load with optimal heap size. */ +/* The memory flags are mutually exclusive. */ +#define _MINT_F_MEMPROTECTION 0xf0 /* Masks out protection bits. */ +#define _MINT_F_MEMPRIVATE 0x00 /* Memory is private. */ +#define _MINT_F_MEMGLOBAL 0x10 /* Read/write access to mem allowed. */ +#define _MINT_F_MEMSUPER 0x20 /* Only supervisor access allowed. */ +#define _MINT_F_MEMREADABLE 0x30 /* Any read access OK. */ +#define _MINT_F_SHTEXT 0x800 /* Program's text may be shared */ + +/* Option flags. */ +static flagword prg_flags = (_MINT_F_FASTLOAD | _MINT_F_ALTLOAD + | _MINT_F_ALTALLOC | _MINT_F_MEMPRIVATE); + +/* If override_stack_size is TRUE, then the executable stack size + * must be overriden with the value of stack_size. */ +static bfd_boolean override_stack_size = FALSE; +static bfd_signed_vma stack_size; + +/* MiNT format extra command line options. */ + +/* Used for setting flags in the MiNT header. */ +#define OPTION_FASTLOAD (300) +#define OPTION_NO_FASTLOAD (OPTION_FASTLOAD + 1) +#define OPTION_FASTRAM (OPTION_NO_FASTLOAD + 1) +#define OPTION_NO_FASTRAM (OPTION_FASTRAM + 1) +#define OPTION_FASTALLOC (OPTION_NO_FASTRAM + 1) +#define OPTION_NO_FASTALLOC (OPTION_FASTALLOC + 1) +#define OPTION_BESTFIT (OPTION_NO_FASTALLOC + 1) +#define OPTION_NO_BESTFIT (OPTION_BESTFIT + 1) +#define OPTION_BASEREL (OPTION_NO_BESTFIT + 1) +#define OPTION_NO_BASEREL (OPTION_BASEREL + 1) +#define OPTION_MEM_PRIVATE (OPTION_NO_BASEREL + 1) +#define OPTION_MEM_GLOBAL (OPTION_MEM_PRIVATE + 1) +#define OPTION_MEM_SUPER (OPTION_MEM_GLOBAL + 1) +#define OPTION_MEM_READONLY (OPTION_MEM_SUPER + 1) +#define OPTION_PRG_FLAGS (OPTION_MEM_READONLY + 1) +#define OPTION_STACK (OPTION_PRG_FLAGS + 1) + +static void +gld${EMULATION_NAME}_add_options + (int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl, + struct option **longopts, int nrl ATTRIBUTE_UNUSED, + struct option **really_longopts ATTRIBUTE_UNUSED) +{ + static const struct option xtra_long[] = { + {"mfastload", no_argument, NULL, OPTION_FASTLOAD}, + {"mno-fastload", no_argument, NULL, OPTION_NO_FASTLOAD}, + {"mfastram", no_argument, NULL, OPTION_FASTRAM}, + {"mno-fastram", no_argument, NULL, OPTION_NO_FASTRAM}, + {"maltram", no_argument, NULL, OPTION_FASTRAM}, + {"mno-altram", no_argument, NULL, OPTION_NO_FASTRAM}, + {"mfastalloc", no_argument, NULL, OPTION_FASTALLOC}, + {"mno-fastalloc", no_argument, NULL, OPTION_NO_FASTALLOC}, + {"maltalloc", no_argument, NULL, OPTION_FASTALLOC}, + {"mno-altalloc", no_argument, NULL, OPTION_NO_FASTALLOC}, + {"mbest-fit", no_argument, NULL, OPTION_BESTFIT}, + {"mno-best-fit", no_argument, NULL, OPTION_NO_BESTFIT}, + {"mbaserel", no_argument, NULL, OPTION_BASEREL}, + {"mno-baserel", no_argument, NULL, OPTION_NO_BASEREL}, + {"mshared-text", no_argument, NULL, OPTION_BASEREL}, + {"mno-shared-text", no_argument, NULL, OPTION_NO_BASEREL}, + {"msharable-text", no_argument, NULL, OPTION_BASEREL}, + {"mno-sharable-text", no_argument, NULL, OPTION_NO_BASEREL}, + /* Memory protection bits. */ + {"mprivate-memory", no_argument, NULL, OPTION_MEM_PRIVATE }, + {"mglobal-memory", no_argument, NULL, OPTION_MEM_GLOBAL}, + {"msuper-memory", no_argument, NULL, OPTION_MEM_SUPER}, + {"mreadable-memory", no_argument, NULL, OPTION_MEM_READONLY}, + {"mreadonly-memory", no_argument, NULL, OPTION_MEM_READONLY}, + {"mprg-flags", required_argument, NULL, OPTION_PRG_FLAGS}, + {"stack", required_argument, NULL, OPTION_STACK}, + {NULL, no_argument, NULL, 0} + }; + + *longopts = (struct option *) + xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); + memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); +} + +static bfd_boolean +gld${EMULATION_NAME}_handle_option (int optc) +{ + switch (optc) + { + default: + return FALSE; + + case OPTION_FASTLOAD: + prg_flags |= _MINT_F_FASTLOAD; + break; + + case OPTION_NO_FASTLOAD: + prg_flags &= ~_MINT_F_FASTLOAD; + break; + + case OPTION_FASTRAM: + prg_flags |= _MINT_F_ALTLOAD; + break; + + case OPTION_NO_FASTRAM: + prg_flags &= ~_MINT_F_ALTLOAD; + break; + + case OPTION_FASTALLOC: + prg_flags |= _MINT_F_ALTALLOC; + break; + + case OPTION_NO_FASTALLOC: + prg_flags &= ~_MINT_F_ALTALLOC; + break; + + case OPTION_BESTFIT: + prg_flags |= _MINT_F_BESTFIT; + break; + + case OPTION_NO_BESTFIT: + prg_flags &= ~_MINT_F_BESTFIT; + break; + + case OPTION_BASEREL: + prg_flags |= _MINT_F_SHTEXT; + break; + + case OPTION_NO_BASEREL: + prg_flags &= ~_MINT_F_SHTEXT; + break; + + case OPTION_MEM_PRIVATE: + prg_flags &= ~_MINT_F_MEMPROTECTION; + break; + + case OPTION_MEM_GLOBAL: + prg_flags &= ~_MINT_F_MEMPROTECTION; + prg_flags |= _MINT_F_MEMPRIVATE; + break; + + case OPTION_MEM_SUPER: + prg_flags &= ~_MINT_F_MEMPROTECTION; + prg_flags |= _MINT_F_MEMSUPER; + break; + + case OPTION_MEM_READONLY: + prg_flags &= ~_MINT_F_MEMPROTECTION; + prg_flags |= _MINT_F_MEMREADABLE; + break; + + case OPTION_PRG_FLAGS: + { + char* tail; + unsigned long flag_value = strtoul (optarg, &tail, 0); + + if (*tail != '\0') + einfo (_("%P: warning: ignoring invalid program flags %s\n"), optarg); + else + prg_flags = flag_value; + + break; + } + case OPTION_STACK: + { + char* tail; + long size = strtol (optarg, &tail, 0); + + if (*tail == 'K' || *tail == 'k') + { + size *= 1024; + ++tail; + } + else if (*tail == 'M' || *tail == 'm') + { + size *= 1024*1024; + ++tail; + } + + if (*tail != '\0') + einfo (_("%P: warning: ignoring invalid stack size %s\n"), optarg); + else + { + stack_size = (bfd_signed_vma) size; + override_stack_size = TRUE; + } + + break; + } + } + return TRUE; +} + +/* This callback is called when ld is invoked + with the --help and --target-help options. */ + +static void +gld_${EMULATION_NAME}_list_options (FILE *file) +{ + fprintf (file, _(" --m[no-]fastload Enable/Disable not cleaning the heap on startup\n")); + fprintf (file, _(" --m[no-]altram, --m[no-]fastram\n")); + fprintf (file, _(" Enable/Disable loading into alternate RAM\n")); + fprintf (file, _(" --m[no-]altalloc, --m[no-]fastalloc\n")); + fprintf (file, _(" Enable/Disable malloc from alternate RAM\n")); + fprintf (file, _(" --m[no-]best-fit Enable/Disable loading with optimal heap size\n")); + fprintf (file, _(" --m[no-]sharable-text, --m[no-]shared-text, --m[no-]baserel\n")); + fprintf (file, _(" Enable/Disable sharing the text segment\n")); + fprintf (file, "\n"); + fprintf (file, _("The following memory options are mutually exclusive:\n")); + fprintf (file, _(" --mprivate-memory Process memory is not accessible\n")); + fprintf (file, _(" --mglobal-memory Process memory is readable and writable\n")); + fprintf (file, _(" --msuper-memory Process memory is accessible in supervisor mode\n")); + fprintf (file, _(" --mreadonly-memory, --mreadable-memory\n")); + fprintf (file, _(" Process memory is readable but not writable\n")); + fprintf (file, "\n"); + fprintf (file, _(" --mprg-flags <value> Set all the flags with an integer raw value\n")); + fprintf (file, _(" --stack <size> Override the stack size (suffix k or M allowed)\n")); +} + +/* This callback is called by lang_for_each_statement. It checks that the + output sections speficied in the linker script are compatible with the MiNT + executable format. */ + +static void +gld${EMULATION_NAME}_check_output_sections (lang_statement_union_type *s) +{ + if (s->header.type == lang_output_section_statement_enum) + { + lang_output_section_statement_type *oss = &s->output_section_statement; + + if (strcmp(oss->name, ".text") == 0 && oss->bfd_section->vma != ${TEXT_START_ADDR}) + einfo (_("%F%P: the VMA of section %A must be 0x%V, but actual value is 0x%V\n"), + oss->bfd_section, ${TEXT_START_ADDR}, oss->bfd_section->vma); + else if (strcmp(oss->name, ".data") == 0 && oss->addr_tree != NULL) + einfo (_("%F%P: the VMA of section %A must not be specified\n"), + oss->bfd_section); + else if (strcmp(oss->name, ".bss") == 0 && oss->addr_tree != NULL) + einfo (_("%F%P: the VMA of section %A must not be specified\n"), + oss->bfd_section); + } +} + +/* This callback is called by lang_for_each_statement. It looks for the data + statements of type REL generated by the linker, and adds a TPA relocation + entry for them. This is used by the CONSTRUCTORS list. */ + +static void +gld${EMULATION_NAME}_add_tpa_relocs (lang_statement_union_type *s) +{ + if (s->header.type == lang_data_statement_enum) + { + lang_data_statement_type *ds = &s->data_statement; + + if (ds->exp->type.node_code == REL) + { + if (ds->type == LONG) + { + bfd_vma tpa_address = ds->output_section->vma + ds->output_offset; + if (!bfd_m68kmint_add_tpa_relocation_entry(link_info.output_bfd, tpa_address)) + einfo (_("%F%P:%B: unable to add a relocation entry\n"), link_info.output_bfd); + } + else + { + einfo (_("%F%P:%B: invalid size for TPA relocation entry in section %A, offset 0x%V\n"), + link_info.output_bfd, ds->output_section, ds->output_offset); + } + } + } +} + +/* Final emulation specific call. */ + +static void +gld${EMULATION_NAME}_finish (void) +{ + /* Do nothing if we are not generating a MiNT executable (ex: binary). */ + if (strcmp (bfd_get_target (link_info.output_bfd), "${OUTPUT_FORMAT}") != 0) + return; + + /* Check the output sections. */ + lang_for_each_statement (gld${EMULATION_NAME}_check_output_sections); + + /* Set the GEMDOS executable header flags. */ + if (!bfd_m68kmint_set_extended_flags (link_info.output_bfd, prg_flags)) + einfo (_("%F%P:%B: unable to set the header flags\n"), link_info.output_bfd); + + /* Override the stack size. */ + if (override_stack_size) + if (!bfd_m68kmint_set_stack_size (link_info.output_bfd, stack_size)) + einfo (_("%F%P:%B: unable to set the stack size\n"), link_info.output_bfd); + + /* Generate TPA relocation entries for the data statements. */ + lang_for_each_statement (gld${EMULATION_NAME}_add_tpa_relocs); +} + +EOF + +# Put these extra routines in ld_${EMULATION_NAME}_emulation +# +LDEMUL_ADD_OPTIONS=gld${EMULATION_NAME}_add_options +LDEMUL_HANDLE_OPTION=gld${EMULATION_NAME}_handle_option +LDEMUL_LIST_OPTIONS=gld_${EMULATION_NAME}_list_options +LDEMUL_FINISH=gld${EMULATION_NAME}_finish --- binutils-2.22.51.0.1/ld/Makefile.am.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/ld/Makefile.am 2012-01-13 20:48:18.146640876 +0100 @@ -324,6 +324,7 @@ ALL_EMULATION_SOURCES = \ em68kelf.c \ em68kelfnbsd.c \ em68klinux.c \ + em68kmint.c \ em68knbsd.c \ em68kpsos.c \ em88kbcs.c \ @@ -1402,6 +1403,10 @@ em68kelfnbsd.c: $(srcdir)/emulparams/m68 em68klinux.c: $(srcdir)/emulparams/m68klinux.sh \ $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} ${GENSCRIPTS} m68klinux "$(tdir_m68klinux)" +em68kmint.c: $(srcdir)/emulparams/m68kmint.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/mint.em \ + $(srcdir)/scripttempl/m68kmint.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kmint "$(tdir_m68kmint)" em68knbsd.c: $(srcdir)/emulparams/m68knbsd.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} ${GENSCRIPTS} m68knbsd "$(tdir_m68knbsd)" --- binutils-2.22.51.0.1/ld/Makefile.in.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/ld/Makefile.in 2012-01-13 20:48:18.146640876 +0100 @@ -630,6 +630,7 @@ ALL_EMULATION_SOURCES = \ em68kelf.c \ em68kelfnbsd.c \ em68klinux.c \ + em68kmint.c \ em68knbsd.c \ em68kpsos.c \ em88kbcs.c \ @@ -1260,6 +1261,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelfnbsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68klinux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kmint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68knbsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kpsos.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em88kbcs.Po@am__quote@ @@ -2857,6 +2859,10 @@ em68kelfnbsd.c: $(srcdir)/emulparams/m68 em68klinux.c: $(srcdir)/emulparams/m68klinux.sh \ $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} ${GENSCRIPTS} m68klinux "$(tdir_m68klinux)" +em68kmint.c: $(srcdir)/emulparams/m68kmint.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/mint.em \ + $(srcdir)/scripttempl/m68kmint.sc ${GEN_DEPENDS} + ${GENSCRIPTS} m68kmint "$(tdir_m68kmint)" em68knbsd.c: $(srcdir)/emulparams/m68knbsd.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} ${GENSCRIPTS} m68knbsd "$(tdir_m68knbsd)" --- binutils-2.22.51.0.1/ld/scripttempl/m68kmint.sc.mint~ 2012-01-13 20:50:30.353302751 +0100 +++ binutils-2.22.51.0.1/ld/scripttempl/m68kmint.sc 2012-01-13 20:50:30.353302751 +0100 @@ -0,0 +1,35 @@ +cat <<EOF +${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})} +${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})} +${RELOCATING+${LIB_SEARCH_DIRS}} +SECTIONS +{ + ${RELOCATING+/* The VMA of the .text section is ${TEXT_START_ADDR} instead of 0 + because the extended MiNT header is just before, + at the beginning of the TEXT segment. */} + .text ${RELOCATING+${TEXT_START_ADDR}}: + { + CREATE_OBJECT_SYMBOLS + *(.text) + ${CONSTRUCTING+CONSTRUCTORS} + ${RELOCATING+_etext = .;} + ${RELOCATING+__etext = .;} + } + + .data : + { + *(.data) + ${RELOCATING+_edata = .;} + ${RELOCATING+__edata = .;} + } + + .bss : + { + ${RELOCATING+__bss_start = .;} + *(.bss) + *(COMMON) + ${RELOCATING+_end = .;} + ${RELOCATING+__end = .;} + } +} +EOF --- binutils-2.22.51.0.1/libiberty/hex.c.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/libiberty/hex.c 2012-01-13 20:50:30.353302751 +0100 @@ -24,7 +24,7 @@ Boston, MA 02110-1301, USA. */ #include "libiberty.h" #include "safe-ctype.h" /* for HOST_CHARSET_ASCII */ -#if EOF != -1 +#if !(EOF == -1) /* gcc 2.95.3 has bug in '!=' operator for negative constants */ #error "hex.c requires EOF == -1" #endif --- binutils-2.22.51.0.1/libiberty/safe-ctype.c.mint~ 2011-11-18 21:05:53.000000000 +0100 +++ binutils-2.22.51.0.1/libiberty/safe-ctype.c 2012-01-13 20:50:30.356636085 +0100 @@ -119,7 +119,7 @@ sets of characters: #include <safe-ctype.h> #include <stdio.h> /* for EOF */ -#if EOF != -1 +#if !(EOF == -1) /* gcc 2.95.3 has bug in '!=' operator for negative constants */ #error "<safe-ctype.h> requires EOF == -1" #endif