123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 |
- /* @(#)comm4.c 1.6 */
- /*
- * Micro processor assembler framework written by
- * Johan Stevenson, Vrije Universiteit, Amsterdam
- * modified by
- * Johan Stevenson, Han Schaminee and Hans de Vries
- * Philips S&I, T&M, PMDS, Eindhoven
- */
- #include "comm0.h"
- #include "comm1.h"
- #include "y.tab.h"
- extern YYSTYPE yylval;
- /* ========== Machine independent C routines ========== */
- stop() {
- #if DEBUG < 2
- unlink(temppath);
- #ifdef LISTING
- unlink(listpath);
- #endif
- #endif
- exit(nerrors != 0);
- }
- main(argc, argv)
- char **argv;
- {
- register char *p;
- register i;
- static char sigs[] = {
- SIGHUP, SIGINT, SIGQUIT, SIGTERM, 0
- };
- /* this test should be performed by the
- * preprocessor, but it cannot
- */
- if ((S_ETC|S_COM|S_VAR|S_DOT) != S_ETC)
- fatal("incorrect type bits");
- progname = *argv++; argc--;
- for (p = sigs; i = *p++; )
- if (signal(i, SIG_IGN) != SIG_IGN)
- signal(i, stop);
- for (i = 0; i < argc; i++) {
- p = argv[i];
- if (*p++ != '-')
- continue;
- switch (*p++) {
- case 'o':
- if (*p != NULL) {
- aoutpath = p;
- break;
- }
- argv[i] = 0;
- if (++i >= argc)
- fatal("-o needs filename");
- aoutpath = argv[i];
- break;
- case 'd':
- #ifdef LISTING
- dflag = 0;
- while (*p >= '0' && *p <= '7')
- dflag = (dflag << 3) + *p++ - '0';
- if ((dflag & 0777) == 0)
- dflag |= 0700;
- dflag &= ~4;
- #endif
- break;
- case 's':
- sflag = 0;
- while (*p >= '0' && *p <= '7')
- sflag = (sflag << 3) + *p++ - '0';
- break;
- case 'r':
- #ifdef RELOCATION
- #ifdef ASLD
- rflag = 1;
- #endif ASLD
- #endif RELOCATION
- break;
- case 'b':
- #ifdef THREE_PASS
- bflag = 1;
- #endif
- break;
- #ifndef ASLD
- case 'u':
- case '\0':
- uflag = 1;
- break;
- #endif
- default:
- continue;
- }
- argv[i] = 0;
- }
- #ifdef RELOCATION
- if (rflag)
- sflag |= SYM_SCT;
- #endif RELOCATION
- pass_1(argc, argv);
- #ifdef THREE_PASS
- pass_23(PASS_2);
- #endif
- pass_23(PASS_3);
- stop();
- }
- /* ---------- pass 1: arguments, modules, archives ---------- */
- pass_1(argc, argv)
- char **argv;
- {
- register i;
- register char *p;
- register item_t *ip;
- #ifdef ASLD
- char armagic[SZMAGIC];
- #else
- register nfile = 0;
- #endif
- tempfile = fftemp(temppath, "asTXXXXXX");
- #ifdef LISTING
- listmode = dflag;
- if (listmode & 0440)
- listfile = fftemp(listpath, "asLXXXXXX");
- #endif
- for (ip = keytab; ip->i_type; ip++)
- item_insert(ip, H_KEY+hash(ip->i_name));
- machstart(PASS_1);
- while (--argc >= 0) {
- p = *argv++;
- if (p == 0)
- continue;
- #ifdef ASLD
- 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
- &&
- strncmp(armagic, ARMAGIC, SZMAGIC) == 0
- ) {
- archive();
- fclose(input);
- continue;
- }
- rewind(input);
- #endif
- parse(p);
- fclose(input);
- }
- commfinish();
- machfinish(PASS_1);
- #ifdef ASLD
- if (unresolved) {
- nerrors++;
- fflush(stdout);
- fprintf(stderr, "unresolved references:\n");
- for (i = 0; i < H_SIZE; i++) {
- ip = hashtab[H_GLOBAL+i];
- while (ip != 0) {
- if ((ip->i_type & (S_EXT|S_TYP)) == (S_EXT|S_UND))
- fprintf(stderr, "\t%s\n", ip->i_name);
- ip = ip->i_next;
- }
- }
- }
- #else
- if (unresolved)
- outhead.oh_flags |= HF_LINK;
- if (nfile == 0)
- fatal("no source file");
- #endif
- }
- #ifdef ASLD
- archive()
- {
- register long offset;
- register i;
- register long modsize;
- char modhead[SZMHEAD];
- archmode++;
- offset = SZMAGIC;
- for (;;) {
- if (unresolved == 0)
- break;
- fseek(input, offset, 0);
- if (fread(modhead, SZMHEAD, 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;
- 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]));
- }
- offset += modsize;
- }
- archmode = 0;
- }
- needed()
- {
- register c, first;
- register item_t *ip;
- register need;
- #ifdef LISTING
- register save;
- save = listflag; listflag = 0;
- #endif
- need = 0;
- peekc = -1;
- first = 1;
- for (;;) {
- c = nextchar();
- if (c == '\n') {
- first = 1;
- continue;
- }
- if (c == ' ' || c == '\t' || c == ',')
- continue;
- if (ISALPHA(c) == 0)
- break;
- if ((ip = item_search(readident(c))) == 0) {
- if (first)
- break;
- continue;
- }
- if (first) {
- if (ip != &keytab[KEYDEFINE])
- break;
- first = 0;
- }
- if ((ip->i_type & S_TYP) == S_UND) {
- need++;
- break;
- }
- }
- #ifdef LISTING
- listflag = save;
- #endif
- return(need);
- }
- #endif ASLD
- parse(s)
- char *s;
- {
- register i;
- register item_t *ip;
- register char *p;
- for (p = s; *p; )
- if (*p++ == '/')
- s = p;
- #ifdef ASLD
- yylval.y_strp = s;
- putval(MODULE);
- #endif
- for (i = 0; i < FB_SIZE; i++)
- fb_ptr[FB_BACK+i] = 0;
- newmodule(s);
- peekc = -1;
- yyparse();
- /*
- * Check for undefined symbols
- */
- #ifdef ASLD
- for (i = 0; i < H_SIZE; i++) {
- while (ip = hashtab[H_LOCAL+i]) {
- /*
- * cleanup local queue
- */
- hashtab[H_LOCAL+i] = ip->i_next;
- /*
- * make undefined references extern
- */
- if ((ip->i_type & (S_VAR|S_TYP)) == S_UND)
- ip->i_type |= S_EXT;
- /*
- * relink externals in global queue
- */
- if (ip->i_type & S_EXT)
- item_insert(ip, H_GLOBAL+i);
- }
- }
- #else
- for (i = 0; i < H_SIZE; i++) {
- for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) {
- if (ip->i_type & S_EXT)
- continue;
- if (ip->i_type != S_UND)
- continue;
- if (uflag == 0)
- serror("undefined symbol %s", ip->i_name);
- ip->i_type |= S_EXT;
- }
- }
- #endif
- /*
- * Check for undefined numeric labels
- */
- for (i = 0; i < FB_SIZE; i++) {
- if ((ip = fb_ptr[FB_FORW+i]) == 0)
- continue;
- serror("undefined label %d", i);
- fb_ptr[FB_FORW+i] = 0;
- }
- }
- pass_23(n)
- {
- register i;
- #ifdef ASLD
- register addr_t base = 0;
- #endif
- register sect_t *sp;
- if (nerrors)
- stop();
- pass = n;
- #ifdef LISTING
- listmode >>= 3;
- if (listmode & 4)
- ffreopen(listpath, listfile);
- listeoln = 1;
- #endif
- #ifdef THREE_PASS
- nbits = 0;
- #endif
- for (i = 0; i < FB_SIZE; i++)
- fb_ptr[FB_FORW+i] = fb_ptr[FB_HEAD+i];
- outhead.oh_nemit = 0;
- for (sp = sect; sp < §[outhead.oh_nsect]; sp++) {
- #ifdef ASLD
- if (sp->s_flag & BASED) {
- base = sp->s_base;
- if (base % sp->s_lign)
- fatal("base not aligned");
- } else {
- base += (sp->s_lign - 1);
- base -= (base % sp->s_lign);
- sp->s_base = base;
- }
- base += sp->s_size;
- base += sp->s_comm;
- #endif
- outhead.oh_nemit += sp->s_size - sp->s_zero;
- }
- if (pass == PASS_3)
- setupoutput();
- for (sp = sect; sp < §[outhead.oh_nsect]; sp++) {
- sp->s_size = 0;
- sp->s_zero = 0;
- #ifdef THREE_PASS
- sp->s_gain = 0;
- #endif
- }
- machstart(n);
- #ifndef ASLD
- newmodule(modulename);
- #endif ASLD
- ffreopen(temppath, tempfile);
- yyparse();
- commfinish();
- machfinish(n);
- }
- newmodule(s)
- char *s;
- {
- switchsect(S_UND);
- modulename = s;
- lineno = 1;
- if ((sflag & (SYM_EXT|SYM_LOC|SYM_LAB)) && PASS_SYMB)
- newsymb(s, S_MOD, (short)0, (valu_t)0);
- #ifdef LISTING
- listtemp = 0;
- if (dflag & 01000)
- listtemp = listmode;
- listflag = listtemp;
- #endif
- }
- setupoutput()
- {
- register sect_t *sp;
- register long off;
- struct outsect 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);
- /*
- * section table generation
- */
- off = SZ_HEAD;
- off += (long)outhead.oh_nsect * SZ_SECT;
- for (sp = sect; sp < §[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);
- }
- #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;
- 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;
- sp = §[(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;
- }
- #ifdef THREE_PASS
- if (pass == PASS_2)
- ip->i_valu -= sp->s_gain;
- #endif
- if ((sflag & SYM_EXT) && PASS_SYMB)
- newsymb(
- ip->i_name,
- ip->i_type & (S_EXT|S_TYP),
- (short)0,
- load(ip)
- );
- }
- #endif
- if (PASS_SYMB == 0)
- return;
- #ifndef ASLD
- /*
- * produce symbol table entries for undefined's
- */
- for (i = 0; i<H_SIZE; i++)
- for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) {
- if (ip->i_type != (S_EXT|S_UND))
- continue;
- if (pass != PASS_3)
- /*
- * save symbol table index
- * 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
- );
- }
- #endif ASLD
- /*
- * produce symbol table entries for sections
- */
- if (sflag & SYM_SCT)
- for (sp = sect; sp < §[outhead.oh_nsect]; sp++) {
- ip = sp->s_item;
- newsymb(
- ip->i_name,
- (short)(ip->i_type | S_SCT),
- (short)0,
- load(ip)
- );
- }
- }
|