/* $Id: rd.c,v 1.1 2005/06/23 09:50:54 philip Exp $ */ /* * (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