Annotation of researchv9/cmd/sun/as/scan.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)scan.c 1.1 86/02/03 Copyr 1984 Sun Micro";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 1984 by Sun Microsystems, Inc.
        !             7:  */
        !             8: 
        !             9: #include "as.h"
        !            10: #include "scan.h" 
        !            11: #include <sys/signal.h>
        !            12: 
        !            13: /* process lines from source file, returns when EOF detected */
        !            14: 
        !            15: #define LSIZE  4*BUFSIZ+2      /* max size of input line + fudge */
        !            16: 
        !            17: 
        !            18: char *sassign(),*exp(),*term();
        !            19: struct ins_bkt * sopcode();
        !            20: int slabel();
        !            21: 
        !            22: char iline[LSIZE];     /* current input line resides */
        !            23: int  line_no;          /* current input line number */
        !            24: char code[CODE_MAX];   /* where generated code is stored */
        !            25: long dot;              /* offset in current csect */
        !            26: int  bc;               /* size of code for current line */
        !            27: int  opshow = 0;
        !            28: long break_line = -1, break_pass = 1;
        !            29: 
        !            30: /* for local labels: ``[0-9]:'', and references ``[0-9][bh]'' */
        !            31: extern int   ll_val[10];
        !            32: extern char * ll_format;
        !            33: 
        !            34: sexit(){
        !            35:        exit(3);
        !            36: }
        !            37: 
        !            38: main(argc,argv)
        !            39:        char *argv[];
        !            40: {
        !            41:        stabkt_head = stabkt_tail = NULL;      /* initialize stabs/d  symbol table */
        !            42:        signal( SIGINT, sexit );
        !            43:        init(argc,argv);                       /* Initialization */
        !            44:        scan();                                /* 1st pass through .s file */
        !            45:        prog_end();                            /* end of 1st pass          */
        !            46: 
        !            47:        /*
        !            48:        * Resolve the unresolved addresses in .stabs and .stabd directives.
        !            49:        * .stabs type 0x24 (N_Fun for procedure name), 0x26 (N_STSYM for static
        !            50:        * symbol), and 0x64 (N_SO for source file name) have a labeled-address
        !            51:        * tagged in the directive in the last field "value".  These addresses
        !            52:        * have to be resolved during or before the 2nd Pass (in this version
        !            53:        * resolved before the second pass).
        !            54:        */
        !            55: 
        !            56:        scan();                        /* 2nd pass through .s file */
        !            57:        prog_end();                    /* end of 2nd pass          */
        !            58:        exit(errors? -1: 0);
        !            59: } /* end main */
        !            60: 
        !            61: scan()
        !            62: {
        !            63:        register int i;
        !            64:        register char *p;        /* pointer into input line */
        !            65:        char *token;             /* pointer to beginning of last token */
        !            66:        struct ins_bkt * opindex;/* index of opcode on current line */
        !            67:        struct oper exp_arg ;    /* argument for exp */
        !            68: 
        !            69:        /* setup stupid local-lable array */
        !            70:        for( i = 0; i < 10; ll_val[i++] = -1 ) ;
        !            71: 
        !            72: one_more_file:
        !            73:        while (iline[LSIZE-2]='\0', fgets(iline,LSIZE,source_file[current_file]) == iline) {
        !            74:              line_no++;
        !            75:              if (line_no == break_line && pass == break_pass) break_here();
        !            76:              /* a cheap way to find if the line was too long */
        !            77:              if (iline[LSIZE-2] != '\0'){ PROG_ERROR(E_LINELONG); continue; }
        !            78:              p = iline;
        !            79: 
        !            80:              /* see what's the first thing on the line. if newline or comment
        !            81:               * char just ignore line all together.  if start of symbol see
        !            82:               * what follows.  otherwise error.
        !            83:               */
        !            84:  restart:      skipb(p);
        !            85:              i = cinfo[*p];    /* see what we know about next char */
        !            86:              /* hack to make # in col 1 a comment -- for cpp leavings */
        !            87:              if (i == EOL || i == IMM) {
        !            88:                  /* further hack to make ; in line act as seperator. */
        !            89:                  if (*p == ';'){ p++; goto restart;}
        !            90:                  continue;
        !            91:              }
        !            92:              if (!(i & (S|D))) { PROG_ERROR(E_BADCHAR); continue; }
        !            93:              bc = 0;
        !            94:              code_length = 0;
        !            95: 
        !            96:              /* what follows is either label or opcode, gobble it up */
        !            97:              token = p;
        !            98:              skips(p);
        !            99:              skipb(p);
        !           100:              i = cinfo[*p];
        !           101: 
        !           102:              /* if next char is ":", this is label definition */
        !           103:              if (i == COL) { p++; slabel(token); goto restart; }
        !           104: 
        !           105:              /* if next char is "=", this is label assignment */
        !           106:              if (i == EQL) {
        !           107:                    p = sassign(++p,token);
        !           108:                    if (cinfo[*p] != EOL) PROG_ERROR(E_BADCHAR);
        !           109:                    goto update;
        !           110:              }
        !           111:  
        !           112:               /* check for cpid following op code */
        !           113:  
        !           114:                 if (i == IND)
        !           115:                         {    
        !           116:                         *p = ' ' ;      /* Blank out the @ sign. */
        !           117:                         p = p + 1 ;     /* Increment pointer past @. */
        !           118:                         p = exp(p, &exp_arg) ; /* Evaluate current cpid.*/
        !           119:                         current_cpid = exp_arg.value_o ;
        !           120:                         skipb(p) ;      /* Skip blanks to next field. */
        !           121:                         }
        !           122:                 else
        !           123:                         current_cpid = implicit_cpid ;
        !           124: 
        !           125: 
        !           126:              /* otherwise this must be opcode, find its index */
        !           127:              if ((opindex = sopcode(token)) == 0) {
        !           128:                PROG_ERROR(E_OPCODE);
        !           129:                continue;
        !           130:              }
        !           131: 
        !           132:              if (i == EOL) { numops = 0; goto doins; }
        !           133: 
        !           134:              /* keep reading operands until we run out of room or hit EOL */
        !           135:              for (numops = 1; numops <= OPERANDS_MAX; numops++) {
        !           136:                    p = soperand(p,&operands[numops-1]);
        !           137:                    if (opshow) printop(&operands[numops-1]);
        !           138:                    skipb(p);
        !           139:                    i = cinfo[*p];
        !           140:                    if (i == COM) { p++; skipb(p); continue; }
        !           141:                    if (i == EOL) goto doins;
        !           142:                    PROG_ERROR(E_OPERAND);
        !           143:                    goto next;
        !           144:              }
        !           145:              PROG_ERROR(E_NUMOPS);
        !           146:   next:              continue;
        !           147: 
        !           148:   doins:      instruction(opindex);
        !           149:   update:     dot += bc;
        !           150:              dot_bkt->value_s = dot;
        !           151:          
        !           152:              /* hack to make ; in line act as seperator. */
        !           153:              if (*p == ';'){ p++; goto restart;}
        !           154:        }
        !           155:        if (pass == 1)
        !           156:                rewind(source_file[current_file]);
        !           157:        if (current_file < file_count-1) {
        !           158:                current_file++;
        !           159:                goto one_more_file;};
        !           160: } /* end Scan */
        !           161: 
        !           162: /* lookup token in opcode hash table, return 0 if not found */
        !           163: struct ins_bkt * 
        !           164: sopcode(token)
        !           165:   register char *token;
        !           166: {
        !           167:   register struct ins_ptr *ipp;
        !           168:   char *mnem = token;
        !           169:   char savechar;
        !           170: 
        !           171:   /* make asciz version of mnemonic */
        !           172:   while (cinfo[*token] & T) token++;
        !           173:   savechar = *token;
        !           174:   *token = '\0';
        !           175: 
        !           176:   /* look through appropriate hash bucket */
        !           177:   ipp = ins_hash_tab[hash(mnem)];
        !           178:   while (ipp) { 
        !           179:        if (strcmp(ipp->name_p,mnem) == 0) break;
        !           180:          ipp = ipp->next_p;
        !           181:        }
        !           182:   *token = savechar;
        !           183: 
        !           184:   if( ipp == 0) return 0;
        !           185:   return(ipp->this_p);
        !           186: } /* end sopcode */
        !           187: 
        !           188: /* handle definition of label */
        !           189: slabel(t)
        !           190:     char * t;
        !           191: {
        !           192:     register char *token = t;
        !           193:     register char *p;
        !           194:     struct sym_bkt *sbp;
        !           195:     char nextc;
        !           196:     static char ltoken[20];
        !           197: 
        !           198:     /* make asciz version of label */
        !           199:     p = token;
        !           200:     while (cinfo[*p] & T) p++;
        !           201:     nextc = *p; /* may be a , a + a \n ... */
        !           202:     *p = '\0';
        !           203: 
        !           204:     /* look for numeric-only labels, as opposed to numeric-$ labels */
        !           205:     if ( (p == token+1) && (cinfo[token[0]]&D)){
        !           206:        sprintf( ltoken, ll_format, token[0], ++ll_val[token[0]-'0'] );
        !           207:        token=ltoken;
        !           208:     }
        !           209: 
        !           210:     /* find/enter symbol in the symbol table */
        !           211:     sbp = lookup(token);
        !           212: 
        !           213:     /* on pass 1 look for multiply defined symbols.  if ok, label
        !           214:        value is dot in current csect
        !           215:     */
        !           216: #ifdef EBUG
        !           217:     if (debflag)
        !           218:        printf("Label %s, line %d offset 0x%X\n", sbp->name_s, line_no, dot );
        !           219: #endif
        !           220:     if (pass==1) { 
        !           221:        if (sbp->attr_s & (S_LABEL|S_REG)) {
        !           222:                prog_error(E_MULTSYM);
        !           223:        }
        !           224:         sbp->attr_s |= S_LABEL | S_DEC | S_DEF;
        !           225:         sbp->csect_s = cur_csect_name;
        !           226:        if (cur_csect_name == C_TEXT)
        !           227:            ntlabels += 1;      /* count text labels */
        !           228:         sbp->value_s = dot;
        !           229:     } 
        !           230:     else if (sbp->csect_s!=cur_csect_name || sbp->value_s!=dot){
        !           231:        prog_error(E_PHASE);
        !           232: #ifdef EBUG
        !           233:        if (debflag)
        !           234:            printf("    was 0x%x, but is 0x%x\n", sbp->value_s, dot);
        !           235: #endif
        !           236:     }
        !           237: 
        !           238:     if (!(cinfo[t[0]] & D)) 
        !           239:        last_symbol = sbp;
        !           240: 
        !           241: /* fprintf(stderr,"slabel(%s) = %ld\n",token,Dot); */
        !           242: 
        !           243:     *p = nextc; /* replace next character before proceeding */
        !           244: } /* end slabel */
        !           245: 
        !           246: /* handle assignment to a label, return updated line pointer */
        !           247: char *
        !           248: sassign(lptr,token)
        !           249:   register char *token;
        !           250:   register char *lptr;
        !           251: {
        !           252:   register char *p;
        !           253:   register struct sym_bkt *sbp;
        !           254:   struct oper value;
        !           255:   char nextc;
        !           256: 
        !           257:   /* make asciz version of label */
        !           258:   p = token;
        !           259:   while (cinfo[*p] & T) p++;
        !           260:   nextc = *p;
        !           261:   *p = '\0';
        !           262: 
        !           263:   /* find/enter symbol in the symbol table, and get its new value */
        !           264:   sbp = lookup(token);
        !           265:   lptr = exp(lptr,&value);
        !           266: 
        !           267:   /* if assignment is to dot, we'll treat it specially */
        !           268:   if (sbp == dot_bkt) {
        !           269:        int deltadot;
        !           270:        static char zed[1024];
        !           271:        if (value.sym_o && value.sym_o->csect_s!=cur_csect_name)
        !           272:            PROG_ERROR(E_OPERAND);
        !           273:        deltadot = value.value_o - dot;
        !           274:        if (deltadot<0)
        !           275:            PROG_ERROR(E_OPERAND);
        !           276: 
        !           277:        operands[0].value_o = deltadot;
        !           278:        skip_op( NULL );
        !           279:   } else {
        !           280:        sbp->value_s = value.value_o;
        !           281:        sbp->csect_s = (value.sym_o!=NULL) ? value.sym_o->csect_s : C_UNDEF;
        !           282:        if (sbp->csect_s  == C_TEXT)
        !           283:            ntlabels += 1;      /* count text labels */
        !           284:        if (sbp->attr_s & S_LABEL) {
        !           285:             PROG_ERROR(E_EQUALS);
        !           286:        } else if (value.type_o == T_REG)
        !           287:            sbp->attr_s = (sbp->attr_s&S_EXT) | S_REG | S_DEC | S_DEF;
        !           288:        else
        !           289:            sbp->attr_s = (sbp->attr_s&S_EXT)  |
        !           290:                ((value.sym_o!=NULL) ?
        !           291:                 (value.sym_o->attr_s & ~(S_LABEL|S_PERM)): (S_DEC | S_DEF));
        !           292:    }
        !           293: 
        !           294:    if (opshow) fprintf(stderr,"sassign(%s) = %ld, %ld\n",
        !           295:        token, value.value_o, sbp->attr_s);
        !           296: 
        !           297:     *p = nextc;
        !           298: 
        !           299:     /* return update line pointer */
        !           300:     skipb(lptr);
        !           301:     return(lptr);
        !           302: } /* end sassign */
        !           303: 
        !           304: /* hashing routine for Symbol and Instruction hash tables */
        !           305: hash(s)
        !           306:        register char *s;
        !           307: {
        !           308:        register int i = 0;
        !           309: 
        !           310:        while (*s) i = i*10 + *s++ - ' ';
        !           311:        i = i % HASH_MAX;
        !           312:        return(i<0 ? i+HASH_MAX : i);
        !           313: } /* end hash */
        !           314: 
        !           315: break_here(){ }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.