123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /*
- Reading the EM object file
- */
- /* $Id$ */
- #include <stdio.h>
- #include <local.h> /* for VERSION */
- #include <em_spec.h>
- #include <as_spec.h> /* for as_magic */
- #include "logging.h"
- #include "nofloat.h"
- #include "global.h"
- #include "log.h"
- #include "warn.h"
- #include "mem.h"
- #include "shadow.h"
- #include "read.h"
- #include "text.h"
- #ifndef NOFLOAT
- extern double str2double();
- #endif /* NOFLOAT */
- /************************************************************************
- * Read object file contents. *
- ************************************************************************
- * *
- * rd_open() - open object file. *
- * rd_header() - read object file header. *
- * rd_text() - read program text. *
- * rd_gda() - read global data area. *
- * rd_proctab() - read procedure descriptors, *
- * rd_close() - close object file. *
- * *
- ************************************************************************/
- /* EM header Part 1 variables */
- int FLAGS;
- /* EM header Part 2 variables */
- size NTEXT;
- size NDATA;
- long NPROC;
- long ENTRY;
- long NLINE;
- size SZDATA;
- PRIVATE FILE *load_fp; /* Filepointer of load file */
- PRIVATE ptr rd_repeat();
- PRIVATE ptr rd_descr();
- PRIVATE int rd_byte();
- PRIVATE long rd_int();
- rd_open(fname)
- char *fname;
- { /* Open loadfile */
- if ((load_fp = fopen(fname, "r")) == NULL) {
- fatal("Cannot open loadfile '%s'", fname);
- }
- }
- rd_header()
- {
- /* Part 1 */
- if (rd_int(2L) != as_magic)
- fatal("Bad magic number in loadfile");
- FLAGS = rd_int(2L);
- if (rd_int(2L) != 0)
- fatal("Unresolved references in loadfile");
- if (rd_int(2L) != VERSION)
- fatal("Incorrect version number in loadfile");
- /* We only allow the following wordsize/pointersize combinations: */
- /* 2/2, 2/4, 4/4 */
- /* A fatal error will be generated if other combinations occur. */
-
- wsize = rd_int(2L);
- if (!(wsize == 2 || wsize == 4))
- fatal("Bad wordsize in loadfile");
- dwsize = 2 * wsize; /* set double wordsize */
- wsizem1 = wsize - 1; /* wordsize - 1 used often */
-
- psize = rd_int(2L);
- if (!(psize == 2 || psize == 4) || psize < wsize)
- fatal("Bad pointersize in loadfile");
- if (2 * psize > FRALimit)
- fatal("FRA maximum size too small");
-
- rd_int(2L); /* Entry 7 is unused */
- rd_int(2L); /* Entry 8 is unused */
- /* Part 2 */
- NTEXT = rd_int(psize);
- NDATA = rd_int(psize);
- NPROC = rd_int(psize);
- ENTRY = rd_int(psize);
- if (ENTRY < 0 || ENTRY >= NPROC)
- fatal("Bad entry point");
- NLINE = rd_int(psize);
- if (NLINE == 0) {
- warning(WNLINEZR);
- NLINE = I_MAXS4;
- }
- SZDATA = rd_int(psize);
- rd_int(psize); /* entry 7 is unused */
- rd_int(psize); /* entry 8 is unused */
- }
- rd_text()
- {
- fread(text, 1, (int) DB, load_fp);
- }
- rd_gda()
- {
- register int type, prev_type;
- register ptr pos, prev_pos; /* prev_pos invalid if prev_type==0 */
- register long i;
-
- type = prev_type = 0;
- pos = prev_pos = i2p(0);
- for (i = 1; i <= NDATA; i++) {
- type = btol(rd_byte());
- LOG((" r6 rd_gda(), i = %ld, pos = %u", i, pos));
- if (type == 0) {
- /* repetition descriptor */
- register size count = rd_int(psize);
-
- LOG((" r6 rd_gda(), case 0: count = %lu", count));
- if (prev_type == 0) {
- fatal("Type 0 initialisation on type 0");
- }
- pos = rd_repeat(pos, count, prev_pos);
- prev_type = 0;
- }
- else {
- /* filling descriptor */
- register size count = btol(rd_byte());
-
- LOG((" r6 rd_gda(), case %d: count = %lu",
- type, count));
- prev_pos = pos;
- pos = rd_descr(type, count, prev_pos);
- prev_type = type;
- }
- }
- /* now protect the LIN and FIL area */
- dt_prot(i2p(0), (long)LINSIZE);
- dt_prot(i2p(4), psize);
- }
- rd_proctab()
- {
- register long p;
- init_proctab();
- for (p = 0; p < NPROC; p++) {
- register long nloc = rd_int(psize);
- register ptr ep = i2p(rd_int(psize));
- add_proc(nloc, ep);
- }
- end_init_proctab();
- }
- rd_close()
- {
- fclose(load_fp);
- load_fp = 0;
- }
- /************************************************************************
- * Read functions for several types. *
- ************************************************************************
- * *
- * rd_repeat() - repeat the previous initialisation *
- * rd_descr() - read a descriptor *
- * rd_byte() - read one byte, return a int. *
- * rd_int(n) - read n byte integer, return a long. *
- * *
- ************************************************************************/
- /************************************************************************
- * Reading a floating point number *
- * *
- * A double is 8 bytes, so it can contain 4- and 8-byte (EM) *
- * floating point numbers. That's why a 4-byte floating point *
- * number is also stored in a double. *
- ************************************************************************/
- PRIVATE ptr rd_repeat(pos, count, prev_pos)
- ptr pos, prev_pos;
- size count;
- {
- register size diff = pos - prev_pos;
- register size j;
-
- for (j = 0; j < count; j++) {
- register long i;
- for (i = 0; i < diff; i++) {
- data_loc(pos) = data_loc(pos - diff);
- #ifdef LOGGING
- /* copy shadow byte, including protection bit */
- dt_sh(pos) = dt_sh(pos - diff);
- #endif /* LOGGING */
- pos++;
- }
- }
- return pos;
- }
- PRIVATE ptr rd_descr(type, count, pos)
- int type;
- size count;
- ptr pos;
- {
- register size j;
- char fl_rep[128]; /* fp number representation */
- register int fl_cnt;
-
- switch (type) {
- case 1: /* m uninitialized words */
- j = count;
- while (j--) {
- dt_stw(pos, 0L);
- pos += wsize;
- }
- break;
- case 2: /* m initialized bytes */
- j = count;
- while (j--) {
- dt_stn(pos++, btol(rd_byte()), 1L);
- }
- break;
- case 3: /* m initialized wordsize integers */
- for (j = 0; j < count; j++) {
- dt_stw(pos, rd_int(wsize));
- pos += wsize;
- }
- break;
- case 4: /* m initialized data pointers */
- for (j = 0; j < count; j++) {
- dt_stdp(pos, i2p(rd_int(psize)));
- pos += psize;
- }
- break;
- case 5: /* m initialized instruction pointers */
- for (j = 0; j < count; j++) {
- dt_stip(pos, i2p(rd_int(psize)));
- pos += psize;
- }
- break;
- case 6: /* initialized integer of size m */
- case 7: /* initialized unsigned int of size m */
- if ((j = count) != 1 && j != 2 && j != 4)
- fatal("Bad integersize during initialisation");
- dt_stn(pos, rd_int(j), j);
- pos += j;
- break;
- case 8: /* initialized float of size m */
- if ((j = count) != 4 && j != 8)
- fatal("Bad floatsize during initialisation");
- /* get fp representation */
- fl_cnt = 0;
- while (fl_rep[fl_cnt] = rd_byte()) {
- fl_cnt++;
- if (fl_cnt >= sizeof (fl_rep)) {
- fatal("Initialized float longer than %d chars",
- sizeof (fl_rep));
- }
- }
- #ifndef NOFLOAT
- /* store the float */
- dt_stf(pos, str2double(fl_rep), j);
- #else /* NOFLOAT */
- /* we cannot store the float */
- warning(WFLINIT);
- #endif /* NOFLOAT */
- pos += j;
- break;
- default:
- fatal("Unknown initializer type in global data.");
- break;
- }
- return pos;
- }
- PRIVATE int rd_byte()
- {
- register int i;
-
- if ((i = getc(load_fp)) == EOF)
- fatal("EOF reached during initialization");
- return (i);
- }
- PRIVATE long rd_int(n)
- size n;
- {
- register long l;
- register int i;
-
- l = btol(rd_byte());
- for (i = 1; i < n; i++) {
- l |= (btol(rd_byte()) << (i*8));
- }
- return (l);
- }
|