123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- /* $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"
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.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 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)
- {
- 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)
- {
- if ((outfile = open(f, 0)) < 0)
- return 0;
- return rd_fdopen(outfile);
- }
- static int offcnt;
- int rd_fdopen(int fd)
- {
- 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(struct outhead *head)
- {
- long off;
- OUTREAD(PARTEMIT, (char *) head, (long) SZ_HEAD);
- #if BYTE_ORDER == 0x0123
- if (sizeof(struct outhead) != SZ_HEAD)
- #endif
- {
- 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)
- {
- long off = OFF_RELO(*head) + rd_base;
- BEGINSEEK(PARTRELO, off);
- }
- void rd_sect(struct outsect *sect, unsigned int cnt)
- {
- 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(int s)
- {
- OUTSECT(s);
- sectionnr = s;
- }
- /*
- * 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);
- #if BYTE_ORDER == 0x0123
- if (sizeof(struct outrelo) != SZ_RELO)
- #endif
- {
- 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 BYTE_ORDER == 0x0123
- if (sizeof(struct outname) != SZ_NAME)
- #endif
- {
- 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
|