ack/util/int/read.c

334 lines
7.1 KiB
C
Raw Normal View History

2019-03-17 14:42:00 +00:00
/** @file
* Reading the EM object file
*/
1988-06-22 16:57:09 +00:00
1994-06-24 11:31:16 +00:00
/* $Id$ */
1988-06-22 16:57:09 +00:00
#include <stdio.h>
2019-03-17 14:42:00 +00:00
#include "local.h" /* for VERSION */
#include "em_spec.h"
#include "as_spec.h" /* for as_magic */
1988-06-22 16:57:09 +00:00
#include "logging.h"
#include "nofloat.h"
#include "global.h"
#include "log.h"
2019-03-17 14:42:00 +00:00
#include "io.h"
#include "data.h"
#include "proctab.h"
1988-06-22 16:57:09 +00:00
#include "warn.h"
#include "mem.h"
#include "shadow.h"
#include "read.h"
#include "text.h"
#ifndef NOFLOAT
extern double str2double();
#endif /* NOFLOAT */
1988-06-22 16:57:09 +00:00
/************************************************************************
* 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;
2019-03-17 14:42:00 +00:00
PRIVATE FILE *load_fp; /* Filepointer of load file */
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
PRIVATE ptr rd_repeat(ptr, size, ptr);
PRIVATE ptr rd_descr(int, size, ptr);
PRIVATE int rd_byte(void);
PRIVATE long rd_int(size);
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
void rd_open(char *fname)
{ /* Open loadfile */
if ((load_fp = fopen(fname, "r")) == NULL)
{
1988-06-22 16:57:09 +00:00
fatal("Cannot open loadfile '%s'", fname);
}
}
2019-03-17 14:42:00 +00:00
void rd_header(void)
1988-06-22 16:57:09 +00:00
{
/* Part 1 */
1988-10-03 14:44:39 +00:00
if (rd_int(2L) != as_magic)
1988-06-22 16:57:09 +00:00
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. */
2019-03-17 14:42:00 +00:00
1988-06-22 16:57:09 +00:00
wsize = rd_int(2L);
if (!(wsize == 2 || wsize == 4))
fatal("Bad wordsize in loadfile");
2019-03-17 14:42:00 +00:00
dwsize = 2 * wsize; /* set double wordsize */
wsizem1 = wsize - 1; /* wordsize - 1 used often */
1988-06-22 16:57:09 +00:00
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");
2019-03-17 14:42:00 +00:00
rd_int(2L); /* Entry 7 is unused */
rd_int(2L); /* Entry 8 is unused */
1988-06-22 16:57:09 +00:00
/* 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);
2019-03-17 14:42:00 +00:00
if (NLINE == 0)
{
1988-06-22 16:57:09 +00:00
warning(WNLINEZR);
NLINE = I_MAXS4;
}
SZDATA = rd_int(psize);
2019-03-17 14:42:00 +00:00
rd_int(psize); /* entry 7 is unused */
rd_int(psize); /* entry 8 is unused */
1988-06-22 16:57:09 +00:00
}
2019-03-17 14:42:00 +00:00
void rd_text(void)
1988-06-22 16:57:09 +00:00
{
fread(text, 1, (int) DB, load_fp);
}
2019-03-17 14:42:00 +00:00
void rd_gda(void)
1988-06-22 16:57:09 +00:00
{
register int type, prev_type;
2019-03-17 14:42:00 +00:00
register ptr pos, prev_pos; /* prev_pos invalid if prev_type==0 */
1988-06-22 16:57:09 +00:00
register long i;
2019-03-17 14:42:00 +00:00
1988-06-22 16:57:09 +00:00
type = prev_type = 0;
pos = prev_pos = i2p(0);
2019-03-17 14:42:00 +00:00
for (i = 1; i <= NDATA; i++)
{
1988-06-22 16:57:09 +00:00
type = btol(rd_byte());
LOG((" r6 rd_gda(), i = %ld, pos = %u", i, pos));
2019-03-17 14:42:00 +00:00
if (type == 0)
{
1988-06-22 16:57:09 +00:00
/* repetition descriptor */
register size count = rd_int(psize);
2019-03-17 14:42:00 +00:00
1988-06-22 16:57:09 +00:00
LOG((" r6 rd_gda(), case 0: count = %lu", count));
2019-03-17 14:42:00 +00:00
if (prev_type == 0)
{
1988-06-22 16:57:09 +00:00
fatal("Type 0 initialisation on type 0");
}
pos = rd_repeat(pos, count, prev_pos);
prev_type = 0;
}
2019-03-17 14:42:00 +00:00
else
{
1988-06-22 16:57:09 +00:00
/* filling descriptor */
register size count = btol(rd_byte());
2019-03-17 14:42:00 +00:00
LOG((" r6 rd_gda(), case %d: count = %lu", type, count));
1988-06-22 16:57:09 +00:00
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);
}
2019-03-17 14:42:00 +00:00
void rd_proctab(void)
1988-06-22 16:57:09 +00:00
{
register long p;
init_proctab();
2019-03-17 14:42:00 +00:00
for (p = 0; p < NPROC; p++)
{
1988-06-22 16:57:09 +00:00
register long nloc = rd_int(psize);
register ptr ep = i2p(rd_int(psize));
add_proc(nloc, ep);
}
end_init_proctab();
}
2019-03-17 14:42:00 +00:00
void rd_close(void)
1988-06-22 16:57:09 +00:00
{
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. *
1988-06-22 16:57:09 +00:00
************************************************************************/
2019-03-17 14:42:00 +00:00
PRIVATE ptr rd_repeat(ptr pos, size count, ptr prev_pos)
1988-06-22 16:57:09 +00:00
{
register size diff = pos - prev_pos;
register size j;
2019-03-17 14:42:00 +00:00
for (j = 0; j < count; j++)
{
1988-06-22 16:57:09 +00:00
register long i;
2019-03-17 14:42:00 +00:00
for (i = 0; i < diff; i++)
{
1988-06-22 16:57:09 +00:00
data_loc(pos) = data_loc(pos - diff);
#ifdef LOGGING
/* copy shadow byte, including protection bit */
dt_sh(pos) = dt_sh(pos - diff);
#endif /* LOGGING */
1988-06-22 16:57:09 +00:00
pos++;
}
}
return pos;
}
2019-03-17 14:42:00 +00:00
PRIVATE ptr rd_descr(int type, size count, ptr pos)
1988-06-22 16:57:09 +00:00
{
register size j;
2019-03-17 14:42:00 +00:00
char fl_rep[128]; /* fp number representation */
1988-06-22 16:57:09 +00:00
register int fl_cnt;
2019-03-17 14:42:00 +00:00
switch (type)
{
case 1: /* m uninitialized words */
1988-06-22 16:57:09 +00:00
j = count;
2019-03-17 14:42:00 +00:00
while (j--)
{
1989-11-22 13:38:37 +00:00
dt_stw(pos, 0L);
1988-06-22 16:57:09 +00:00
pos += wsize;
}
break;
2019-03-17 14:42:00 +00:00
case 2: /* m initialized bytes */
1988-06-22 16:57:09 +00:00
j = count;
2019-03-17 14:42:00 +00:00
while (j--)
{
1988-06-22 16:57:09 +00:00
dt_stn(pos++, btol(rd_byte()), 1L);
}
break;
2019-03-17 14:42:00 +00:00
case 3: /* m initialized wordsize integers */
for (j = 0; j < count; j++)
{
1989-11-22 13:38:37 +00:00
dt_stw(pos, rd_int(wsize));
1988-06-22 16:57:09 +00:00
pos += wsize;
}
break;
2019-03-17 14:42:00 +00:00
case 4: /* m initialized data pointers */
for (j = 0; j < count; j++)
{
1988-06-22 16:57:09 +00:00
dt_stdp(pos, i2p(rd_int(psize)));
pos += psize;
}
break;
2019-03-17 14:42:00 +00:00
case 5: /* m initialized instruction pointers */
for (j = 0; j < count; j++)
{
1988-06-22 16:57:09 +00:00
dt_stip(pos, i2p(rd_int(psize)));
pos += psize;
}
break;
2019-03-17 14:42:00 +00:00
case 6: /* initialized integer of size m */
case 7: /* initialized unsigned int of size m */
1988-06-22 16:57:09 +00:00
if ((j = count) != 1 && j != 2 && j != 4)
fatal("Bad integersize during initialisation");
dt_stn(pos, rd_int(j), j);
pos += j;
break;
2019-03-17 14:42:00 +00:00
case 8: /* initialized float of size m */
1988-06-22 16:57:09 +00:00
if ((j = count) != 4 && j != 8)
fatal("Bad floatsize during initialisation");
/* get fp representation */
fl_cnt = 0;
2019-03-17 14:42:00 +00:00
while ( (fl_rep[fl_cnt] = rd_byte()) )
{
1988-06-22 16:57:09 +00:00
fl_cnt++;
2019-03-17 14:42:00 +00:00
if (fl_cnt >= sizeof(fl_rep))
{
fatal("Initialized float longer than %d chars", sizeof(fl_rep));
1988-06-22 16:57:09 +00:00
}
}
#ifndef NOFLOAT
/* store the float */
dt_stf(pos, str2double(fl_rep), j);
#else /* NOFLOAT */
1988-06-22 16:57:09 +00:00
/* we cannot store the float */
warning(WFLINIT);
#endif /* NOFLOAT */
1988-06-22 16:57:09 +00:00
pos += j;
break;
default:
fatal("Unknown initializer type in global data.");
break;
}
return pos;
}
2019-03-17 14:42:00 +00:00
PRIVATE int rd_byte(void)
1988-06-22 16:57:09 +00:00
{
register int i;
2019-03-17 14:42:00 +00:00
1989-11-22 13:38:37 +00:00
if ((i = getc(load_fp)) == EOF)
1988-06-22 16:57:09 +00:00
fatal("EOF reached during initialization");
return (i);
}
2019-03-17 14:42:00 +00:00
PRIVATE long rd_int(size n)
1988-06-22 16:57:09 +00:00
{
register long l;
register int i;
2019-03-17 14:42:00 +00:00
1988-06-22 16:57:09 +00:00
l = btol(rd_byte());
2019-03-17 14:42:00 +00:00
for (i = 1; i < n; i++)
{
l |= (btol(rd_byte()) << (i * 8));
1988-06-22 16:57:09 +00:00
}
return (l);
}