|
|
researchv10 Norman
/* @(#)kas1.c 1.2 */
#undef vax
#define pdp11 1
#include <stdio.h>
#include "a.out.h"
#include <sys/kmc.h>
#include "kas.h"
FILE *txtfil;
int hshused;
int lineno = 1;
struct symtab *nextsym = {symtab};
#ifdef vax
struct filehdr hdr;
struct aouthdr aout;
struct scnhdr scn;
struct syment sym;
#endif
#ifdef pdp11
struct exec hdr;
#endif
extern char yytext[];
main(argc, argv)
char **argv;
{
register struct symtab *sp, *ip;
int c;
register struct symtab **hp;
int infound = 0;
outfile = "a.out";
while (argc > 1) {
if (argv[1][0]=='-' && argv[1][1]=='o') {
if (argc <3) {
fprintf(stderr, "missing -o file\n");
exit(1);
}
outfile = argv[2];
argc -= 2;
argv += 2;
continue;
}
if (argv[1][0]=='-' && argv[1][1]=='d') {
if (argc <3) {
fprintf(stderr, "missing -d file");
exit(1);
}
dbfile = argv[2];
dbmode++;
if ((dbfd = open(dbfile, 2))<0) {
fprintf(stderr, "can not open %s\n", dbfile);
exit(2);
}
signal(2,1);
argc -= 2;
argv += 2;
continue;
}
if (infound) {
fprintf(stderr, "too many arguments\n");
exit(1);
}
infound++;
infile = argv[1];
if (freopen(infile, "r", stdin) == NULL) {
fprintf(stderr, "can not open %s\n", infile);
exit(2);
}
argc--;
argv++;
}
for (ip=instab; ip->name[0]!=0; ip++) {
register char *p1, *p2;
for (p1=ip->name,p2=yytext; p2<yytext+NCPS;)
*p2++ = *p1++;
*p2++ = 0;
hp = lookup(0);
if (*hp==NULL) {
*hp = ip;
}
}
yytext[0] = '.'; yytext[1] = '\0';
dot = *lookup(1);
yyparse();
if (dbmode)
exit(0);
txtfil = fopen(outfile, "w");
if (txtfil==NULL) {
fprintf(stderr, "can not create %s\n", outfile);
exit(1);
}
#ifdef vax
hdr.f_magic = VAXROMAGIC;
hdr.f_nscns = 2;
aout.magic = 0410;
aout.tsize = tsize*2;
aout.dsize = (dsize+1)&~1;
aout.bsize = 0;
hdr.f_timdat = time(NULL);
hdr.f_symptr = sizeof(struct filehdr)
+ (2 * sizeof(struct scnhdr))
+ sizeof(struct aouthdr)
+ aout.tsize
+ aout.dsize ;
hdr.f_nsyms = nextsym-symtab;
hdr.f_opthdr = sizeof(struct aouthdr);
hdr.f_flags = F_AR32WR|F_LNNO|F_RELFLG;
fwrite(&hdr, sizeof hdr, 1, txtfil);
fwrite(&aout, sizeof aout, 1, txtfil);
strncpy(scn.s_name,_TEXT,sizeof(scn.s_name));
scn.s_size = aout.tsize;
scn.s_scnptr = sizeof(struct filehdr) + sizeof(struct aouthdr) +
(2 * sizeof(struct scnhdr));
fwrite(&scn, sizeof scn, 1, txtfil);
strncpy(scn.s_name,_DATA,sizeof(scn.s_name));
scn.s_size = aout.dsize;
scn.s_scnptr += aout.tsize;
fwrite(&scn, sizeof scn, 1, txtfil);
fwrite(ispace, aout.tsize, 1, txtfil);
fwrite(dspace, aout.dsize, 1, txtfil);
#endif
#ifdef pdp11
hdr.a_magic = 0410;
hdr.a_text = tsize*2;
hdr.a_data = (dsize+1)&~1;
hdr.a_syms = (int)nextsym-(int)symtab;
hdr.a_flag = 1;
fwrite(&hdr, sizeof hdr, 1, txtfil);
fwrite(ispace, hdr.a_text, 1, txtfil);
fwrite(dspace, hdr.a_data, 1, txtfil);
#endif
for (sp=symtab; sp<nextsym; sp++) {
#ifdef pdp11
sp->type >>= 12;
#endif
#ifdef vax
strncpy(sym.n_name, sp->name, SYMNMLEN);
sym.n_value = sp->value;
if (sp->type == XTEXT)
sym.n_scnum = 1;
else
sym.n_scnum = 2;
sym.n_sclass = C_EXT;
fwrite(&sym, 1, SYMESZ, txtfil);
#endif
if (sp->type == XUNDEF)
fprintf(stderr, "%.8s undefined\n", sp->name);
}
#ifdef pdp11
fwrite(symtab, sizeof(symtab[0]), nextsym-symtab, txtfil);
#endif
exit(anyerrs!=0);
}
struct symtab **
lookup(instflg)
{
int ihash;
register struct symtab **hp;
register char *p1, *p2;
ihash = 0;
p1 = yytext;
while (*p1) {
ihash <<= 1;
ihash += *p1++;
}
ihash &= 077777;
while (p1<yytext+NCPS)
*p1++ = 0;
hp = &hshtab[ihash%NHASH];
while (*hp) {
p2 = (*hp)->name;
for (p1=yytext; p1<yytext+NCPS;)
if (*p1++ != *p2++)
goto no;
return(hp);
no:
if (++hp >= &hshtab[NHASH])
hp = hshtab;
}
if(++hshused >= NHASH) {
yyerror("Symbol table overflow");
exit(2);
}
if (instflg) {
for (p1=yytext,p2=nextsym->name; p1<yytext+NCPS;)
*p2++ = *p1++;
*hp = nextsym++;
}
return(hp);
}
cksrc(s, d)
{
switch(d&(7<<8)) {
case DSTREGH:
case DSTREGL:
case DSTREG:
case DSTBREG:
if ((s&017) != (d&017)) {
yyerror("illegal source");
return(d);
}
}
return(s|d);
}
ckreg(s, d)
{
switch(d&(7<<8)) {
case DSTREGH:
case DSTREGL:
if ((s&017) != 0) {
yyerror("illegal source");
return(d);
}
break;
case DSTREG:
case DSTBREG:
if ((s&017) != (d&017)) {
yyerror("illegal source");
return(d);
}
}
return(s|d);
}
ckdst(a, b)
{
if ((a&DSTMARI) && (b&DSTMARI)) {
yyerror("illegal destination");
return(a);
}
if ((a&DSTBREG) && (b&DSTBREG)) {
if ((((a&DSTBREG)!=DSTBRG) || ((b&DSTBREG)!=DSTREG))
&& (((b&DSTBREG)!=DSTBRG) || ((a&DSTBREG)!=DSTREG))) {
yyerror("illegal destination");
return(a);
}
}
return(a|b);
}
putins(ins)
{
char csr[8];
register p;
p = dot->value++;
if (dot->value==NKMCI) {
dot->value = 0;
}
if ((p&01777)==01777) {
yyerror("warning: text 1k boundary crossing");
}
if (dbmode) {
if (reloc[p]&RLCBR) {
yyerror("undefined trace instruction");
reloc[p] = 0;
return;
}
if (ksty(KMS, csr, ins)==0)
fprintf(stdout, "%4o%4o%4o%4o%7o\n",
csr[2]&0377,csr[3]&0377,csr[4]&0377,csr[5]&0377,ins);
return;
}
if (reloc[p]&RLUSE) {
yyerror("text location redefined");
return;
}
ispace[p] = ins;
reloc[p] |= RLUSE;
if (++p>tsize)
tsize = p;
}
putdat(ins)
{
register p;
p = dot->value++;
if (dot->value==NKMCD)
dot->value = 0;
if (dbmode) {
lseek(dbfd, (long)(p+NKMCI*2), 0);
write(dbfd, &ins, 1);
return;
}
if (dspace[p]) {
yyerror("data location redefined");
return;
}
dspace[p] = ins;
if (++p>dsize)
dsize = p;
}
backup(sp, val)
register struct symtab *sp;
{
register backp, next;
for (backp = sp->value; backp; backp = (reloc[next]&RLBUP)) {
next = backp&RLNEXT;
switch(backp&RLCMASK) {
case RLCBR:
if ((next&~01777) != (val&~01777))
yyerror("forward branch error");
ispace[next] |= (val&01400)<<3;
case RLCMV:
ispace[next] |= val&0377;
break;
case RLCPOP:
ispace[next] |= (val>>8)&0377;
break;
case RLCPG:
ispace[next] |= (val&01400)<<3;
break;
}
}
sp->value = val;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.