Pristine Ack-5.5
[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         rd_proctab();
112
113         rd_close();
114
115         /* Set up the arguments and environment */
116
117         vecp = ARGB;                    /* start of environ vector copy */
118         dppush(vecp);                   /* push address of env pointer */
119         strp = vecp + env_vec_size;     /* start of environ strings */
120         for (p = environ; *p != (char *) 0; p++) {
121                 dt_stdp(vecp, strp);
122                 strp = storestring(strp, *p);
123                 vecp += psize;
124         }
125         dt_stdp(vecp, i2p(0));          /* terminating zero */
126
127         vecp = strp;                    /* start of argument vector copy */
128         dppush(vecp);                   /* push address of argv pointer */
129         strp = vecp + arg_vec_size;     /* start of argument strings */
130         for (p = av; *p != (char *) 0; p++) {
131                 dt_stdp(vecp, strp);
132                 strp = storestring(strp, *p);
133                 vecp += psize;
134         }
135         dt_stdp(vecp, i2p(0));          /* terminating zero */
136
137         wpush((long) ac);       /* push argc */
138 }
139
140 PRIVATE size alignedstrlen(s)
141         char *s;
142 {
143         register size len = strlen(s) + 1;
144
145         return (len + wsize - 1) / wsize * wsize;
146 }
147
148 PRIVATE ptr storestring(addr, s)
149         ptr addr;
150         char *s;
151 {
152         /*      Store string, aligned to a fit multiple of wsize bytes.
153                 Return first address on a wordsize boundary after string.
154         */
155         register size oldlen = strlen(s) + 1;
156         register size newlen = ((oldlen + wsize - 1) / wsize) * wsize;
157         register long i;
158
159         LOG(("@g6 storestring(%lu, %s), oldlen = %ld, newlen = %ld",
160                         addr, s, oldlen, newlen));
161         ch_in_data(addr, newlen);
162         ch_aligned(addr, newlen);
163
164         /* copy data of source string */
165         for (i = 0; i < oldlen; i++) {
166                 data_loc(addr + i) = *s++;
167                 dt_int(addr + i);
168         }
169         /* pad until newlen */
170         for (; i < newlen; i++) {
171                 data_loc(addr + i) = (char) 0;
172                 dt_int(addr + i);
173         }
174         return (addr + i);
175 }
176
177 #ifdef  LOGGING
178 dt_clear_area(from, to)
179         ptr from;
180         register ptr to;
181 {
182         /* includes *from but excludes *to */
183         register ptr a;
184
185         for (a = from; a < to; a++) {
186                 dt_undef(a);
187         }
188 }
189
190 st_clear_area(from, to)
191         ptr from;
192         register ptr to;
193 {
194         /* includes both *from and *to (since ML+1 is unexpressible) */
195         register ptr a;
196
197         for (a = from; a >= to; a--) {
198                 st_undef(a);
199         }
200 }
201 #endif  /* LOGGING */
202