84 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#define _SYSTEM 1
 | 
						|
 | 
						|
#include <minix/type.h>
 | 
						|
#include <minix/const.h>
 | 
						|
#include <a.out.h>
 | 
						|
#include <assert.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <libexec.h>
 | 
						|
 | 
						|
int read_header_aout(
 | 
						|
  const char *exec_hdr,		/* executable header */
 | 
						|
  size_t exec_len,		/* executable file size */
 | 
						|
  int *sep_id,			/* true iff sep I&D */
 | 
						|
  vir_bytes *text_bytes,	/* place to return text size */
 | 
						|
  vir_bytes *data_bytes,	/* place to return initialized data size */
 | 
						|
  vir_bytes *bss_bytes,		/* place to return bss size */
 | 
						|
  phys_bytes *tot_bytes,	/* place to return total size */
 | 
						|
  vir_bytes *pc,		/* program entry point (initial PC) */
 | 
						|
  int *hdrlenp
 | 
						|
)
 | 
						|
{
 | 
						|
/* Read the header and extract the text, data, bss and total sizes from it. */
 | 
						|
  struct exec *hdr;		/* a.out header is read in here */
 | 
						|
 | 
						|
  /* Read the header and check the magic number.  The standard MINIX header
 | 
						|
   * is defined in <a.out.h>.  It consists of 8 chars followed by 6 longs.
 | 
						|
   * Then come 4 more longs that are not used here.
 | 
						|
   *	Byte 0: magic number 0x01
 | 
						|
   *	Byte 1: magic number 0x03
 | 
						|
   *	Byte 2: normal = 0x10 (not checked, 0 is OK), separate I/D = 0x20
 | 
						|
   *	Byte 3: CPU type, Intel 16 bit = 0x04, Intel 32 bit = 0x10,
 | 
						|
   *            Motorola = 0x0B, Sun SPARC = 0x17
 | 
						|
   *	Byte 4: Header length = 0x20
 | 
						|
   *	Bytes 5-7 are not used.
 | 
						|
   *
 | 
						|
   *	Now come the 6 longs
 | 
						|
   *	Bytes  8-11: size of text segments in bytes
 | 
						|
   *	Bytes 12-15: size of initialized data segment in bytes
 | 
						|
   *	Bytes 16-19: size of bss in bytes
 | 
						|
   *	Bytes 20-23: program entry point
 | 
						|
   *	Bytes 24-27: total memory allocated to program (text, data + stack)
 | 
						|
   *	Bytes 28-31: size of symbol table in bytes
 | 
						|
   * The longs are represented in a machine dependent order,
 | 
						|
   * little-endian on the 8088, big-endian on the 68000.
 | 
						|
   * The header is followed directly by the text and data segments, and the
 | 
						|
   * symbol table (if any). The sizes are given in the header. Only the
 | 
						|
   * text and data segments are copied into memory by exec. The header is
 | 
						|
   * used here only. The symbol table is for the benefit of a debugger and
 | 
						|
   * is ignored here.
 | 
						|
   */
 | 
						|
 | 
						|
  assert(exec_hdr != NULL);
 | 
						|
 | 
						|
  hdr = (struct exec *)exec_hdr;
 | 
						|
  if (exec_len < A_MINHDR) return(ENOEXEC);
 | 
						|
 | 
						|
  /* Check magic number, cpu type, and flags. */
 | 
						|
  if (BADMAG(*hdr)) return(ENOEXEC);
 | 
						|
#if defined(__i386__)
 | 
						|
  if (hdr->a_cpu != A_I80386) return(ENOEXEC);
 | 
						|
#endif
 | 
						|
  if ((hdr->a_flags & ~(A_NSYM | A_EXEC | A_SEP)) != 0) return(ENOEXEC);
 | 
						|
 | 
						|
  *sep_id = !!(hdr->a_flags & A_SEP);	    /* separate I & D or not */
 | 
						|
 | 
						|
  /* Get text and data sizes. */
 | 
						|
  *text_bytes = (vir_bytes) hdr->a_text;	/* text size in bytes */
 | 
						|
  *data_bytes = (vir_bytes) hdr->a_data;	/* data size in bytes */
 | 
						|
  *bss_bytes  = (vir_bytes) hdr->a_bss;	/* bss size in bytes */
 | 
						|
  *tot_bytes  = hdr->a_total;		/* total bytes to allocate for prog */
 | 
						|
  if (*tot_bytes == 0) return(ENOEXEC);
 | 
						|
 | 
						|
  if (!*sep_id) {
 | 
						|
	/* If I & D space is not separated, it is all considered data. Text=0*/
 | 
						|
	*data_bytes += *text_bytes;
 | 
						|
	*text_bytes = 0;
 | 
						|
  }
 | 
						|
  *pc = hdr->a_entry;	/* initial address to start execution */
 | 
						|
  *hdrlenp = hdr->a_hdrlen & BYTE;		/* header length */
 | 
						|
 | 
						|
  return(OK);
 | 
						|
}
 |