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