ack/modules/src/object/wr.c

362 lines
6.9 KiB
C
Raw Normal View History

1994-06-24 11:31:16 +00:00
/* $Id$ */
1987-03-09 15:15:03 +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".
*/
1987-01-05 17:31:38 +00:00
/*
* You can choose between two strategies:
* - Open the output file several times, once for each logical part, and
* write to it in multiple places.
* - Open the output file once and seek back and forth to each logical
* part. In this case #define OUTSEEK.
*/
2017-11-11 18:08:13 +00:00
#include <fcntl.h>
1993-11-10 11:49:49 +00:00
#include "obj.h"
1987-01-05 17:31:38 +00:00
/*
* Parts of the output file.
*/
static long offset[MAXSECT];
1989-11-16 15:52:08 +00:00
struct fil __parts[NPARTS];
1987-01-05 17:31:38 +00:00
#ifdef OUTSEEK
static int outfile;
static long currpos;
1989-11-16 15:52:08 +00:00
#endif
1989-11-17 15:56:53 +00:00
int __sectionnr;
#define sectionnr __sectionnr
1989-11-16 15:52:08 +00:00
static int offcnt;
1987-01-05 17:31:38 +00:00
1993-11-10 11:49:49 +00:00
void
2017-11-11 18:08:13 +00:00
__wr_flush(struct fil *ptr)
1989-11-16 15:52:08 +00:00
{
#ifdef OUTSEEK
1990-12-11 10:38:22 +00:00
/* seek to correct position even if we aren't going to write now */
if (currpos != ptr->currpos) {
currpos = lseek(ptr->fd, ptr->currpos, 0);
}
1989-11-16 15:52:08 +00:00
#endif
1990-12-11 10:38:22 +00:00
if (ptr->pnow > ptr->pbegin) {
1989-11-16 15:52:08 +00:00
wr_bytes(ptr->fd, ptr->pbegin, (long)(ptr->pnow - ptr->pbegin));
ptr->currpos += ptr->pnow - ptr->pbegin;
1990-12-11 10:38:22 +00:00
#ifdef OUTSEEK
currpos = ptr->currpos;
#endif
1989-11-17 15:56:53 +00:00
if (ptr < &__parts[PARTEMIT+SECTCNT]) {
1989-11-16 15:52:08 +00:00
offset[sectionnr] = ptr->currpos;
}
1987-01-05 17:31:38 +00:00
}
1989-11-16 15:52:08 +00:00
ptr->cnt = WBUFSIZ;
ptr->pnow = ptr->pbuf;
ptr->pbegin = ptr->pbuf;
1987-01-05 17:31:38 +00:00
}
1993-11-10 11:49:49 +00:00
static void
2017-11-11 18:08:13 +00:00
OUTWRITE(int p, const char *b, long n)
/* p = part number, b = buffer pointer, n = write count */
1989-11-16 15:52:08 +00:00
{
2017-11-11 18:08:13 +00:00
struct fil *ptr = &__parts[p];
char *pn = ptr->pnow;
int i;
1989-11-16 15:52:08 +00:00
long m;
i = ptr->cnt;
if (i < WBUFSIZ) {
if (n > i) {
__wr_flush(ptr);
wr_bytes(ptr->fd, b, (long) i);
n -= i;
b += i;
ptr->currpos += i;
1990-12-11 10:38:22 +00:00
#ifdef OUTSEEK
currpos = ptr->currpos;
#endif
1989-11-17 15:56:53 +00:00
if (ptr < &__parts[PARTEMIT+SECTCNT]) {
1989-11-16 15:52:08 +00:00
offset[sectionnr] = ptr->currpos;
}
}
else {
i = n;
ptr->cnt -= i;
n = 0;
while (i > 0) {
*pn++ = *b++;
i--;
}
ptr->pnow = pn;
}
}
if (ptr->cnt == 0 || ptr->cnt == WBUFSIZ) {
__wr_flush(ptr);
m = n & ~(WBUFSIZ - 1);
if (m != 0) {
wr_bytes(ptr->fd, b, m);
b += m;
n &= WBUFSIZ - 1;
ptr->currpos += m;
1990-12-11 10:38:22 +00:00
#ifdef OUTSEEK
currpos = ptr->currpos;
#endif
1989-11-17 15:56:53 +00:00
if (ptr < &__parts[PARTEMIT+SECTCNT]) {
1989-11-16 15:52:08 +00:00
offset[sectionnr] = ptr->currpos;
}
}
i = n;
if (i != 0) {
n = 0;
pn = ptr->pnow;
ptr->cnt -= i;
while (i > 0) {
*pn++ = *b++;
i--;
}
ptr->pnow = pn;
}
}
}
1987-01-05 17:31:38 +00:00
1993-11-10 11:49:49 +00:00
static void
2017-11-11 18:08:13 +00:00
BEGINSEEK(int p, long o)
/* p = part number, o = offset in file */
1989-11-16 15:52:08 +00:00
{
2017-11-11 18:08:13 +00:00
struct fil *ptr = &__parts[p];
1987-01-05 17:31:38 +00:00
1989-11-16 15:52:08 +00:00
#ifdef OUTSEEK
ptr->fd = outfile;
ptr->currpos = o;
#else
ptr->currpos = lseek(ptr->fd, o, 0);
#endif
1989-11-17 15:56:53 +00:00
if (p >= PARTRELO) o = 0; /* no attempt to align writes
for the time being */
1989-11-16 15:52:08 +00:00
ptr->cnt = WBUFSIZ - ((int)o & (WBUFSIZ-1));
ptr->pbegin = ptr->pbuf + (WBUFSIZ - ptr->cnt);
ptr->pnow = ptr->pbegin;
}
1987-01-05 17:31:38 +00:00
/*
* Open the output file according to the chosen strategy.
*/
int
2017-11-11 18:08:13 +00:00
wr_open(const char *f)
1987-01-05 17:31:38 +00:00
{
2017-11-11 18:08:13 +00:00
struct fil *fdp;
1987-01-05 17:31:38 +00:00
close(creat(f, 0666));
#ifdef OUTSEEK
if ((outfile = open(f, 1)) < 0)
return 0;
currpos = 0;
1989-11-16 15:52:08 +00:00
#else /* not OUTSEEK */
for (fdp = &__parts[PARTEMIT]; fdp < &__parts[NPARTS]; fdp++)
if ((fdp->fd = open(f, 1)) < 0)
1987-01-05 17:31:38 +00:00
return 0;
1989-11-16 15:52:08 +00:00
#endif /* not OUTSEEK */
1987-01-05 17:31:38 +00:00
offcnt = 0;
return 1;
}
1993-11-10 11:49:49 +00:00
void
1987-01-05 17:31:38 +00:00
wr_close()
{
2017-11-11 18:08:13 +00:00
struct fil *ptr;
1987-01-05 17:31:38 +00:00
1989-11-16 15:52:08 +00:00
for (ptr = &__parts[PARTEMIT]; ptr < &__parts[NPARTS]; ptr++) {
__wr_flush(ptr);
#ifndef OUTSEEK
close(ptr->fd);
#endif /* not OUTSEEK */
ptr->fd = -1;
1987-01-05 17:31:38 +00:00
}
#ifdef OUTSEEK
close(outfile);
1987-01-13 15:10:23 +00:00
outfile = -1;
1989-11-16 15:52:08 +00:00
#endif /* OUTSEEK */
1987-01-05 17:31:38 +00:00
}
1993-11-10 11:49:49 +00:00
void
2017-11-11 18:08:13 +00:00
wr_ohead(const struct outhead *head)
1987-01-05 17:31:38 +00:00
{
1989-11-16 15:52:08 +00:00
{
2017-11-11 18:08:13 +00:00
long off = OFF_RELO(*head);
1989-11-16 15:52:08 +00:00
BEGINSEEK(PARTEMIT, 0L);
BEGINSEEK(PARTRELO, off);
off += (long) head->oh_nrelo * SZ_RELO;
BEGINSEEK(PARTNAME, off);
off += (long) head->oh_nname * SZ_NAME;
BEGINSEEK(PARTCHAR, off);
1987-01-05 17:31:38 +00:00
#ifdef SYMDBUG
1989-11-16 15:52:08 +00:00
off += head->oh_nchar;
BEGINSEEK(PARTDBUG, off);
1987-01-05 17:31:38 +00:00
#endif
1989-11-16 15:52:08 +00:00
}
1987-01-05 17:31:38 +00:00
{
1991-09-18 09:48:15 +00:00
char buf[SZ_HEAD];
2017-11-11 18:08:13 +00:00
char *c = &buf[0];
1987-01-05 17:31:38 +00:00
put2(head->oh_magic, c); c += 2;
put2(head->oh_stamp, c); c += 2;
put2(head->oh_flags, c); c += 2;
put2(head->oh_nsect, c); c += 2;
put2(head->oh_nrelo, c); c += 2;
put2(head->oh_nname, c); c += 2;
put4(head->oh_nemit, c); c += 4;
put4(head->oh_nchar, c);
1991-09-18 09:48:15 +00:00
OUTWRITE(PARTEMIT, buf, (long)SZ_HEAD);
1987-01-05 17:31:38 +00:00
}
}
1993-11-10 11:49:49 +00:00
void
2017-11-11 18:08:13 +00:00
wr_sect(const struct outsect *sect, unsigned int cnt)
1987-01-05 17:31:38 +00:00
{
2017-11-11 18:08:13 +00:00
{ unsigned int i = cnt;
1987-01-05 17:31:38 +00:00
1991-09-18 09:48:15 +00:00
while (i--) {
if (offcnt >= 1 && offcnt < SECTCNT) {
BEGINSEEK(PARTEMIT+offcnt, sect->os_foff);
}
offset[offcnt++] = sect->os_foff;
sect++;
1989-11-17 15:56:53 +00:00
}
1991-09-18 09:48:15 +00:00
sect -= cnt;
}
while (cnt)
{
2017-11-11 18:08:13 +00:00
char *c;
unsigned int i;
1991-09-18 09:48:15 +00:00
i = __parts[PARTEMIT].cnt/SZ_SECT;
c = __parts[PARTEMIT].pnow;
if (i > cnt) i = cnt;
cnt -= i;
__parts[PARTEMIT].cnt -= (i*SZ_SECT);
while (i--) {
put4(sect->os_base, c); c += 4;
put4(sect->os_size, c); c += 4;
put4(sect->os_foff, c); c += 4;
1989-11-16 15:52:08 +00:00
put4(sect->os_flen, c); c += 4;
put4(sect->os_lign, c); c += 4;
1991-09-18 09:48:15 +00:00
sect++;
}
__parts[PARTEMIT].pnow = c;
if (cnt) {
__wr_flush(&__parts[PARTEMIT]);
1987-01-05 17:31:38 +00:00
}
}
}
1993-11-10 11:49:49 +00:00
void
2017-11-11 18:08:13 +00:00
wr_outsect(int s)
/* s = section number */
1987-01-05 17:31:38 +00:00
{
2017-11-11 18:08:13 +00:00
struct fil *ptr = &__parts[PARTEMIT + getsect(sectionnr)];
1989-11-16 15:52:08 +00:00
1989-11-17 15:56:53 +00:00
if (s != sectionnr && s >= (SECTCNT-1) && sectionnr >= (SECTCNT-1)) {
1989-11-16 15:52:08 +00:00
#ifdef OUTSEEK
if (currpos != ptr->currpos)
currpos = lseek(ptr->fd, ptr->currpos, 0);
#endif
wr_bytes(ptr->fd, ptr->pbegin, (long)(ptr->pnow - ptr->pbegin));
1990-12-11 10:38:22 +00:00
ptr->currpos += ptr->pnow - ptr->pbegin;
1989-11-16 15:52:08 +00:00
#ifdef OUTSEEK
1990-12-11 10:38:22 +00:00
currpos = ptr->currpos;
1989-11-16 15:52:08 +00:00
#endif
offset[sectionnr] = ptr->currpos;
1989-11-17 15:56:53 +00:00
if (offset[s] != ptr->currpos) {
ptr->currpos = lseek(ptr->fd, offset[s], 0);
1990-12-11 10:38:22 +00:00
#ifdef OUTSEEK
currpos = ptr->currpos;
#endif
1989-11-17 15:56:53 +00:00
}
1989-11-16 15:52:08 +00:00
ptr->cnt = WBUFSIZ - ((int)offset[s] & (WBUFSIZ-1));
ptr->pbegin = ptr->pbuf + (WBUFSIZ - ptr->cnt);
ptr->pnow = ptr->pbegin;
1987-01-05 17:31:38 +00:00
}
1989-11-16 15:52:08 +00:00
sectionnr = s;
1987-01-05 17:31:38 +00:00
}
/*
* We don't have to worry about byte order here.
*/
1993-11-10 11:49:49 +00:00
void
2017-11-11 18:08:13 +00:00
wr_emit(const char *emit, long cnt)
1987-01-05 17:31:38 +00:00
{
1989-11-17 15:56:53 +00:00
OUTWRITE(PARTEMIT + getsect(sectionnr) , emit, cnt);
1987-01-05 17:31:38 +00:00
}
1993-11-10 11:49:49 +00:00
void
2017-11-11 18:08:13 +00:00
wr_relo(const struct outrelo *relo, unsigned int cnt)
1987-01-05 17:31:38 +00:00
{
1989-11-16 15:52:08 +00:00
while (cnt)
1987-01-05 17:31:38 +00:00
{
2017-11-11 18:08:13 +00:00
char *c;
unsigned int i;
1989-11-16 15:52:08 +00:00
i = __parts[PARTRELO].cnt/SZ_RELO;
c = __parts[PARTRELO].pnow;
if (i > cnt) i = cnt;
cnt -= i;
__parts[PARTRELO].cnt -= (i*SZ_RELO);
while (i--) {
put2(relo->or_type, c); c += 2;
put2(relo->or_sect, c); c += 2;
1987-01-05 17:31:38 +00:00
put2(relo->or_nami, c); c += 2;
put4(relo->or_addr, c); c += 4;
relo++;
1989-11-16 15:52:08 +00:00
}
__parts[PARTRELO].pnow = c;
if (cnt) {
__wr_flush(&__parts[PARTRELO]);
1987-01-05 17:31:38 +00:00
}
}
}
1993-11-10 11:49:49 +00:00
void
2017-11-11 18:08:13 +00:00
wr_name(const struct outname *name, unsigned int cnt)
1987-01-05 17:31:38 +00:00
{
1989-11-16 15:52:08 +00:00
while (cnt)
1987-01-05 17:31:38 +00:00
{
2017-11-11 18:08:13 +00:00
char *c;
unsigned int i;
1989-11-16 15:52:08 +00:00
i = __parts[PARTNAME].cnt/SZ_NAME;
c = __parts[PARTNAME].pnow;
if (i > cnt) i = cnt;
cnt -= i;
__parts[PARTNAME].cnt -= (i*SZ_NAME);
while (i--) {
put4(name->on_foff, c); c += 4;
put2(name->on_type, c); c += 2;
put2(name->on_desc, c); c += 2;
put4(name->on_valu, c); c += 4;
1987-01-05 17:31:38 +00:00
name++;
}
1989-11-16 15:52:08 +00:00
__parts[PARTNAME].pnow = c;
if (cnt) __wr_flush(&__parts[PARTNAME]);
1987-01-05 17:31:38 +00:00
}
}
1993-11-10 11:49:49 +00:00
void
2017-11-11 18:08:13 +00:00
wr_string(const char *addr, long len)
1987-01-05 17:31:38 +00:00
{
OUTWRITE(PARTCHAR, addr, len);
}
#ifdef SYMDBUG
1993-11-10 11:49:49 +00:00
void
1987-01-05 17:31:38 +00:00
wr_dbug(buf, size)
char *buf;
long size;
{
OUTWRITE(PARTDBUG, buf, size);
}
#endif /* SYMDBUG */