|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)ps.c 1.1 86/02/03 Copyr 1985 Sun Micro";
3: #endif
4:
5: /*
6: * Copyright (c) 1985 by Sun Microsystems, Inc.
7: */
8:
9: #include "as.h"
10: #include <a.out.h>
11:
12: /* a sop here to the cross-assemblers */
13: #define put_words( x, y ) put_text( x, y )
14: #define CSECT_MAX 5 /* number of control sections. */
15: /* Csect descriptor */
16: struct csect {
17: char *name_cs; /* print name */
18: long len_cs; /* Length in machine addresses, */
19: /* i.e., highest address referenced */
20: long dot_cs; /* current dot in this cs, in machine addresses */
21: short id_cs; /* UNIX a.out name for this csect */
22: short which_cs; /* C_name for csect */
23: };
24:
25: struct csect csect[CSECT_MAX] = {
26: ".text", 0,0,N_TEXT,C_TEXT, /* text csect */
27: ".data", 0,0,N_DATA,C_DATA, /* data csect */
28: ".data1",0,0,N_DATA,C_DATA1, /* data csect */
29: ".data2",0,0,N_DATA,C_DATA2, /* data csect */
30: ".bss", 0,0,N_BSS, C_BSS /* uninitialized csect */
31: } ;
32:
33: short cur_csect_name = C_TEXT;
34:
35: int cansdi = (C_TEXT == C_TEXT) ; /* i.e. yes */
36:
37:
38: prog_end()
39: {
40: register int i;
41: register struct csect *p;
42:
43: /* pass 2 */
44: if (pass > 1) /* On the second pass, */
45: { fix_rel(); /* patch up object file */
46: return;
47: }
48:
49: /* pass 1 */
50: current_file= 0;
51: new_csect( C_TEXT ); /* end in text segment */
52: /* export these values to sdi_resolve */
53: if (even_align_flag == 0)
54: {
55: dsize = (csect[C_DATA-1].len_cs + 3) & ~3;
56: d1size = (csect[C_DATA1-1].len_cs + 3) & ~3;
57: d2size = (csect[C_DATA2-1].len_cs + 3) & ~3;
58: bsize = (csect[C_BSS-1].len_cs + 3) & ~3;
59: tsize = (csect[C_TEXT-1].len_cs + 3) & ~3; /* make long aligned */
60: }
61: else
62: {
63: dsize = (csect[C_DATA-1].len_cs + 1) & ~1;
64: d1size = (csect[C_DATA1-1].len_cs + 1) & ~1;
65: d2size = (csect[C_DATA2-1].len_cs + 1) & ~1;
66: bsize = (csect[C_BSS-1].len_cs + 1) & ~1;
67: tsize = (csect[C_TEXT-1].len_cs + 1) & ~1; /* make word aligned */
68: }
69:
70: sdi_resolve(); /* resolve span dependent instructions */
71:
72: csect[C_TEXT-1].len_cs += sdi_inc( csect[C_TEXT-1].len_cs, NULL);
73: /* re-compute values for sym_fix and rel_header */
74: if (even_align_flag == 0)
75: {
76: dsize = (csect[C_DATA-1].len_cs + 3) & ~3;
77: d1size = (csect[C_DATA1-1].len_cs + 3) & ~3;
78: d2size = (csect[C_DATA2-1].len_cs + 3) & ~3;
79: bsize = (csect[C_BSS-1].len_cs + 3) & ~3;
80: tsize = (csect[C_TEXT-1].len_cs + 3) & ~3; /* make long aligned */
81: }
82: else
83: {
84: dsize = (csect[C_DATA-1].len_cs + 1) & ~1;
85: d1size = (csect[C_DATA1-1].len_cs + 1) & ~1;
86: d2size = (csect[C_DATA2-1].len_cs + 1) & ~1;
87: bsize = (csect[C_BSS-1].len_cs + 1) & ~1;
88: tsize = (csect[C_TEXT-1].len_cs + 1) & ~1; /* make word aligned */
89: }
90: sym_fix(); /* relocate and globalize */
91: rel_header(); /* Initialize output stuff */
92: start_pass(); /* Init per-pass variables */
93: return;
94: } /* end prog_end */
95:
96: /* Initialize per-pass variables */
97: start_pass()
98: {
99: register int i;
100:
101: last_symbol = dot_bkt; /* last defined symbol at start of pass */
102: line_no = 0;
103: errors = 0;
104: implicit_cpid = INITIAL_CPID ;
105: pass++;
106: if (pass == 1) {
107: for (i=0; i<CSECT_MAX; i++)
108: csect[i].dot_cs = 0;
109: } else {
110: csect[C_TEXT-1].dot_cs = 0;
111: csect[C_DATA-1].dot_cs = tsize;
112: csect[C_DATA1-1].dot_cs = tsize + dsize;
113: csect[C_DATA2-1].dot_cs = tsize + dsize + d1size;
114: csect[C_BSS-1].dot_cs = tsize + dsize + d1size + d2size;
115: }
116: dot = 0;
117: new_csect( C_TEXT ); /* start in text segment */
118: } /* end Start_pass */
119:
120:
121: /* .even handler */
122: even_op( ip, nops )
123: struct ins_bkt *ip;
124: {
125: int align_val, dot_delta;
126: if (nops == 0 ){
127: /* just plain .even */
128: align_val = 2;
129: } else {
130: /* .align something */
131: if (operands[0].sym_o)
132: PROG_ERROR(E_OPERAND);
133: align_val = operands[0].value_o;
134: }
135: switch( align_val ){
136: case 1: /* no-op */
137: break;
138: case 4:
139: if (cansdi){
140: PROG_ERROR(E_ALIGN);
141: break;
142: }
143: /* FALL THROUGH */
144: case 2:
145: dot_delta = align_val - (dot%align_val);
146: if (dot_delta != 0 && dot_delta != align_val){
147: dot += dot_delta;
148: wcode[0] = 0;
149: wcode[1] = 0;
150: put_text(wcode, dot_delta);
151: }
152: break;
153: default:
154: PROG_ERROR(E_OPERAND);
155: }
156: } /* end Even */
157:
158: byteword( ip )
159: struct ins_bkt *ip;
160: {
161: register int i;
162: register struct oper *p;
163:
164: for (i=0, p=operands; i < numops; i++, p++) {
165: if (p->type_o != T_NORMAL) {
166: p->sym_o = 0;
167: p->type_o = T_NORMAL;
168: p->value_o = 0;
169: PROG_ERROR(E_OPERAND);
170: } else if (p->sym_o)
171: put_rel(p, ip->subop_i, dot+bc,(p->flags_o&O_COMPLEX)!=0);
172:
173: switch (ip->subop_i){
174: case SUBOP_L: *(unsigned *)code = p->value_o;
175: /* if cross-assembling, we die here */
176: put_words(wcode,4);
177: bc += 4;
178: break;
179:
180: case SUBOP_W: wcode[0] = p->value_o;
181: put_words(wcode,2);
182: bc += 2;
183: break;
184:
185: case SUBOP_B: code[0] = p->value_o;
186: put_text(code,1);
187: bc++;
188: break;
189: } /* end switch */
190: } /* end for */
191: } /* end ByteWord */
192:
193: /* handle .ascii and .asciz pseudo ops -- zero<>0 indicates that
194: * user wants zero byte at end of string.
195: */
196: ascii_op( ip )
197: struct ins_bkt *ip;
198: {
199: register char *p;
200: char c;
201: /*
202: * opval_i[0] == 1 => ASCIZ
203: * 0 => ASCII
204: */
205:
206: if (numops!=1 || operands[0].type_o!=T_STRING){
207: PROG_ERROR(E_OPERAND);
208: return;
209: }
210: p = operands[0].stringval_o;
211: while (*p) {
212: bc++;
213: if ((c = *p++) != '\\') {
214: put_text(&c,1);
215: } else switch ( c = *p){
216: case '\\':
217: case '"':
218: put_text(&c, 1);
219: p++;
220: break;
221: default:
222: {
223: register i;
224: /* \octal number. Max of 3 octal digits */
225:
226: for(i=0,c=0;i<3;i++) {
227: if ((*p >= '0') && (*p <= '7')) {
228: c = c * 8 + (*p++) - '0';
229: } else
230: break;
231: }
232: put_text(&c,1);
233: }
234: }
235: }
236: if (ip->opval_i[0]) { put_text(p,1); bc++; }
237: } /* end Ascii */
238:
239: /*
240: * handle .float and .double pseudo-ops. We distinguish by the opcode in
241: * the instruction bucket handed us. We expect >=0 operands of type
242: * T_FLOAT or T_DOUBLE.
243: */
244: float_op( ip )
245: struct ins_bkt *ip;
246: {
247: register int i;
248: register struct oper *p;
249: double d;
250: float f;
251:
252: switch (ip->op_i){
253: case OP_FLOAT:
254: for (i=0, p=operands; i < numops; i++, p++) {
255: switch (p->type_o){
256: default:
257: PROG_ERROR( E_OPERAND );
258: f = 0.0;
259: break;
260: case T_NORMAL:
261: if (p->sym_o )
262: PROG_ERROR( E_CONSTANT );
263: f = (double) p->value_o;
264: break;
265: case T_FLOAT:
266: f = p->fval_o; break;
267: case T_DOUBLE:
268: f = (float) p->dval_o; break;
269: }
270: put_text((char *) &f, sizeof f );
271: bc += sizeof f;
272: }
273: break;
274: case OP_DOUBLE:
275: for (i=0, p=operands; i < numops; i++, p++) {
276: switch (p->type_o){
277: default:
278: PROG_ERROR( E_OPERAND );
279: d = 0.0;
280: break;
281: case T_NORMAL:
282: if (p->sym_o )
283: PROG_ERROR( E_CONSTANT );
284: d = (double) p->value_o;
285: break;
286: case T_FLOAT:
287: d = (double) p->fval_o; break;
288: case T_DOUBLE:
289: d = p->dval_o; break;
290: }
291: put_text((char *) &d, sizeof d );
292: bc += sizeof d;
293: }
294: break;
295: default:
296: sys_error("broken .float\n");
297: }
298: }
299:
300: csect_op( ip )
301: struct ins_bkt *ip;
302: {
303: new_csect( (int)(ip->op_i) - (int)OP_TEXT + C_TEXT );
304: }
305:
306: new_csect( cname )
307: int cname;
308: {
309: register struct sym_bkt *sbp; /* for defining new symbol */
310: register struct csect *csp; /* ptr to current csect */
311: extern struct sym_bkt *last_symbol; /* used for local symbols */
312: extern struct sym_bkt *dot_bkt; /* sym_bkt for location counter */
313:
314: /* update current csect */
315: csp = &csect[ cur_csect_name -1 ];
316: csp->dot_cs = dot;
317: if (dot > csp->len_cs) csp->len_cs = dot;
318: /* now install new one */
319: csp = &csect[cname-1];
320: cur_csect_name = csp->which_cs;
321: dot = csp->dot_cs;
322: dot_bkt->csect_s = cur_csect_name;/* update dot's csect. dot_bkt->value_s */
323: dot_bkt->value_s = dot;
324: /* will be updated in the main loop */
325: sbp = lookup(csp->name_cs);
326: sbp->attr_s |= S_DEC | S_DEF | S_LOCAL | S_PERM;
327: sbp->csect_s = cur_csect_name;
328: cansdi = !Jflag && (cur_csect_name==C_TEXT);
329: sbp->value_s = 0;
330: } /* end New_csect */
331:
332:
333: proc_op( ip )
334: struct ins_bkt *ip;
335: {
336: if (pass == 1) makesdi( NULL, 0, 0 );
337: }
338:
339: globl_op( ip )
340: struct ins_bkt *ip;
341: {
342: register int i;
343: register struct sym_bkt *sbp;
344:
345: if (pass == 1)
346: for (i=0; i<numops; i++) {
347: sbp = operands[i].sym_o;
348: if (sbp == NULL) {
349: PROG_ERROR(E_SYMBOL);
350: } else {
351: sbp->attr_s |= S_DEC | S_EXT; /* declared and external */
352: if (!(sbp->attr_s & S_DEF)){
353: sbp->csect_s = C_UNDEF; /* don't know which */
354: }
355: }
356: }
357: return;
358: } /* end Globl */
359:
360:
361: comm_op( ip )
362: struct ins_bkt *ip;
363: {
364: register struct sym_bkt *sbp;
365:
366: sbp = operands[0].sym_o;
367: if (sbp == NULL) {
368: PROG_ERROR(E_OPERAND);
369: return;
370: }
371: if (ip->op_i == OP_COMM ){
372: /* .comm */
373: if (pass == 1){
374: sbp->csect_s = C_UNDEF; /* make it undefined */
375: sbp->attr_s |= S_DEC | S_EXT | S_COMM;
376: sbp->value_s = operands[1].value_o;
377: }
378: } else {
379: /* .lcomm */
380: /*
381: * switch to bss segment;
382: * bump dot and plant label;
383: * switch back
384: */
385: auto save_csect = cur_csect_name;
386: new_csect( C_BSS );
387: if (pass == 1) {
388: sbp->attr_s |=S_LABEL|S_DEC|S_DEF;
389: sbp->csect_s = C_BSS;
390: sbp->value_s = dot;
391: } else {
392: if (sbp->csect_s != C_BSS || sbp->value_s != dot)
393: prog_error(E_MULTSYM);
394: }
395: dot += operands[1].value_o;
396: new_csect( save_csect );
397: }
398: }
399:
400: skip_op( ip )
401: struct ins_bkt *ip;
402: {
403: register i;
404: static int zed[1024] = {0};
405: bc += i = operands[0].value_o;
406: if (cur_csect_name != C_BSS){
407: while (i>sizeof zed){
408: put_text(zed, sizeof zed);
409: i -= sizeof zed;
410: }
411: if (i) {
412: put_text(zed,i);
413: }
414: }
415: }
416:
417: cpid_op( ip )
418: struct ins_bkt *ip ;
419: {
420: implicit_cpid = operands[0].value_o ;
421: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.