c8a0e2f4c6
This commit finalizes support for cross compilation. The tools directory are all links to the actual tools and are built on the host system to build Minix. build.sh is the work horse that takes care of all environment settings. It's slightly adjusted for Minix. The /usr/src/Makefile has additional targets needed for cross compilation.
330 lines
9.8 KiB
Text
330 lines
9.8 KiB
Text
$NetBSD$
|
|
|
|
--- bfd/i386minix.c.orig Sat Feb 26 00:58:30 2011
|
|
+++ bfd/i386minix.c
|
|
@@ -0,0 +1,325 @@
|
|
+/* BFD back-end for i386 minix a.out binaries.
|
|
+ Copyright 1990, 1991, 1992, 1994, 1996, 1997, 2001, 2002, 2003
|
|
+ Free Software Foundation, Inc.
|
|
+
|
|
+This file is part of BFD, the Binary File Descriptor library.
|
|
+
|
|
+This program is free software; you can redistribute it and/or modify
|
|
+it under the terms of the GNU General Public License as published by
|
|
+the Free Software Foundation; either version 2 of the License, or
|
|
+(at your option) any later version.
|
|
+
|
|
+This program is distributed in the hope that it will be useful,
|
|
+but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+GNU General Public License for more details.
|
|
+
|
|
+You should have received a copy of the GNU General Public License
|
|
+along with this program; if not, write to the Free Software
|
|
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
+
|
|
+/***************/
|
|
+/* EXEC FORMAT */
|
|
+/***************/
|
|
+#include <a.out.h>
|
|
+
|
|
+#define external_exec exec
|
|
+#define EXEC_BYTES_SIZE sizeof( struct exec )
|
|
+
|
|
+#define OMAGIC 0407 /* Object file or impure executable. */
|
|
+#define NMAGIC 0410 /* Code indicating pure executable. */
|
|
+#define ZMAGIC 0x0301 /* Code indicating demand-paged executable. */
|
|
+#define BMAGIC 0415 /* Used by a b.out object. */
|
|
+
|
|
+#ifndef QMAGIC
|
|
+#define QMAGIC 0314
|
|
+#endif
|
|
+# ifndef N_BADMAG
|
|
+# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
|
|
+ && N_MAGIC(x) != NMAGIC \
|
|
+ && N_MAGIC(x) != ZMAGIC \
|
|
+ && N_MAGIC(x) != QMAGIC)
|
|
+# endif /* N_BADMAG */
|
|
+
|
|
+#define N_HEADER_IN_TEXT(x) 0
|
|
+
|
|
+#define N_TXTOFF(x) EXEC_BYTES_SIZE
|
|
+#define N_TXTADDR(x) 0
|
|
+
|
|
+#define N_TXTSIZE(x) ((x).a_text)
|
|
+#ifdef SUPPORT_SEP
|
|
+#define MINIX_IS_SEP(x) 0 /*-> gcv.c HCLICK STUFF*/
|
|
+#define N_DATADDR(x) (MINIX_IS_SEP(x) ? align((x).a_text,HCLICK) : (x).a_text )
|
|
+#else
|
|
+#define N_DATADDR(x) ((x).a_text)
|
|
+#endif
|
|
+
|
|
+/* Are these values correct? */
|
|
+#define TARGET_PAGE_SIZE 1
|
|
+#define SEGMENT_SIZE 1
|
|
+
|
|
+#define DEFAULT_STACK 5 * 1024 * 1024 /* 5 MB stack */
|
|
+
|
|
+#define DEFAULT_ARCH bfd_arch_i386
|
|
+
|
|
+/* 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 (i386minix_,OP)
|
|
+#define NAME(a,b) i386minix_32_##b
|
|
+#define TARGETNAME "a.out-i386-minix"
|
|
+#define NO_WRITE_HEADER_KLUDGE 1
|
|
+
|
|
+#define ARCH_SIZE 32
|
|
+
|
|
+#include "bfd.h"
|
|
+#include "sysdep.h"
|
|
+/*#include "libbfd.h"*/
|
|
+#include "aout/aout64.h"
|
|
+#include "libaout.h"
|
|
+
|
|
+
|
|
+#define i386minix_32_get_section_contents _bfd_generic_get_section_contents
|
|
+
|
|
+#define SET_ARCH_MACH(abfd, exec) \
|
|
+ bfd_set_arch_mach(abfd, DEFAULT_ARCH, 0)
|
|
+
|
|
+static bfd_boolean i386minix_write_object_contents PARAMS ((bfd *));
|
|
+#define MY_write_object_contents i386minix_write_object_contents
|
|
+
|
|
+static int MY(swap_exec_header_in) PARAMS ((bfd *, struct external_exec *, struct internal_exec *));
|
|
+static void MY(swap_exec_header_out) PARAMS ((bfd *, struct internal_exec *, struct external_exec *));
|
|
+
|
|
+#define NAME_swap_exec_header_in MY(swap_exec_header_in)
|
|
+#define NAME_swap_exec_header_out MY(swap_exec_header_out)
|
|
+
|
|
+#define MY_object_p MY(object_p)
|
|
+static const bfd_target * MY(object_p) (bfd *);
|
|
+
|
|
+
|
|
+static bfd_boolean MY (set_sizes) PARAMS ((bfd *));
|
|
+
|
|
+#define MY_backend_data &MY(backend_data)
|
|
+static const struct aout_backend_data MY(backend_data) = {
|
|
+ 0, /* zmagic contiguous */
|
|
+ 1, /* text incl header */
|
|
+ 0, /* entry is text address */
|
|
+ 0, /* exec_hdr_flags */
|
|
+ 0, /* text vma? */
|
|
+ MY(set_sizes),
|
|
+ 1, /* exec header not counted */
|
|
+ 0, /* add_dynamic_symbols */
|
|
+ 0, /* add_one_symbol */
|
|
+ 0, /* link_dynamic_object */
|
|
+ 0, /* write_dynamic_symbol */
|
|
+ 0, /* check_dynamic_reloc */
|
|
+ 0 /* finish_dynamic_link */
|
|
+};
|
|
+
|
|
+#include "aoutx.h"
|
|
+
|
|
+#include "aout-target.h"
|
|
+
|
|
+/****************/
|
|
+/* WRITE HEADER */
|
|
+/****************/
|
|
+static void
|
|
+MY(swap_exec_header_out) (abfd, execp, bytes)
|
|
+ bfd *abfd;
|
|
+ struct internal_exec *execp;
|
|
+ struct external_exec *bytes;
|
|
+{
|
|
+ int total;
|
|
+ int stack;
|
|
+
|
|
+ /* Now fill in fields in the raw data, from the fields in the exec struct. */
|
|
+ H_PUT_16 (abfd, N_MAGIC(*execp), bytes->a_magic);
|
|
+
|
|
+ bytes->a_flags = 0;
|
|
+ if ( bytes->a_syms )
|
|
+ bytes->a_flags |= A_NSYM;
|
|
+
|
|
+ bytes->a_cpu = A_I80386;
|
|
+
|
|
+ bytes->a_hdrlen = EXEC_BYTES_SIZE;
|
|
+
|
|
+ bytes->a_unused = 0;
|
|
+ bytes->a_version = 0;
|
|
+
|
|
+ PUT_WORD (abfd, execp->a_text , &bytes->a_text);
|
|
+ PUT_WORD (abfd, execp->a_data , &bytes->a_data);
|
|
+ PUT_WORD (abfd, execp->a_bss , &bytes->a_bss);
|
|
+ PUT_WORD (abfd, execp->a_entry , &bytes->a_entry);
|
|
+
|
|
+ stack = DEFAULT_STACK;
|
|
+ total = execp->a_data + execp->a_bss + stack;
|
|
+#if 0
|
|
+ if ( MINIX_IS_SEP( abfd ) )
|
|
+ bytes->a_flags |= A_SEP;
|
|
+ else
|
|
+#endif
|
|
+ total += execp->a_text;
|
|
+
|
|
+ PUT_WORD (abfd, total , &bytes->a_total);
|
|
+ PUT_WORD (abfd, execp->a_syms , &bytes->a_syms);
|
|
+ PUT_WORD (abfd, execp->a_trsize, &bytes->a_trsize);
|
|
+ PUT_WORD (abfd, execp->a_drsize, &bytes->a_drsize);
|
|
+
|
|
+ bytes->a_tbase = bytes->a_dbase = 0;
|
|
+}
|
|
+
|
|
+#define i386minix_32_swap_exec_header_out MY(swap_exec_header_out)
|
|
+/* WRITE_HEADERS calls NAME(aout,swap_exec_header_out)
|
|
+ which I need to overwrite. Unfortunately aoutx.h doesn't have a
|
|
+ NAME_swap_exec_header_out like it does for -_in.
|
|
+ So I have to redefine the outcome of NAME(aout,swap_exec_header_out) to
|
|
+ my own function before using WRITE_HEADERS */
|
|
+
|
|
+/* Set the machine type correctly. */
|
|
+static bfd_boolean
|
|
+i386minix_write_object_contents (abfd)
|
|
+ bfd *abfd;
|
|
+{
|
|
+ struct external_exec exec_bytes;
|
|
+ struct internal_exec *execp = exec_hdr (abfd);
|
|
+
|
|
+ N_SET_MACHTYPE (*execp, M_386);
|
|
+
|
|
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
|
|
+
|
|
+ WRITE_HEADERS (abfd, execp);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+/* undo renaming to be able to include aoutx.h */
|
|
+#undef i386minix_32_swap_exec_header_out
|
|
+
|
|
+/***************/
|
|
+/* READ HEADER */
|
|
+/***************/
|
|
+/* define if aoutx.h is included: */
|
|
+/* UNTRUE: but including it generates a conflict with swap_exe_header_out, so don't include it */
|
|
+
|
|
+/* return -1 if header is wrong
|
|
+ * otherwise return the bytes left to read */
|
|
+static int
|
|
+MY(swap_exec_header_in) (abfd, bytes, execp)
|
|
+ bfd *abfd;
|
|
+ struct external_exec *bytes;
|
|
+ struct internal_exec *execp;
|
|
+{
|
|
+ /* The internal_exec structure has some fields that are unused in this
|
|
+ configuration (IE for i960), so ensure that all such uninitialized
|
|
+ fields are zero'd out. There are places where two of these structs
|
|
+ are memcmp'd, and thus the contents do matter. */
|
|
+ memset ((PTR) execp, 0, sizeof (struct internal_exec));
|
|
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
|
|
+
|
|
+ /*fill a_info*/
|
|
+ N_SET_MAGIC(*execp, H_GET_16 (abfd, bytes->a_magic));
|
|
+ N_SET_MACHTYPE(*execp, M_386);
|
|
+ N_SET_FLAGS(*execp, 0);
|
|
+
|
|
+ /*check integrity*/
|
|
+ if ( N_BADMAG( *execp ) )
|
|
+ return -1;
|
|
+
|
|
+ if ( bytes->a_cpu != A_I80386 )
|
|
+ return -1;
|
|
+
|
|
+ if ( bytes->a_hdrlen < A_MINHDR )
|
|
+ return -1;
|
|
+
|
|
+#if 0
|
|
+ if ( bytes->a_flags & A_SEP )
|
|
+ dosomething();
|
|
+#endif
|
|
+
|
|
+ /*fill the rest*/
|
|
+ execp->a_text = GET_WORD (abfd, &bytes->a_text);
|
|
+ execp->a_data = GET_WORD (abfd, &bytes->a_data);
|
|
+ execp->a_bss = GET_WORD (abfd, &bytes->a_bss);
|
|
+ execp->a_syms = GET_WORD (abfd, &bytes->a_syms);
|
|
+ execp->a_entry = GET_WORD (abfd, &bytes->a_entry);
|
|
+
|
|
+ if ( bytes->a_hdrlen < A_MINHDR + 2 * sizeof(long) )
|
|
+ return bytes->a_hdrlen - A_MINHDR;
|
|
+
|
|
+ if (bfd_bread (&bytes->a_trsize, 2 * sizeof(long), abfd) != 2 * sizeof(long))
|
|
+ return -1;
|
|
+
|
|
+ execp->a_trsize = GET_WORD (abfd, &bytes->a_trsize);
|
|
+ execp->a_drsize = GET_WORD (abfd, &bytes->a_drsize);
|
|
+
|
|
+ bfd_seek (abfd, -2 * sizeof(long), SEEK_CUR);
|
|
+
|
|
+ /*store other fields of external_exec?*/
|
|
+ return bytes->a_hdrlen - A_MINHDR;
|
|
+}
|
|
+
|
|
+static const bfd_target *
|
|
+MY(object_p) (abfd)
|
|
+ bfd *abfd;
|
|
+{
|
|
+ struct external_exec exec_bytes; /* Raw exec header from file */
|
|
+ struct internal_exec exec; /* Cleaned-up exec header */
|
|
+ const bfd_target *target;
|
|
+ int left;
|
|
+ bfd_size_type amt = A_MINHDR;
|
|
+
|
|
+ if (bfd_bread ((PTR) &exec_bytes, amt, abfd) != amt)
|
|
+ {
|
|
+ if (bfd_get_error () != bfd_error_system_call)
|
|
+ bfd_set_error (bfd_error_wrong_format);
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* let MY(swap_exec_header_in) check the header */
|
|
+ if ( (left = MY(swap_exec_header_in) (abfd, &exec_bytes, &exec)) == -1 )
|
|
+ {
|
|
+ /* incorrect header */
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* skip rest of header */
|
|
+ if ( bfd_seek( abfd, left, SEEK_CUR ) )
|
|
+ return 0;
|
|
+
|
|
+ target = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback));
|
|
+
|
|
+ int adjust = (A_MINHDR + left) - EXEC_BYTES_SIZE;
|
|
+
|
|
+ /* adjust file positions with the bytes left to be read from the header */
|
|
+ obj_textsec (abfd)->filepos += adjust;
|
|
+ obj_datasec (abfd)->filepos += adjust;
|
|
+
|
|
+ obj_textsec (abfd)->rel_filepos += adjust;
|
|
+ obj_datasec (abfd)->rel_filepos += adjust;
|
|
+
|
|
+ obj_sym_filepos (abfd) += adjust;
|
|
+ obj_str_filepos (abfd) += adjust;
|
|
+
|
|
+ adata(abfd).exec_bytes_size = A_MINHDR + left;
|
|
+
|
|
+#ifdef ENTRY_CAN_BE_ZERO
|
|
+ /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage)
|
|
+ * means that it isn't obvious if EXEC_P should be set.
|
|
+ * All of the following must be true for an executable:
|
|
+ * There must be no relocations, the bfd can be neither an
|
|
+ * archive nor an archive element, and the file must be executable. */
|
|
+
|
|
+ if (exec.a_trsize + exec.a_drsize == 0
|
|
+ && bfd_get_format(abfd) == bfd_object && abfd->my_archive == NULL)
|
|
+ {
|
|
+ struct stat buf;
|
|
+#ifndef S_IXUSR
|
|
+#define S_IXUSR 0100 /* Execute by owner. */
|
|
+#endif
|
|
+ if (stat(abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR))
|
|
+ abfd->flags |= EXEC_P;
|
|
+ }
|
|
+#endif /* ENTRY_CAN_BE_ZERO */
|
|
+
|
|
+ return target;
|
|
+}
|