Version that uses libobject.a

This commit is contained in:
ceriel 1986-12-01 15:41:29 +00:00
parent b44e39cce8
commit e188fe0956
8 changed files with 181 additions and 262 deletions

View file

@ -15,7 +15,6 @@
* DEBUG: for debugging purposes only
* TMPDIR: directory for temporary files
* ASLD: combined assembler/linker
* AOUTSEEK: seek on a.out instead of multiple opens
*/
/* ========== constants (use #undef, #define in mach0.c) ========== */
@ -64,10 +63,6 @@
/* ========== default option setting ========== */
#ifndef NOLD
#define ASLD /* default ON */
#endif
#ifndef ASLD
#ifndef RELOCATION
separate linker only possible if relocation info produced
@ -91,7 +86,7 @@ _include <signal.h>
#endif
#ifdef ASLD
#include "aar.h"
#include "arch.h"
#endif
#include "out.h"
@ -155,6 +150,7 @@ _include <signal.h>
/* miscellaneous */
#define KEYDEFINE 0
#define KEYSECT 12
#define DOTGAIN DOTSCT->s_gain
/* ========== type declarations ========== */
@ -179,6 +175,17 @@ struct item_t {
char *i_name; /* symbol name */
};
struct common_t {
struct common_t *
c_next;
struct item_t *c_it;
#ifndef ASLD
valu_t c_size;
#endif
};
typedef struct common_t common_t;
typedef struct item_t item_t;
struct sect_t {
@ -213,24 +220,17 @@ typedef struct sect_t sect_t;
/*
* extra type bits out of S_ETC, internal use only
#ifndef DUK
* S_COM:
* - symbols declared by .comm
#endif DUK
* S_VAR:
* - type not known at end of PASS_1 (S_VAR|S_UND)
* - value not known at end of PASS_2 (S_VAR|S_ABS)
* S_DOT:
* - dot expression
*/
#ifndef DUK
#define S_COM 0x0100
#endif DUK
#define S_VAR 0x0200
#define S_DOT 0x0400
/* should be tested by preprocessor
* due to error in preprocessor it cannot
* test performed at runtime now
* test performed at compiletime by a switch now
* #if (S_ETC|S_COM|S_VAR|S_DOT) != S_ETC
* incorrect type bits
* #endif
@ -243,10 +243,16 @@ typedef struct sect_t sect_t;
#define PARTCHAR 3
#define PARTS 4
#ifdef AOUTSEEK
#define AOUTPART(p) if(aoutpart!=p){aoutpart=p;fseek(aoutfile,aoutseek[p],0);}
#define AOUTPUTC(c,p) {putc(c,aoutfile);aoutseek[p]++;if(ferror(aoutfile))werror();}
#ifdef BYTES_REVERSED
#ifdef WORDS_REVERSED
#define MACHREL_BWR (RELBR|RELWR)
#else
#define AOUTPART(p) /* empty */
#define AOUTPUTC(c,p) {putc(c,aoutfile[p]);if(ferror(aoutfile[p]))werror();}
#define MACHREL_BWR (RELBR)
#endif
#else
#ifdef WORDS_REVERSED
#define MACHREL_BWR (RELWR)
#else
#define MACHREL_BWR (0)
#endif
#endif

View file

@ -20,6 +20,7 @@ extern short sflag INIT(SYM_DEF);
/* -s option (symbol table info) */
extern char *progname; /* for error messages */
extern char *modulename; /* for error messages */
extern common_t *commons; /* header of commons list */
#ifdef ASLD
extern short archmode; /* scanning archives */
@ -52,14 +53,6 @@ extern char temppath[50];
extern FILE *input;
extern FILE *tempfile;
#ifdef AOUTSEEK
extern FILE *aoutfile;
extern int aoutpart INIT(-1);
extern long aoutseek[PARTS];
#else
extern FILE *aoutfile[PARTS];
#endif
extern char stringbuf[STRINGMAX];
/* contains last string value */
@ -72,6 +65,8 @@ extern sect_t *DOTSCT; /* &sect[DOTTYP-S_MIN] or NULL */
extern addr_t DOTVAL; /* DOTSCT->s_size + DOTSCT->s_base */
extern short DOTTYP; /* S_MIN..S_MAX or S_UND */
extern ushort nname; /* Counts name table index in PASS_3 */
extern item_t *hashtab[H_TOTAL];
extern short hashindex; /* see item_search() */

View file

@ -229,25 +229,7 @@ datalist
{
#ifdef RELOCATION
if (rflag != 0 && PASS_RELO)
#ifdef DUK
#ifdef BYTES_REVERSED
#ifdef WORDS_REVERSED
newrelo($1.typ,
(int)$<y_word>0 | RELBR | RELWR
);
#else WORDS_REVERSED
newrelo($1.typ, (int)$<y_word>0|RELBR);
#endif WORDS_REVERSED
#else BYTES_REVERSED
#ifdef WORDS_REVERSED
newrelo($1.typ, (int)$<y_word>0|RELWR);
#else WORDS_REVERSED
newrelo($1.typ, (int)$<y_word>0);
#endif WORDS_REVERSED
#endif BYTES_REVERSED
#else DUK
newrelo($1.typ, (int)$<y_word>0);
#endif DUK
newrelo($1.typ, (int)$<y_word>0|MACHREL_BWR);
#endif
emitx($1.val, (int)$<y_word>0);
}
@ -255,25 +237,7 @@ datalist
{
#ifdef RELOCATION
if (rflag != 0 && PASS_RELO)
#ifdef DUK
#ifdef BYTES_REVERSED
#ifdef WORDS_REVERSED
newrelo($3.typ,
(int)$<y_word>0 | RELBR | RELWR
);
#else WORDS_REVERSED
newrelo($3.typ, (int)$<y_word>0|RELBR);
#endif WORDS_REVERSED
#else BYTES_REVERSED
#ifdef WORDS_REVERSED
newrelo($3.typ, (int)$<y_word>0|RELWR);
#else WORDS_REVERSED
newrelo($3.typ, (int)$<y_word>0);
#endif WORDS_REVERSED
#endif BYTES_REVERSED
#else DUK
newrelo($3.typ, (int)$<y_word>0);
#endif DUK
newrelo($3.typ, (int)$<y_word>0|MACHREL_BWR);
#endif
emitx($3.val, (int)$<y_word>0);
}

View file

@ -9,16 +9,10 @@
#include "comm1.h"
#undef extern
struct outhead outhead = {
O_MAGIC, O_STAMP, 0
#ifndef DUK
#ifdef BYTES_REVERSED
| HF_BREV
#endif
#ifdef WORDS_REVERSED
| HF_WREV
#endif
#endif DUK
};
#include "y.tab.h"

View file

@ -34,11 +34,14 @@ char **argv;
SIGHUP, SIGINT, SIGQUIT, SIGTERM, 0
};
/* this test should be performed by the
* preprocessor, but it cannot
/* the next test should be performed by the
* preprocessor, but it cannot, so it is performed by the compiler.
*/
if ((S_ETC|S_COM|S_VAR|S_DOT) != S_ETC)
fatal("incorrect type bits");
switch(0) {
case 1: break;
case (S_ETC|S_COM|S_VAR|S_DOT) != S_ETC : break;
}
progname = *argv++; argc--;
for (p = sigs; i = *p++; )
@ -106,6 +109,7 @@ char **argv;
pass_23(PASS_2);
#endif
pass_23(PASS_3);
wr_close();
stop();
}
@ -114,11 +118,10 @@ char **argv;
pass_1(argc, argv)
char **argv;
{
register i;
register char *p;
register item_t *ip;
#ifdef ASLD
char armagic[SZMAGIC];
char armagic[2];
#else
register nfile = 0;
#endif
@ -136,24 +139,25 @@ char **argv;
p = *argv++;
if (p == 0)
continue;
#ifdef ASLD
#ifndef ASLD
if (nfile != 0)
fatal("second source file %s", p);
nfile++;
#endif
if (p[0] == '-' && p[1] == '\0') {
input = stdin;
parse("STDIN");
continue;
}
#else
if (nfile != 0)
fatal("second source file %s", p);
nfile++;
#endif
if ((input = fopen(p, "r")) == NULL)
fatal("can't open %s", p);
#ifdef ASLD
if (
fread(armagic, SZMAGIC, 1, input) == 1
fread(armagic, 2, 1, input) == 1
&&
strncmp(armagic, ARMAGIC, SZMAGIC) == 0
((armagic[0]&0377) |
((unsigned)(armagic[1]&0377)<<8)) == ARMAG
) {
archive();
fclose(input);
@ -168,6 +172,8 @@ char **argv;
machfinish(PASS_1);
#ifdef ASLD
if (unresolved) {
register int i;
nerrors++;
fflush(stdout);
fprintf(stderr, "unresolved references:\n");
@ -189,40 +195,35 @@ char **argv;
}
#ifdef ASLD
archive()
{
archive() {
register long offset;
register i;
register long modsize;
char modhead[SZMHEAD];
struct ar_hdr header;
char getsize[AR_TOTAL];
archmode++;
offset = SZMAGIC;
offset = 2;
for (;;) {
if (unresolved == 0)
break;
fseek(input, offset, 0);
if (fread(modhead, SZMHEAD, 1, input) != 1)
fseek(input,offset,0);
if (fread(getsize,AR_TOTAL,1,input) != 1)
break;
if (
strncmp(&modhead[OFF_BEG], STR_BEG, LEN_BEG)
||
strncmp(&modhead[OFF_END], STR_END, LEN_END)
)
fatal("bad archive");
offset += SZMHEAD;
modsize = atol(&modhead[OFF_SIZ]);
archsize = modsize;
offset += AR_TOTAL;
strncpy(header.ar_name,getsize,sizeof header.ar_name) ;
header.ar_size= (((((long) (getsize[AR_SIZE+1]&0377))<<8)+
((long) (getsize[AR_SIZE ]&0377))<<8)+
((long) (getsize[AR_SIZE+3]&0377))<<8)+
((long) (getsize[AR_SIZE+2]&0377)) ;
archsize = header.ar_size;
if (needed()) {
fseek(input, offset, 0);
archsize = modsize;
for (i = 0; i < LEN_NAM; i++)
if (modhead[OFF_NAM+i] == ' ')
break;
modhead[OFF_NAM+i] = '\0';
parse(remember(&modhead[OFF_NAM]));
fseek(input,offset,0);
archsize = header.ar_size;
header.ar_name[14] = '\0';
parse(remember(header.ar_name));
}
offset += modsize;
offset += header.ar_size;
while (offset % 2)
offset++;
}
archmode = 0;
}
@ -257,6 +258,12 @@ needed()
continue;
}
if (first) {
if (ip == &keytab[KEYSECT]) {
while ((c = nextchar()) != '\n')
;
continue;
}
if (ip != &keytab[KEYDEFINE])
break;
first = 0;
@ -417,24 +424,12 @@ setupoutput()
register sect_t *sp;
register long off;
struct outsect outsect;
register struct outsect *pos = &outsect;
#ifdef AOUTSEEK
#define AOUTseek(p,o) {aoutseek[p]=o;}
aoutfile = ffcreat(aoutpath);
#else
#define AOUTseek(p,o) {fseek(aoutfile[p],o,0);}
aoutfile[PARTEMIT]=ffcreat(aoutpath);
#ifdef RELOCATION
aoutfile[PARTRELO]=ffcreat(aoutpath);
#endif
aoutfile[PARTNAME]=ffcreat(aoutpath);
aoutfile[PARTCHAR]=ffcreat(aoutpath);
#endif
/*
* header generation
*/
AOUTseek(PARTEMIT, 0);
putofmt((char *)&outhead, SF_HEAD, PARTEMIT);
if (! wr_open(aoutpath)) {
fatal("can't create %s", aoutpath);
}
wr_ohead(&outhead);
/*
* section table generation
*/
@ -442,52 +437,56 @@ setupoutput()
off += (long)outhead.oh_nsect * SZ_SECT;
for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
sp->s_foff = off;
outsect.os_base = SETBASE(sp);
outsect.os_size = sp->s_size + sp->s_comm;
outsect.os_foff = sp->s_foff;
outsect.os_flen = sp->s_size - sp->s_zero;
outsect.os_lign = sp->s_lign;
off += outsect.os_flen;
putofmt((char *)&outsect, SF_SECT, PARTEMIT);
pos->os_base = SETBASE(sp);
pos->os_size = sp->s_size + sp->s_comm;
pos->os_foff = sp->s_foff;
pos->os_flen = sp->s_size - sp->s_zero;
pos->os_lign = sp->s_lign;
off += pos->os_flen;
wr_sect(pos, 1);
}
#ifdef RELOCATION
AOUTseek(PARTRELO, off);
off += (long)outhead.oh_nrelo * SZ_RELO;
#endif
if (sflag == 0)
return;
AOUTseek(PARTNAME, off);
off += (long)outhead.oh_nname * SZ_NAME;
AOUTseek(PARTCHAR, off);
outhead.oh_nchar = off; /* see newsymb() */
#undef AOUTseek
}
commfinish()
{
register i;
#ifndef ASLD
register int i;
#endif
register struct common_t *cp;
register item_t *ip;
register sect_t *sp;
register valu_t addr;
switchsect(S_UND);
#ifdef ASLD
/*
* assign .comm labels and produce .comm symbol table entries
*/
for (i = 0; i<H_SIZE; i++)
for (ip = hashtab[H_GLOBAL+i]; ip; ip = ip->i_next) {
if ((ip->i_type & S_COM) == 0)
continue;
for (cp = commons; cp; cp = cp->c_next) {
ip = cp->c_it;
#ifndef ASLD
if (!( ip->i_type & S_EXT)) {
#endif
sp = &sect[(ip->i_type & S_TYP) - S_MIN];
if (pass == PASS_1) {
addr = sp->s_size + sp->s_comm;
sp->s_comm += ip->i_valu;
ip->i_valu = addr;
#ifndef ASLD
ip->i_type &= ~S_COM;
#endif
}
#ifdef ASLD
#ifdef THREE_PASS
if (pass == PASS_2)
if (pass == PASS_2) {
ip->i_valu -= sp->s_gain;
}
#endif
if ((sflag & SYM_EXT) && PASS_SYMB)
newsymb(
@ -496,8 +495,27 @@ commfinish()
(short)0,
load(ip)
);
#else not ASLD
#ifdef THREE_PASS
if (pass == PASS_2) {
cp->c_size -= sp->s_gain;
}
#endif THREE_PASS
}
#endif
if (pass == PASS_1) cp->c_size = ip->i_valu;
if (PASS_SYMB) {
if (pass != PASS_3 && (ip->i_type & S_EXT)) {
ip->i_valu = outhead.oh_nname;
}
newsymb(
ip->i_name,
ip->i_type,
(short) 0,
cp->c_size
);
}
#endif not ASLD
}
if (PASS_SYMB == 0)
return;
#ifndef ASLD
@ -514,15 +532,14 @@ commfinish()
* for possible relocation
*/
ip->i_valu = outhead.oh_nname;
if (sflag & SYM_SCT)
newsymb(
ip->i_name,
S_EXT|S_UND,
(short)0,
(valu_t)0
);
newsymb(
ip->i_name,
S_EXT|S_UND,
(short)0,
(valu_t)0
);
}
#endif ASLD
#endif not ASLD
/*
* produce symbol table entries for sections
*/

View file

@ -162,13 +162,7 @@ getval(c)
#endif
case STRING:
p = stringbuf;
#ifdef DUK
*p++ = n = getc(tempfile);
p[n] = '\0';
break;
#else DUK
*p++ = n = getc(tempfile); break;
#endif DUK
*p++ = n = getc(tempfile); p[n] = '\0'; break;
case OP_EQ:
case OP_NE:
case OP_LE:
@ -360,18 +354,12 @@ instring(termc)
break;
if (c == '\\')
c = inescape();
#ifdef DUK
if (p >= &stringbuf[STRINGMAX - 1])
#else DUK
if (p >= &stringbuf[STRINGMAX])
#endif DUK
fatal("string buffer overflow");
*p++ = c;
}
stringbuf[0] = p - stringbuf - 1;
#ifdef DUK
*p = '\0';
#endif DUK
return(STRING);
}

View file

@ -106,11 +106,11 @@ register item_t *ip;
sp = &sect[typ - S_MIN];
sp->s_item = ip;
sp->s_lign = ALIGNSECT;
#ifdef DUK
#ifndef ASLD
ip->i_type = typ;
#else DUK
#else
ip->i_type = typ | S_EXT;
#endif DUK
#endif
ip->i_valu = 0;
} else if (typ >= S_MIN) {
sp = &sect[typ - S_MIN];
@ -142,16 +142,14 @@ valu_t base;
}
/*
* NOTE: A rather different solution is used for ASLD and NOLD:
* ASLD:
* NOTE: A rather different solution is used for ASLD and not ASLD:
* ASLD, or local commons:
* - maximum length of .comm is recorded in i_valu during PASS_1
* - address of .comm is recorded in i_valu in later passes:
* assigned at end of PASS_1, corrected for s_gain at end of PASS_2
* - symbol table entries are produced in commfinish()
* NOLD:
* - i_valu cannot be used since it is needed for relocation info
* - only one .comm with a particular symbol is allowed per module
* - symbol table entries are produced in newcomm()
* not ASLD:
* - maximum length of .comm is recorded in i_valu during PASS_1
* - i_valu is used for relocation info during PASS_3
*/
newcomm(ip, val)
register item_t *ip;
@ -165,31 +163,15 @@ valu_t val;
/* printf("declare %s: %o\n", ip->i_name, DOTTYP); */
if ((ip->i_type & ~S_EXT) == S_UND) {
--unresolved;
ip->i_type = S_COM|S_EXT|DOTTYP;
#ifdef ASLD
ip->i_type = S_COM|DOTTYP|(ip->i_type&S_EXT);
ip->i_valu = val;
} else if (ip->i_type == (S_COM|S_EXT|DOTTYP)) {
new_common(ip);
} else if (ip->i_type == (S_COM|DOTTYP|(ip->i_type&S_EXT))) {
if (ip->i_valu < val)
ip->i_valu = val;
#endif
} else
serror("multiple declared");
}
#ifndef ASLD
if (PASS_SYMB == 0)
return;
if (pass != PASS_3)
/*
* save symbol table index
* for possible relocation
*/
ip->i_valu = outhead.oh_nname;
#ifdef DUK
newsymb(ip->i_name, S_COM|S_EXT|DOTTYP, (short)0, val);
#else DUK
newsymb(ip->i_name, S_EXT|DOTTYP, (short)0, val);
#endif DUK
#endif
}
switchsect(newtyp)
@ -207,12 +189,7 @@ short newtyp;
assert(newtyp >= S_MIN);
sp = &sect[newtyp - S_MIN];
if (pass == PASS_3) {
#ifdef AOUTSEEK
aoutpart = -1;
aoutseek[PARTEMIT] = sp->s_foff + sp->s_size - sp->s_zero;
#else
fseek(aoutfile[PARTEMIT], sp->s_foff + sp->s_size - sp->s_zero, 0);
#endif
wr_outsect(newtyp - S_MIN);
}
DOTVAL = sp->s_size + sp->s_base;
DOTSCT = sp;
@ -254,9 +231,8 @@ valu_t bytes;
DOTGAIN += (bytes - 1) - gap;
#endif
}
/* I don't play the os_zero game here, but plainly write out zero's */
/* Led abuses trailing zero parts */
while (gap--) emit1(0) ;
DOTVAL += gap;
sp->s_zero += gap;
}
#ifdef RELOCATION
@ -264,9 +240,7 @@ newrelo(s, n)
short s;
{
struct outrelo outrelo;
#ifdef DUK
int iscomm;
#endif DUK
if (rflag == 0)
return;
@ -284,9 +258,7 @@ short s;
* b=a
* a: .data2 0
*/
#ifdef DUK
iscomm = s & S_COM;
#endif DUK
s &= ~S_COM;
if ((n & RELPC) == 0 && s == S_ABS)
return;
@ -300,11 +272,7 @@ short s;
outrelo.or_type = (char)n;
outrelo.or_sect = (char)DOTTYP;
#ifndef ASLD
#ifdef DUK
if (s == S_UND || iscomm) {
#else DUK
if (s == S_UND) {
#endif DUK
assert(relonami != 0);
outrelo.or_nami = relonami-1;
relonami = 0;
@ -326,7 +294,7 @@ short s;
;
}
outrelo.or_addr = (long)DOTVAL;
putofmt((char *)&outrelo, SF_RELO, PARTRELO);
wr_relo(&outrelo, 1);
}
#endif
@ -347,17 +315,37 @@ valu_t valu;
outhead.oh_nname++;
return;
}
nname++;
if (name) {
AOUTPART(PARTCHAR);
int len = strlen(name) + 1;
wr_string(name, len);
outname.on_foff = outhead.oh_nchar;
do {
AOUTPUTC(*name, PARTCHAR);
outhead.oh_nchar++;
} while (*name++);
outhead.oh_nchar += len;
} else
outname.on_foff = 0;
outname.on_type = type;
outname.on_desc = desc;
outname.on_valu = valu & ~((0xFFFFFFFF)<<(8*sizeof(valu_t)));
putofmt((char *)&outname, SF_NAME, PARTNAME);
wr_name(&outname, 1);
}
new_common(ip)
item_t *ip;
{
register struct common_t *cp;
static nleft = 0;
static struct common_t *next;
if (--nleft < 0) {
next = (struct common_t *) sbrk(MEMINCR);
if ((int) next == -1) {
fatal("out of memory");
}
nleft += (MEMINCR / sizeof (struct common_t));
}
cp = next++;
cp->c_next = commons;
cp->c_it = ip;
commons = cp;
}

View file

@ -19,11 +19,7 @@ register item_t *ip;
return(ip->i_valu);
return(ip->i_valu + sect[typ].s_base);
#else
#ifdef DUK
if ((ip->i_type & S_TYP) == S_UND || (ip->i_type & S_COM)) {
#else DUK
if ((ip->i_type & S_TYP) == S_UND) {
#endif DUK
if (pass == PASS_3) {
if (relonami != 0)
serror("relocation error");
@ -200,6 +196,7 @@ small(fitsmall, gain)
assert(fitsmall || (*p & bit) == 0);
return(*p & bit);
}
/*NOTREACHED*/
}
#endif
@ -229,12 +226,12 @@ char arg;
DOTSCT->s_zero = 0;
break;
case PASS_3:
AOUTPART(PARTEMIT);
wr_outsect(DOTTYP-S_MIN);
while (DOTSCT->s_zero) {
AOUTPUTC(0, PARTEMIT);
wr_putc(0);
DOTSCT->s_zero--;
}
AOUTPUTC(arg, PARTEMIT);
wr_putc(arg);
break;
}
DOTVAL++;
@ -262,7 +259,7 @@ long arg;
emitx(val, n)
valu_t val;
register n;
int n;
{
switch (n) {
case 1:
@ -312,7 +309,7 @@ char *s;
FILE *
fftemp(path, tail)
char *path;
char *path, *tail;
{
register char *dir;
@ -326,36 +323,6 @@ char *path;
return(ffcreat(mktemp(path)));
}
putofmt(p, s, part)
register char *p;
register char *s;
{
register i;
register long l;
AOUTPART(part);
while (i = *s++) {
switch (i -= '0') {
/* case 0: p++; break; */
case 1:
l = (long) *((char *)p); p += sizeof(char );
break;
case 2:
l = (long) *((short *)p); p += sizeof(short);
break;
case 4:
l = (long) *((long *)p); p += sizeof(long );
break;
default:
assert(0);
}
while (--i >= 0) {
AOUTPUTC((int)l, part);
l >>= 8;
}
}
}
/* ---------- Error handling ---------- */
yyerror(){} /* we will do our own error printing */
@ -365,7 +332,7 @@ nosect()
fatal("no sections");
}
werror()
wr_fatal()
{
fatal("write error");
}