123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* @(#)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 ========== */
- void stop(int signal)
- {
- #if DEBUG < 2
- unlink(temppath);
- #ifdef LISTING
- unlink(listpath);
- #endif
- #endif
- exit(nerrors != 0);
- }
- int main(int argc, char *argv[])
- {
- char *p;
- int i;
- static char sigs[] = {
- SIGHUP, SIGINT, SIGQUIT, SIGTERM, 0
- };
- /* the next test should be performed by the
- * preprocessor, but it cannot, so it is performed by the compiler.
- */
- 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++); )
- 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 != '\0') {
- aoutpath = p;
- break;
- }
- argv[i] = 0;
- if (++i >= argc)
- fatal("-o needs filename");
- aoutpath = argv[i];
- break;
- case 'T':
- if (*p != '\0') {
- extern char *tmp_dir;
- tmp_dir = p;
- }
- 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);
- wr_close();
- stop(0);
- return 0;
- }
- /* ---------- pass 1: arguments, modules, archives ---------- */
- int pass_1(int argc, char *argv[])
- {
- char *p;
- item_t *ip;
- #ifdef ASLD
- char armagic[2];
- #else
- int nfile = 0;
- #endif
- #ifdef THREE_PASS
- bitindex = -1;
- nbits = BITCHUNK;
- #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;
- #ifndef ASLD
- if (nfile != 0)
- fatal("second source file %s", p);
- nfile++;
- #else
- if (p[0] == '-' && p[1] == '\0') {
- input = stdin;
- parse("STDIN");
- continue;
- }
- #endif
- if ((input = fopen(p, "r")) == NULL)
- fatal("can't open %s", p);
- #ifdef ASLD
- if (
- fread(armagic, 2, 1, input) == 1
- &&
- ((armagic[0]&0377) |
- ((unsigned)(armagic[1]&0377)<<8)) == ARMAG
- ) {
- archive();
- fclose(input);
- continue;
- }
- rewind(input);
- #endif
- parse(p);
- fclose(input);
- }
- #ifndef ASLD
- if (nfile == 0) {
- input = stdin;
- parse("STDIN");
- }
- #endif
- commfinish();
- machfinish(PASS_1);
- #ifdef ASLD
- if (unresolved) {
- int i;
- 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
- return 0;
- }
- #ifdef ASLD
- void archive()
- {
- long offset;
- struct ar_hdr header;
- char getsize[AR_TOTAL];
- archmode++;
- offset = 2;
- for (;;) {
- if (unresolved == 0)
- break;
- fseek(input,offset,0);
- if (fread(getsize,AR_TOTAL,1,input) != 1)
- break;
- 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 = header.ar_size;
- header.ar_name[14] = '\0';
- parse(remember(header.ar_name));
- }
- offset += header.ar_size;
- while (offset % 2)
- offset++;
- }
- archmode = 0;
- }
- int needed()
- {
- c, first;
- item_t *ip;
- int need;
- #ifdef LISTING
- int 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[KEYSECT]) {
- while ((c = nextchar()) != '\n')
- ;
- continue;
- }
- 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 */
- void parse(char *s)
- {
- int i;
- item_t *ip;
- 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;
- }
- }
- void pass_23(int n)
- {
- int i;
- #ifdef ASLD
- ADDR_T base = 0;
- #endif
- sect_t *sp;
- if (nerrors)
- stop(0);
- pass = n;
- #ifdef LISTING
- listmode >>= 3;
- if (listmode & 4)
- ffreopen(listpath, listfile);
- listeoln = 1;
- #endif
- #ifdef THREE_PASS
- bitindex = -1;
- nbits = BITCHUNK;
- #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);
- }
- void newmodule(char *s)
- {
- static char nmbuf[STRINGMAX];
- switchsect(S_UND);
- if (s && s != modulename) {
- strncpy(nmbuf, s, STRINGMAX-1);
- modulename = nmbuf;
- }
- else modulename = s;
- lineno = 1;
- #ifdef NEEDED
- /*
- * problem: it shows the name of the tempfile, not any name
- * the user is familiar with. Moreover, it is not reproducable.
- */
- if ((sflag & (SYM_EXT|SYM_LOC|SYM_LAB)) && PASS_SYMB)
- newsymb(s, S_MOD, 0, (valu_t)0);
- #endif
- #ifdef LISTING
- listtemp = 0;
- if (dflag & 01000)
- listtemp = listmode;
- listflag = listtemp;
- #endif
- }
- void setupoutput()
- {
- sect_t *sp;
- long off;
- struct outsect outsect;
- struct outsect *pos = &outsect;
- if (! wr_open(aoutpath)) {
- fatal("can't create %s", aoutpath);
- }
- wr_ohead(&outhead);
- /*
- * 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;
- 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
- off += (long)outhead.oh_nrelo * SZ_RELO;
- #endif
- if (sflag == 0)
- return;
- off += (long)outhead.oh_nname * SZ_NAME;
- outhead.oh_nchar = off; /* see newsymb() */
- }
- void commfinish()
- {
- #ifndef ASLD
- int i;
- #endif
- struct common_t *cp;
- item_t *ip;
- sect_t *sp;
- valu_t addr;
- switchsect(S_UND);
- /*
- * assign .comm labels and produce .comm symbol table entries
- */
- for (cp = commons; cp; cp = cp->c_next) {
- ip = cp->c_it;
- #ifndef ASLD
- if (!( ip->i_type & S_EXT)) {
- #endif
- 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;
- #ifndef ASLD
- ip->i_type &= ~S_COM;
- #endif
- }
- #ifdef ASLD
- #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),
- 0,
- load(ip)
- );
- #else /* not ASLD */
- #ifdef THREE_PASS
- if (pass == PASS_2) {
- cp->c_size -= sp->s_gain;
- }
- #endif /* THREE_PASS */
- }
- 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,
- 0,
- cp->c_size
- );
- }
- #endif /* not ASLD */
- }
- 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;
- newsymb(
- ip->i_name,
- S_EXT|S_UND,
- 0,
- (valu_t)0
- );
- }
- #endif /* not 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,
- (ip->i_type | S_SCT),
- 0,
- load(ip)
- );
- }
- }
|