|
|
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(){ }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.