234 lines
3.9 KiB
C
234 lines
3.9 KiB
C
/* $Id$ */
|
|
/*
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "out.h"
|
|
#include "object.h"
|
|
#include "obj.h"
|
|
|
|
/*
|
|
* 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 FILE* 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(int p, char* b, long n)
|
|
{
|
|
register long l = outseek[p];
|
|
|
|
if (currpos != l) {
|
|
fseek(outfile, l, SEEK_SET);
|
|
}
|
|
rd_bytes(outfile, b, n);
|
|
l += n;
|
|
currpos = l;
|
|
outseek[p] = l;
|
|
}
|
|
|
|
/*
|
|
* Open the output file according to the chosen strategy.
|
|
*/
|
|
int rd_open(const char* filename)
|
|
{
|
|
|
|
if ((outfile = fopen(filename, "rb")) == NULL)
|
|
return 0;
|
|
return rd_fdopen(outfile);
|
|
}
|
|
|
|
static int offcnt;
|
|
|
|
int rd_fdopen(FILE* fd)
|
|
{
|
|
register int i;
|
|
|
|
for (i = 0; i < NPARTS; i++) outseek[i] = 0;
|
|
offcnt = 0;
|
|
rd_base = ftell(fd);
|
|
if (rd_base < 0) {
|
|
return 0;
|
|
}
|
|
currpos = rd_base;
|
|
outseek[PARTEMIT] = currpos;
|
|
outfile = fd;
|
|
sectionnr = 0;
|
|
return 1;
|
|
}
|
|
|
|
void rd_close(void)
|
|
{
|
|
|
|
fclose(outfile);
|
|
outfile = NULL;
|
|
}
|
|
|
|
FILE* rd_fd(void)
|
|
{
|
|
return outfile;
|
|
}
|
|
|
|
void
|
|
rd_ohead(struct outhead* head)
|
|
{
|
|
register long off;
|
|
|
|
OUTREAD(PARTEMIT, (char *) head, (long) SZ_HEAD);
|
|
{
|
|
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(struct outhead* head)
|
|
{
|
|
register long off = OFF_RELO(*head) + rd_base;
|
|
|
|
BEGINSEEK(PARTRELO, off);
|
|
}
|
|
|
|
void
|
|
rd_sect(struct outsect* sect, 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--;
|
|
|
|
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(int sectno)
|
|
{
|
|
OUTSECT(sectno);
|
|
sectionnr = sectno;
|
|
}
|
|
|
|
/*
|
|
* We don't have to worry about byte order here.
|
|
*/
|
|
void
|
|
rd_emit(char* emit, long cnt)
|
|
{
|
|
OUTREAD(PARTEMIT, emit, cnt);
|
|
offset[sectionnr] += cnt;
|
|
}
|
|
|
|
void
|
|
rd_relo(struct outrelo* relo, unsigned int cnt)
|
|
{
|
|
|
|
OUTREAD(PARTRELO, (char *) relo, (long) cnt * SZ_RELO);
|
|
{
|
|
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);
|
|
c -= 2; relo->or_sect = uget2(c);
|
|
c -= 2; relo->or_type = uget2(c);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
rd_name(struct outname* name, unsigned int cnt)
|
|
{
|
|
|
|
OUTREAD(PARTNAME, (char *) name, (long) cnt * SZ_NAME);
|
|
{
|
|
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(char* addr, long len)
|
|
{
|
|
|
|
OUTREAD(PARTCHAR, addr, len);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SYMDBUG
|
|
void
|
|
rd_dbug(char* buf, long size)
|
|
{
|
|
OUTREAD(PARTDBUG, buf, size);
|
|
}
|
|
#endif
|