|
|
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.