Initial revision
This commit is contained in:
parent
eb28fd80f9
commit
b63bf2720c
60
modules/src/object/Makefile
Normal file
60
modules/src/object/Makefile
Normal file
|
@ -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
|
49
modules/src/object/byte_order.c
Normal file
49
modules/src/object/byte_order.c
Normal file
|
@ -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;
|
||||
}
|
287
modules/src/object/object.3
Normal file
287
modules/src/object/object.3
Normal file
|
@ -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.
|
30
modules/src/object/object.h
Normal file
30
modules/src/object/object.h
Normal file
|
@ -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
|
237
modules/src/object/rd.c
Normal file
237
modules/src/object/rd.c
Normal file
|
@ -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
|
29
modules/src/object/rd_arhdr.c
Normal file
29
modules/src/object/rd_arhdr.c
Normal file
|
@ -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
|
||||
}
|
22
modules/src/object/rd_bytes.c
Normal file
22
modules/src/object/rd_bytes.c
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
10
modules/src/object/rd_int2.c
Normal file
10
modules/src/object/rd_int2.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "object.h"
|
||||
|
||||
int
|
||||
rd_int2(fd)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
rd_bytes(fd, buf, 2L);
|
||||
return get2(buf);
|
||||
}
|
10
modules/src/object/rd_long.c
Normal file
10
modules/src/object/rd_long.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "object.h"
|
||||
|
||||
long
|
||||
rd_long(fd)
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
rd_bytes(fd, buf, 4L);
|
||||
return get4(buf);
|
||||
}
|
21
modules/src/object/rd_ranlib.c
Normal file
21
modules/src/object/rd_ranlib.c
Normal file
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
10
modules/src/object/rd_unsig2.c
Normal file
10
modules/src/object/rd_unsig2.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "object.h"
|
||||
|
||||
unsigned int
|
||||
rd_unsigned2(fd)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
rd_bytes(fd, buf, 2L);
|
||||
return uget2(buf);
|
||||
}
|
314
modules/src/object/wr.c
Normal file
314
modules/src/object/wr.c
Normal file
|
@ -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
|
29
modules/src/object/wr_arhdr.c
Normal file
29
modules/src/object/wr_arhdr.c
Normal file
|
@ -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
|
||||
}
|
20
modules/src/object/wr_bytes.c
Normal file
20
modules/src/object/wr_bytes.c
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
9
modules/src/object/wr_int2.c
Normal file
9
modules/src/object/wr_int2.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "object.h"
|
||||
|
||||
wr_int2(fd, i)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
put2(i, buf);
|
||||
wr_bytes(fd, buf, 2L);
|
||||
}
|
10
modules/src/object/wr_long.c
Normal file
10
modules/src/object/wr_long.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "object.h"
|
||||
|
||||
wr_long(fd, l)
|
||||
long l;
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
put4(l, buf);
|
||||
wr_bytes(fd, buf, 4L);
|
||||
}
|
15
modules/src/object/wr_putc.c
Normal file
15
modules/src/object/wr_putc.c
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
31
modules/src/object/wr_ranlib.c
Normal file
31
modules/src/object/wr_ranlib.c
Normal file
|
@ -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
|
||||
}
|
Loading…
Reference in a new issue