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_close() - close object file. *
36 ************************************************************************/
38 /* EM header Part 1 variables */
42 /* EM header Part 2 variables */
51 PRIVATE FILE *load_fp; /* Filepointer of load file */
53 PRIVATE ptr rd_repeat();
54 PRIVATE ptr rd_descr();
55 PRIVATE int rd_byte();
56 PRIVATE long rd_int();
61 if ((load_fp = fopen(fname, "r")) == NULL) {
62 fatal("Cannot open loadfile '%s'", fname);
69 if (rd_int(2L) != as_magic)
70 fatal("Bad magic number in loadfile");
75 fatal("Unresolved references in loadfile");
77 if (rd_int(2L) != VERSION)
78 fatal("Incorrect version number in loadfile");
80 /* We only allow the following wordsize/pointersize combinations: */
82 /* A fatal error will be generated if other combinations occur. */
85 if (!(wsize == 2 || wsize == 4))
86 fatal("Bad wordsize in loadfile");
88 dwsize = 2 * wsize; /* set double wordsize */
89 wsizem1 = wsize - 1; /* wordsize - 1 used often */
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");
97 rd_int(2L); /* Entry 7 is unused */
98 rd_int(2L); /* Entry 8 is unused */
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);
114 SZDATA = rd_int(psize);
116 rd_int(psize); /* entry 7 is unused */
117 rd_int(psize); /* entry 8 is unused */
122 fread(text, 1, (int) DB, load_fp);
127 register int type, prev_type;
128 register ptr pos, prev_pos; /* prev_pos invalid if prev_type==0 */
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));
137 /* repetition descriptor */
138 register size count = rd_int(psize);
140 LOG((" r6 rd_gda(), case 0: count = %lu", count));
141 if (prev_type == 0) {
142 fatal("Type 0 initialisation on type 0");
144 pos = rd_repeat(pos, count, prev_pos);
148 /* filling descriptor */
149 register size count = btol(rd_byte());
151 LOG((" r6 rd_gda(), case %d: count = %lu",
154 pos = rd_descr(type, count, prev_pos);
159 /* now protect the LIN and FIL area */
160 dt_prot(i2p(0), (long)LINSIZE);
161 dt_prot(i2p(4), psize);
170 /************************************************************************
171 * Read functions for several types. *
172 ************************************************************************
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. *
179 ************************************************************************/
181 /************************************************************************
182 * Reading a floating point number *
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 ************************************************************************/
189 PRIVATE ptr rd_repeat(pos, count, prev_pos)
193 register size diff = pos - prev_pos;
196 for (j = 0; j < count; j++) {
199 for (i = 0; i < diff; i++) {
200 data_loc(pos) = data_loc(pos - diff);
202 /* copy shadow byte, including protection bit */
203 dt_sh(pos) = dt_sh(pos - diff);
211 PRIVATE ptr rd_descr(type, count, pos)
217 char fl_rep[128]; /* fp number representation */
221 case 1: /* m uninitialized words */
228 case 2: /* m initialized bytes */
231 dt_stn(pos++, btol(rd_byte()), 1L);
234 case 3: /* m initialized wordsize integers */
235 for (j = 0; j < count; j++) {
236 dt_stw(pos, rd_int(wsize));
240 case 4: /* m initialized data pointers */
241 for (j = 0; j < count; j++) {
242 dt_stdp(pos, i2p(rd_int(psize)));
246 case 5: /* m initialized instruction pointers */
247 for (j = 0; j < count; j++) {
248 dt_stip(pos, i2p(rd_int(psize)));
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);
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 */
264 while (fl_rep[fl_cnt] = rd_byte()) {
266 if (fl_cnt >= sizeof (fl_rep)) {
267 fatal("Initialized float longer than %d chars",
272 /* store the float */
273 dt_stf(pos, str2double(fl_rep), j);
275 /* we cannot store the float */
281 fatal("Unknown initializer type in global data.");
287 PRIVATE int rd_byte()
291 if ((i = getc(load_fp)) == EOF)
292 fatal("EOF reached during initialization");
296 PRIVATE long rd_int(n)
303 for (i = 1; i < n; i++) {
304 l |= (btol(rd_byte()) << (i*8));