Initial revision
authorceriel <none@none>
Mon, 5 Jan 1987 17:31:38 +0000 (17:31 +0000)
committerceriel <none@none>
Mon, 5 Jan 1987 17:31:38 +0000 (17:31 +0000)
18 files changed:
modules/src/object/Makefile [new file with mode: 0644]
modules/src/object/byte_order.c [new file with mode: 0644]
modules/src/object/object.3 [new file with mode: 0644]
modules/src/object/object.h [new file with mode: 0644]
modules/src/object/rd.c [new file with mode: 0644]
modules/src/object/rd_arhdr.c [new file with mode: 0644]
modules/src/object/rd_bytes.c [new file with mode: 0644]
modules/src/object/rd_int2.c [new file with mode: 0644]
modules/src/object/rd_long.c [new file with mode: 0644]
modules/src/object/rd_ranlib.c [new file with mode: 0644]
modules/src/object/rd_unsig2.c [new file with mode: 0644]
modules/src/object/wr.c [new file with mode: 0644]
modules/src/object/wr_arhdr.c [new file with mode: 0644]
modules/src/object/wr_bytes.c [new file with mode: 0644]
modules/src/object/wr_int2.c [new file with mode: 0644]
modules/src/object/wr_long.c [new file with mode: 0644]
modules/src/object/wr_putc.c [new file with mode: 0644]
modules/src/object/wr_ranlib.c [new file with mode: 0644]

diff --git a/modules/src/object/Makefile b/modules/src/object/Makefile
new file mode 100644 (file)
index 0000000..88f8477
--- /dev/null
@@ -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 (file)
index 0000000..cc9990e
--- /dev/null
@@ -0,0 +1,49 @@
+#include <stdio.h>
+
+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 (file)
index 0000000..52bd8ac
--- /dev/null
@@ -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 <out.h>
+.br
+.B #include <arch.h>
+.br
+.B #include <ranlib.h>
+.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 (file)
index 0000000..87eb933
--- /dev/null
@@ -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 (file)
index 0000000..52c1f71
--- /dev/null
@@ -0,0 +1,237 @@
+#include <out.h>
+#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 (file)
index 0000000..00a1ca7
--- /dev/null
@@ -0,0 +1,29 @@
+#include <arch.h>
+#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 (file)
index 0000000..e46f4cb
--- /dev/null
@@ -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 (file)
index 0000000..7dbc2b5
--- /dev/null
@@ -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 (file)
index 0000000..af369be
--- /dev/null
@@ -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 (file)
index 0000000..f1797cf
--- /dev/null
@@ -0,0 +1,21 @@
+#include <ranlib.h>
+#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 (file)
index 0000000..5321c0d
--- /dev/null
@@ -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 (file)
index 0000000..5bcf55c
--- /dev/null
@@ -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 <out.h>
+#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 (file)
index 0000000..f7ac67b
--- /dev/null
@@ -0,0 +1,29 @@
+#include <arch.h>
+#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 (file)
index 0000000..8dccc4b
--- /dev/null
@@ -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 (file)
index 0000000..d836a4a
--- /dev/null
@@ -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 (file)
index 0000000..1d9217e
--- /dev/null
@@ -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 (file)
index 0000000..c5b05c5
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+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 (file)
index 0000000..f20772c
--- /dev/null
@@ -0,0 +1,31 @@
+#include <ranlib.h>
+#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
+}