Add em22 compile, change EM machine executable format to put proc table in text
[Ack-5.5.git] / util / int / read.c
1 /*
2         Reading the EM object file
3 */
4
5 /* $Id: read.c,v 2.6 1994/06/24 10:48:47 ceriel Exp $ */
6
7 #include        <stdio.h>
8 #include        <local.h>               /* for VERSION */
9 #include        <em_spec.h>
10 #include        <as_spec.h>             /* for as_magic */
11
12 #include        "logging.h"
13 #include        "nofloat.h"
14 #include        "global.h"
15 #include        "log.h"
16 #include        "warn.h"
17 #include        "mem.h"
18 #include        "shadow.h"
19 #include        "read.h"
20 #include        "text.h"
21
22 #ifndef NOFLOAT
23 extern double str2double();
24 #endif  /* NOFLOAT */
25
26 /************************************************************************
27  *      Read object file contents.                                      *
28  ************************************************************************
29  *                                                                      *
30  *      rd_open()       - open object file.                             *
31  *      rd_header()     - read object file header.                      *
32  *      rd_text()       - read program text.                            *
33  *      rd_gda()        - read global data area.                        *
34  *      rd_close()      - close object file.                            *
35  *                                                                      *
36  ************************************************************************/
37
38 /* EM header Part 1 variables */
39
40 int FLAGS;
41
42 /* EM header Part 2 variables */
43
44 size NTEXT;
45 size NDATA;
46 long NPROC;
47 long ENTRY;
48 long NLINE;
49 size SZDATA;
50
51 PRIVATE FILE *load_fp;                  /* Filepointer of load file */
52
53 PRIVATE ptr rd_repeat();
54 PRIVATE ptr rd_descr();
55 PRIVATE int rd_byte();
56 PRIVATE long rd_int();
57
58 rd_open(fname)
59         char *fname;
60 {       /* Open loadfile */
61         if ((load_fp = fopen(fname, "r")) == NULL) {
62                 fatal("Cannot open loadfile '%s'", fname);
63         }
64 }
65
66 rd_header()
67 {
68         /* Part 1 */
69         if (rd_int(2L) != as_magic)
70                 fatal("Bad magic number in loadfile");
71
72         FLAGS = rd_int(2L);
73
74         if (rd_int(2L) != 0)
75                 fatal("Unresolved references in loadfile");
76
77         if (rd_int(2L) != VERSION)
78                 fatal("Incorrect version number in loadfile");
79
80         /* We only allow the following wordsize/pointersize combinations: */
81         /*      2/2, 2/4, 4/4                                             */
82         /* A fatal error will be generated if other combinations occur.   */
83         
84         wsize = rd_int(2L);
85         if (!(wsize == 2 || wsize == 4))
86                 fatal("Bad wordsize in loadfile");
87
88         dwsize = 2 * wsize;             /* set double wordsize */
89         wsizem1 = wsize - 1;            /* wordsize - 1 used often */
90         
91         psize = rd_int(2L);
92         if (!(psize == 2 || psize == 4) || psize < wsize)
93                 fatal("Bad pointersize in loadfile");
94         if (2 * psize > FRALimit)
95                 fatal("FRA maximum size too small");
96         
97         rd_int(2L);                     /* Entry 7 is unused */
98         rd_int(2L);                     /* Entry 8 is unused */
99
100         /* Part 2 */
101         NTEXT = rd_int(psize);
102         NDATA = rd_int(psize);
103         NPROC = rd_int(psize);
104         if (NPROC < 0 || NPROC * psize * 3 > NTEXT)
105                 fatal("Bad proc table");
106         ENTRY = rd_int(psize);
107         if (ENTRY < 0 || ENTRY >= NPROC)
108                 fatal("Bad entry point");
109         NLINE = rd_int(psize);
110         if (NLINE == 0) {
111                 warning(WNLINEZR);
112                 NLINE = I_MAXS4;
113         }
114         SZDATA = rd_int(psize);
115
116         rd_int(psize);                  /* entry 7 is unused */
117         rd_int(psize);                  /* entry 8 is unused */
118 }
119
120 rd_text()
121 {
122         fread(text, 1, (int) DB, load_fp);
123 }
124
125 rd_gda()
126 {
127         register int type, prev_type;
128         register ptr pos, prev_pos;     /* prev_pos invalid if prev_type==0 */
129         register long i;
130         
131         type = prev_type = 0;
132         pos = prev_pos = i2p(0);
133         for (i = 1; i <= NDATA; i++) {
134                 type = btol(rd_byte());
135                 LOG((" r6 rd_gda(), i = %ld, pos = %u", i, pos));
136                 if (type == 0) {
137                         /* repetition descriptor */
138                         register size count = rd_int(psize);
139                         
140                         LOG((" r6 rd_gda(), case 0: count = %lu", count));
141                         if (prev_type == 0) {
142                                 fatal("Type 0 initialisation on type 0");
143                         }
144                         pos = rd_repeat(pos, count, prev_pos);
145                         prev_type = 0;
146                 }
147                 else {
148                         /* filling descriptor */
149                         register size count = btol(rd_byte());
150                         
151                         LOG((" r6 rd_gda(), case %d: count = %lu",
152                                 type, count));
153                         prev_pos = pos;
154                         pos = rd_descr(type, count, prev_pos);
155                         prev_type = type;
156                 }
157         }
158
159         /* now protect the LIN and FIL area */
160         dt_prot(i2p(0), (long)LINSIZE);
161         dt_prot(i2p(4), psize);
162 }
163
164 rd_close()
165 {
166         fclose(load_fp);
167         load_fp = 0;
168 }
169
170 /************************************************************************
171  *      Read functions for several types.                               *
172  ************************************************************************
173  *                                                                      *
174  *      rd_repeat()     - repeat the previous initialisation            *
175  *      rd_descr()      - read a descriptor                             *
176  *      rd_byte()       - read one byte, return a int.                  *
177  *      rd_int(n)       - read n byte integer, return a long.           *
178  *                                                                      *
179  ************************************************************************/
180
181 /************************************************************************
182  *              Reading a floating point number                         *
183  *                                                                      *
184  *      A double is 8 bytes, so it can contain 4- and 8-byte (EM)       *
185  *      floating point numbers. That's why a 4-byte floating point      *
186  *      number is also stored in a double.                              *
187  ************************************************************************/
188
189 PRIVATE ptr rd_repeat(pos, count, prev_pos)
190         ptr pos, prev_pos;
191         size count;
192 {
193         register size diff = pos - prev_pos;
194         register size j;
195         
196         for (j = 0; j < count; j++) {
197                 register long i;
198
199                 for (i = 0; i < diff; i++) {
200                         data_loc(pos) = data_loc(pos - diff);
201 #ifdef  LOGGING
202                         /* copy shadow byte, including protection bit */
203                         dt_sh(pos) = dt_sh(pos - diff);
204 #endif  /* LOGGING */
205                         pos++;
206                 }
207         }
208         return pos;
209 }
210
211 PRIVATE ptr rd_descr(type, count, pos)
212         int type;
213         size count;
214         ptr pos;
215 {
216         register size j;
217         char fl_rep[128];               /* fp number representation */
218         register int fl_cnt;
219                 
220         switch (type) {
221         case 1:                 /* m uninitialized words */
222                 j = count;
223                 while (j--) {
224                         dt_stw(pos, 0L);
225                         pos += wsize;
226                 }
227                 break;
228         case 2:                 /* m initialized bytes */
229                 j = count;
230                 while (j--) {
231                         dt_stn(pos++, btol(rd_byte()), 1L);
232                 }
233                 break;
234         case 3:                 /* m initialized wordsize integers */
235                 for (j = 0; j < count; j++) {
236                         dt_stw(pos, rd_int(wsize));
237                         pos += wsize;
238                 }
239                 break;
240         case 4:                 /* m initialized data pointers */
241                 for (j = 0; j < count; j++) {
242                         dt_stdp(pos, i2p(rd_int(psize)));
243                         pos += psize;
244                 }
245                 break;
246         case 5:                 /* m initialized instruction pointers */
247                 for (j = 0; j < count; j++) {
248                         dt_stip(pos, i2p(rd_int(psize)));
249                         pos += psize;
250                 }
251                 break;
252         case 6:                 /* initialized integer of size m */
253         case 7:                 /* initialized unsigned int of size m */
254                 if ((j = count) != 1 && j != 2 && j != 4)
255                         fatal("Bad integersize during initialisation");
256                 dt_stn(pos, rd_int(j), j);
257                 pos += j;
258                 break;
259         case 8:                 /* initialized float of size m */
260                 if ((j = count) != 4 && j != 8)
261                         fatal("Bad floatsize during initialisation");
262                 /* get fp representation */
263                 fl_cnt = 0;
264                 while (fl_rep[fl_cnt] = rd_byte()) {
265                         fl_cnt++;
266                         if (fl_cnt >= sizeof (fl_rep)) {
267                                 fatal("Initialized float longer than %d chars",
268                                         sizeof (fl_rep));
269                         }
270                 }
271 #ifndef NOFLOAT
272                 /* store the float */
273                 dt_stf(pos, str2double(fl_rep), j);
274 #else   /* NOFLOAT */
275                 /* we cannot store the float */
276                 warning(WFLINIT);
277 #endif  /* NOFLOAT */
278                 pos += j;
279                 break;
280         default:
281                 fatal("Unknown initializer type in global data.");
282                 break;
283         }
284         return pos;
285 }
286
287 PRIVATE int rd_byte()
288 {
289         register int i;
290         
291         if ((i = getc(load_fp)) == EOF)
292                 fatal("EOF reached during initialization");
293         return (i);
294 }
295
296 PRIVATE long rd_int(n)
297         size n;
298 {
299         register long l;
300         register int i;
301         
302         l = btol(rd_byte());
303         for (i = 1; i < n; i++) {
304                 l |= (btol(rd_byte()) << (i*8));
305         }
306         return (l);
307 }
308