minix/commands/autil/rd.c

260 lines
4.3 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 "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