Add em22 compile, change EM machine executable format to put proc table in text
[Ack-5.5.git] / util / int / init.c
1 /*
2         Startup routines
3 */
4
5 /* $Id: init.c,v 2.4 1994/06/24 10:47:31 ceriel Exp $ */
6
7 #include        <stdio.h>
8
9 #include        <em_abs.h>
10 #include        "logging.h"
11 #include        "global.h"
12 #include        "log.h"
13 #include        "alloc.h"
14 #include        "warn.h"
15 #include        "mem.h"
16 #include        "shadow.h"
17 #include        "trap.h"
18 #include        "read.h"
19
20
21 /****************************************************************
22  *      The EM-machine is not implemented as a contiguous       *
23  *      piece of memory. Instead there are a number of          *
24  *      "floating" pieces of memory, each representing a        *
25  *      specific part of the machine. There are separate        *
26  *      allocations for:                                        *
27  *              - stack and local area (stack),                 *
28  *              - heap area & global data area (data),          *
29  *              - program text & procedure descriptors (text).  *
30  *      The names in parenthesis are the names of the global    *
31  *      variables used within our program, pointing to          *
32  *      the beginning of such an area. The sizes of the global  *
33  *      data area and the program text can be determined        *
34  *      once and for all in the "rd_header" routine.            *
35  ****************************************************************/
36
37 extern char **environ;
38
39 PRIVATE ptr storestring();
40 PRIVATE size alignedstrlen();
41
42 char *load_name;
43
44 init(ac, av)
45         int ac;
46         char **av;
47 {
48         register char **p;
49         register size env_vec_size;     /* size of environ vector */
50         register size arg_vec_size;     /* size of argument vector */
51         register size string_size = 0;  /* total size arg, env, strings */
52         register ptr ARGB, vecp, strp;
53         
54         init_ofiles(1);                 /* Initialize all output files */
55         init_signals();
56
57         /* Read the load file header, to obtain wsize and psize */
58         load_name = av[0];
59         rd_open(load_name);             /* Open object file */
60
61         rd_header();                    /* Read in load file header */
62
63         /* Initialize wsize- and psize-dependent variables */
64
65         init_rsb();
66         i_minsw = (wsize == 2) ? I_MINS2 : I_MINS4;
67         i_maxsw = (wsize == 2) ? I_MAXS2 : I_MAXS4;
68         i_maxuw = (wsize == 2) ? I_MAXU2 : I_MAXU4;
69         max_addr = i2p(((psize == 2) ? I_MAXU2 : I_MAXS4) / wsize * wsize) - 1;
70         min_off = (psize == 2) ? (-MAX_OFF2-1) : (-MAX_OFF4-1);
71         max_off = (psize == 2) ? MAX_OFF2 : MAX_OFF4;
72
73         /* Determine nr of bytes, needed to store arguments/environment */
74
75         env_vec_size = 0;               /* length of environ vector copy */
76         for (p = environ; *p != (char *) 0; p++) {
77                 string_size += alignedstrlen(*p);
78                 env_vec_size += psize;
79         }
80         env_vec_size += psize;          /* terminating zero */
81
82         arg_vec_size = 0;               /* length of argument vector copy */
83         for (p = av; *p != (char *) 0; p++) {
84                 string_size += alignedstrlen(*p);
85                 arg_vec_size += psize;
86         }
87         arg_vec_size += psize;          /* terminating zero */
88
89         /* One pseudo-register */
90         ARGB = i2p(SZDATA);             /* command arguments base */
91
92         /* Initialize segments */
93         init_text();
94         init_data(ARGB + arg_vec_size + env_vec_size + string_size);
95         init_stack();
96         init_FRA();
97         init_AB_list();
98
99         /* Initialize trap registers */
100         TrapPI = 0;                     /* set Trap Procedure Identifier */
101         OnTrap = TR_ABORT;              /* there cannot be a trap handler yet*/
102         IgnMask = PreIgnMask;           /* copy Ignore Mask from preset */
103
104         /* Initialize Exit Status */
105         ES_def = UNDEFINED;             /* set Exit Status illegal */
106
107         /* Read partitions */
108
109         rd_text();
110         rd_gda();
111
112         rd_close();
113
114         /* Set up the arguments and environment */
115
116         vecp = ARGB;                    /* start of environ vector copy */
117         dppush(vecp);                   /* push address of env pointer */
118         strp = vecp + env_vec_size;     /* start of environ strings */
119         for (p = environ; *p != (char *) 0; p++) {
120                 dt_stdp(vecp, strp);
121                 strp = storestring(strp, *p);
122                 vecp += psize;
123         }
124         dt_stdp(vecp, i2p(0));          /* terminating zero */
125
126         vecp = strp;                    /* start of argument vector copy */
127         dppush(vecp);                   /* push address of argv pointer */
128         strp = vecp + arg_vec_size;     /* start of argument strings */
129         for (p = av; *p != (char *) 0; p++) {
130                 dt_stdp(vecp, strp);
131                 strp = storestring(strp, *p);
132                 vecp += psize;
133         }
134         dt_stdp(vecp, i2p(0));          /* terminating zero */
135
136         wpush((long) ac);       /* push argc */
137 }
138
139 PRIVATE size alignedstrlen(s)
140         char *s;
141 {
142         register size len = strlen(s) + 1;
143
144         return (len + wsize - 1) / wsize * wsize;
145 }
146
147 PRIVATE ptr storestring(addr, s)
148         ptr addr;
149         char *s;
150 {
151         /*      Store string, aligned to a fit multiple of wsize bytes.
152                 Return first address on a wordsize boundary after string.
153         */
154         register size oldlen = strlen(s) + 1;
155         register size newlen = ((oldlen + wsize - 1) / wsize) * wsize;
156         register long i;
157
158         LOG(("@g6 storestring(%lu, %s), oldlen = %ld, newlen = %ld",
159                         addr, s, oldlen, newlen));
160         ch_in_data(addr, newlen);
161         ch_aligned(addr, newlen);
162
163         /* copy data of source string */
164         for (i = 0; i < oldlen; i++) {
165                 data_loc(addr + i) = *s++;
166                 dt_int(addr + i);
167         }
168         /* pad until newlen */
169         for (; i < newlen; i++) {
170                 data_loc(addr + i) = (char) 0;
171                 dt_int(addr + i);
172         }
173         return (addr + i);
174 }
175
176 #ifdef  LOGGING
177 dt_clear_area(from, to)
178         ptr from;
179         register ptr to;
180 {
181         /* includes *from but excludes *to */
182         register ptr a;
183
184         for (a = from; a < to; a++) {
185                 dt_undef(a);
186         }
187 }
188
189 st_clear_area(from, to)
190         ptr from;
191         register ptr to;
192 {
193         /* includes both *from and *to (since ML+1 is unexpressible) */
194         register ptr a;
195
196         for (a = from; a >= to; a--) {
197                 st_undef(a);
198         }
199 }
200 #endif  /* LOGGING */
201