Initial entry
This commit is contained in:
320
util/int/read.c
Normal file
320
util/int/read.c
Normal file
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
Reading the EM object file
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "e.out.h"
|
||||
#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) != 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 */
|
||||
|
||||
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. In this case only the *
|
||||
* the 4 LSB's are used. These bytes contain the most important *
|
||||
* information, the MSB's are just for precision. *
|
||||
************************************************************************/
|
||||
|
||||
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_stn(pos, 0L, wsize);
|
||||
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_stn(pos, rd_int(wsize), 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 = fgetc(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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user