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
#
.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.
LIBDIR=../../lib
PREFLAGS= -DNDEBUG -DNASSERT
CFLAGS = -O $(PREFLAGS)
EM = ../..
LIBDIR= $(EM)/lib
PREFLAGS= -I$(EM)/h -DNDEBUG -DNASSERT
CFLAGS = $(PREFLAGS) -O
LDFLAGS =
LINTFLAGS=-phbxac $(PREFLAGS)
LDLIBS = $(EM)/modules/lib/libstr.a $(EM)/modules/lib/libobj.a
LINTFLAGS=-phbxa $(PREFLAGS)
PR = pr
PRFLAGS =
# 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
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
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 byte_order.o error.o extract.o finish.o main.o memory.o\
OFILES = archive.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
# 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)
$(CC) $(LDFLAGS) $(OFILES) $(LDLIBS) -o led
mach.c: mach.c,v
co -q mach.c
install:led
cp led $(LIBDIR)/em_led
@ -49,103 +34,65 @@ cmp: led
cmp led $(LIBDIR)/em_led
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)
rm -f `cat checked.out` checked.out
pr: $(CVFILES) $(HVFILES) mach.c
@-for i in $?; do\
co -q -p $$i | $(PR) $(PRFLAGS) -h `basename $$i ,v`;\
done
pr: $(CFILES) $(HFILES) mach.c
$(PR) $(PRFLAGS) $?
@touch pr
opr:
make pr | opr
clean:
rm *.o led
rm -f Out *.o led nohup.out
depend:
-for i in $(CFILES); do\
if test ! -f $$i; then\
echo $$i >> checked.out;\
co -q $$i;\
fi;\
done
makedepend $(CFILES)
rm -f `cat checked.out` checked.out
# The next lines are generated automatically.
# AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
archive.o: ../../h/arch.h
archive.o: ../../h/out.h
archive.o: ../../h/ranlib.h
archive.o: const.h
archive.o: debug.h
archive.o: defs.h
archive.o: memory.h
byte_order.o: assert.h
byte_order.o: const.h
error.o: ../../h/out.h
error.o: const.h
extract.o: ../../h/out.h
extract.o: const.h
extract.o: debug.h
extract.o: defs.h
extract.o: memory.h
extract.o: orig.h
extract.o: scan.h
finish.o: ../../h/out.h
finish.o: const.h
finish.o: defs.h
finish.o: memory.h
finish.o: orig.h
finish.o: scan.h
main.o: ../../h/out.h
main.o: const.h
main.o: debug.h
main.o: defs.h
main.o: memory.h
main.o: orig.h
memory.o: ../../h/out.h
memory.o: assert.h
memory.o: const.h
memory.o: debug.h
memory.o: mach.c
memory.o: memory.h
output.o: ../../h/out.h
output.o: const.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: const.h
relocate.o: ../../h/out.h
relocate.o: const.h
relocate.o: debug.h
relocate.o: defs.h
relocate.o: orig.h
save.o: ../../h/arch.h
save.o: ../../h/out.h
save.o: assert.h
save.o: const.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: const.h
scan.o: memory.h
scan.o: scan.h
sym.o: ../../h/out.h
sym.o: const.h
sym.o: memory.h
write.o: ../../h/out.h
write.o: assert.h
write.o: const.h
write.o: memory.h

View file

@ -1,56 +1,12 @@
This file contains a summary of the bugs/features/inconsistencies
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:
1 - Local commons are not handled by led and not produced by as.
using .comm for unitialized data is not correct because (from C)
two uninitialized static declarations for the same name in
different modules will be handled as external commons and thus
be overlayed.
Must, and will be handled by as.
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
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.
The major troublemaker seems to be the extra padding byte at the end
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$";
#endif
#include "../../h/arch.h"
#include "../../h/out.h"
#include "../../h/ranlib.h"
#include <arch.h>
#include <out.h>
#include <ranlib.h>
#include "const.h"
#include "debug.h"
#include "defs.h"
@ -30,20 +30,21 @@ getsymdeftable()
register struct ranlib *ran;
register long count;
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);
off = hard_alloc(ALLORANL, nran * sizeof(struct ranlib));
if (off == BADOFF)
fatal("no space for ranlib structs");
ran = (struct ranlib *)address(ALLORANL, off);
read_table(ran, count);
nchar = getlong();
rd_ranlib(infile, ran, count);
nchar = rd_long(infile);
debug("%ld ranlib chars\n", nchar, 0, 0, 0);
if ((off = hard_alloc(ALLORANL, nchar)) == BADOFF)
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);
while (count--) {
/*
@ -60,7 +61,6 @@ getsymdeftable()
}
extern char *modulname;
extern long position;
/*
* Process archive with table of contents. The table of contents tells
@ -107,7 +107,6 @@ arch()
get_archive_header(&arhdr);
modulname = arhdr.ar_name;
debug("%s defines %s\n", modulname, string, 0, 0);
position = ran->ran_pos + AR_SIZE;
resolved = TRUE;
/*
* This archive member is going to be linked,
@ -170,7 +169,6 @@ arch2()
get_archive_header(&arhdr);
modulname = arhdr.ar_name;
debug("%s: archive member\n", modulname, 0, 0, 0);
position = *pos + AR_SIZE;
finish();
}
localpos += sizeof(long); /* Skip ENDLIB. */

View file

@ -5,18 +5,12 @@ typedef int bool;
#define FALSE 0
#define TRUE 1
#define S_ZER 0x2000 /* Internal use only. */
#define WIDTH 8 /* Number of bits in a 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 SFLAG 0x02 /* -s flag given. */
#define MAXSECT 64 /* Maximum number of sections. */
#define PLAIN 0 /* Input file is a normal file. */
#define ARCHIVE 1 /* Input file is an archive. */

View file

@ -2,10 +2,11 @@
#ifdef NDEBUG
#define debug(s, a1, a2, a3, a4) dummy()
#define debug(s, a1, a2, a3, a4)
#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

View file

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

View file

@ -2,7 +2,7 @@
static char rcsid[] = "$Header$";
#endif
#include "../../h/out.h"
#include <out.h>
#include "const.h"
#include "debug.h"
#include "defs.h"
@ -47,23 +47,20 @@ get_names(head)
register struct outhead *head;
{
register int nnames;
register ind_t sectindex, nameindex, charindex;
register ind_t nameindex, charindex;
register ind_t charoff;
extern int flagword;
nnames = head->oh_nname;
sectindex = IND_SECT(*head);
nameindex = IND_NAME(*head);
charindex = IND_CHAR(*head);
charoff = OFF_CHAR(*head);
while (nnames--) {
register struct outsect *sects;
struct outname name; /* A local copy. */
/*
* Because savelocal/getexternal might relocate the modules
* we have to compute the core addresses again.
*/
sects = (struct outsect *)modulptr(sectindex);
name = *(struct outname *)modulptr(nameindex);
/*
* Change the offset in file into an offset in the memory area.
@ -73,7 +70,7 @@ get_names(head)
*/
if (name.on_foff)
name.on_foff += charindex - charoff;
namerelocate(&name, sects);
namerelocate(&name);
if (name.on_type & S_EXT) {
getexternal(&name);
} else {
@ -111,14 +108,19 @@ process(head)
nsect = head->oh_nsect;
outsp = outsect;
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_size += sects->os_size;
/*
* Add all flen's and all (size - flen == zero)'s of
* preceding sections with the same number.
*/
orig->org_flen += sects->os_flen;
orig->org_zero += sects->os_size - sects->os_flen;
orig->org_size = outsp->os_size;
orig++; outsp++; sects++;
}
}
@ -127,21 +129,13 @@ process(head)
* Add relocation constant for names in user defined sections.
* The value of a common name indicates a size instead of an offset,
* 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
* sections with the same size.
*/
namerelocate(name, sects)
namerelocate(name)
register struct outname *name;
struct outsect *sects;
{
register int type = name->on_type;
register int sectindex;
if ((type & S_TYP) == S_UND || (type & S_TYP) == S_ABS)
return;
@ -150,14 +144,7 @@ namerelocate(name, sects)
return;
}
sectindex = (type & S_TYP) - S_MIN;
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;
}
name->on_valu += relorig[(type & S_TYP) - S_MIN].org_size;
}
/*

View file

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

View file

@ -7,7 +7,7 @@ static char rcsid[] = "$Header$";
*/
#include <stdio.h>
#include "../../h/out.h"
#include <out.h>
#include "const.h"
#include "debug.h"
#include "defs.h"
@ -15,6 +15,9 @@ static char rcsid[] = "$Header$";
#include "orig.h"
extern bool incore;
#ifndef NDEBUG
int DEB = 0;
#endif
static initializations();
static first_pass();
@ -65,7 +68,6 @@ initializations(argc, argv)
progname = argv[0];
passnumber = FIRST;
determine_ordering();
init_core();
init_symboltable();
outhead.oh_magic = O_MAGIC;
@ -76,6 +78,7 @@ initializations(argc, argv)
int flagword = 0; /* To store command-line options. */
char *outputname = "a.out"; /* Name of the resulting object file. */
int exitstatus = 0;
/*
* Scan the arguments.
@ -90,7 +93,7 @@ first_pass(argv)
int sectno;
int h;
extern int atoi();
extern char *index();
extern char *strindex();
extern int hash();
extern struct outname *searchname();
@ -111,7 +114,7 @@ first_pass(argv)
* section <section number>.
*/
sectno = atoi(++argp);
if ((argp = index(argp, ':')) == (char *)0)
if ((argp = strindex(argp, ':')) == (char *)0)
fatal("usage: -a<section number>:<alignment>");
setlign(sectno, number(++argp));
break;
@ -124,10 +127,15 @@ first_pass(argv)
* <section number>.
*/
sectno = atoi(++argp);
if ((argp = index(argp, ':')) == (char *)0)
if ((argp = strindex(argp, ':')) == (char *)0)
fatal("usage: -b<section number>:<base>");
setbase(sectno, number(++argp));
break;
#ifndef NDEBUG
case 'd':
DEB = 1;
break;
#endif
case 'o':
/*
* The `name' argument after -o is used as name
@ -311,7 +319,6 @@ pass1(file)
static
evaluate()
{
if (!(flagword & RFLAG))
norm_commons();
complete_sections();
if (!(flagword & RFLAG))
@ -324,7 +331,7 @@ extern ushort NGlobals, NLocals;
* Sect_comm[N] is the number of common bytes in section N.
* 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
@ -347,10 +354,14 @@ norm_commons()
if (ISUNDEFINED(name)) {
if (!und) {
und = TRUE;
outhead.oh_flags |= HF_LINK;
flagword = (flagword & ~SFLAG) | RFLAG;
if (!(flagword & RFLAG)) {
exitstatus = 1;
fprintf(stderr, "Undefined:\n");
}
outhead.oh_flags |= HF_LINK;
if (flagword & RFLAG) break;
flagword = (flagword & ~SFLAG) | RFLAG;
}
fprintf(stderr, "\t%s\n",
address(ALLOGCHR, (ind_t)name->on_foff)
);
@ -398,8 +409,7 @@ complete_sections()
foff = SZ_HEAD + outhead.oh_nsect * SZ_SECT;
for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) {
relorig[sectindex].org_flen = (long)0;
relorig[sectindex].org_zero = (long)0;
relorig[sectindex].org_size = (long)0;
outsect[sectindex].os_foff = foff;
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
* part, the size of the normal part is also a "base".
* Add the base of the section of a name to its value.
*/
addbase(name)
struct outname *name;
@ -511,10 +520,6 @@ addbase(name)
if (name->on_type & S_COM)
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;
debug( "%s: type 0x%x, value %ld\n",
address((name->on_type & S_EXT) ? ALLOGCHR : ALLOLCHR,
@ -564,9 +569,3 @@ pass2(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.
*/
#include "../../h/out.h"
#include <out.h>
#include "const.h"
#include "assert.h"
#include "debug.h"
@ -19,8 +19,6 @@ static copy_down();
static copy_up();
static free_saved_moduls();
static writelong();
static sectswap();
static reloswap();
static namecpy();
struct memory mems[NMEMS];
@ -201,11 +199,11 @@ copy_up(mem, dist)
*/
ind_t
alloc(piece, size)
register int piece;
int piece;
register long size;
{
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;
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,
* we must order the bytes in the ushorts and longs as ACK prescribes.
*/
write_bytes()
{
ushort nsect, nrelo;
ushort nsect;
long offchar;
int fd;
register struct memory *mem;
extern ushort NLocals, NGlobals;
extern long NLChars, NGChars;
@ -366,16 +360,11 @@ write_bytes()
extern struct outhead outhead;
extern struct outsect outsect[];
extern char *outputname;
int sectionno = 0;
nsect = outhead.oh_nsect;
nrelo = outhead.oh_nrelo;
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.
* Also, we used another kind of on_foff than on file.
@ -391,66 +380,34 @@ write_bytes()
offchar + NLChars
);
}
if ((fd = creat(outputname, 0666)) < 0)
if (! wr_open(outputname)) {
fatal("can't create %s", outputname);
}
/*
* These pieces must always be written.
*/
writelong(fd, (char *)&outhead, (ind_t)SZ_HEAD);
writelong(fd, (char *)outsect, (ind_t)nsect * SZ_SECT);
wr_ohead(&outhead);
wr_sect(outsect, nsect);
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.
*/
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)) {
writelong(fd, mems[ALLOLOCL].mem_base, mems[ALLOLOCL].mem_full);
writelong(fd, mems[ALLOGLOB].mem_base, mems[ALLOGLOB].mem_full);
writelong(fd, mems[ALLOLCHR].mem_base + 1, (ind_t)NLChars);
writelong(fd, mems[ALLOGCHR].mem_base + 1, (ind_t)NGChars);
wr_name((struct outname *) mems[ALLOLOCL].mem_base,
NLocals);
wr_name((struct outname *) mems[ALLOGLOB].mem_base,
NGlobals+nsect);
wr_string(mems[ALLOLCHR].mem_base + 1, (long)NLChars);
wr_string(mems[ALLOGCHR].mem_base + 1, (long)NGChars);
#ifdef SYMDBUG
writelong(fd, mems[ALLODBUG].mem_base, mems[ALLODBUG].mem_full);
wr_dbug(mems[ALLODBUG].mem_base, mems[ALLODBUG].mem_full);
#endif SYMDBUG
}
close(fd);
}
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);
wr_close();
}
static
@ -462,8 +419,6 @@ namecpy(name, nname, offchar)
while (nname--) {
if (name->on_foff)
name->on_foff += offchar - 1;
if (bytes_reversed || words_reversed)
swap((char *)name, SF_NAME);
name++;
}
}

View file

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

View file

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

View file

@ -2,157 +2,9 @@
static char rcsid[] = "$Header$";
#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. */
extern bool bytes_reversed;
extern bool words_reversed;
ushort
getushort()
rd_fatal()
{
ushort ubuf;
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;
}
fatal("read error");
}

View file

@ -2,7 +2,7 @@
static char rcsid[] = "$Header$";
#endif
#include "../../h/out.h"
#include <out.h>
#include "const.h"
#include "debug.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 struct outsect outsect[];
extern struct orig relorig[];
@ -148,10 +115,9 @@ extern struct orig relorig[];
* in position of the section of local.
*/
static ushort
addrelo(relo, names, sects, valu_out)
addrelo(relo, names, valu_out)
struct outrelo *relo;
struct outname *names;
struct outsect *sects;
long *valu_out; /* Out variable. */
{
register struct outname *local = &names[relo->or_nami];
@ -161,13 +127,7 @@ addrelo(relo, names, sects, valu_out)
if ((local->on_type & S_SCT)) {
register int sectindex = (local->on_type & S_TYP) - S_MIN;
if (refers_zero(valu, relo, sects[sectindex].os_flen)) {
valu -= sects[sectindex].os_flen;
valu += outsect[sectindex].os_flen;
valu += relorig[sectindex].org_zero;
} else {
valu += relorig[sectindex].org_flen;
}
valu += relorig[sectindex].org_size;
valu += outsect[sectindex].os_base;
index += NGlobals + sectindex;
} else {
@ -196,12 +156,11 @@ addrelo(relo, names, sects, valu_out)
* which the header is pointed to by `head'. Relocation is relative to the
* names in `names'; `relo' tells how to relocate.
*/
relocate(head, emit, names, relo, sects)
relocate(head, emit, names, relo)
struct outhead *head;
char *emit;
struct outname names[];
struct outrelo *relo;
struct outsect *sects;
{
long valu;
int sectindex = relo->or_sect - S_MIN;
@ -220,7 +179,7 @@ relocate(head, emit, names, relo, sects)
*/
if (relo->or_nami < head->oh_nname) {
/* First two cases. */
relo->or_nami = addrelo(relo, names, sects, &valu);
relo->or_nami = addrelo(relo, names, &valu);
} else {
/*
* 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
* section. We already added the origin of the referencED 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)
valu -= relorig[sectindex].org_flen+outsect[sectindex].os_base;
valu -= relorig[sectindex].org_size+outsect[sectindex].os_base;
/*
* 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
* 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.
*/
#include "../../h/arch.h"
#include "../../h/out.h"
#include <arch.h>
#include <out.h>
#include "const.h"
#include "assert.h"
#include "memory.h"

View file

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

View file

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

View file

@ -2,105 +2,23 @@
static char rcsid[] = "$Header$";
#endif
/*
* 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 <stdio.h>
#include "../../h/out.h"
#include "const.h"
#include "assert.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 outsect outsect[];
extern int flagword;
extern struct orig relorig[];
extern bool bytes_reversed, words_reversed;
extern bool incore;
wr_fatal()
{
fatal("write error");
}
static long offchar;
static long off_char;
/*
* Open the output file according to the chosen strategy.
@ -108,52 +26,16 @@ static long offchar;
*/
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;
register struct outhead *hd = &outhead;
close(creat(outputname, 0666));
#ifdef OUTSEEK
if ((outfile = open(outputname, WRITE)) < 0)
fatal("can't write %s", outputname);
#else OUTSEEK
for (fdp = &outfile[PARTEMIT]; fdp < &outfile[NPARTS]; fdp++)
if ((*fdp = open(outputname, WRITE)) < 0)
fatal("can't write %s", outputname);
#endif OUTSEEK
assert(! incore);
if (! wr_open(outputname)) {
fatal("cannot write %s", outputname);
}
wr_ohead(hd);
wr_sect(outsect, hd->oh_nsect);
off_char = OFF_CHAR(*hd);
}
static struct outname *
@ -198,103 +80,42 @@ end_write()
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)
register char *emit;
char *emit;
int sectindex;
long cnt;
{
wr_outsect(sectindex);
wr_emit(emit, cnt);
}
wrt_nulls(sectindex, cnt)
register long cnt;
{
register int n;
static char nullbuf[BUFSIZ];
assert(!incore);
OUTPART(PARTEMIT);
OUTSECT(sectindex);
wr_outsect(sectindex);
while (cnt) {
n = cnt >= BUFSIZ ? BUFSIZ : cnt;
OUTWRITE(emit, n);
emit += n;
register int n = cnt >= BUFSIZ ? BUFSIZ : cnt;
wr_emit(nullbuf, (long)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)
register struct outname *name;
{
assert(!incore);
assert(!(flagword & SFLAG));
if (name->on_mptr != (char *)0) {
register int len = strlen(name->on_mptr) + 1;
register long len = strlen(name->on_mptr) + 1;
OUTPART(PARTCHAR);
OUTWRITE(name->on_mptr, len);
name->on_foff = offchar;
offchar += len;
wr_string(name->on_mptr, len);
name->on_foff = off_char;
off_char += len;
} else {
name->on_foff = (long)0;
}
OUTPART(PARTNAME);
if (bytes_reversed || words_reversed)
swap((char *)name, SF_NAME);
OUTWRITE((char *)name, SZ_NAME);
wr_name(name, 1);
}
#ifdef SYMDBUG
wrt_dbug(buf, size)
char *buf;
int size;
{
assert(!incore);
assert(!(flagword & SFLAG));
OUTPART(PARTDBUG);
OUTWRITE((char *)buf, size);
}
#endif SYMDBUG