247 lines
4.5 KiB
C
247 lines
4.5 KiB
C
/* $Header$ */
|
|
/*
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
*/
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include "out.h"
|
|
#include "object.h"
|
|
#include "rd.h"
|
|
#include "rd_bytes.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(int p, 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(char *f)
|
|
{
|
|
int outfile = open(f, 0);
|
|
if (outfile < 0)
|
|
return 0;
|
|
return rd_fdopen(outfile);
|
|
}
|
|
|
|
static int offcnt;
|
|
|
|
int rd_fdopen(int 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(register struct outhead *head)
|
|
{
|
|
register long off;
|
|
|
|
OUTREAD(PARTEMIT, (char *) head, (long) SZ_HEAD);
|
|
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
|
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 ! (BYTES_REVERSED || WORDS_REVERSED)
|
|
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);
|
|
}
|
|
offset[--offcnt] = sect->os_foff + rd_base;
|
|
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
|
if (sizeof(struct outsect) != SZ_SECT)
|
|
#endif
|
|
{
|
|
c -= 4; sect->os_size = get4(c);
|
|
c -= 4; sect->os_base = get4(c);
|
|
}
|
|
}
|
|
}
|
|
|
|
void rd_outsect(int 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 ! (BYTES_REVERSED || WORDS_REVERSED)
|
|
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(struct outname *name, unsigned int cnt)
|
|
{
|
|
|
|
OUTREAD(PARTNAME, (char *) name, (long) cnt * SZ_NAME);
|
|
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
|
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(char *addr, long len)
|
|
{
|
|
OUTREAD(PARTCHAR, addr, len);
|
|
}
|
|
|
|
#ifdef SYMDBUG
|
|
void rd_dbug(char *buf, long size)
|
|
{
|
|
OUTREAD(PARTDBUG, buf, size);
|
|
}
|
|
#endif
|