260 lines
4.3 KiB
C
260 lines
4.3 KiB
C
|
/*
|
||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||
|
*/
|
||
|
#include "obj.h"
|
||
|
|
||
|
extern long lseek();
|
||
|
|
||
|
/*
|
||
|
* Parts of the output file.
|
||
|
*/
|
||
|
#undef PARTEMIT
|
||
|
#undef PARTRELO
|
||
|
#undef PARTNAME
|
||
|
#undef PARTCHAR
|
||
|
#undef PARTDBUG
|
||
|
#undef NPARTS
|
||
|
|
||
|
#define PARTEMIT 0
|
||
|
#define PARTRELO 1
|
||
|
#define PARTNAME 2
|
||
|
#define PARTCHAR 3
|
||
|
#ifdef SYMDBUG
|
||
|
#define PARTDBUG 4
|
||
|
#else
|
||
|
#define PARTDBUG 3
|
||
|
#endif
|
||
|
#define NPARTS (PARTDBUG + 1)
|
||
|
|
||
|
static long offset[MAXSECT];
|
||
|
|
||
|
static int outfile;
|
||
|
static long outseek[NPARTS];
|
||
|
static long currpos;
|
||
|
static long rd_base;
|
||
|
#define OUTSECT(i) \
|
||
|
(outseek[PARTEMIT] = offset[i])
|
||
|
#define BEGINSEEK(p, o) \
|
||
|
(outseek[(p)] = (o))
|
||
|
|
||
|
static int sectionnr;
|
||
|
|
||
|
static void
|
||
|
OUTREAD(p, b, n)
|
||
|
char *b;
|
||
|
long n;
|
||
|
{
|
||
|
register long l = outseek[p];
|
||
|
|
||
|
if (currpos != l) {
|
||
|
lseek(outfile, l, 0);
|
||
|
}
|
||
|
rd_bytes(outfile, b, n);
|
||
|
l += n;
|
||
|
currpos = l;
|
||
|
outseek[p] = l;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Open the output file according to the chosen strategy.
|
||
|
*/
|
||
|
int
|
||
|
rd_open(f)
|
||
|
char *f;
|
||
|
{
|
||
|
|
||
|
if ((outfile = open(f, 0)) < 0)
|
||
|
return 0;
|
||
|
return rd_fdopen(outfile);
|
||
|
}
|
||
|
|
||
|
static int offcnt;
|
||
|
|
||
|
int
|
||
|
rd_fdopen(fd)
|
||
|
{
|
||
|
register int i;
|
||
|
|
||
|
for (i = 0; i < NPARTS; i++) outseek[i] = 0;
|
||
|
offcnt = 0;
|
||
|
rd_base = lseek(fd, 0L, 1);
|
||
|
if (rd_base < 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
currpos = rd_base;
|
||
|
outseek[PARTEMIT] = currpos;
|
||
|
outfile = fd;
|
||
|
sectionnr = 0;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
rd_close()
|
||
|
{
|
||
|
|
||
|
close(outfile);
|
||
|
outfile = -1;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
rd_fd()
|
||
|
{
|
||
|
return outfile;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
rd_ohead(head)
|
||
|
register struct outhead *head;
|
||
|
{
|
||
|
register long off;
|
||
|
|
||
|
OUTREAD(PARTEMIT, (char *) head, (long) SZ_HEAD);
|
||
|
#if BYTE_ORDER == 0x0123
|
||
|
if (sizeof(struct outhead) != SZ_HEAD)
|
||
|
#endif
|
||
|
{
|
||
|
register char *c = (char *) head + (SZ_HEAD-4);
|
||
|
|
||
|
head->oh_nchar = get4(c);
|
||
|
c -= 4; head->oh_nemit = get4(c);
|
||
|
c -= 2; head->oh_nname = uget2(c);
|
||
|
c -= 2; head->oh_nrelo = uget2(c);
|
||
|
c -= 2; head->oh_nsect = uget2(c);
|
||
|
c -= 2; head->oh_flags = uget2(c);
|
||
|
c -= 2; head->oh_stamp = uget2(c);
|
||
|
c -= 2; head->oh_magic = uget2(c);
|
||
|
}
|
||
|
off = OFF_RELO(*head) + rd_base;
|
||
|
BEGINSEEK(PARTRELO, off);
|
||
|
off += (long) head->oh_nrelo * SZ_RELO;
|
||
|
BEGINSEEK(PARTNAME, off);
|
||
|
off += (long) head->oh_nname * SZ_NAME;
|
||
|
BEGINSEEK(PARTCHAR, off);
|
||
|
#ifdef SYMDBUG
|
||
|
off += head->oh_nchar;
|
||
|
BEGINSEEK(PARTDBUG, off);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void
|
||
|
rd_rew_relos(head)
|
||
|
register struct outhead *head;
|
||
|
{
|
||
|
register long off = OFF_RELO(*head) + rd_base;
|
||
|
|
||
|
BEGINSEEK(PARTRELO, off);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
rd_sect(sect, cnt)
|
||
|
register struct outsect *sect;
|
||
|
register unsigned int cnt;
|
||
|
{
|
||
|
register char *c = (char *) sect + cnt * SZ_SECT;
|
||
|
|
||
|
OUTREAD(PARTEMIT, (char *) sect, (long)cnt * SZ_SECT);
|
||
|
sect += cnt;
|
||
|
offcnt += cnt;
|
||
|
while (cnt--) {
|
||
|
sect--;
|
||
|
#if BYTE_ORDER == 0x0123
|
||
|
if (sizeof(struct outsect) != SZ_SECT)
|
||
|
#endif
|
||
|
{
|
||
|
c -= 4; sect->os_lign = get4(c);
|
||
|
c -= 4; sect->os_flen = get4(c);
|
||
|
c -= 4; sect->os_foff = get4(c);
|
||
|
c -= 4; sect->os_size = get4(c);
|
||
|
c -= 4; sect->os_base = get4(c);
|
||
|
}
|
||
|
offset[--offcnt] = sect->os_foff + rd_base;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
rd_outsect(s)
|
||
|
{
|
||
|
OUTSECT(s);
|
||
|
sectionnr = s;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* We don't have to worry about byte order here.
|
||
|
*/
|
||
|
void
|
||
|
rd_emit(emit, cnt)
|
||
|
char *emit;
|
||
|
long cnt;
|
||
|
{
|
||
|
OUTREAD(PARTEMIT, emit, cnt);
|
||
|
offset[sectionnr] += cnt;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
rd_relo(relo, cnt)
|
||
|
register struct outrelo *relo;
|
||
|
register unsigned int cnt;
|
||
|
{
|
||
|
|
||
|
OUTREAD(PARTRELO, (char *) relo, (long) cnt * SZ_RELO);
|
||
|
#if BYTE_ORDER == 0x0123
|
||
|
if (sizeof(struct outrelo) != SZ_RELO)
|
||
|
#endif
|
||
|
{
|
||
|
register char *c = (char *) relo + (long) cnt * SZ_RELO;
|
||
|
|
||
|
relo += cnt;
|
||
|
while (cnt--) {
|
||
|
relo--;
|
||
|
c -= 4; relo->or_addr = get4(c);
|
||
|
c -= 2; relo->or_nami = uget2(c);
|
||
|
relo->or_sect = *--c;
|
||
|
relo->or_type = *--c;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
rd_name(name, cnt)
|
||
|
register struct outname *name;
|
||
|
register unsigned int cnt;
|
||
|
{
|
||
|
|
||
|
OUTREAD(PARTNAME, (char *) name, (long) cnt * SZ_NAME);
|
||
|
#if BYTE_ORDER == 0x0123
|
||
|
if (sizeof(struct outname) != SZ_NAME)
|
||
|
#endif
|
||
|
{
|
||
|
register char *c = (char *) name + (long) cnt * SZ_NAME;
|
||
|
|
||
|
name += cnt;
|
||
|
while (cnt--) {
|
||
|
name--;
|
||
|
c -= 4; name->on_valu = get4(c);
|
||
|
c -= 2; name->on_desc = uget2(c);
|
||
|
c -= 2; name->on_type = uget2(c);
|
||
|
c -= 4; name->on_foff = get4(c);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
rd_string(addr, len)
|
||
|
char *addr;
|
||
|
long len;
|
||
|
{
|
||
|
|
||
|
OUTREAD(PARTCHAR, addr, len);
|
||
|
}
|
||
|
|
||
|
#ifdef SYMDBUG
|
||
|
void
|
||
|
rd_dbug(buf, size)
|
||
|
char *buf;
|
||
|
long size;
|
||
|
{
|
||
|
OUTREAD(PARTDBUG, buf, size);
|
||
|
}
|
||
|
#endif
|