A new version, that no longer tries to move all null parts to the end

of a segment. It also uses the "object" library to read and write ACK-
object files and libraries.
This commit is contained in:
ceriel 1986-10-20 10:17:57 +00:00
parent 8ffde3c86a
commit baf5b74da2
18 changed files with 212 additions and 719 deletions

View file

@ -2,36 +2,24 @@
# Author: L.J. Bekema @ VU Informatica, Amsterdam # Author: L.J. Bekema @ VU Informatica, Amsterdam
# #
.SUFFIXES: .c,v .h .h,v
.c,v.o:
co -q $*.c
$(CC) $(CFLAGS) -c $*.c
rm -f $*.c
.h,v.h:
co -q $*.h
# Definitions for the making programs. # Definitions for the making programs.
LIBDIR=../../lib EM = ../..
PREFLAGS= -DNDEBUG -DNASSERT LIBDIR= $(EM)/lib
CFLAGS = -O $(PREFLAGS) PREFLAGS= -I$(EM)/h -DNDEBUG -DNASSERT
CFLAGS = $(PREFLAGS) -O
LDFLAGS = LDFLAGS =
LINTFLAGS=-phbxac $(PREFLAGS) LDLIBS = $(EM)/modules/lib/libstr.a $(EM)/modules/lib/libobj.a
LINTFLAGS=-phbxa $(PREFLAGS)
PR = pr PR = pr
PRFLAGS = PRFLAGS =
# Some convenient macro definitions. # Some convenient macro definitions.
CFILES = archive.c byte_order.c error.c extract.c finish.c main.c memory.c\ CFILES = archive.c error.c extract.c finish.c main.c memory.c\
output.c read.c relocate.c save.c scan.c sym.c write.c output.c read.c relocate.c save.c scan.c sym.c write.c
CVFILES = archive.c,v byte_order.c,v error.c,v extract.c,v finish.c,v main.c,v\
memory.c,v output.c,v read.c,v relocate.c,v save.c,v scan.c,v\
sym.c,v write.c,v
HFILES = assert.h const.h debug.h defs.h memory.h orig.h scan.h HFILES = assert.h const.h debug.h defs.h memory.h orig.h scan.h
HVFILES = assert.h,v const.h,v debug.h,v defs.h,v memory.h,v orig.h,v scan.h,v OFILES = archive.o error.o extract.o finish.o main.o memory.o\
OFILES = archive.o byte_order.o error.o extract.o finish.o main.o memory.o\
output.o read.o relocate.o save.o scan.o sym.o write.o output.o read.o relocate.o save.o scan.o sym.o write.o
# Things that can be made. # Things that can be made.
@ -39,9 +27,6 @@ OFILES = archive.o byte_order.o error.o extract.o finish.o main.o memory.o\
led: $(OFILES) led: $(OFILES)
$(CC) $(LDFLAGS) $(OFILES) $(LDLIBS) -o led $(CC) $(LDFLAGS) $(OFILES) $(LDLIBS) -o led
mach.c: mach.c,v
co -q mach.c
install:led install:led
cp led $(LIBDIR)/em_led cp led $(LIBDIR)/em_led
@ -49,103 +34,65 @@ cmp: led
cmp led $(LIBDIR)/em_led cmp led $(LIBDIR)/em_led
lint: lint:
-for i in $(CFILES) $(HFILES) mach.c; do\
if test ! -f $$i; then\
echo $$i >> checked.out;\
co -q $$i;\
fi;\
done
lint $(LINTFLAGS) $(CFILES) lint $(LINTFLAGS) $(CFILES)
rm -f `cat checked.out` checked.out
pr: $(CVFILES) $(HVFILES) mach.c pr: $(CFILES) $(HFILES) mach.c
@-for i in $?; do\ $(PR) $(PRFLAGS) $?
co -q -p $$i | $(PR) $(PRFLAGS) -h `basename $$i ,v`;\
done
@touch pr @touch pr
opr: opr:
make pr | opr make pr | opr
clean: clean:
rm *.o led rm -f Out *.o led nohup.out
depend: depend:
-for i in $(CFILES); do\
if test ! -f $$i; then\
echo $$i >> checked.out;\
co -q $$i;\
fi;\
done
makedepend $(CFILES) makedepend $(CFILES)
rm -f `cat checked.out` checked.out
# The next lines are generated automatically. # The next lines are generated automatically.
# AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO # AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
archive.o: ../../h/arch.h
archive.o: ../../h/out.h
archive.o: ../../h/ranlib.h
archive.o: const.h archive.o: const.h
archive.o: debug.h archive.o: debug.h
archive.o: defs.h archive.o: defs.h
archive.o: memory.h archive.o: memory.h
byte_order.o: assert.h
byte_order.o: const.h
error.o: ../../h/out.h
error.o: const.h error.o: const.h
extract.o: ../../h/out.h
extract.o: const.h extract.o: const.h
extract.o: debug.h extract.o: debug.h
extract.o: defs.h extract.o: defs.h
extract.o: memory.h extract.o: memory.h
extract.o: orig.h extract.o: orig.h
extract.o: scan.h extract.o: scan.h
finish.o: ../../h/out.h
finish.o: const.h finish.o: const.h
finish.o: defs.h finish.o: defs.h
finish.o: memory.h finish.o: memory.h
finish.o: orig.h finish.o: orig.h
finish.o: scan.h finish.o: scan.h
main.o: ../../h/out.h
main.o: const.h main.o: const.h
main.o: debug.h main.o: debug.h
main.o: defs.h main.o: defs.h
main.o: memory.h main.o: memory.h
main.o: orig.h main.o: orig.h
memory.o: ../../h/out.h
memory.o: assert.h memory.o: assert.h
memory.o: const.h memory.o: const.h
memory.o: debug.h memory.o: debug.h
memory.o: mach.c memory.o: mach.c
memory.o: memory.h memory.o: memory.h
output.o: ../../h/out.h
output.o: const.h output.o: const.h
output.o: memory.h output.o: memory.h
read.o: ../../h/arch.h
read.o: ../../h/out.h
read.o: ../../h/ranlib.h
read.o: assert.h read.o: assert.h
read.o: const.h read.o: const.h
relocate.o: ../../h/out.h
relocate.o: const.h relocate.o: const.h
relocate.o: debug.h relocate.o: debug.h
relocate.o: defs.h relocate.o: defs.h
relocate.o: orig.h relocate.o: orig.h
save.o: ../../h/arch.h
save.o: ../../h/out.h
save.o: assert.h save.o: assert.h
save.o: const.h save.o: const.h
save.o: memory.h save.o: memory.h
scan.o: ../../h/arch.h
scan.o: ../../h/out.h
scan.o: ../../h/ranlib.h
scan.o: assert.h scan.o: assert.h
scan.o: const.h scan.o: const.h
scan.o: memory.h scan.o: memory.h
scan.o: scan.h scan.o: scan.h
sym.o: ../../h/out.h
sym.o: const.h sym.o: const.h
sym.o: memory.h sym.o: memory.h
write.o: ../../h/out.h
write.o: assert.h write.o: assert.h
write.o: const.h write.o: const.h
write.o: memory.h write.o: memory.h

View file

@ -1,56 +1,12 @@
This file contains a summary of the bugs/features/inconsistencies This file contains a summary of the bugs/features/inconsistencies
Robbert and Ed found while making the linker usable for the 68000 and amoeba. Robbert and Ed found while making the linker usable for the 68000 and amoeba.
I (Ceriel Jacobs) took the liberty of removing the ones that I fixed from
this list.
There is something wrong with the way the combination of
assembler and linker handle bss.
In the original (Duk's) the assembler translated .space and, worse, .align
to a sequence of zero's. If this sequence was at the end of a segment
within a module the assembler didn't put zero in the segment but sets
os_flen to the amount of space initialized before the zero space
and os_size to the segements size. (os_size - os_flen) is then the
size of the space filled by zeroes.
For the sake of clarity, let us call 0...os_flen-1 initialized space
and os_flen..os_size-1 uninitialized space.
Now the linker, it does a nasty trick. It gathers the uninitialized space
of all modules within a segment and puts it consequtively at the end
of the segment. I think that I understand the reason: This way you can keep
your resultant a.out smaller and you don't need a special bss segment
(a la unix). But it is incorrect, the net effect is that the .align's
at the end of segments within a module do have the desired effect,
the space thus allocated is removed to 'higher spheres' thereby
leaving the first items of that segment in the inmediatly following
modules at unaligned boundaries.
What should be done is that the linker leaves the initialized and
the unitialized code alone and regards the whole a a chunk that can be
relocated. Only producing a difference of os_size and os_flen for
the zeroes at the very end of the segment. Thereby collapsing all
.space (and .align) commands into zero space only if they
are in consequtive modules at the end of the segment, with modules
NOT containing any initialized data.
I already, ad-hoc, changed the code of the assembler to producing 'hard'
zeroes when aligning. The trick could also be done for .space
but is a bit harder here.
The reason: .space is also used to allocate space in the BSS segment
if that produced zeroes in the a.out file (0..bss_size) we would
have a.out files that are far too large.
This feature of the linker also caused weird effects for names that
are defined as the very last in a section within a module, without
any data (initialized or uninitialezed) after it.
The names a regarded as pointing into the uninitialized space and
thus relocated to the end of the section.
The sequence
.sect .data
begdata:
.sect ....
in an head_em.s resulted in the relocation of begdata to the END
of the .data segment.
Another problem form the commons: Another problem form the commons:
1 - Local commons are not handled by led and not produced by as. 1 - Local commons are not handled by led and not produced by as.
using .comm for unitialized data is not correct because (from C) Must, and will be handled by as.
two uninitialized static declarations for the same name in
different modules will be handled as external commons and thus
be overlayed.
2 - The commons are allocated at the very end of the first pass, after the 2 - The commons are allocated at the very end of the first pass, after the
initialezed data has been allocated in the segments. The order on which initialezed data has been allocated in the segments. The order on which
the commons are allocated seems to be random. That way it is impossible the commons are allocated seems to be random. That way it is impossible
@ -67,6 +23,3 @@ replacing/adding/deleting modules is likely to produce libraries
with incorrect ranlib entries. with incorrect ranlib entries.
The major troublemaker seems to be the extra padding byte at the end The major troublemaker seems to be the extra padding byte at the end
of odd sized modules. of odd sized modules.
Led should return a non-zero value when it has found Undefined symbols
or has another reason for not being able to produce a correct output file.

View file

@ -2,9 +2,9 @@
static char rcsid[] = "$Header$"; static char rcsid[] = "$Header$";
#endif #endif
#include "../../h/arch.h" #include <arch.h>
#include "../../h/out.h" #include <out.h>
#include "../../h/ranlib.h" #include <ranlib.h>
#include "const.h" #include "const.h"
#include "debug.h" #include "debug.h"
#include "defs.h" #include "defs.h"
@ -30,20 +30,21 @@ getsymdeftable()
register struct ranlib *ran; register struct ranlib *ran;
register long count; register long count;
register long nran, nchar; register long nran, nchar;
extern long getlong(); extern long rd_long();
extern int infile;
count = nran = getlong(); count = nran = rd_long(infile);
debug("%ld ranlib structs, ", nran, 0, 0, 0); debug("%ld ranlib structs, ", nran, 0, 0, 0);
off = hard_alloc(ALLORANL, nran * sizeof(struct ranlib)); off = hard_alloc(ALLORANL, nran * sizeof(struct ranlib));
if (off == BADOFF) if (off == BADOFF)
fatal("no space for ranlib structs"); fatal("no space for ranlib structs");
ran = (struct ranlib *)address(ALLORANL, off); ran = (struct ranlib *)address(ALLORANL, off);
read_table(ran, count); rd_ranlib(infile, ran, count);
nchar = getlong(); nchar = rd_long(infile);
debug("%ld ranlib chars\n", nchar, 0, 0, 0); debug("%ld ranlib chars\n", nchar, 0, 0, 0);
if ((off = hard_alloc(ALLORANL, nchar)) == BADOFF) if ((off = hard_alloc(ALLORANL, nchar)) == BADOFF)
fatal("no space for ranlib strings"); fatal("no space for ranlib strings");
read_char(address(ALLORANL, off), nchar); rd_bytes(infile, address(ALLORANL, off), nchar);
ran = (struct ranlib *)address(ALLORANL, (ind_t)0); ran = (struct ranlib *)address(ALLORANL, (ind_t)0);
while (count--) { while (count--) {
/* /*
@ -60,7 +61,6 @@ getsymdeftable()
} }
extern char *modulname; extern char *modulname;
extern long position;
/* /*
* Process archive with table of contents. The table of contents tells * Process archive with table of contents. The table of contents tells
@ -107,7 +107,6 @@ arch()
get_archive_header(&arhdr); get_archive_header(&arhdr);
modulname = arhdr.ar_name; modulname = arhdr.ar_name;
debug("%s defines %s\n", modulname, string, 0, 0); debug("%s defines %s\n", modulname, string, 0, 0);
position = ran->ran_pos + AR_SIZE;
resolved = TRUE; resolved = TRUE;
/* /*
* This archive member is going to be linked, * This archive member is going to be linked,
@ -170,7 +169,6 @@ arch2()
get_archive_header(&arhdr); get_archive_header(&arhdr);
modulname = arhdr.ar_name; modulname = arhdr.ar_name;
debug("%s: archive member\n", modulname, 0, 0, 0); debug("%s: archive member\n", modulname, 0, 0, 0);
position = *pos + AR_SIZE;
finish(); finish();
} }
localpos += sizeof(long); /* Skip ENDLIB. */ localpos += sizeof(long); /* Skip ENDLIB. */

View file

@ -5,18 +5,12 @@ typedef int bool;
#define FALSE 0 #define FALSE 0
#define TRUE 1 #define TRUE 1
#define S_ZER 0x2000 /* Internal use only. */
#define WIDTH 8 /* Number of bits in a byte. */ #define WIDTH 8 /* Number of bits in a byte. */
#define BYTEMASK 0xFF /* Mask to get low order byte. */ #define BYTEMASK 0xFF /* Mask to get low order byte. */
#define MININT (1 << (sizeof(int) * WIDTH - 1))
#define MAXCHUNK (-(MININT + 1)) /* Highest count we write(2). */
#define RFLAG 0x01 /* -r flag given. */ #define RFLAG 0x01 /* -r flag given. */
#define SFLAG 0x02 /* -s flag given. */ #define SFLAG 0x02 /* -s flag given. */
#define MAXSECT 64 /* Maximum number of sections. */
#define PLAIN 0 /* Input file is a normal file. */ #define PLAIN 0 /* Input file is a normal file. */
#define ARCHIVE 1 /* Input file is an archive. */ #define ARCHIVE 1 /* Input file is an archive. */

View file

@ -2,10 +2,11 @@
#ifdef NDEBUG #ifdef NDEBUG
#define debug(s, a1, a2, a3, a4) dummy() #define debug(s, a1, a2, a3, a4)
#else #else
extern int DEB;
#define debug(s, a1, a2, a3, a4) printf(s, a1, a2, a3, a4) #define debug(s, a1, a2, a3, a4) (DEB && printf(s, a1, a2, a3, a4))
#endif #endif

View file

@ -4,7 +4,7 @@ static char rcsid[] = "$Header$";
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
static short nerrors = 0; static short nerrors = 0;
@ -13,11 +13,14 @@ static diag();
stop() stop()
{ {
extern char *outputname; extern char *outputname;
extern int exitstatus;
if (nerrors) if (nerrors) {
unlink(outputname); unlink(outputname);
exit(nerrors); exit(nerrors);
}
exit(exitstatus);
} }
trap_signals() trap_signals()

View file

@ -2,7 +2,7 @@
static char rcsid[] = "$Header$"; static char rcsid[] = "$Header$";
#endif #endif
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
#include "debug.h" #include "debug.h"
#include "defs.h" #include "defs.h"
@ -47,23 +47,20 @@ get_names(head)
register struct outhead *head; register struct outhead *head;
{ {
register int nnames; register int nnames;
register ind_t sectindex, nameindex, charindex; register ind_t nameindex, charindex;
register ind_t charoff; register ind_t charoff;
extern int flagword; extern int flagword;
nnames = head->oh_nname; nnames = head->oh_nname;
sectindex = IND_SECT(*head);
nameindex = IND_NAME(*head); nameindex = IND_NAME(*head);
charindex = IND_CHAR(*head); charindex = IND_CHAR(*head);
charoff = OFF_CHAR(*head); charoff = OFF_CHAR(*head);
while (nnames--) { while (nnames--) {
register struct outsect *sects;
struct outname name; /* A local copy. */ struct outname name; /* A local copy. */
/* /*
* Because savelocal/getexternal might relocate the modules * Because savelocal/getexternal might relocate the modules
* we have to compute the core addresses again. * we have to compute the core addresses again.
*/ */
sects = (struct outsect *)modulptr(sectindex);
name = *(struct outname *)modulptr(nameindex); name = *(struct outname *)modulptr(nameindex);
/* /*
* Change the offset in file into an offset in the memory area. * Change the offset in file into an offset in the memory area.
@ -73,7 +70,7 @@ get_names(head)
*/ */
if (name.on_foff) if (name.on_foff)
name.on_foff += charindex - charoff; name.on_foff += charindex - charoff;
namerelocate(&name, sects); namerelocate(&name);
if (name.on_type & S_EXT) { if (name.on_type & S_EXT) {
getexternal(&name); getexternal(&name);
} else { } else {
@ -111,14 +108,19 @@ process(head)
nsect = head->oh_nsect; nsect = head->oh_nsect;
outsp = outsect; outsp = outsect;
while (nsect--) { while (nsect--) {
outsp->os_size += sects->os_size; if (sects->os_flen) {
/* contains non-zero stuff */
outsp->os_flen = outsp->os_size + sects->os_flen;
}
else {
outsp->os_flen += sects->os_flen; outsp->os_flen += sects->os_flen;
}
outsp->os_size += sects->os_size;
/* /*
* Add all flen's and all (size - flen == zero)'s of * Add all flen's and all (size - flen == zero)'s of
* preceding sections with the same number. * preceding sections with the same number.
*/ */
orig->org_flen += sects->os_flen; orig->org_size = outsp->os_size;
orig->org_zero += sects->os_size - sects->os_flen;
orig++; outsp++; sects++; orig++; outsp++; sects++;
} }
} }
@ -127,21 +129,13 @@ process(head)
* Add relocation constant for names in user defined sections. * Add relocation constant for names in user defined sections.
* The value of a common name indicates a size instead of an offset, * The value of a common name indicates a size instead of an offset,
* and hence shouldn't be relocated. * and hence shouldn't be relocated.
* The value of a name in the zero part of a section is relative from the
* beginning of the section, not from the beginning of the zero part; but
* all zero parts will be put after the normal section contents, so we
* must subtract the flen of its section from the value (and later on add
* the total flen of its section) and add the accumulated size of all
* zero parts in preceding sections with the same number.
* Otherwise we just add the accumulated size of all normal parts in preceding * Otherwise we just add the accumulated size of all normal parts in preceding
* sections with the same size. * sections with the same size.
*/ */
namerelocate(name, sects) namerelocate(name)
register struct outname *name; register struct outname *name;
struct outsect *sects;
{ {
register int type = name->on_type; register int type = name->on_type;
register int sectindex;
if ((type & S_TYP) == S_UND || (type & S_TYP) == S_ABS) if ((type & S_TYP) == S_UND || (type & S_TYP) == S_ABS)
return; return;
@ -150,14 +144,7 @@ namerelocate(name, sects)
return; return;
} }
sectindex = (type & S_TYP) - S_MIN; name->on_valu += relorig[(type & S_TYP) - S_MIN].org_size;
if (name->on_valu >= sects[sectindex].os_flen) {
name->on_type |= S_ZER;
name->on_valu -= sects[sectindex].os_flen;
name->on_valu += relorig[sectindex].org_zero;
} else {
name->on_valu += relorig[sectindex].org_flen;
}
} }
/* /*

View file

@ -2,7 +2,7 @@
static char rcsid[] = "$Header$"; static char rcsid[] = "$Header$";
#endif #endif
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
#include "defs.h" #include "defs.h"
#include "memory.h" #include "memory.h"
@ -38,7 +38,7 @@ finish()
adjust_names(names, head, chars); adjust_names(names, head, chars);
handle_relos(head, sects, names); handle_relos(head, sects, names);
if (!incore && !(flagword & SFLAG)) { if (!incore && !(flagword & SFLAG)) {
put_locals(names, head->oh_nname, sects); put_locals(names, head->oh_nname);
#ifdef SYMDBUG #ifdef SYMDBUG
put_dbug(OFF_DBUG(*head)); put_dbug(OFF_DBUG(*head));
#endif SYMDBUG #endif SYMDBUG
@ -86,6 +86,7 @@ handle_relos(head, sects, names)
register char *emit; register char *emit;
extern char *getemit(); extern char *getemit();
extern struct outrelo *nextrelo(); extern struct outrelo *nextrelo();
static long zeros[MAXSECT];
if (incore) { if (incore) {
nrelo = head->oh_nrelo; sectindex = -1; nrelo = head->oh_nrelo; sectindex = -1;
@ -95,7 +96,7 @@ handle_relos(head, sects, names)
sectindex = relo->or_sect - S_MIN; sectindex = relo->or_sect - S_MIN;
emit = getemit(head, sects, sectindex); emit = getemit(head, sects, sectindex);
} }
relocate(head, emit, names, relo, sects); relocate(head, emit, names, relo);
relo++; relo++;
} }
} else { } else {
@ -105,16 +106,22 @@ handle_relos(head, sects, names)
while (nrelo--) { while (nrelo--) {
relo = nextrelo(); relo = nextrelo();
if (relo->or_sect - S_MIN == sectindex) { if (relo->or_sect - S_MIN == sectindex) {
relocate(head,emit,names,relo,sects); relocate(head,emit,names,relo);
/* /*
* Write out the (probably changed) * Write out the (probably changed)
* relocation information. * relocation information.
*/ */
if (flagword & RFLAG) if (flagword & RFLAG)
wrt_relo(relo); wr_relo(relo, 1);
} }
} }
if (sects[sectindex].os_flen) {
wrt_nulls(sectindex, zeros[sectindex]);
zeros[sectindex] = 0;
wrt_emit(emit, sectindex, sects[sectindex].os_flen); wrt_emit(emit, sectindex, sects[sectindex].os_flen);
}
zeros[sectindex] += sects[sectindex].os_size -
sects[sectindex].os_flen;
/* /*
* XXX We should be able to free the emitted bytes. * XXX We should be able to free the emitted bytes.
*/ */
@ -126,14 +133,13 @@ handle_relos(head, sects, names)
* Write out the local names that must be saved. * Write out the local names that must be saved.
*/ */
static static
put_locals(name, nnames, sects) put_locals(name, nnames)
register struct outname *name; register struct outname *name;
register ushort nnames; register ushort nnames;
register struct outsect *sects;
{ {
while (nnames--) { while (nnames--) {
if ((name->on_type & S_EXT) == 0 && mustsavelocal(name)) { if ((name->on_type & S_EXT) == 0 && mustsavelocal(name)) {
namerelocate(name, sects); namerelocate(name);
addbase(name); addbase(name);
wrt_name(name); wrt_name(name);
} }
@ -154,8 +160,8 @@ compute_origins(sect, nsect)
register struct orig *orig = relorig; register struct orig *orig = relorig;
while (nsect--) { while (nsect--) {
orig->org_flen += sect->os_flen;
orig->org_zero += sect->os_size - sect->os_flen; orig->org_size += sect->os_size;
orig++; sect++; orig++; sect++;
} }
} }
@ -173,14 +179,12 @@ put_dbug(offdbug)
register int nbytes; register int nbytes;
register long dbugsize; register long dbugsize;
extern long objectsize; extern long objectsize;
extern long position;
dbugsize = objectsize - offdbug; dbugsize = objectsize - offdbug;
seek(position + offdbug);
while (dbugsize) { while (dbugsize) {
nbytes = dbugsize > 512 ? 512 : dbugsize; nbytes = dbugsize > 512 ? 512 : dbugsize;
read_char(buf, (long)nbytes); rd_dbug(buf, (long)nbytes);
wrt_dbug(buf, nbytes); wr_dbug(buf, (long) nbytes);
dbugsize -= nbytes; dbugsize -= nbytes;
} }
} }

View file

@ -7,7 +7,7 @@ static char rcsid[] = "$Header$";
*/ */
#include <stdio.h> #include <stdio.h>
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
#include "debug.h" #include "debug.h"
#include "defs.h" #include "defs.h"
@ -15,6 +15,9 @@ static char rcsid[] = "$Header$";
#include "orig.h" #include "orig.h"
extern bool incore; extern bool incore;
#ifndef NDEBUG
int DEB = 0;
#endif
static initializations(); static initializations();
static first_pass(); static first_pass();
@ -65,7 +68,6 @@ initializations(argc, argv)
progname = argv[0]; progname = argv[0];
passnumber = FIRST; passnumber = FIRST;
determine_ordering();
init_core(); init_core();
init_symboltable(); init_symboltable();
outhead.oh_magic = O_MAGIC; outhead.oh_magic = O_MAGIC;
@ -76,6 +78,7 @@ initializations(argc, argv)
int flagword = 0; /* To store command-line options. */ int flagword = 0; /* To store command-line options. */
char *outputname = "a.out"; /* Name of the resulting object file. */ char *outputname = "a.out"; /* Name of the resulting object file. */
int exitstatus = 0;
/* /*
* Scan the arguments. * Scan the arguments.
@ -90,7 +93,7 @@ first_pass(argv)
int sectno; int sectno;
int h; int h;
extern int atoi(); extern int atoi();
extern char *index(); extern char *strindex();
extern int hash(); extern int hash();
extern struct outname *searchname(); extern struct outname *searchname();
@ -111,7 +114,7 @@ first_pass(argv)
* section <section number>. * section <section number>.
*/ */
sectno = atoi(++argp); sectno = atoi(++argp);
if ((argp = index(argp, ':')) == (char *)0) if ((argp = strindex(argp, ':')) == (char *)0)
fatal("usage: -a<section number>:<alignment>"); fatal("usage: -a<section number>:<alignment>");
setlign(sectno, number(++argp)); setlign(sectno, number(++argp));
break; break;
@ -124,10 +127,15 @@ first_pass(argv)
* <section number>. * <section number>.
*/ */
sectno = atoi(++argp); sectno = atoi(++argp);
if ((argp = index(argp, ':')) == (char *)0) if ((argp = strindex(argp, ':')) == (char *)0)
fatal("usage: -b<section number>:<base>"); fatal("usage: -b<section number>:<base>");
setbase(sectno, number(++argp)); setbase(sectno, number(++argp));
break; break;
#ifndef NDEBUG
case 'd':
DEB = 1;
break;
#endif
case 'o': case 'o':
/* /*
* The `name' argument after -o is used as name * The `name' argument after -o is used as name
@ -311,7 +319,6 @@ pass1(file)
static static
evaluate() evaluate()
{ {
if (!(flagword & RFLAG))
norm_commons(); norm_commons();
complete_sections(); complete_sections();
if (!(flagword & RFLAG)) if (!(flagword & RFLAG))
@ -324,7 +331,7 @@ extern ushort NGlobals, NLocals;
* Sect_comm[N] is the number of common bytes in section N. * Sect_comm[N] is the number of common bytes in section N.
* It is computed after pass 1. * It is computed after pass 1.
*/ */
static long sect_comm[MAXSECT]; long sect_comm[MAXSECT];
/* /*
* If there are undefined names, we print them and we set a flag so that * If there are undefined names, we print them and we set a flag so that
@ -347,10 +354,14 @@ norm_commons()
if (ISUNDEFINED(name)) { if (ISUNDEFINED(name)) {
if (!und) { if (!und) {
und = TRUE; und = TRUE;
outhead.oh_flags |= HF_LINK; if (!(flagword & RFLAG)) {
flagword = (flagword & ~SFLAG) | RFLAG; exitstatus = 1;
fprintf(stderr, "Undefined:\n"); fprintf(stderr, "Undefined:\n");
} }
outhead.oh_flags |= HF_LINK;
if (flagword & RFLAG) break;
flagword = (flagword & ~SFLAG) | RFLAG;
}
fprintf(stderr, "\t%s\n", fprintf(stderr, "\t%s\n",
address(ALLOGCHR, (ind_t)name->on_foff) address(ALLOGCHR, (ind_t)name->on_foff)
); );
@ -398,8 +409,7 @@ complete_sections()
foff = SZ_HEAD + outhead.oh_nsect * SZ_SECT; foff = SZ_HEAD + outhead.oh_nsect * SZ_SECT;
for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) { for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) {
relorig[sectindex].org_flen = (long)0; relorig[sectindex].org_size = (long)0;
relorig[sectindex].org_zero = (long)0;
outsect[sectindex].os_foff = foff; outsect[sectindex].os_foff = foff;
foff += outsect[sectindex].os_flen; foff += outsect[sectindex].os_flen;
@ -497,8 +507,7 @@ tstbit(indx, string)
} }
/* /*
* Add the base of the section of a name to its value. For a name in the zero * Add the base of the section of a name to its value.
* part, the size of the normal part is also a "base".
*/ */
addbase(name) addbase(name)
struct outname *name; struct outname *name;
@ -511,10 +520,6 @@ addbase(name)
if (name->on_type & S_COM) if (name->on_type & S_COM)
return; return;
if (name->on_type & S_ZER) {
name->on_valu += outsect[sectindex].os_flen;
name->on_type &= ~S_ZER;
}
name->on_valu += outsect[sectindex].os_base; name->on_valu += outsect[sectindex].os_base;
debug( "%s: type 0x%x, value %ld\n", debug( "%s: type 0x%x, value %ld\n",
address((name->on_type & S_EXT) ? ALLOGCHR : ALLOLCHR, address((name->on_type & S_EXT) ? ALLOGCHR : ALLOLCHR,
@ -564,9 +569,3 @@ pass2(file)
} }
closefile(file); closefile(file);
} }
#ifdef NDEBUG
dummy() { ; }
#endif

View file

@ -9,7 +9,7 @@ static char rcsid[] = "$Header$";
* is done and pieces after the one that requested the growth are moved up. * is done and pieces after the one that requested the growth are moved up.
*/ */
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
#include "assert.h" #include "assert.h"
#include "debug.h" #include "debug.h"
@ -19,8 +19,6 @@ static copy_down();
static copy_up(); static copy_up();
static free_saved_moduls(); static free_saved_moduls();
static writelong(); static writelong();
static sectswap();
static reloswap();
static namecpy(); static namecpy();
struct memory mems[NMEMS]; struct memory mems[NMEMS];
@ -201,11 +199,11 @@ copy_up(mem, dist)
*/ */
ind_t ind_t
alloc(piece, size) alloc(piece, size)
register int piece; int piece;
register long size; register long size;
{ {
register ind_t incr = 0; register ind_t incr = 0;
register ind_t left = mems[piece].mem_left; ind_t left = mems[piece].mem_left;
register ind_t full = mems[piece].mem_full; register ind_t full = mems[piece].mem_full;
assert(passnumber == FIRST || (!incore && piece == ALLOMODL)); assert(passnumber == FIRST || (!incore && piece == ALLOMODL));
@ -347,18 +345,14 @@ freeze_core()
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
extern bool bytes_reversed;
extern bool words_reversed;
/* /*
* To transform the various pieces of the output in core to the file format, * To transform the various pieces of the output in core to the file format,
* we must order the bytes in the ushorts and longs as ACK prescribes. * we must order the bytes in the ushorts and longs as ACK prescribes.
*/ */
write_bytes() write_bytes()
{ {
ushort nsect, nrelo; ushort nsect;
long offchar; long offchar;
int fd;
register struct memory *mem; register struct memory *mem;
extern ushort NLocals, NGlobals; extern ushort NLocals, NGlobals;
extern long NLChars, NGChars; extern long NLChars, NGChars;
@ -366,16 +360,11 @@ write_bytes()
extern struct outhead outhead; extern struct outhead outhead;
extern struct outsect outsect[]; extern struct outsect outsect[];
extern char *outputname; extern char *outputname;
int sectionno = 0;
nsect = outhead.oh_nsect; nsect = outhead.oh_nsect;
nrelo = outhead.oh_nrelo;
offchar = OFF_CHAR(outhead); offchar = OFF_CHAR(outhead);
if (bytes_reversed || words_reversed) {
swap((char *)&outhead, SF_HEAD);
sectswap(outsect, nsect);
reloswap(nrelo);
}
/* /*
* We allocated two areas: one for local and one for global names. * We allocated two areas: one for local and one for global names.
* Also, we used another kind of on_foff than on file. * Also, we used another kind of on_foff than on file.
@ -391,66 +380,34 @@ write_bytes()
offchar + NLChars offchar + NLChars
); );
} }
if ((fd = creat(outputname, 0666)) < 0) if (! wr_open(outputname)) {
fatal("can't create %s", outputname); fatal("can't create %s", outputname);
}
/* /*
* These pieces must always be written. * These pieces must always be written.
*/ */
writelong(fd, (char *)&outhead, (ind_t)SZ_HEAD); wr_ohead(&outhead);
writelong(fd, (char *)outsect, (ind_t)nsect * SZ_SECT); wr_sect(outsect, nsect);
for (mem = &mems[ALLOEMIT]; mem < &mems[ALLORELO]; mem++) for (mem = &mems[ALLOEMIT]; mem < &mems[ALLORELO]; mem++)
writelong(fd, mem->mem_base, mem->mem_full); wrt_emit(mem->mem_base, sectionno++, mem->mem_full);
/* /*
* The rest depends on the flags. * The rest depends on the flags.
*/ */
if (flagword & RFLAG) if (flagword & RFLAG)
writelong(fd, mems[ALLORELO].mem_base, mems[ALLORELO].mem_full); wr_relo((struct outrelo *) mems[ALLORELO].mem_base,
outhead.oh_nrelo);
if (!(flagword & SFLAG)) { if (!(flagword & SFLAG)) {
writelong(fd, mems[ALLOLOCL].mem_base, mems[ALLOLOCL].mem_full); wr_name((struct outname *) mems[ALLOLOCL].mem_base,
writelong(fd, mems[ALLOGLOB].mem_base, mems[ALLOGLOB].mem_full); NLocals);
writelong(fd, mems[ALLOLCHR].mem_base + 1, (ind_t)NLChars); wr_name((struct outname *) mems[ALLOGLOB].mem_base,
writelong(fd, mems[ALLOGCHR].mem_base + 1, (ind_t)NGChars); NGlobals+nsect);
wr_string(mems[ALLOLCHR].mem_base + 1, (long)NLChars);
wr_string(mems[ALLOGCHR].mem_base + 1, (long)NGChars);
#ifdef SYMDBUG #ifdef SYMDBUG
writelong(fd, mems[ALLODBUG].mem_base, mems[ALLODBUG].mem_full); wr_dbug(mems[ALLODBUG].mem_base, mems[ALLODBUG].mem_full);
#endif SYMDBUG #endif SYMDBUG
} }
close(fd); wr_close();
}
static
writelong(fd, base, size)
register int fd;
register char *base;
register ind_t size;
{
register int chunk;
while (size) {
chunk = size > (ind_t)MAXCHUNK ? MAXCHUNK : size;
write(fd, base, chunk);
size -= chunk;
base += chunk;
}
}
static
sectswap(sect, nsect)
register struct outsect *sect;
register ushort nsect;
{
while (nsect--)
swap((char *)sect++, SF_SECT);
}
static
reloswap(nrelo)
register ushort nrelo;
{
register struct outrelo *relo;
relo = (struct outrelo *)mems[ALLORELO].mem_base;
while (nrelo--)
swap((char *)relo++, SF_RELO);
} }
static static
@ -462,8 +419,6 @@ namecpy(name, nname, offchar)
while (nname--) { while (nname--) {
if (name->on_foff) if (name->on_foff)
name->on_foff += offchar - 1; name->on_foff += offchar - 1;
if (bytes_reversed || words_reversed)
swap((char *)name, SF_NAME);
name++; name++;
} }
} }

View file

@ -1,6 +1,5 @@
/* $Header$ */ /* $Header$ */
struct orig { struct orig {
long org_flen; /* Accumulated length of preceding sections. */ long org_size; /* Accumulated length of preceding sections. */
long org_zero; /* " " " zeroparts. */
}; };

View file

@ -2,7 +2,7 @@
static char rcsid[] = "$Header$"; static char rcsid[] = "$Header$";
#endif #endif
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
#include "memory.h" #include "memory.h"

View file

@ -2,157 +2,9 @@
static char rcsid[] = "$Header$"; static char rcsid[] = "$Header$";
#endif #endif
/*
* Routines to read in the various parts of the object file.
*/
#include "../../h/arch.h"
#include "../../h/out.h"
#include "../../h/ranlib.h"
#include "const.h"
#include "assert.h"
int infile; /* The current input file. */ int infile; /* The current input file. */
extern bool bytes_reversed; rd_fatal()
extern bool words_reversed;
ushort
getushort()
{ {
ushort ubuf; fatal("read error");
if (read(infile, (char *)&ubuf, 2) != 2)
fatal("premature EOF");
if (bytes_reversed)
swap((char *)&ubuf, "2");
return ubuf;
}
long
getlong()
{
long lbuf;
if (read(infile, (char *)&lbuf, 4) != 4)
fatal("premature EOF");
if (bytes_reversed || words_reversed)
swap((char *)&lbuf, "4");
return lbuf;
}
read_head(head)
register struct outhead *head;
{
if (read(infile, (char *)head, SZ_HEAD) != SZ_HEAD)
fatal("premature EOF");
if (bytes_reversed || words_reversed)
swap((char *)head, SF_HEAD);
if (BADMAGIC(*head))
fatal("bad magic number");
}
read1(fd, val)
char *val ; {
if ( read(fd, val, 1)!=1 ) return 0 ;
return 1 ;
}
read2(fd, val)
int *val ; {
char rch[2] ;
if ( read(fd, rch, 2)!=2 ) return 0 ;
*val= (rch[0]&0377) + ((rch[1]&0377)<<8) ;
return 1 ;
}
read4(fd, val)
long *val ; {
int v1,v2 ;
if ( !read2(fd, &v1) ) return 0 ;
if ( !read2(fd, &v2) ) return 0 ;
*val = ((long)v1<<16) + (unsigned)v2 ;
return 1 ;
}
read_arhdr(arhdr)
register struct ar_hdr *arhdr;
{
if ( read(infile,arhdr->ar_name,sizeof arhdr->ar_name)!=
sizeof arhdr->ar_name) {
goto peof ;
}
if ( !read4(infile,&arhdr->ar_date) ) goto peof ;
if ( !read1(infile,&arhdr->ar_uid) ) goto peof ;
if ( !read1(infile,&arhdr->ar_gid) ) goto peof ;
if ( !read2(infile,&arhdr->ar_mode) ) goto peof ;
if ( !read4(infile,&arhdr->ar_size) ) goto peof ;
return ;
peof:
fatal("Prematute EOF") ;
}
read_table(ran, cnt)
register struct ranlib *ran;
register long cnt;
{
read_char((char *)ran, cnt * SZ_RAN);
if (bytes_reversed || words_reversed)
while (cnt--)
swap((char *)ran++, SF_RAN);
}
read_sect(sect, cnt)
register struct outsect *sect;
register ushort cnt;
{
if (read(infile, (char *)sect, cnt * SZ_SECT) != cnt * SZ_SECT)
fatal("premature EOF");
if (bytes_reversed || words_reversed)
while (cnt--)
swap((char *)sect++, SF_SECT);
}
read_emit(emit, cnt)
register char *emit;
register long cnt;
{
read_char(emit, cnt);
}
read_relo(relo, cnt)
register struct outrelo *relo;
register ushort cnt;
{
read_char((char *)relo, (long)cnt * SZ_RELO);
if (bytes_reversed || words_reversed)
while (cnt--)
swap((char *)relo++, SF_RELO);
}
read_name(name, cnt)
register struct outname *name;
register ushort cnt;
{
read_char((char *)name, (long)cnt * SZ_NAME);
if (bytes_reversed || words_reversed)
while (cnt--)
swap((char *)name++, SF_NAME);
}
/*
* We don't have to worry about byte order here.
*/
read_char(string, cnt)
register char *string;
register long cnt;
{
register int n;
while (cnt) {
n = cnt >= MAXCHUNK ? MAXCHUNK : cnt;
if (read(infile, string, n) != n)
fatal("premature EOF");
string += n;
cnt -= n;
}
} }

View file

@ -2,7 +2,7 @@
static char rcsid[] = "$Header$"; static char rcsid[] = "$Header$";
#endif #endif
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
#include "debug.h" #include "debug.h"
#include "defs.h" #include "defs.h"
@ -98,39 +98,6 @@ putvalu(valu, addr, type)
} }
} }
/*
* Returns whether `valu' refers to the zero part of its section.
* The address of its zero part (relative to the beginning of the section)
* is in `zero_addr'. If `valu' is used in a pc-relative address computation,
* we have to do that computation ourselves. A pc-relative address is the
* difference between the address of the byte after the value and the "real"
* address:
* referencing address + its size + pc-relative address == "real" address.
*/
static bool
refers_zero(valu, relo, zero_addr)
register long valu;
struct outrelo *relo;
long zero_addr;
{
if (relo->or_type & RELPC) {
valu += relo->or_addr;
/*
* Below is a dirty switch-statement. But an even dirtier
* statement would be: valu += (relo->or_type & RELSZ),
* because in that case you would have to know the values
* of the RELO[124] symbols.
*/
switch (relo->or_type & RELSZ) {
case RELO4: valu += 1;
valu += 1;
case RELO2: valu += 1;
case RELO1: valu += 1;
}
}
return valu >= zero_addr;
}
extern ushort NLocals, NGlobals; extern ushort NLocals, NGlobals;
extern struct outsect outsect[]; extern struct outsect outsect[];
extern struct orig relorig[]; extern struct orig relorig[];
@ -148,10 +115,9 @@ extern struct orig relorig[];
* in position of the section of local. * in position of the section of local.
*/ */
static ushort static ushort
addrelo(relo, names, sects, valu_out) addrelo(relo, names, valu_out)
struct outrelo *relo; struct outrelo *relo;
struct outname *names; struct outname *names;
struct outsect *sects;
long *valu_out; /* Out variable. */ long *valu_out; /* Out variable. */
{ {
register struct outname *local = &names[relo->or_nami]; register struct outname *local = &names[relo->or_nami];
@ -161,13 +127,7 @@ addrelo(relo, names, sects, valu_out)
if ((local->on_type & S_SCT)) { if ((local->on_type & S_SCT)) {
register int sectindex = (local->on_type & S_TYP) - S_MIN; register int sectindex = (local->on_type & S_TYP) - S_MIN;
if (refers_zero(valu, relo, sects[sectindex].os_flen)) { valu += relorig[sectindex].org_size;
valu -= sects[sectindex].os_flen;
valu += outsect[sectindex].os_flen;
valu += relorig[sectindex].org_zero;
} else {
valu += relorig[sectindex].org_flen;
}
valu += outsect[sectindex].os_base; valu += outsect[sectindex].os_base;
index += NGlobals + sectindex; index += NGlobals + sectindex;
} else { } else {
@ -196,12 +156,11 @@ addrelo(relo, names, sects, valu_out)
* which the header is pointed to by `head'. Relocation is relative to the * which the header is pointed to by `head'. Relocation is relative to the
* names in `names'; `relo' tells how to relocate. * names in `names'; `relo' tells how to relocate.
*/ */
relocate(head, emit, names, relo, sects) relocate(head, emit, names, relo)
struct outhead *head; struct outhead *head;
char *emit; char *emit;
struct outname names[]; struct outname names[];
struct outrelo *relo; struct outrelo *relo;
struct outsect *sects;
{ {
long valu; long valu;
int sectindex = relo->or_sect - S_MIN; int sectindex = relo->or_sect - S_MIN;
@ -220,7 +179,7 @@ relocate(head, emit, names, relo, sects)
*/ */
if (relo->or_nami < head->oh_nname) { if (relo->or_nami < head->oh_nname) {
/* First two cases. */ /* First two cases. */
relo->or_nami = addrelo(relo, names, sects, &valu); relo->or_nami = addrelo(relo, names, &valu);
} else { } else {
/* /*
* Third case: it is absolute. The relocation of absolute * Third case: it is absolute. The relocation of absolute
@ -234,11 +193,9 @@ relocate(head, emit, names, relo, sects)
* the change in distance between the referencING and referencED * the change in distance between the referencING and referencED
* section. We already added the origin of the referencED section; * section. We already added the origin of the referencED section;
* now we subtract the origin of the referencING section. * now we subtract the origin of the referencING section.
* Note that the the value to be relocated cannot lie within the
* zero part.
*/ */
if (relo->or_type & RELPC) if (relo->or_type & RELPC)
valu -= relorig[sectindex].org_flen+outsect[sectindex].os_base; valu -= relorig[sectindex].org_size+outsect[sectindex].os_base;
/* /*
* Now put the value back. * Now put the value back.
@ -250,5 +207,5 @@ relocate(head, emit, names, relo, sects)
* relocated to its offset in the new section. `Or_addr' must again be * relocated to its offset in the new section. `Or_addr' must again be
* in the normal part, of course. * in the normal part, of course.
*/ */
relo->or_addr += relorig[sectindex].org_flen; relo->or_addr += relorig[sectindex].org_size;
} }

View file

@ -6,8 +6,8 @@ static char rcsid[] = "$Header$";
* If everything is kept in core, we must save some things for the second pass. * If everything is kept in core, we must save some things for the second pass.
*/ */
#include "../../h/arch.h" #include <arch.h>
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
#include "assert.h" #include "assert.h"
#include "memory.h" #include "memory.h"

View file

@ -6,13 +6,14 @@ static char rcsid[] = "$Header$";
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#endif SYMDBUG #endif SYMDBUG
#include "../../h/arch.h" #include <arch.h>
#include "../../h/out.h" #include <out.h>
#include "../../h/ranlib.h" #include <ranlib.h>
#include "const.h" #include "const.h"
#include "assert.h" #include "assert.h"
#include "memory.h" #include "memory.h"
#include "scan.h" #include "scan.h"
#include "debug.h"
#define READ 0 #define READ 0
@ -29,7 +30,6 @@ extern int passnumber;
char *archname; /* Name of archive, if reading from archive. */ char *archname; /* Name of archive, if reading from archive. */
char *modulname; /* Name of object module. */ char *modulname; /* Name of object module. */
long position; /* Byte offset within cuurent input file. */
#ifdef SYMDBUG #ifdef SYMDBUG
long objectsize; long objectsize;
#endif SYMDBUG #endif SYMDBUG
@ -65,7 +65,6 @@ getfile(filename)
struct stat statbuf; struct stat statbuf;
extern int fstat(); extern int fstat();
#endif SYMDBUG #endif SYMDBUG
extern ushort getushort();
archname = (char *)0; archname = (char *)0;
modulname = (char *)0; modulname = (char *)0;
@ -73,7 +72,7 @@ getfile(filename)
if (passnumber == FIRST || !incore) { if (passnumber == FIRST || !incore) {
if ((infile = open(filename, READ)) < 0) if ((infile = open(filename, READ)) < 0)
fatal("can't read %s", filename); fatal("can't read %s", filename);
magic_number = getushort(); magic_number = rd_unsigned2(infile);
} else { } else {
modulbase = modulptr((ind_t)0); modulbase = modulptr((ind_t)0);
magic_number = *(ushort *)modulbase; magic_number = *(ushort *)modulbase;
@ -88,7 +87,6 @@ getfile(filename)
objectsize = statbuf.st_size; objectsize = statbuf.st_size;
} }
#endif SYMDBUG #endif SYMDBUG
position = (long)0;
seek((long)0); seek((long)0);
modulname = filename; modulname = filename;
return PLAIN; return PLAIN;
@ -97,7 +95,7 @@ getfile(filename)
case AALMAG: case AALMAG:
archname = filename; archname = filename;
if (passnumber == FIRST) { if (passnumber == FIRST) {
read_arhdr(&archive_header); rd_arhdr(infile, &archive_header);
if (strcmp(archive_header.ar_name, SYMDEF)) if (strcmp(archive_header.ar_name, SYMDEF))
fatal("no table of contents"); fatal("no table of contents");
} else if (incore) { } else if (incore) {
@ -123,7 +121,7 @@ get_archive_header(archive_header)
register struct ar_hdr *archive_header; register struct ar_hdr *archive_header;
{ {
if (passnumber == FIRST || !incore) { if (passnumber == FIRST || !incore) {
read_arhdr(archive_header); rd_arhdr(infile, archive_header);
} else { } else {
/* Copy structs. */ /* Copy structs. */
*archive_header = *(struct ar_hdr *)modulbase; *archive_header = *(struct ar_hdr *)modulbase;
@ -138,8 +136,10 @@ get_archive_header(archive_header)
get_modul() get_modul()
{ {
if (passnumber == FIRST) { if (passnumber == FIRST) {
rd_fdopen(infile);
scan_modul(); scan_modul();
} else if (!incore) { } else if (!incore) {
rd_fdopen(infile);
read_modul(); read_modul();
} }
} }
@ -161,11 +161,9 @@ scan_modul()
if (space) { if (space) {
sect = (struct outsect *)modulptr(IND_SECT(*head)); sect = (struct outsect *)modulptr(IND_SECT(*head));
get_indirect(head, sect); get_indirect(head, sect);
} else {
lseek(infile, OFF_NAME(*head) - OFF_EMIT(*head), 1);
} }
read_name((struct outname *)modulptr(IND_NAME(*head)), head->oh_nname); rd_name((struct outname *)modulptr(IND_NAME(*head)), head->oh_nname);
read_char((char *)modulptr(IND_CHAR(*head)), head->oh_nchar); rd_string((char *)modulptr(IND_CHAR(*head)), head->oh_nchar);
#ifdef SYMDBUG #ifdef SYMDBUG
if (space) { if (space) {
get_dbug(*(ind_t *)modulptr(IND_DBUG(*head)), get_dbug(*(ind_t *)modulptr(IND_DBUG(*head)),
@ -191,7 +189,7 @@ all_alloc()
if (hard_alloc(ALLOMODL, (long)sizeof(struct outhead)) == BADOFF) if (hard_alloc(ALLOMODL, (long)sizeof(struct outhead)) == BADOFF)
fatal("no space for module header"); fatal("no space for module header");
read_head((struct outhead *)modulptr(IND_HEAD)); rd_ohead((struct outhead *)modulptr(IND_HEAD));
/* /*
* Copy the header because we need it so often. * Copy the header because we need it so often.
*/ */
@ -226,7 +224,7 @@ direct_alloc(head)
size = modulsize(head) - sizeof(struct outhead) - rest; size = modulsize(head) - sizeof(struct outhead) - rest;
if (hard_alloc(ALLOMODL, size) == BADOFF) if (hard_alloc(ALLOMODL, size) == BADOFF)
fatal("no space for module"); fatal("no space for module");
read_sect((struct outsect *)modulptr(sectindex), nsect); rd_sect((struct outsect *)modulptr(sectindex), nsect);
return incore && alloc(ALLOMODL, rest) != BADOFF; return incore && alloc(ALLOMODL, rest) != BADOFF;
} }
@ -281,8 +279,28 @@ putemitindex(sectindex, emitoff, allopiece)
long flen; long flen;
ind_t emitindex; ind_t emitindex;
extern ind_t alloc(); extern ind_t alloc();
static long zeros[MAXSECT];
register long zero = zeros[allopiece - ALLOEMIT];
/*
* Notice that "sectindex" is not a section number!
* It contains the offset of the section from the beginning
* of the module. Thus, it cannot be used to index "zeros".
* AIAIAIAIA
*/
flen = ((struct outsect *)modulptr(sectindex))->os_flen; flen = ((struct outsect *)modulptr(sectindex))->os_flen;
if (flen && zero) {
if ((emitindex = alloc(allopiece, zero)) != BADOFF){
register char *p = address(allopiece, emitindex);
debug("Zeros %ld\n", zero, 0,0,0);
while (zero--) *p++ = 0;
}
else return FALSE;
}
zeros[allopiece - ALLOEMIT] =
((struct outsect *) modulptr(sectindex))->os_size - flen;
if ((emitindex = alloc(allopiece, flen)) != BADOFF) { if ((emitindex = alloc(allopiece, flen)) != BADOFF) {
*(ind_t *)modulptr(emitoff) = emitindex; *(ind_t *)modulptr(emitoff) = emitindex;
return TRUE; return TRUE;
@ -343,13 +361,14 @@ get_indirect(head, sect)
ind_t *reloindex; ind_t *reloindex;
emitindex = (ind_t *)modulptr(IND_EMIT(*head)); emitindex = (ind_t *)modulptr(IND_EMIT(*head));
nsect = head->oh_nsect; piece = ALLOEMIT; piece = ALLOEMIT;
while (nsect--) { for (nsect = 0; nsect < head->oh_nsect; nsect++) {
read_emit(address(piece, *emitindex), sect->os_flen); rd_outsect(nsect);
rd_emit(address(piece, *emitindex), sect->os_flen);
piece++; emitindex++; sect++; piece++; emitindex++; sect++;
} }
reloindex = (ind_t *)modulptr(IND_RELO(*head)); reloindex = (ind_t *)modulptr(IND_RELO(*head));
read_relo((struct outrelo *)address(ALLORELO, *reloindex), rd_relo((struct outrelo *)address(ALLORELO, *reloindex),
head->oh_nrelo head->oh_nrelo
); );
} }
@ -398,7 +417,6 @@ read_modul()
ushort nsect, nname; ushort nsect, nname;
long size; long size;
long nchar; long nchar;
long skip;
extern ind_t hard_alloc(); extern ind_t hard_alloc();
assert(passnumber == SECOND); assert(passnumber == SECOND);
@ -406,11 +424,10 @@ read_modul()
if (hard_alloc(ALLOMODL, (long)sizeof(struct outhead)) == BADOFF) if (hard_alloc(ALLOMODL, (long)sizeof(struct outhead)) == BADOFF)
fatal("no space for module header"); fatal("no space for module header");
head = (struct outhead *)modulptr(IND_HEAD); head = (struct outhead *)modulptr(IND_HEAD);
read_head(head); rd_ohead(head);
nsect = head->oh_nsect; sectindex = IND_SECT(*head); nsect = head->oh_nsect; sectindex = IND_SECT(*head);
nname = head->oh_nname; nameindex = IND_NAME(*head); nname = head->oh_nname; nameindex = IND_NAME(*head);
nchar = head->oh_nchar; charindex = IND_CHAR(*head); nchar = head->oh_nchar; charindex = IND_CHAR(*head);
skip = OFF_NAME(*head) - OFF_EMIT(*head);
#ifdef SYMDBUG #ifdef SYMDBUG
size = modulsize(head) - (nsect * sizeof(ind_t) + 2 * sizeof(ind_t)); size = modulsize(head) - (nsect * sizeof(ind_t) + 2 * sizeof(ind_t));
#else SYMDBUG #else SYMDBUG
@ -423,10 +440,9 @@ read_modul()
names = (struct outname *)modulptr(nameindex); names = (struct outname *)modulptr(nameindex);
chars = modulptr(charindex); chars = modulptr(charindex);
read_sect(sects, nsect); rd_sect(sects, nsect);
lseek(infile, skip, 1); rd_name(names, nname);
read_name(names, nname); rd_string(chars, nchar);
read_char(chars, nchar);
} }
/* /*
@ -437,8 +453,7 @@ static long
align(size) align(size)
register long size; register long size;
{ {
size += sizeof(double) - 1; return (size + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
return size - (size & (sizeof(double) - 1));
} }
/* /*
@ -488,8 +503,7 @@ startrelo(head)
if (incore) { if (incore) {
reloindex = *(ind_t *)(modulbase + IND_RELO(*head)); reloindex = *(ind_t *)(modulbase + IND_RELO(*head));
walkrelo = (struct outrelo *)address(ALLORELO, reloindex); walkrelo = (struct outrelo *)address(ALLORELO, reloindex);
} else }
lseek(infile, position + OFF_RELO(*head), 0);
} }
struct outrelo * struct outrelo *
@ -500,7 +514,7 @@ nextrelo()
if (incore) if (incore)
return walkrelo++; return walkrelo++;
read_relo(&relobuf, (ushort)1); rd_relo(&relobuf, 1);
return &relobuf; return &relobuf;
} }
@ -524,8 +538,8 @@ getemit(head, sects, sectindex)
ret = core_alloc(ALLOMODL, sects[sectindex].os_flen); ret = core_alloc(ALLOMODL, sects[sectindex].os_flen);
if (ret == (char *)0) if (ret == (char *)0)
fatal("no space for section contents"); fatal("no space for section contents");
lseek(infile, position + sects[sectindex].os_foff, 0); rd_outsect(sectindex);
read_emit(ret, sects[sectindex].os_flen); rd_emit(ret, sects[sectindex].os_flen);
return ret; return ret;
} }
/* /*

View file

@ -6,9 +6,10 @@ static char rcsid[] = "$Header$";
* Symbol table management. * Symbol table management.
*/ */
#include "../../h/out.h" #include <out.h>
#include "const.h" #include "const.h"
#include "memory.h" #include "memory.h"
#include "debug.h"
/* /*
* Symbol table types. Each hash table entry contains the offset of a symbol * Symbol table types. Each hash table entry contains the offset of a symbol
@ -55,17 +56,23 @@ searchname(string, hashval)
register struct symbol *sym; register struct symbol *sym;
symindex = hashtable[hashval]; symindex = hashtable[hashval];
debug("looking for %s %d %ld:", string, hashval, hashtable[hashval], 0);
while (symindex != BADOFF) { while (symindex != BADOFF) {
sym = (struct symbol *)address(ALLOSYMB, symindex); sym = (struct symbol *)address(ALLOSYMB, symindex);
name = (struct outname *)address(ALLOGLOB, sym->sy_name); name = (struct outname *)address(ALLOGLOB, sym->sy_name);
namestring = address(ALLOGCHR, (ind_t)name->on_foff); namestring = address(ALLOGCHR, (ind_t)name->on_foff);
rcp = string; rcp = string;
debug("comp %s;", namestring, 0, 0, 0);
while (*rcp == *namestring++) while (*rcp == *namestring++)
if (*rcp++ == '\0') if (*rcp++ == '\0') {
debug("found %x, %x, %lx\n",
name->on_type, name->on_desc, name->on_valu, 0);
return name; return name;
}
symindex = sym->sy_next; symindex = sym->sy_next;
} }
/* Not found. */ /* Not found. */
debug("not found\n", 0, 0, 0, 0);
return (struct outname *)0; return (struct outname *)0;
} }
@ -82,13 +89,15 @@ entername(name, hashval)
ind_t savindex; ind_t savindex;
ind_t symindex; ind_t symindex;
ind_t namindex; ind_t namindex;
struct symbol *sym; register struct symbol *sym;
struct outname *newname; struct outname *newname;
extern ind_t savechar(); extern ind_t savechar();
extern ind_t hard_alloc(); extern ind_t hard_alloc();
debug("entername %s %d %x %x", modulptr((ind_t)name->on_foff), hashval, name->on_type, name->on_desc);
savindex = savechar(ALLOGCHR, (ind_t)name->on_foff); savindex = savechar(ALLOGCHR, (ind_t)name->on_foff);
symindex = hard_alloc(ALLOSYMB, (long)sizeof(struct symbol)); symindex = hard_alloc(ALLOSYMB, (long)sizeof(struct symbol));
debug("; %ld\n", symindex, 0, 0, 0);
namindex = hard_alloc(ALLOGLOB, (long)sizeof(struct outname)); namindex = hard_alloc(ALLOGLOB, (long)sizeof(struct outname));
if (savindex == BADOFF || symindex == BADOFF || namindex == BADOFF) if (savindex == BADOFF || symindex == BADOFF || namindex == BADOFF)
fatal("symbol table overflow"); fatal("symbol table overflow");

View file

@ -2,105 +2,23 @@
static char rcsid[] = "$Header$"; static char rcsid[] = "$Header$";
#endif #endif
/* #include <out.h>
* 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 <stdio.h> #include <stdio.h>
#include "../../h/out.h"
#include "const.h" #include "const.h"
#include "assert.h" #include "assert.h"
#include "memory.h" #include "memory.h"
#include "orig.h"
static openoutput();
static wrt_head();
static wrt_sect();
extern long lseek();
#define WRITE 1 /* Argument to open(). */
/*
* Parts of the output file.
*/
#define PARTEMIT 0
#define PARTRELO 1
#define PARTNAME 2
#define PARTCHAR 3
#ifdef SYMDBUG
#define PARTDBUG 4
#else SYMDBUG
#define PARTDBUG PARTCHAR
#endif SYMDBUG
#define NPARTS (PARTDBUG + 1)
/*
* Call OUTPART() with the part you want to write on as argument, before
* you call OUTWRITE().
*/
static int outpart = NPARTS;
#ifdef OUTSEEK
static int outfile;
static long outseek[NPARTS];
#define OUTPART(p) \
{ if (outpart != (p)) {\
outpart = (p);\
lseek(outfile, outseek[(p)], 0);\
}\
}
#define OUTSECT(i) \
{ outpart = NPARTS;\
outseek[PARTEMIT] =\
outsect[(i)].os_foff + relorig[(i)].org_flen;\
}
#define OUTWRITE(b, n) \
{ if (write(outfile, (b), (n)) != (n))\
fatal("write error");\
outseek[outpart] += (n);\
}
#define BEGINSEEK(p, o) \
{ outseek[(p)] = (o);\
}
#else OUTSEEK
static int outfile[NPARTS];
#define OUTPART(p) \
{ outpart = (p);\
}
#define OUTSECT(i) \
{ lseek( outfile[PARTEMIT],\
outsect[(i)].os_foff + relorig[(i)].org_flen,\
0\
);\
}
#define OUTWRITE(b, n) \
{ if (write(outfile[outpart], (b), (n)) != (n))\
fatal("write error");\
}
#define BEGINSEEK(p, o) \
{ lseek(outfile[(p)], (o), 0);\
}
#endif OUTSEEK
extern struct outhead outhead; extern struct outhead outhead;
extern struct outsect outsect[]; extern struct outsect outsect[];
extern int flagword; extern int flagword;
extern struct orig relorig[];
extern bool bytes_reversed, words_reversed;
extern bool incore; extern bool incore;
wr_fatal()
{
fatal("write error");
}
static long offchar; static long off_char;
/* /*
* Open the output file according to the chosen strategy. * Open the output file according to the chosen strategy.
@ -108,52 +26,16 @@ static long offchar;
*/ */
begin_write() begin_write()
{ {
register long off;
openoutput();
BEGINSEEK(PARTEMIT, (long)0);
wrt_head(&outhead);
wrt_sect(outsect, outhead.oh_nsect);
off = SZ_HEAD + (long)outhead.oh_nsect * SZ_SECT + outhead.oh_nemit;
if (flagword & RFLAG) {
/* A relocation table will be produced. */
BEGINSEEK(PARTRELO, off);
off += (long)outhead.oh_nrelo * SZ_RELO;
}
if (flagword & SFLAG)
return;
/* A name table will be produced. */
BEGINSEEK(PARTNAME, off);
off += (long)outhead.oh_nname * SZ_NAME;
BEGINSEEK(PARTCHAR, off);
offchar = off; /* See wrt_name(). */
#ifdef SYMDBUG
off += outhead.oh_nchar;
BEGINSEEK(PARTDBUG, off);
#endif SYMDBUG
}
static
openoutput()
{
#ifndef OUTSEEK
register int *fdp;
#endif OUTSEEK
extern char *outputname; extern char *outputname;
register struct outhead *hd = &outhead;
close(creat(outputname, 0666)); assert(! incore);
#ifdef OUTSEEK if (! wr_open(outputname)) {
if ((outfile = open(outputname, WRITE)) < 0) fatal("cannot write %s", outputname);
fatal("can't write %s", outputname); }
#else OUTSEEK wr_ohead(hd);
for (fdp = &outfile[PARTEMIT]; fdp < &outfile[NPARTS]; fdp++) wr_sect(outsect, hd->oh_nsect);
if ((*fdp = open(outputname, WRITE)) < 0) off_char = OFF_CHAR(*hd);
fatal("can't write %s", outputname);
#endif OUTSEEK
} }
static struct outname * static struct outname *
@ -198,103 +80,42 @@ end_write()
wrt_name(sectname(sectindex)); wrt_name(sectname(sectindex));
} }
static
wrt_head(head)
register struct outhead *head;
{
assert(!incore);
OUTPART(PARTEMIT);
if (bytes_reversed || words_reversed)
swap((char *)head, SF_HEAD);
OUTWRITE((char *)head, SZ_HEAD);
/*
* Swap back because we will need it again.
*/
if (bytes_reversed || words_reversed)
swap((char *)head, SF_HEAD);
}
static
wrt_sect(sect, cnt)
register struct outsect *sect;
register ushort cnt;
{
assert(!incore);
OUTPART(PARTEMIT);
while (cnt--) {
if (bytes_reversed || words_reversed)
swap((char *)sect, SF_SECT);
OUTWRITE((char *)sect, SZ_SECT);
/*
* Swap back because we will need it again.
*/
if (bytes_reversed || words_reversed)
swap((char *)sect, SF_SECT);
sect++;
}
}
/*
* We don't have to worry about byte order here.
*/
wrt_emit(emit, sectindex, cnt) wrt_emit(emit, sectindex, cnt)
register char *emit; char *emit;
int sectindex; int sectindex;
long cnt;
{
wr_outsect(sectindex);
wr_emit(emit, cnt);
}
wrt_nulls(sectindex, cnt)
register long cnt; register long cnt;
{ {
register int n; static char nullbuf[BUFSIZ];
assert(!incore); wr_outsect(sectindex);
OUTPART(PARTEMIT);
OUTSECT(sectindex);
while (cnt) { while (cnt) {
n = cnt >= BUFSIZ ? BUFSIZ : cnt; register int n = cnt >= BUFSIZ ? BUFSIZ : cnt;
OUTWRITE(emit, n); wr_emit(nullbuf, (long)n);
emit += n;
cnt -= n; cnt -= n;
} }
} }
wrt_relo(relo)
register struct outrelo *relo;
{
assert(!incore);
assert(flagword & RFLAG);
OUTPART(PARTRELO);
if (bytes_reversed || words_reversed)
swap((char *)relo, SF_RELO);
OUTWRITE((char *)relo, SZ_RELO);
}
wrt_name(name) wrt_name(name)
register struct outname *name; register struct outname *name;
{ {
assert(!incore); assert(!incore);
assert(!(flagword & SFLAG)); assert(!(flagword & SFLAG));
if (name->on_mptr != (char *)0) { if (name->on_mptr != (char *)0) {
register int len = strlen(name->on_mptr) + 1; register long len = strlen(name->on_mptr) + 1;
OUTPART(PARTCHAR); wr_string(name->on_mptr, len);
OUTWRITE(name->on_mptr, len); name->on_foff = off_char;
name->on_foff = offchar; off_char += len;
offchar += len;
} else { } else {
name->on_foff = (long)0; name->on_foff = (long)0;
} }
OUTPART(PARTNAME); wr_name(name, 1);
if (bytes_reversed || words_reversed)
swap((char *)name, SF_NAME);
OUTWRITE((char *)name, SZ_NAME);
} }
#ifdef SYMDBUG
wrt_dbug(buf, size)
char *buf;
int size;
{
assert(!incore);
assert(!(flagword & SFLAG));
OUTPART(PARTDBUG);
OUTWRITE((char *)buf, size);
}
#endif SYMDBUG