3 #include <minix/type.h>
4 #include <minix/const.h>
12 const char *exec_hdr
, /* executable header */
13 size_t exec_len
, /* executable file size */
14 int *sep_id
, /* true iff sep I&D */
15 vir_bytes
*text_bytes
, /* place to return text size */
16 vir_bytes
*data_bytes
, /* place to return initialized data size */
17 vir_bytes
*bss_bytes
, /* place to return bss size */
18 phys_bytes
*tot_bytes
, /* place to return total size */
19 vir_bytes
*pc
, /* program entry point (initial PC) */
23 /* Read the header and extract the text, data, bss and total sizes from it. */
24 struct exec
*hdr
; /* a.out header is read in here */
26 /* Read the header and check the magic number. The standard MINIX header
27 * is defined in <a.out.h>. It consists of 8 chars followed by 6 longs.
28 * Then come 4 more longs that are not used here.
29 * Byte 0: magic number 0x01
30 * Byte 1: magic number 0x03
31 * Byte 2: normal = 0x10 (not checked, 0 is OK), separate I/D = 0x20
32 * Byte 3: CPU type, Intel 16 bit = 0x04, Intel 32 bit = 0x10,
33 * Motorola = 0x0B, Sun SPARC = 0x17
34 * Byte 4: Header length = 0x20
35 * Bytes 5-7 are not used.
37 * Now come the 6 longs
38 * Bytes 8-11: size of text segments in bytes
39 * Bytes 12-15: size of initialized data segment in bytes
40 * Bytes 16-19: size of bss in bytes
41 * Bytes 20-23: program entry point
42 * Bytes 24-27: total memory allocated to program (text, data + stack)
43 * Bytes 28-31: size of symbol table in bytes
44 * The longs are represented in a machine dependent order,
45 * little-endian on the 8088, big-endian on the 68000.
46 * The header is followed directly by the text and data segments, and the
47 * symbol table (if any). The sizes are given in the header. Only the
48 * text and data segments are copied into memory by exec. The header is
49 * used here only. The symbol table is for the benefit of a debugger and
53 assert(exec_hdr
!= NULL
);
55 hdr
= (struct exec
*)exec_hdr
;
56 if (exec_len
< A_MINHDR
) return(ENOEXEC
);
58 /* Check magic number, cpu type, and flags. */
59 if (BADMAG(*hdr
)) return(ENOEXEC
);
61 if (hdr
->a_cpu
!= A_I80386
) return(ENOEXEC
);
63 if ((hdr
->a_flags
& ~(A_NSYM
| A_EXEC
| A_SEP
)) != 0) return(ENOEXEC
);
65 *sep_id
= !!(hdr
->a_flags
& A_SEP
); /* separate I & D or not */
67 /* Get text and data sizes. */
68 *text_bytes
= (vir_bytes
) hdr
->a_text
; /* text size in bytes */
69 *data_bytes
= (vir_bytes
) hdr
->a_data
; /* data size in bytes */
70 *bss_bytes
= (vir_bytes
) hdr
->a_bss
; /* bss size in bytes */
71 *tot_bytes
= hdr
->a_total
; /* total bytes to allocate for prog */
72 if (*tot_bytes
== 0) return(ENOEXEC
);
75 /* If I & D space is not separated, it is all considered data. Text=0*/
76 *data_bytes
+= *text_bytes
;
79 *pc
= hdr
->a_entry
; /* initial address to start execution */
80 *hdrlenp
= hdr
->a_hdrlen
& BYTE
; /* header length */