ack/util/ass/assrl.c

324 lines
7.4 KiB
C
Raw Normal View History

1984-07-02 15:35:56 +00:00
/*
1987-03-10 01:26:51 +00:00
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
1984-07-02 15:35:56 +00:00
*
*/
2019-03-17 14:41:25 +00:00
#include <stdio.h>
1984-07-02 15:35:56 +00:00
#include "ass00.h"
#include "assex.h"
2019-03-17 14:41:25 +00:00
#include "asscm.h"
#include "assrl.h"
1984-07-02 15:35:56 +00:00
1984-11-08 12:08:31 +00:00
1984-07-02 15:35:56 +00:00
#define COPYFINAL 1
#define COPYTEMP 0
/*
* collection of routines to deal with relocation business
*/
2019-03-17 14:41:25 +00:00
static void dataprocess(FILE *, FILE *);
static void textprocess(FILE *, FILE *);
relc_t * text_reloc(glob_t *glosym, FOFFSET off, int typ)
{
1984-07-02 15:35:56 +00:00
/*
* prepare the relocation that has to be done at text-offset off
* according to global symbol glosym.
* NOTE: The pointer glosym will point into mglobs[], while at
* the time copyout() is called all the symbols here
* will have disappeared.
* The procedure upd_reloc() will change this pointer
* into the one in xglobs[] later.
*/
2019-03-17 14:41:25 +00:00
register relc_t *nxtextreloc;
1984-07-02 15:35:56 +00:00
2019-03-17 14:41:25 +00:00
nxtextreloc = rlp_cast getarea(sizeof *nxtextreloc);
if (!f_text)
{
f_text = nxtextreloc;
}
else
{
l_text->r_next = nxtextreloc;
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
nxtextreloc->r_next = rlp_cast 0;
l_text = nxtextreloc;
1984-07-02 15:35:56 +00:00
nxtextreloc->r_off = off;
nxtextreloc->r_val.rel_gp = glosym;
2019-03-17 14:41:25 +00:00
nxtextreloc->r_typ = typ; /* flags of instruction */
return (nxtextreloc);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
relc_t * data_reloc(char *arg ,FOFFSET off, int typ)
{
1984-07-02 15:35:56 +00:00
/*
* Same as above.
*/
2019-03-17 14:41:25 +00:00
register relc_t *nxdatareloc;
1984-07-02 15:35:56 +00:00
2019-03-17 14:41:25 +00:00
nxdatareloc = rlp_cast getarea(sizeof *nxdatareloc);
if (!f_data)
{
f_data = nxdatareloc;
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
else
{
l_data->r_next = nxdatareloc;
}
nxdatareloc->r_next = rlp_cast 0;
l_data = nxdatareloc;
1984-07-02 15:35:56 +00:00
nxdatareloc->r_off = off;
nxdatareloc->r_val.rel_lp = lbp_cast arg;
nxdatareloc->r_typ = typ;
2019-03-17 14:41:25 +00:00
return (nxdatareloc);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
void copyout(void)
{
register int i;
int remtext;
1984-07-02 15:35:56 +00:00
/*
* Make the e.out file that looks as follows:
*
* __________________________
* | MAGIC | \
* | FLAGS | \
* | UNRESOLVED | \
* | VERSION | | 8*(2-byte word) header
* | WORDSIZE | | for interpreter selection
* | PTRSIZE | /
* | <UNUSED> | /
* | <UNUSED> | /
* | NTEXT | \
* | NDATA | \
* | NPROC | \
* | ENTRY-POINT | | 8*(wordsize-word) header
* | NLINES | | for interpreter proper
* | <UNUSED> | /
* | <UNUSED> | /
* | <UNUSED> | /
* |________________________|
* | |
* | TEXT | zero filled
* | | if not word multiple
* |________________________|
* | |
* | DATA |
* | |
* |________________________|
* | |
* | PROCTABLE |
* | |
* |________________________|
*
*
*/
2019-03-17 14:41:25 +00:00
remtext = textbytes % wordsize;
if (remtext != 0)
remtext = wordsize - remtext;
1984-07-02 15:35:56 +00:00
2022-07-18 18:25:56 +00:00
if ((ifile = fopen(eout, "wb")) == 0)
1984-07-02 15:35:56 +00:00
fatal("can't create e.out");
2019-03-17 14:41:25 +00:00
rewind(tfile);
rewind(dfile);
xput16(as_magic, ifile);
xput16(intflags, ifile);
xput16(unresolved, ifile);
xput16(VERSION, ifile);
xput16(wordsize, ifile);
xput16(ptrsize, ifile);
xput16(0, ifile);
xput16(0, ifile);
xputa(textbytes + remtext, ifile);
xputa((cons_t) datablocks, ifile);
xputa((cons_t) procnum, ifile);
xputa((cons_t) searchproc(MAIN, xprocs, oursize->n_xproc)->p_num, ifile);
xputa((cons_t) sourcelines, ifile);
xputa((cons_t) databytes, ifile);
xputa((cons_t) 0, ifile);
xputa((cons_t) 0, ifile);
textprocess(tfile, ifile);
while (remtext--)
xputc(0, ifile);
1984-07-02 15:35:56 +00:00
2019-03-17 14:41:25 +00:00
dataprocess(dfile, ifile);
for (i = 0; i < procnum; i++)
{
xputarb(ptrsize, proctab[i].pr_loc, ifile);
xputarb(ptrsize, proctab[i].pr_off, ifile);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
if (fclose(ifile) == EOF)
;
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
static void dataprocess(FILE *f1, FILE *outf)
{
1984-07-02 15:35:56 +00:00
relc_t datareloc;
FOFFSET i;
2019-03-17 14:41:25 +00:00
register int ieof;
1984-07-02 15:35:56 +00:00
2019-03-17 14:41:25 +00:00
rewind(rdfile);
ieof = getblk(rdfile, (char *) (&datareloc.r_off),
sizeof datareloc - sizeof datareloc.r_next);
for (i = 0; i < dataoff && !ieof; i++)
{
if (i == datareloc.r_off)
{
switch (datareloc.r_typ)
{
1984-07-02 15:35:56 +00:00
case RELADR:
2019-03-17 14:41:25 +00:00
xputa(xgeta(f1) + datareloc.r_val.rel_i, outf);
i += ptrsize - 1;
break;
1984-07-02 15:35:56 +00:00
case RELGLO:
2019-03-17 14:41:25 +00:00
if (datareloc.r_val.rel_gp->g_status & DEF)
{
xputa(xgeta(f1) + datareloc.r_val.rel_gp->g_val.g_addr, outf);
i += ptrsize - 1;
break;
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
if (unresolved == 0)
fatal("Definition botch");
1984-07-02 15:35:56 +00:00
case RELHEAD:
2019-03-17 14:41:25 +00:00
xputc((int) (xgetc(f1) + datareloc.r_val.rel_i), outf);
1984-07-02 15:35:56 +00:00
break;
default:
fatal("Bad r_typ in dataprocess");
}
2019-03-17 14:41:25 +00:00
ieof = getblk(rdfile, (char *) (&datareloc.r_off),
sizeof datareloc - sizeof datareloc.r_next);
}
else
xputc(xgetc(f1), outf);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
for (; i < dataoff; i++)
xputc(xgetc(f1), outf);
if (!ieof && !getblk(rdfile, (char *) &datareloc, 1))
fatal("data relocation botch");
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
static void textprocess(FILE *f1, FILE *outf)
{
1984-07-02 15:35:56 +00:00
relc_t textreloc;
cons_t n;
FOFFSET i;
2019-03-17 14:41:25 +00:00
FILE *otfile;
int insl;
register int ieof;
char *op_curr;
register FOFFSET keep;
1984-07-02 15:35:56 +00:00
2019-03-17 14:41:25 +00:00
rewind(rtfile);
keep = textoff;
textoff = 0;
otfile = tfile;
tfile = outf;
1984-07-02 15:35:56 +00:00
/* This redirects the output of genop */
2019-03-17 14:41:25 +00:00
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
sizeof textreloc - sizeof textreloc.r_next);
for (i = 0; i < keep && !ieof; i++)
{
if (i == textreloc.r_off)
{
if (textreloc.r_typ & RELMNS)
{
n = textreloc.r_val.rel_i;
}
else
{
if (textreloc.r_val.rel_gp->g_status & DEF)
{
n = textreloc.r_val.rel_gp->g_val.g_addr;
}
else
{
if (unresolved == 0)
fatal("Definition botch");
xputc(xgetc(f1), outf);
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
sizeof textreloc - sizeof textreloc.r_next);
continue;
1984-07-02 15:35:56 +00:00
}
}
2019-03-17 14:41:25 +00:00
op_curr = &opchoice[textreloc.r_typ & ~RELMNS];
insl = oplength(*op_curr);
genop(op_curr, n + xgetarb(insl, f1), PAR_G);
i += insl - 1;
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
sizeof textreloc - sizeof textreloc.r_next);
}
else
{
xputc(xgetc(f1), outf);
1984-07-02 15:35:56 +00:00
}
}
2019-03-17 14:41:25 +00:00
for (; i < keep; i++)
xputc(xgetc(f1), outf);
if (!ieof && !getblk(rtfile, (char *) &textreloc, 1))
fatal("text relocation botch");
textoff = keep;
tfile = otfile;
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
void upd_reloc(void)
{
1984-07-02 15:35:56 +00:00
register relc_t *p;
register glob_t *gbp;
/*
* Change reloc-tables such that for every pointer into mglobs
* either the corresponding pointer into xglobs or its value
* is substituted.
*
* Use is made of the known order of mglobs and xglobs
* see also getcore()
*/
2019-03-17 14:41:25 +00:00
while ( (p = f_text) != NULL)
{
gbp = p->r_val.rel_gp;
if (gbp->g_status & DEF)
{
1984-07-02 15:35:56 +00:00
p->r_typ |= RELMNS;
p->r_val.rel_i = gbp->g_val.g_addr;
2019-03-17 14:41:25 +00:00
}
else
1984-07-02 15:35:56 +00:00
p->r_val.rel_gp = gbp->g_val.g_gp;
2019-03-17 14:41:25 +00:00
putblk(rtfile, (char *) (&(p->r_off)), sizeof *p - sizeof p);
f_text = p->r_next;
freearea((area_t) p, sizeof *p);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
while ( (p = f_data) != NULL)
{
if (p->r_typ == RELGLO)
{
gbp = p->r_val.rel_gp;
if (gbp->g_status & DEF)
{
1984-07-02 15:35:56 +00:00
p->r_typ = RELADR;
p->r_val.rel_i = gbp->g_val.g_addr;
2019-03-17 14:41:25 +00:00
}
else
1984-07-02 15:35:56 +00:00
p->r_val.rel_gp = gbp->g_val.g_gp;
}
2019-03-17 14:41:25 +00:00
putblk(rdfile, (char *) (&(p->r_off)), sizeof *p - sizeof p);
f_data = p->r_next;
freearea((area_t) p, sizeof *p);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
l_data = rlp_cast 0;
1984-07-02 15:35:56 +00:00
}