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