From b63bf2720c4d6f93c0cfe05cb133374f85a9e75c Mon Sep 17 00:00:00 2001 From: ceriel Date: Mon, 5 Jan 1987 17:31:38 +0000 Subject: [PATCH] Initial revision --- modules/src/object/Makefile | 60 ++++++ modules/src/object/byte_order.c | 49 +++++ modules/src/object/object.3 | 287 +++++++++++++++++++++++++++++ modules/src/object/object.h | 30 +++ modules/src/object/rd.c | 237 ++++++++++++++++++++++++ modules/src/object/rd_arhdr.c | 29 +++ modules/src/object/rd_bytes.c | 22 +++ modules/src/object/rd_int2.c | 10 + modules/src/object/rd_long.c | 10 + modules/src/object/rd_ranlib.c | 21 +++ modules/src/object/rd_unsig2.c | 10 + modules/src/object/wr.c | 314 ++++++++++++++++++++++++++++++++ modules/src/object/wr_arhdr.c | 29 +++ modules/src/object/wr_bytes.c | 20 ++ modules/src/object/wr_int2.c | 9 + modules/src/object/wr_long.c | 10 + modules/src/object/wr_putc.c | 15 ++ modules/src/object/wr_ranlib.c | 31 ++++ 18 files changed, 1193 insertions(+) create mode 100644 modules/src/object/Makefile create mode 100644 modules/src/object/byte_order.c create mode 100644 modules/src/object/object.3 create mode 100644 modules/src/object/object.h create mode 100644 modules/src/object/rd.c create mode 100644 modules/src/object/rd_arhdr.c create mode 100644 modules/src/object/rd_bytes.c create mode 100644 modules/src/object/rd_int2.c create mode 100644 modules/src/object/rd_long.c create mode 100644 modules/src/object/rd_ranlib.c create mode 100644 modules/src/object/rd_unsig2.c create mode 100644 modules/src/object/wr.c create mode 100644 modules/src/object/wr_arhdr.c create mode 100644 modules/src/object/wr_bytes.c create mode 100644 modules/src/object/wr_int2.c create mode 100644 modules/src/object/wr_long.c create mode 100644 modules/src/object/wr_putc.c create mode 100644 modules/src/object/wr_ranlib.c diff --git a/modules/src/object/Makefile b/modules/src/object/Makefile new file mode 100644 index 000000000..88f84776c --- /dev/null +++ b/modules/src/object/Makefile @@ -0,0 +1,60 @@ +EMHOME = ../../.. +MODULES = $(EMHOME)/modules +INSTALL = $(MODULES)/install +COMPARE = $(MODULES)/compare +CFLAGS = -O -I$(EMHOME)/h +CFILES = rd_arhdr.c wr_arhdr.c \ + rd_ranlib.c wr_ranlib.c \ + rd_bytes.c wr_bytes.c \ + rd.c wr.c \ + wr_putc.c \ + rd_int2.c wr_int2.c \ + rd_unsig2.c \ + rd_long.c wr_long.c +# do not change the order in OFILES +OFILES = rd.o rd_arhdr.o rd_int2.o rd_long.o rd_ranlib.o rd_unsig2.o \ + rd_bytes.o wr_arhdr.o wr_int2.o wr_long.o wr_putc.o wr.o \ + wr_ranlib.o wr_bytes.o + +all: libobject.a + +install: all + $(INSTALL) lib/libobject.a + $(INSTALL) man/object.3 + +compare: all + $(COMPARE) lib/libobject.a + $(COMPARE) man/object.3 + +clean: + rm -f *.[oa] nohup.out Out byte_order byte_order.h + +libobject.a: $(OFILES) + ar r libobject.a $(OFILES) + -sh -c 'ranlib libobject.a' + +depend: byte_order.h + sed '/^#AUTOAUTO/,$$d' Makefile > Makefile.new + echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new + mkdep $(CFILES) | sed 's/\.c:/\.o:/' >> Makefile.new + mv Makefile Makefile.old + mv Makefile.new Makefile + +byte_order: byte_order.o + $(CC) $(LDFLAGS) -o byte_order byte_order.o + +byte_order.h: byte_order + byte_order > byte_order.h + +#AUTOAUTOAUTOAUTOAUTOAUTOAUTO +rd_arhdr.o: byte_order.h object.h +wr_arhdr.o: byte_order.h object.h +rd_ranlib.o: byte_order.h object.h +wr_ranlib.o: byte_order.h object.h +rd.o: byte_order.h object.h +wr.o: byte_order.h object.h +rd_int2.o: byte_order.h object.h +wr_int2.o: byte_order.h object.h +rd_unsig2.o: byte_order.h object.h +rd_long.o: byte_order.h object.h +wr_long.o: byte_order.h object.h diff --git a/modules/src/object/byte_order.c b/modules/src/object/byte_order.c new file mode 100644 index 000000000..cc9990e41 --- /dev/null +++ b/modules/src/object/byte_order.c @@ -0,0 +1,49 @@ +#include + +char bytes_reversed = 0; +char words_reversed = 0; +char char_unsigned = 0; + +/* + * Determine the byte/word order in shorts/longs, assuming the size of a short + * is 2 chars, and the size of a long is 4 chars. Not all theoretical + * possibilities are tested; only bytes reversed and/or words reversed. + */ +determine_ordering() +{ + short s; + long l; + register char *cp; + register short *sp; + + cp = (char *)&s; + cp[0] = 0x01; cp[1] = 0x02; + if (s != 0x01 + (0x02 << 8)) + bytes_reversed = 1; + sp = (short *)&l; + sp[0] = 0x0001; sp[1] = 0x0002; + if (l != 0x0001 + (0x0002L << 16)) + words_reversed = 1; +} + +/* + * determine whether characters are unsigned or signed + */ + +uns_char() +{ + char c = 0200; + int i = c; + + if (i > 0) char_unsigned = 1; +} + +main() +{ + determine_ordering(); + uns_char(); + printf("#define BYTES_REVERSED %d\n", bytes_reversed); + printf("#define WORDS_REVERSED %d\n", words_reversed); + printf("#define CHAR_UNSIGNED %d\n", char_unsigned); + return 0; +} diff --git a/modules/src/object/object.3 b/modules/src/object/object.3 new file mode 100644 index 000000000..52bd8ac52 --- /dev/null +++ b/modules/src/object/object.3 @@ -0,0 +1,287 @@ +.TH OBJECT 3 "October 16, 1986" +.SH NAME +wr_open, wr_close, wr_ohead, wr_sect, wr_outsect, wr_emit, wr_putc, wr_relo, +wr_name, wr_string, wr_arhdr, wr_ranlib, wr_int2, wr_long, +rd_open, rd_fdopen, rd_close, rd_ohead, rd_sect, rd_outsect, +rd_emit, rd_relo, rd_rew_relo, rd_name, rd_string, rd_arhdr, rd_ranlib, +rd_int2, rd_unsigned2, rd_long\ \-\ routines to read +and write ACK-object files and libraries +.SH SYNOPSIS +.B #include +.br +.B #include +.br +.B #include +.PP +.B int wr_open(filename) +.br +.B char *filename; +.PP +.B wr_close() +.PP +.B wr_ohead(head) +.br +.B struct outsect *head; +.PP +.B wr_sect(sect, cnt) +.br +.B struct outsect *sect; +.br +.B unsigned int cnt; +.PP +.B wr_outsect(sectionnr) +.br +.B int sectionnr; +.PP +.B wr_emit(emit, cnt) +.br +.B char *emit; +.br +.B long cnt; +.PP +.B wr_putc(ch) +.PP +.B wr_relo(relo, cnt) +.br +.B struct outrelo *relo; +.br +.B unsigned int cnt; +.PP +.B wr_name(name, cnt) +.br +.B struct name *name; +.br +.B unsigned int cnt; +.PP +.B wr_string(stringaddr, cnt) +.br +.B char *stringaddr; +.br +.B long cnt; +.PP +.B wr_arhdr(fd, arhdr) +.br +.B struct arhdr *arhdr; +.PP +.B wr_ranlib(fd, ran, cnt) +.br +.B struct ranlib *ran; +.br +.B long cnt; +.PP +.B wr_int2(fd, i) +.PP +.B wr_long(fd, l) +.br +.B long l; +.PP +.B int rd_open(filename) +.br +.B char *filename; +.PP +.B int rd_fdopen(fd) +.PP +.B rd_close() +.PP +.B rd_ohead(head) +.br +.B struct outsect *head; +.PP +.B rd_sect(sect, cnt) +.br +.B struct outsect *sect; +.br +.B unsigned int cnt; +.PP +.B rd_outsect(sectionnr) +.br +.B int sectionnr; +.PP +.B rd_emit(emit, cnt) +.br +.B char *emit; +.br +.B long cnt; +.PP +.B rd_relo(relo, cnt) +.br +.B struct outrelo *relo; +.br +.B unsigned int cnt; +.PP +.B rd_rew_relo(head) +.br +.B struct outhead *head; +.PP +.B rd_name(name, cnt) +.br +.B struct name *name; +.br +.B unsigned int cnt; +.PP +.B rd_string(stringaddr, cnt) +.br +.B char *stringaddr; +.br +.B long cnt; +.PP +.B rd_arhdr(fd, arhdr) +.br +.B struct arhdr *arhdr; +.PP +.B rd_ranlib(fd, ran, cnt) +.br +.B struct ranlib *ran; +.br +.B long cnt; +.PP +.B int rd_int2(fd) +.PP +.B unsigned int rd_unsigned2(fd) +.PP +.B long rd_long(fd) +.SH DESCRIPTION +These routines come in handy when reading or writing ACK-object files +or libraries. No checking is performed. +.PP +.I Wr_open +opens the file +.I filename +for writing and initializes some of this modules local variables. +It must be called before writing parts of the object file. +It returns 1 if it succeeds, 0 if it fails. +.PP +.I Wr_close +closes the object file. Don't forget to call it, because it might +flush internal buffers. +.PP +.I Wr_ohead +writes the +.I head +header structure. +This routine must be called before the routines to write the other +parts. +.PP +.I Wr_sect +writes +.I cnt +section headers, starting at +.IB sect . +Before writing a section, its section header must be written. +.PP +.I Wr_outsect +indicates that the next section to be written is +.IB sectionnr . +This routine can be used to switch between sections. +.PP +.I Wr_emit +writes +.I cnt +bytes, starting at +.IB emit , +of the current section. +.PP +.I Wr_putc +adds character +.I ch +to the current section. +.PP +.I Wr_relo +writes +.I cnt +outrelo structures, indicated by +.IB relo , +in the relocation information part of the object file. +.PP +.I Wr_name +writes +.I cnt +outname structures, indicated by +.IB name , +in the name-table part of the object file. +.PP +.I Wr_string +writes +.I cnt +bytes, indicated by +.IB stringaddr , +in the string table part of the object file. +.PP +The next few routines can be used independantly: +.I Wr_arhdr +writes the archive member header +.I arhdr +to file descriptor +.IB fd . +.PP +.I Wr_ranlib +writes +.I cnt +ranlib structures, indicated by +.IB ran , +to file descriptor +.IB fd. +.PP +.I Wr_int2 +writes a 2-byte integer +.I i +to file descriptor +.IB fd , +low order byte first. +.PP +.I Wr_long +writes a 4-byte integer +.I l +to file descriptor +.IB fd , +low order word first, low order byte first. +.PP +Most of the +.I rd_ +routines are the opposite of the +.I wr_ +routines. However, a few of them deserve special mentioning: +.PP +.I Rd_fdopen +initialises for reading an "object file" from file descriptor +.IB fd , +at its current position. +This is useful for reading an object that resides in an archive. +It returns 1 if it succeeds, 0 otherwise. +If you use this entry point for reading, you don't have to call +.I rd_close +to close the file. You can close the file yourself. +.PP +.I Rd_rew_relo +rewinds the relocation part, so that it can be read again. +\fILed\fR(1) sometimes needs this. +.PP +.I Rd_unsigned2 +reads two bytes from file descriptor +.I fd +and interpretes them as an unsigned integer. +.PP +When using any of the reading routines, you must define a routine +named +.IB rd_fatal . +It is called when a read fails, and is not supposed to return. +Likewise, a routine +.I wr_fatal +must be defined when using any of the writing routines. +.SH FILES +~em/h/out.h +.br +~em/h/arch.h +.br +~em/h/ranlib.h +.br +~em/modules/lib/libobject.a: the library in which these routines reside +.SH "SEE ALSO" +ack.out(5), arch(1), aal(1) +.SH DIAGNOSTICS +The routines +.IB wr_open , +.IB rd_open , +and +.I rd_fdopen +return 0 if they fail, and 1 if they succeed. diff --git a/modules/src/object/object.h b/modules/src/object/object.h new file mode 100644 index 000000000..87eb933e1 --- /dev/null +++ b/modules/src/object/object.h @@ -0,0 +1,30 @@ +#include "byte_order.h" + +#if CHAR_UNSIGNED +#define Xchar(ch) (ch) +#else +#define Xchar(ch) ((ch) & 0377) +#endif + +#if BYTES_REVERSED +#define uget2(c) (Xchar((c)[0]) | ((unsigned) Xchar((c)[1]) << 8)) +#define Xput2(i, c) (((c)[0] = (i)), ((c)[1] = (i) >> 8)) +#define put2(i, c) { register int j = (i); Xput2(j, c); } +#else +#define uget2(c) (* ((unsigned short *) (c))) +#define Xput2(i, c) (* ((short *) (c)) = (i)) +#define put2(i, c) Xput2(i, c) +#endif + +#define get2(c) ((short) uget2(c)) + +#if WORDS_REVERSED || BYTES_REVERSED +#define get4(c) (uget2(c) | ((long) uget2((c)+2) << 16)) +#define put4(l, c) { register long x=(l); \ + Xput2((int)x,c); \ + Xput2((int)(x>>16),(c)+2); \ + } +#else +#define get4(c) (* ((long *) (c))) +#define put4(l, c) (* ((long *) (c)) = (l)) +#endif diff --git a/modules/src/object/rd.c b/modules/src/object/rd.c new file mode 100644 index 000000000..52c1f718f --- /dev/null +++ b/modules/src/object/rd.c @@ -0,0 +1,237 @@ +#include +#include "object.h" + +extern long lseek(); + +/* + * Parts of the output file. + */ +#define PARTEMIT 0 +#define PARTRELO 1 +#define PARTNAME 2 +#define PARTCHAR 3 +#ifdef SYMDBUG +#define PARTDBUG 4 +#else +#define PARTDBUG 3 +#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 +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; + +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; +} + +rd_close() +{ + + close(outfile); +} + +rd_ohead(head) + 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 +} + +rd_rew_relos(head) + register struct outhead *head; +{ + register long off = OFF_RELO(*head) + rd_base; + + BEGINSEEK(PARTRELO, off); +} + +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); +#if ! (BYTES_REVERSED || WORDS_REVERSED) + } +#endif + 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); +#if ! (BYTES_REVERSED || WORDS_REVERSED) + } +#endif + } +} + +rd_outsect(s) +{ + OUTSECT(s); + sectionnr = s; +} + +/* + * We don't have to worry about byte order here. + */ +rd_emit(emit, cnt) + char *emit; + long cnt; +{ + OUTREAD(PARTEMIT, emit, cnt); + offset[sectionnr] += cnt; +} + +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; + } + } +} + +rd_name(name, cnt) + register struct outname *name; + register 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); + } + } +} + +rd_string(addr, len) + char *addr; + long len; +{ + + OUTREAD(PARTCHAR, addr, len); +} + +#ifdef SYMDBUG +rd_dbug(buf, size) + char *buf; + long size; +{ + OUTREAD(PARTDBUG, buf, size); +} +#endif diff --git a/modules/src/object/rd_arhdr.c b/modules/src/object/rd_arhdr.c new file mode 100644 index 000000000..00a1ca7e1 --- /dev/null +++ b/modules/src/object/rd_arhdr.c @@ -0,0 +1,29 @@ +#include +#include "object.h" + +rd_arhdr(fd, arhdr) + register struct ar_hdr *arhdr; +{ +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof (struct ar_hdr) != AR_TOTAL) +#endif + { + char buf[AR_TOTAL]; + register char *c = buf; + register char *p = arhdr->ar_name; + register int i = 14; + + rd_bytes(fd, c, (long) AR_TOTAL); + while (i--) { + *p++ = *c++; + } + arhdr->ar_date = get4(c); c += 4; + arhdr->ar_uid = *c++; + arhdr->ar_gid = *c++; + arhdr->ar_mode = get2(c); c += 2; + arhdr->ar_size = get4(c); + } +#if ! (BYTES_REVERSED || WORDS_REVERSED) + else rd_bytes(fd, (char *) arhdr, (long) AR_TOTAL); +#endif +} diff --git a/modules/src/object/rd_bytes.c b/modules/src/object/rd_bytes.c new file mode 100644 index 000000000..e46f4cb43 --- /dev/null +++ b/modules/src/object/rd_bytes.c @@ -0,0 +1,22 @@ +#define MININT (1 << (sizeof(int) * 8 - 1)) +#define MAXCHUNK (-(MININT + 1)) /* Highest count we write(2). */ + +/* + * We don't have to worry about byte order here. + * Just read "cnt" bytes from file-descriptor "fd". + */ +int +rd_bytes(fd, string, cnt) + register char *string; + register long cnt; +{ + + while (cnt) { + register int n = cnt >= MAXCHUNK ? MAXCHUNK : cnt; + + if (read(fd, string, n) != n) + rd_fatal(); + string += n; + cnt -= n; + } +} diff --git a/modules/src/object/rd_int2.c b/modules/src/object/rd_int2.c new file mode 100644 index 000000000..7dbc2b574 --- /dev/null +++ b/modules/src/object/rd_int2.c @@ -0,0 +1,10 @@ +#include "object.h" + +int +rd_int2(fd) +{ + char buf[2]; + + rd_bytes(fd, buf, 2L); + return get2(buf); +} diff --git a/modules/src/object/rd_long.c b/modules/src/object/rd_long.c new file mode 100644 index 000000000..af369be25 --- /dev/null +++ b/modules/src/object/rd_long.c @@ -0,0 +1,10 @@ +#include "object.h" + +long +rd_long(fd) +{ + char buf[4]; + + rd_bytes(fd, buf, 4L); + return get4(buf); +} diff --git a/modules/src/object/rd_ranlib.c b/modules/src/object/rd_ranlib.c new file mode 100644 index 000000000..f1797cfd3 --- /dev/null +++ b/modules/src/object/rd_ranlib.c @@ -0,0 +1,21 @@ +#include +#include "object.h" + +rd_ranlib(fd, ran, cnt) + register struct ranlib *ran; + register long cnt; +{ + rd_bytes(fd, (char *) ran, cnt * SZ_RAN); +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof (struct ranlib) != SZ_RAN) +#endif + { + register char *c = (char *) ran; + + while (cnt--) { + ran->ran_off = get4(c); c += 4; + ran->ran_pos = get4(c); c += 4; + ran++; + } + } +} diff --git a/modules/src/object/rd_unsig2.c b/modules/src/object/rd_unsig2.c new file mode 100644 index 000000000..5321c0d22 --- /dev/null +++ b/modules/src/object/rd_unsig2.c @@ -0,0 +1,10 @@ +#include "object.h" + +unsigned int +rd_unsigned2(fd) +{ + char buf[2]; + + rd_bytes(fd, buf, 2L); + return uget2(buf); +} diff --git a/modules/src/object/wr.c b/modules/src/object/wr.c new file mode 100644 index 000000000..5bcf55ca0 --- /dev/null +++ b/modules/src/object/wr.c @@ -0,0 +1,314 @@ +/* + * 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. + */ + +#include +#include "object.h" + +extern long lseek(); + +/* + * Parts of the output file. + */ +#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]; + +#ifdef OUTSEEK +static int outfile; +static long outseek[NPARTS]; +static long currpos; +#define OUTSECT(i) \ + (outseek[PARTEMIT] = offset[i]) +static +OUTWRITE(p, b, n) { + char *b; + long n; +{ + register long l = outseek[p]; + + if (currpos != l) { + lseek(outfile, l, 0); + } + wr_bytes(outfile, b, n); + currpos = l + n; + outseek[p] = currpos; +} + +#define BEGINSEEK(p, o) \ + (outseek[(p)] = (o)) + +#else OUTSEEK + +static int outfile[NPARTS]; +static long currpos[NPARTS]; +#define OUTSECT(i) \ + (currpos[PARTEMIT] == offset[(i)] ?\ + 0 :\ + (currpos[PARTEMIT] = offset[(i)],\ + lseek(outfile[PARTEMIT], currpos[PARTEMIT], 0))) +#define OUTWRITE(p, b, n) \ + (wr_bytes(outfile[(p)], (b), (n)), currpos[(p)] += (n)) +#define BEGINSEEK(p, o) \ + (currpos[(p)] = lseek(outfile[(p)], (o), 0)) + +#endif OUTSEEK + +int _ocnt; +char *_pbuf; +static int sectionnr; +static int offcnt; + +/* + * Open the output file according to the chosen strategy. + */ +int +wr_open(f) + char *f; +{ +#ifndef OUTSEEK + register int *fdp; +#endif OUTSEEK + + close(creat(f, 0666)); +#ifdef OUTSEEK + if ((outfile = open(f, 1)) < 0) + return 0; + currpos = 0; +#else OUTSEEK + for (fdp = &outfile[PARTEMIT]; fdp < &outfile[NPARTS]; fdp++) + if ((*fdp = open(f, 1)) < 0) + return 0; +#endif OUTSEEK + offcnt = 0; + return 1; +} + +wr_close() +{ +#ifndef OUTSEEK + register int *fdp; +#endif not OUTSEEK + + if (_ocnt) { + wr_flush(); + } +#ifdef OUTSEEK + close(outfile); +#else not OUTSEEK + for (fdp = &outfile[PARTEMIT]; fdp < &outfile[NPARTS]; fdp++) { + close(*fdp); + } +#endif not OUTSEEK +} + +wr_ohead(head) + register struct outhead *head; +{ + register long off = OFF_RELO(*head); + + 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); +#ifdef SYMDBUG + off += head->oh_nchar; + BEGINSEEK(PARTDBUG, off); +#endif +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof(struct outhead) != SZ_HEAD) +#endif + { + char buf[SZ_HEAD]; + register char *c = buf; + + 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); + OUTWRITE(PARTEMIT, buf, (long) SZ_HEAD); + } +#if ! (BYTES_REVERSED || WORDS_REVERSED) + else OUTWRITE(PARTEMIT, (char *) head, (long) SZ_HEAD); +#endif +} + +wr_sect(sect, cnt1) + register struct outsect *sect; + unsigned int cnt1; +{ + char buf[MAXSECT * SZ_SECT]; + register char *c = buf; + register unsigned int cnt = cnt1; + + while (cnt--) { +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof(struct outsect) != SZ_SECT) +#endif + { + put4(sect->os_base, c); c += 4; + put4(sect->os_size, c); c += 4; + put4(sect->os_foff, c); c += 4; + } + offset[offcnt++] = sect->os_foff; +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof(struct outsect) != SZ_SECT) +#endif + { + put4(sect->os_flen, c); c += 4; + put4(sect->os_lign, c); c += 4; + } + sect++; + } +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof(struct outsect) != SZ_SECT) +#endif + OUTWRITE(PARTEMIT, buf, (long) cnt1 * SZ_SECT); +#if ! (BYTES_REVERSED || WORDS_REVERSED) + else + OUTWRITE(PARTEMIT, (char *) (sect - cnt1), (long) cnt1 * SZ_SECT); +#endif +} + +wr_flush() +{ + OUTWRITE(PARTEMIT, _pbuf, (long) _ocnt); + offset[sectionnr] += _ocnt; + _ocnt = 0; +} + +wr_outsect(s) +{ + if (s != sectionnr) { + if (_ocnt) { + wr_flush(); + } + sectionnr = s; + OUTSECT(s); + } +} + +/* + * We don't have to worry about byte order here. + */ +wr_emit(emit, cnt) + char *emit; + long cnt; +{ + if (_ocnt) wr_flush(); + OUTWRITE(PARTEMIT, emit, cnt); + offset[sectionnr] += cnt; +} + +wr_relo(relo, cnt) + register struct outrelo *relo; + register unsigned int cnt; +{ + long l; + +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof(struct outrelo) != SZ_RELO) +#endif + { + char buf[100 * SZ_RELO]; + register char *c = buf; + register int i = 0; + + while (cnt--) { + *c++ = relo->or_type; + *c++ = relo->or_sect; + put2(relo->or_nami, c); c += 2; + put4(relo->or_addr, c); c += 4; + relo++; + i++; + if (i == 100 || cnt == 0) { + c = buf; + l = (long) (i * SZ_RELO); + OUTWRITE(PARTRELO, c, l); + i = 0; + } + } + } +#if ! (BYTES_REVERSED || WORDS_REVERSED) + else { + l = (long) cnt * SZ_RELO; + OUTWRITE(PARTRELO, (char *) relo, l); + } +#endif +} + +wr_name(name, cnt) + register struct outname *name; + register unsigned int cnt; +{ + long l; + +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof(struct outname) != SZ_NAME) +#endif + { + char buf[100 * SZ_NAME]; + register char *c = buf; + register int i = 0; + + while (cnt--) { + 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; + name++; + i++; + if (i == 100 || !cnt) { + c = buf; + l = (long) (i * SZ_NAME); + OUTWRITE(PARTNAME, c, l); + i = 0; + } + } + } +#if ! (BYTES_REVERSED || WORDS_REVERSED) + else { + l = (long)cnt * SZ_NAME; + OUTWRITE(PARTNAME, (char *) name, l); + } +#endif + +} + +wr_string(addr, len) + char *addr; + long len; +{ + + OUTWRITE(PARTCHAR, addr, len); +} + +#ifdef SYMDBUG + +wr_dbug(buf, size) + char *buf; + long size; +{ + OUTWRITE(PARTDBUG, buf, size); +} + +#endif SYMDBUG diff --git a/modules/src/object/wr_arhdr.c b/modules/src/object/wr_arhdr.c new file mode 100644 index 000000000..f7ac67ba9 --- /dev/null +++ b/modules/src/object/wr_arhdr.c @@ -0,0 +1,29 @@ +#include +#include "object.h" + +wr_arhdr(fd, arhdr) + register struct ar_hdr *arhdr; +{ +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof (struct ar_hdr) != AR_TOTAL) +#endif + { + char buf[AR_TOTAL]; + register char *c = buf; + register char *p = arhdr->ar_name; + register int i = 14; + + while (i--) { + *c++ = *p++; + } + put4(arhdr->ar_date,c); c += 4; + *c++ = arhdr->ar_uid; + *c++ = arhdr->ar_gid; + put2(arhdr->ar_mode,c); c += 2; + put4(arhdr->ar_size,c); + wr_bytes(fd, buf, (long) AR_TOTAL); + } +#if ! (BYTES_REVERSED || WORDS_REVERSED) + else wr_bytes(fd, (char *) arhdr, (long) AR_TOTAL); +#endif +} diff --git a/modules/src/object/wr_bytes.c b/modules/src/object/wr_bytes.c new file mode 100644 index 000000000..8dccc4b16 --- /dev/null +++ b/modules/src/object/wr_bytes.c @@ -0,0 +1,20 @@ +#define MININT (1 << (sizeof(int) * 8 - 1)) +#define MAXCHUNK (-(MININT + 1)) /* Highest count we write(2). */ + +/* + * Just write "cnt" bytes to file-descriptor "fd". + */ +wr_bytes(fd, string, cnt) + register char *string; + register long cnt; +{ + + while (cnt) { + register int n = cnt >= MAXCHUNK ? MAXCHUNK : cnt; + + if (write(fd, string, n) != n) + wr_fatal(); + string += n; + cnt -= n; + } +} diff --git a/modules/src/object/wr_int2.c b/modules/src/object/wr_int2.c new file mode 100644 index 000000000..d836a4a9b --- /dev/null +++ b/modules/src/object/wr_int2.c @@ -0,0 +1,9 @@ +#include "object.h" + +wr_int2(fd, i) +{ + char buf[2]; + + put2(i, buf); + wr_bytes(fd, buf, 2L); +} diff --git a/modules/src/object/wr_long.c b/modules/src/object/wr_long.c new file mode 100644 index 000000000..1d9217ea3 --- /dev/null +++ b/modules/src/object/wr_long.c @@ -0,0 +1,10 @@ +#include "object.h" + +wr_long(fd, l) + long l; +{ + char buf[4]; + + put4(l, buf); + wr_bytes(fd, buf, 4L); +} diff --git a/modules/src/object/wr_putc.c b/modules/src/object/wr_putc.c new file mode 100644 index 000000000..c5b05c57e --- /dev/null +++ b/modules/src/object/wr_putc.c @@ -0,0 +1,15 @@ +#include + +static char buf[BUFSIZ]; + +extern char *_pbuf; +extern int _ocnt; + +wr_putc(ch) +{ + _pbuf = buf; + buf[_ocnt++] = ch; + if (_ocnt == BUFSIZ) { + wr_flush(); + } +} diff --git a/modules/src/object/wr_ranlib.c b/modules/src/object/wr_ranlib.c new file mode 100644 index 000000000..f20772c14 --- /dev/null +++ b/modules/src/object/wr_ranlib.c @@ -0,0 +1,31 @@ +#include +#include "object.h" + +wr_ranlib(fd, ran, cnt) + register struct ranlib *ran; + register long cnt; +{ +#if ! (BYTES_REVERSED || WORDS_REVERSED) + if (sizeof (struct ranlib) != SZ_RAN) +#endif + { + char buf[100 * SZ_RAN]; + + while (cnt) { + register int i = (cnt > 100) ? 100 : cnt; + register char *c = buf; + long j = i * SZ_RAN; + + cnt -= i; + while (i--) { + put4(ran->ran_off,c); c += 4; + put4(ran->ran_pos,c); c += 4; + ran++; + } + wr_bytes(fd, c, j); + } + } +#if ! (BYTES_REVERSED || WORDS_REVERSED) + else wr_bytes(fd, (char *) ran, cnt * SZ_RAN); +#endif +} -- 2.34.1