2 Reading the EM object file
5 /* $Id: read.c,v 2.6 1994/06/24 10:48:47 ceriel Exp $ */
8 #include <local.h> /* for VERSION */
10 #include <as_spec.h> /* for as_magic */
23 extern double str2double();
26 /************************************************************************
27 * Read object file contents. *
28 ************************************************************************
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. *
37 ************************************************************************/
39 /* EM header Part 1 variables */
43 /* EM header Part 2 variables */
52 PRIVATE FILE *load_fp; /* Filepointer of load file */
54 PRIVATE ptr rd_repeat();
55 PRIVATE ptr rd_descr();
56 PRIVATE int rd_byte();
57 PRIVATE long rd_int();
62 if ((load_fp = fopen(fname, "r")) == NULL) {
63 fatal("Cannot open loadfile '%s'", fname);
70 if (rd_int(2L) != as_magic)
71 fatal("Bad magic number in loadfile");
76 fatal("Unresolved references in loadfile");
78 if (rd_int(2L) != VERSION)
79 fatal("Incorrect version number in loadfile");
81 /* We only allow the following wordsize/pointersize combinations: */
83 /* A fatal error will be generated if other combinations occur. */
86 if (!(wsize == 2 || wsize == 4))
87 fatal("Bad wordsize in loadfile");
89 dwsize = 2 * wsize; /* set double wordsize */
90 wsizem1 = wsize - 1; /* wordsize - 1 used often */
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");
98 rd_int(2L); /* Entry 7 is unused */
99 rd_int(2L); /* Entry 8 is unused */
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);
113 SZDATA = rd_int(psize);
115 rd_int(psize); /* entry 7 is unused */
116 rd_int(psize); /* entry 8 is unused */
121 fread(text, 1, (int) DB, load_fp);
126 register int type, prev_type;
127 register ptr pos, prev_pos; /* prev_pos invalid if prev_type==0 */
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));
136 /* repetition descriptor */
137 register size count = rd_int(psize);
139 LOG((" r6 rd_gda(), case 0: count = %lu", count));
140 if (prev_type == 0) {
141 fatal("Type 0 initialisation on type 0");
143 pos = rd_repeat(pos, count, prev_pos);
147 /* filling descriptor */
148 register size count = btol(rd_byte());
150 LOG((" r6 rd_gda(), case %d: count = %lu",
153 pos = rd_descr(type, count, prev_pos);
158 /* now protect the LIN and FIL area */
159 dt_prot(i2p(0), (long)LINSIZE);
160 dt_prot(i2p(4), psize);
168 for (p = 0; p < NPROC; p++) {
169 register long nloc = rd_int(psize);
170 register ptr ep = i2p(rd_int(psize));
183 /************************************************************************
184 * Read functions for several types. *
185 ************************************************************************
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. *
192 ************************************************************************/
194 /************************************************************************
195 * Reading a floating point number *
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 ************************************************************************/
202 PRIVATE ptr rd_repeat(pos, count, prev_pos)
206 register size diff = pos - prev_pos;
209 for (j = 0; j < count; j++) {
212 for (i = 0; i < diff; i++) {
213 data_loc(pos) = data_loc(pos - diff);
215 /* copy shadow byte, including protection bit */
216 dt_sh(pos) = dt_sh(pos - diff);
224 PRIVATE ptr rd_descr(type, count, pos)
230 char fl_rep[128]; /* fp number representation */
234 case 1: /* m uninitialized words */
241 case 2: /* m initialized bytes */
244 dt_stn(pos++, btol(rd_byte()), 1L);
247 case 3: /* m initialized wordsize integers */
248 for (j = 0; j < count; j++) {
249 dt_stw(pos, rd_int(wsize));
253 case 4: /* m initialized data pointers */
254 for (j = 0; j < count; j++) {
255 dt_stdp(pos, i2p(rd_int(psize)));
259 case 5: /* m initialized instruction pointers */
260 for (j = 0; j < count; j++) {
261 dt_stip(pos, i2p(rd_int(psize)));
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);
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 */
277 while (fl_rep[fl_cnt] = rd_byte()) {
279 if (fl_cnt >= sizeof (fl_rep)) {
280 fatal("Initialized float longer than %d chars",
285 /* store the float */
286 dt_stf(pos, str2double(fl_rep), j);
288 /* we cannot store the float */
294 fatal("Unknown initializer type in global data.");
300 PRIVATE int rd_byte()
304 if ((i = getc(load_fp)) == EOF)
305 fatal("EOF reached during initialization");
309 PRIVATE long rd_int(n)
316 for (i = 1; i < n; i++) {
317 l |= (btol(rd_byte()) << (i*8));