1 /* $Id: comm4.c,v 2.18 1994/06/24 13:22:05 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
8 * Micro processor assembler framework written by
9 * Johan Stevenson, Vrije Universiteit, Amsterdam
11 * Johan Stevenson, Han Schaminee and Hans de Vries
12 * Philips S&I, T&M, PMDS, Eindhoven
19 extern YYSTYPE yylval;
21 /* ========== Machine independent C routines ========== */
38 static char sigs[] = {
39 SIGHUP, SIGINT, SIGQUIT, SIGTERM, 0
42 /* the next test should be performed by the
43 * preprocessor, but it cannot, so it is performed by the compiler.
48 case (S_ETC|S_COM|S_VAR|S_DOT) != S_ETC : break;
51 progname = *argv++; argc--;
52 for (p = sigs; i = *p++; )
53 if (signal(i, SIG_IGN) != SIG_IGN)
55 for (i = 0; i < argc; i++) {
67 fatal("-o needs filename");
80 while (*p >= '0' && *p <= '7')
81 dflag = (dflag << 3) + *p++ - '0';
82 if ((dflag & 0777) == 0)
89 while (*p >= '0' && *p <= '7')
90 sflag = (sflag << 3) + *p++ - '0';
97 #endif /* RELOCATION */
118 #endif /* RELOCATION */
128 /* ---------- pass 1: arguments, modules, archives ---------- */
146 tempfile = fftemp(temppath, "asTXXXXXX");
150 listfile = fftemp(listpath, "asLXXXXXX");
152 for (ip = keytab; ip->i_type; ip++)
153 item_insert(ip, H_KEY+hash(ip->i_name));
155 while (--argc >= 0) {
161 fatal("second source file %s", p);
164 if (p[0] == '-' && p[1] == '\0') {
170 if ((input = fopen(p, "r")) == NULL)
171 fatal("can't open %s", p);
174 fread(armagic, 2, 1, input) == 1
177 ((unsigned)(armagic[1]&0377)<<8)) == ARMAG
202 fprintf(stderr, "unresolved references:\n");
203 for (i = 0; i < H_SIZE; i++) {
204 ip = hashtab[H_GLOBAL+i];
206 if ((ip->i_type & (S_EXT|S_TYP)) == (S_EXT|S_UND))
207 fprintf(stderr, "\t%s\n", ip->i_name);
214 outhead.oh_flags |= HF_LINK;
217 fatal("no source file");
225 register long offset;
226 struct ar_hdr header;
227 char getsize[AR_TOTAL];
234 fseek(input,offset,0);
235 if (fread(getsize,AR_TOTAL,1,input) != 1)
238 strncpy(header.ar_name,getsize,sizeof header.ar_name) ;
239 header.ar_size= (((((long) (getsize[AR_SIZE+1]&0377))<<8)+
240 ((long) (getsize[AR_SIZE ]&0377))<<8)+
241 ((long) (getsize[AR_SIZE+3]&0377))<<8)+
242 ((long) (getsize[AR_SIZE+2]&0377)) ;
243 archsize = header.ar_size;
245 fseek(input,offset,0);
246 archsize = header.ar_size;
247 header.ar_name[14] = '\0';
248 parse(remember(header.ar_name));
250 offset += header.ar_size;
266 save = listflag; listflag = 0;
277 if (c == ' ' || c == '\t' || c == ',')
281 if ((ip = item_search(readident(c))) == 0) {
287 if (ip == &keytab[KEYSECT]) {
288 while ((c = nextchar()) != '\n')
293 if (ip != &keytab[KEYDEFINE])
297 if ((ip->i_type & S_TYP) == S_UND) {
323 for (i = 0; i < FB_SIZE; i++)
324 fb_ptr[FB_BACK+i] = 0;
329 * Check for undefined symbols
332 for (i = 0; i < H_SIZE; i++) {
333 while (ip = hashtab[H_LOCAL+i]) {
335 * cleanup local queue
337 hashtab[H_LOCAL+i] = ip->i_next;
339 * make undefined references extern
341 if ((ip->i_type & (S_VAR|S_TYP)) == S_UND)
344 * relink externals in global queue
346 if (ip->i_type & S_EXT)
347 item_insert(ip, H_GLOBAL+i);
351 for (i = 0; i < H_SIZE; i++) {
352 for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) {
353 if (ip->i_type & S_EXT)
355 if (ip->i_type != S_UND)
358 serror("undefined symbol %s", ip->i_name);
364 * Check for undefined numeric labels
366 for (i = 0; i < FB_SIZE; i++) {
367 if ((ip = fb_ptr[FB_FORW+i]) == 0)
369 serror("undefined label %d", i);
370 fb_ptr[FB_FORW+i] = 0;
378 register ADDR_T base = 0;
388 ffreopen(listpath, listfile);
395 for (i = 0; i < FB_SIZE; i++)
396 fb_ptr[FB_FORW+i] = fb_ptr[FB_HEAD+i];
397 outhead.oh_nemit = 0;
398 for (sp = sect; sp < §[outhead.oh_nsect]; sp++) {
400 if (sp->s_flag & BASED) {
402 if (base % sp->s_lign)
403 fatal("base not aligned");
405 base += (sp->s_lign - 1);
406 base -= (base % sp->s_lign);
412 outhead.oh_nemit += sp->s_size - sp->s_zero;
416 for (sp = sect; sp < §[outhead.oh_nsect]; sp++) {
425 newmodule(modulename);
427 ffreopen(temppath, tempfile);
436 static char nmbuf[STRINGMAX];
439 if (s && s != modulename) {
440 strncpy(nmbuf, s, STRINGMAX-1);
447 * problem: it shows the name of the tempfile, not any name
448 * the user is familiar with. Moreover, it is not reproducable.
450 if ((sflag & (SYM_EXT|SYM_LOC|SYM_LAB)) && PASS_SYMB)
451 newsymb(s, S_MOD, 0, (valu_t)0);
465 struct outsect outsect;
466 register struct outsect *pos = &outsect;
468 if (! wr_open(aoutpath)) {
469 fatal("can't create %s", aoutpath);
473 * section table generation
476 off += (long)outhead.oh_nsect * SZ_SECT;
477 for (sp = sect; sp < §[outhead.oh_nsect]; sp++) {
479 pos->os_base = SETBASE(sp);
480 pos->os_size = sp->s_size + sp->s_comm;
481 pos->os_foff = sp->s_foff;
482 pos->os_flen = sp->s_size - sp->s_zero;
483 pos->os_lign = sp->s_lign;
488 off += (long)outhead.oh_nrelo * SZ_RELO;
492 off += (long)outhead.oh_nname * SZ_NAME;
493 outhead.oh_nchar = off; /* see newsymb() */
501 register struct common_t *cp;
504 register valu_t addr;
508 * assign .comm labels and produce .comm symbol table entries
510 for (cp = commons; cp; cp = cp->c_next) {
513 if (!( ip->i_type & S_EXT)) {
515 sp = §[(ip->i_type & S_TYP) - S_MIN];
516 if (pass == PASS_1) {
517 addr = sp->s_size + sp->s_comm;
518 sp->s_comm += ip->i_valu;
521 ip->i_type &= ~S_COM;
526 if (pass == PASS_2) {
527 ip->i_valu -= sp->s_gain;
530 if ((sflag & SYM_EXT) && PASS_SYMB)
533 ip->i_type & (S_EXT|S_TYP),
539 if (pass == PASS_2) {
540 cp->c_size -= sp->s_gain;
542 #endif /* THREE_PASS */
544 if (pass == PASS_1) cp->c_size = ip->i_valu;
546 if (pass != PASS_3 && (ip->i_type & S_EXT)) {
547 ip->i_valu = outhead.oh_nname;
556 #endif /* not ASLD */
562 * produce symbol table entries for undefined's
564 for (i = 0; i<H_SIZE; i++)
565 for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) {
566 if (ip->i_type != (S_EXT|S_UND))
570 * save symbol table index
571 * for possible relocation
573 ip->i_valu = outhead.oh_nname;
581 #endif /* not ASLD */
583 * produce symbol table entries for sections
586 for (sp = sect; sp < §[outhead.oh_nsect]; sp++) {
590 (ip->i_type | S_SCT),