/* File: global.c * * Contains: global, entsym * * This is the handler for the GLOBAL and ENTRY/PUBLIC operands. */ #include "asm.h" FILE *efile; int gfile; extern char finame[]; /* void pflag(); */ /*. ************************************************************************* * * * global * * ------ * * * * handler for GLOBAL operand * * * * global() * * * * returns no value * * * ************************************************************************* */ void global() { publcc(mode == ASEG); } /*. ************************************************************************* * * * entsym * * ------ * * * * handler for ENTRY/PUBLIC operand * * * * entsym() * * * * returns no value * * * ************************************************************************* */ void entsym() { if (mode == ASEG) { eror('S'); return; } publcc(2); } /*. ************************************************************************* * * * publcc * * ------ * * * * handler for all of them * * * * publcc() * * * * * ************************************************************************* */ void publcc(entcod) register int entcod; { register SYM *sp; register unsigned char *pnt; unsigned register char *lp; register int i; SYM symbufx; #if DEBUG printf("public\n"); #endif if (refflg) return; ptable[pdef] |= O6ENT; lp = linpnt; if (entcod == 1 && !gfile && passno == 2) { if ((gfile = creat(finame, 0666)) < 0) { gfile = 0; printl("Can't open global file for write\n"); xdone(1); } symbufx.s_name[0] = 0x06; symbufx.s_name[1] = 0x01; symbufx.s_flag1 = O6H; symbufx.s_flag2 = O6GBL; (void) write(gfile, &symbufx, SSIZE); } while (*lp) { lp = gsym(lp, labbuf); if(regtok(labbuf)) eror('W'); else { if (sp = loc_symbol(labbuf)) { sp->s_flag1 |= SYMENT; if (passno == 2) { if (sp->s_flag1 & SYMUDF) { /* * undefined global symbol */ eror('U'); } else { /* * turn off print '-' "no referrence" flag */ sp->s_flag2 &= ~PNOREF; if (entcod < 2) sp->s_flag2 |= PRTGBL; if (entcod == 1) { /* * output absolute global name */ (void) write(gfile, sp, SSIZE); } else if (entcod == 0 && objfile) { /* output relocatable global name */ clsrec(); putX(O8H); putX(slenth); pnt = sp->s_name; for (i = 0; i < slenth; i++) putX(*pnt ? *pnt++ : SPACE); } } } else reff_symbol(sp, 0); } else if (passno == 1) { turn_on(AFENTS); labflg = 0; sp = proc_symbol(DEFBTK,0); turn_off(AFENTS); reff_symbol(sp, 0); } else eror('U'); } lp = skipsp(lp); if (*lp == COMMA) lp = skipsp(++lp); else if (term(lp)) break; else { dnops(); break; } } turn_off(AFENTS); } /*. ************************************************************************* * * * * * * * * * * ************************************************************************* */ /* * This is the routine that reads in an EXTernal file and adds * the labels and values to the symbol table. */ void etern() { register SYM *sp, *ext; register int length; register unsigned char *pnt1; register unsigned char *tp; char tbuff[50]; char xbuff[50]; SYM xybuff; if (passno == 2) return; if ((length = str(linpnt)) == 0) { dnops(); return; } pnt1 = movbuf(linpnt, tbuff, length, 0); *pnt1 = 0; if (search(tbuff) == 0) { tp = look(tbuff); if (*tp >= 'A' && *tp <= 'Z') (void) strcat(tbuff, ".GBL"); else (void) strcat(tbuff, ".gbl"); } if ((efile = tryopen(tbuff)) == 0) { (void) sprintf(xbuff, "/usr/include/%s", look(tbuff)); if ((efile = tryopen(xbuff)) == 0) { printl("Open failure on GBL file: %s\n", tbuff); return; } (void) strcpy(tbuff,xbuff); } printl("EXT:\t%s\n", tbuff); ext = &xybuff; (void) read(fileno(efile), ext, SSIZE); /* * test for old style global file */ if (ext->s_name[0] == ':' || ext->s_name[0] == '0') { (void) fclose(efile); old_global(tbuff); return; } if (ext->s_flag1 != O6H || ext->s_flag2 != O6GBL) { (void) fclose(efile); printl("%s is not a GBL file\n", linpnt); xdone(0); } while (read(fileno(efile), ext, SSIZE)) { if (loc_symbol(ext->s_name) == 0) { sp = add_symbol(); ext->leftptr = sp->leftptr; ext->rightptr = sp->rightptr; (void) movbuf(ext, sp, SSIZE, -1); #if DEBUG printf("etern:global name=*%s* value=%d\n",sp->s_name,sp->s_value); #endif sp->s_flag1 = SYMGBL | (sp->s_flag1 & SYMSEC); sp->s_psect = pdef; sp->ref_beg = 0; sp->ref_end = 0; } } (void) fclose(efile); efile = 0; } /*. ************************************************************************* * * * extsym * * ------ * * * * This is the handler for the EXTERNal handler * * * * * * * ************************************************************************* */ void extsym() { register SYM *fp; register unsigned char *lp; if (refflg || passno == 2 || mode == ASEG) { if (mode == ASEG) eror('S'); return; } #if DEBUG printf("external\n"); #endif lp = linpnt; turn_on(AFEXTS); while (*lp) { lp = gsym(lp, labbuf); if(regtok(labbuf)) eror('W'); else { if (fp = loc_symbol(labbuf)) { /* pflag(labbuf, fp->s_flag1); */ if (fp->s_psect != pdef) fp->s_flag1 |= SYMEXT; else eror('M'); } else { fp = add_symbol(); load_symbol(fp,0); /* pflag(labbuf, fp->s_flag1); */ } } lp = skipsp(lp); if (*lp == COMMA) lp = skipsp(++lp); else if (term(lp)) break; else { dnops(); break; } } turn_off(AFEXTS); } /* debug purposes only void pflag(name, flag) char *name; char flag; { int i; (void) fprintf(stderr, "%s (%X): ", name, flag); for(i = 0; i < 8; i++) { if(flag & 0x80) (void) fprintf(stderr, "1"); else (void) fprintf(stderr, "0"); flag <<= 1; } (void) fprintf(stderr, "\n"); } */