$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;
+}
