ldivmod, uldivmod: fix qdivrem calls
[minix.git] / lib / libexec / exec_aout.c
blobf3eda79c899f0ccc872b4f7e40f4feadcdc5b758
1 #define _SYSTEM 1
3 #include <minix/type.h>
4 #include <minix/const.h>
5 #include <a.out.h>
6 #include <assert.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <libexec.h>
11 int read_header_aout(
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) */
20 int *hdrlenp
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
50 * is ignored here.
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);
60 #if defined(__i386__)
61 if (hdr->a_cpu != A_I80386) return(ENOEXEC);
62 #endif
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);
74 if (!*sep_id) {
75 /* If I & D space is not separated, it is all considered data. Text=0*/
76 *data_bytes += *text_bytes;
77 *text_bytes = 0;
79 *pc = hdr->a_entry; /* initial address to start execution */
80 *hdrlenp = hdr->a_hdrlen & BYTE; /* header length */
82 return(OK);