|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)rel.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: struct reloc{ struct relocation_info r; struct sym_bkt *rsymbol; }; ! 13: ! 14: /* Handle output file processing for b.out files */ ! 15: ! 16: FILE *tout; /* text portion of output file */ ! 17: FILE *dout; /* data portion of output file */ ! 18: FILE *d1out; /* data portion of output file */ ! 19: FILE *d2out; /* data portion of output file */ ! 20: FILE *rtout; /* text relocation commands */ ! 21: FILE *rdout; /* data relocation commands */ ! 22: ! 23: long rtsize; /* size of text relocation area */ ! 24: long rdsize; /* size of data relocation area */ ! 25: ! 26: char *rname = "/tmp/as68XXXXXXXX"; /* name of file for relocation commands */ ! 27: ! 28: extern int ext_instruction_set; /* = 1 for the 68020 assembler */ ! 29: ! 30: struct exec filhdr; /* header for a.out files, contains sizes */ ! 31: ! 32: /* Initialize files for output and write out the header */ ! 33: rel_header() ! 34: { ! 35: if ((tout = fopen(rel_name, "w")) == NULL || ! 36: (dout = fopen(rel_name, "a")) == NULL || ! 37: (d1out = fopen(rel_name, "a")) == NULL || ! 38: (d2out = fopen(rel_name, "a")) == NULL) ! 39: sys_error("open on output file %s failed", rel_name); ! 40: ! 41: /* Concat(rname, Source_name, ".tmpr"); */ ! 42: mktemp( rname ); ! 43: if ((rtout = fopen(rname, "w")) == NULL ! 44: || (rdout = fopen(rname, "a")) == NULL) ! 45: sys_error("open on output file %s failed", rname); ! 46: filhdr.a_machtype = (ext_instruction_set ? M_68020 : M_68010); ! 47: filhdr.a_magic = OMAGIC; ! 48: filhdr.a_text = tsize; ! 49: filhdr.a_data = dsize+d1size+d2size; ! 50: filhdr.a_trsize = rtsize; ! 51: filhdr.a_drsize = rdsize; ! 52: filhdr.a_bss = bsize; ! 53: filhdr.a_entry = 0; ! 54: ! 55: fseek(tout, 0L, 0); ! 56: fwrite(&filhdr, sizeof(filhdr), 1, tout); ! 57: ! 58: fseek(tout, (long)(N_TXTOFF(filhdr)), 0); /* seek to start of text */ ! 59: fseek(dout, (long)(N_TXTOFF(filhdr)+tsize), 0); ! 60: fseek(rdout, rtsize, 0); ! 61: fseek(d1out, (long)(N_TXTOFF(filhdr)+tsize+dsize), 0); ! 62: fseek(d2out, (long)(N_TXTOFF(filhdr)+tsize+dsize+d1size), 0); ! 63: rtsize = 0; ! 64: rdsize = 0; ! 65: ! 66: } /* end Rel_Header * / ! 67: ! 68: /* ! 69: * Fix_Rel - Fix up the object file ! 70: * For .b files, we have to ! 71: * 1) append the relocation segments ! 72: * 2) fix up the rtsize and rdsize in the header ! 73: * 3) delete the temporary file for relocation commands ! 74: */ ! 75: fix_rel() ! 76: { ! 77: register FILE *fin, *fout; ! 78: long ortsize; ! 79: long i; ! 80: # define FUDGE( x ) ((x)/sizeof(struct reloc))*sizeof(struct relocation_info) ! 81: ! 82: ortsize = filhdr.a_trsize; ! 83: if (ortsize < rtsize ) sys_error("First pass relocation botch\n"); ! 84: filhdr.a_trsize = FUDGE(rtsize); ! 85: if( rflag ){ ! 86: filhdr.a_trsize += FUDGE(rdsize); ! 87: filhdr.a_drsize = 0; ! 88: filhdr.a_text += filhdr.a_data; ! 89: filhdr.a_data = 0; ! 90: } else ! 91: filhdr.a_drsize = FUDGE(rdsize); ! 92: fclose(rtout); ! 93: fclose(rdout); ! 94: if ((fin = fopen(rname, "r")) == NULL) ! 95: sys_error("cannot reopen relocation file %s", rname); ! 96: ! 97: fout = tout; ! 98: ! 99: /* first write text relocation commands */ ! 100: fseek(fout, (long)(N_TXTOFF(filhdr)+filhdr.a_text+filhdr.a_data), 0); ! 101: redosyms(); ! 102: dorseg(fin,fout,rtsize); ! 103: ! 104: /* seek to start of data segment relocation commands */ ! 105: fseek(fin, ortsize, 0); ! 106: dorseg(fin,fout,rdsize); ! 107: /* Now put the full symbol table out there */ ! 108: filhdr.a_syms = sym_write(fout); ! 109: ! 110: /* Now for the string table */ ! 111: i = str_write(fout); ! 112: /* After the table is written, rewrite the length */ ! 113: fseek(fout,N_STROFF(filhdr),0); ! 114: fwrite(&i,sizeof(long),1,fout); ! 115: ! 116: /* now re-write header */ ! 117: fseek(fout, 0, 0); ! 118: fwrite(&filhdr, sizeof(filhdr), 1, fout); ! 119: fclose(fin); ! 120: unlink(rname); ! 121: # undef FUDGE ! 122: } /* Fix_Rel */ ! 123: ! 124: ! 125: dorseg(fin,fout,size) ! 126: register size; ! 127: FILE *fin,*fout; ! 128: { ! 129: struct reloc new; ! 130: while(size) { ! 131: size -= sizeof(new); ! 132: fread(&new,sizeof(new),1,fin); ! 133: if (new.r.r_extern == 1){ ! 134: new.r.r_symbolnum = new.rsymbol->final; ! 135: } ! 136: fwrite(&new.r ,sizeof(new.r ),1,fout); ! 137: } /* end while */ ! 138: } /* end dorseg */ ! 139: ! 140: /* rel_val - Puts value of operand into next bytes of Code ! 141: * updating Code_length. Put_Rel is called to handle possible relocation. ! 142: * If size=L a longword is stored, otherwise a word is stored ! 143: */ ! 144: rel_val(opnd,size, pcrel) ! 145: register struct oper *opnd; ! 146: subop_t size; ! 147: { ! 148: register int i; ! 149: register struct sym_bkt *sp; ! 150: long val; ! 151: char *ccode; /* char version of this */ ! 152: union /* floating point equivalence */ ! 153: { ! 154: unsigned short words[6] ; ! 155: float f ; ! 156: double d ; ! 157: /* extended x ; bcdrecord p ; */ ! 158: } ! 159: float_equivalence ; ! 160: ! 161: i = code_length>>1; /* get index into WCode */ ! 162: if (sp = opnd->sym_o) ! 163: put_rel(opnd, size, dot + code_length, pcrel); ! 164: val = opnd->value_o; ! 165: /* /* ! 166: /* * if we're doing pc-relative relocation, we must bias this data ! 167: /* * by the negative of its own address. The linker, ld, will add in ! 168: /* * the absolute address, then subtract out this assembly's relocation ! 169: /* * constant, leaving us with the pc-relative value. ! 170: /* */ ! 171: /* if (pcrel) ! 172: /* val -= dot + code_length; ! 173: */ ! 174: switch(size) { ! 175: case SUBOP_D: /* Op code specifies double operand. */ ! 176: switch(opnd->immed_o) ! 177: { ! 178: case T_FLOAT : /* Immediate operand was actually single. */ ! 179: float_equivalence.d = (double) opnd->fval_o ; ! 180: break ; ! 181: case T_DOUBLE : /* Immediate operand was actually double. */ ! 182: float_equivalence.d = (double) opnd->dval_o ; ! 183: break ; ! 184: default: /* Immediate operand was integer. */ ! 185: float_equivalence.d = (double) opnd->value_o ; ! 186: break ; ! 187: } ! 188: wcode[i++] = float_equivalence.words[0] ; ! 189: wcode[i++] = float_equivalence.words[1] ; ! 190: wcode[i++] = float_equivalence.words[2] ; ! 191: wcode[i++] = float_equivalence.words[3] ; ! 192: code_length += 8 ; ! 193: break ; ! 194: ! 195: case SUBOP_S: /* Op code specifies single operand. */ ! 196: switch(opnd->immed_o) ! 197: { ! 198: case T_FLOAT : /* Immediate operand was actually single. */ ! 199: float_equivalence.f = (float) opnd->fval_o ; ! 200: break ; ! 201: case T_DOUBLE : /* Immediate operand was actually double. */ ! 202: float_equivalence.f = (float) opnd->dval_o ; ! 203: break ; ! 204: default: /* Immediate operand was integer. */ ! 205: float_equivalence.f = (float) opnd->value_o ; ! 206: break ; ! 207: } ! 208: wcode[i++] = float_equivalence.words[0] ; ! 209: wcode[i++] = float_equivalence.words[1] ; ! 210: code_length += 4 ; ! 211: break ; ! 212: ! 213: case SUBOP_L: wcode[i++] = val>>16; ! 214: code_length += 2; ! 215: val &= 0xFFFF; ! 216: /* fall through ... */ ! 217: case SUBOP_W: ! 218: default: ! 219: if ((short)val > 32767 || (short)val < -32768) ! 220: PROG_ERROR( E_OFFSET ); ! 221: wcode[i] = val; ! 222: code_length += 2; ! 223: break; ! 224: case SUBOP_B: ! 225: if ((char)val > 255 || (char)val < -256) ! 226: PROG_ERROR( E_OFFSET ); ! 227: ccode = (char *)wcode; ! 228: ccode[code_length++] = val; ! 229: } ! 230: } /* end rel_val */ ! 231: ! 232: /* Version of Put_Text which puts whole words, thus enforcing the mapping ! 233: * of bytes to words. ! 234: */ ! 235: ! 236: #ifdef mc68000 ! 237: put_words(code,nbytes) ! 238: char *code; ! 239: { ! 240: if (nbytes & 1) sys_error("Put_Words given odd nbytes=%d\n",nbytes); ! 241: put_text(code,nbytes); ! 242: } ! 243: #endif ! 244: ! 245: #ifndef mc68000 ! 246: Put_Words(code,nbytes) ! 247: register char *code; ! 248: { register char *cc, ch; ! 249: register int i; ! 250: char tcode[100]; ! 251: ! 252: cc = tcode; ! 253: for (i=0; i<nbytes; i++) tcode[i] = code[i]; ! 254: i = nbytes>>1; ! 255: if (nbytes & 1) Sys_Error("Put_Words given odd nbytes=%d\n",nbytes); ! 256: while (i--) { ch = *cc; *cc = cc[1]; *++cc = ch; cc++; } ! 257: Put_Text(tcode,nbytes); ! 258: } ! 259: #endif ! 260: ! 261: /* Put_Text - Write out text to proper portion of file */ ! 262: ! 263: put_text(code,length) ! 264: register char *code; ! 265: { ! 266: if (pass != 2) return; ! 267: switch(cur_csect_name){ ! 268: case C_TEXT: ! 269: fwrite(code, length, 1, tout); break; ! 270: case C_DATA: ! 271: fwrite(code, length, 1, dout); break; ! 272: case C_DATA1: ! 273: fwrite(code, length, 1, d1out); break; ! 274: case C_DATA2: ! 275: fwrite(code, length, 1, d2out); break; ! 276: } ! 277: /* else ignore bss segment */ ! 278: } /* end Put_Text */ ! 279: ! 280: ! 281: /* set up relocation word for operand: ! 282: * opnd pointer to operand structure ! 283: * size 0 = byte, 1 = word, 2 = long/address ! 284: * offset offset into WCode & WReloc array ! 285: */ ! 286: ! 287: put_rel(opnd, size, offset, pcrel) ! 288: struct oper *opnd; ! 289: subop_t size; ! 290: long offset; ! 291: { ! 292: struct reloc r; ! 293: int tz = (rflag)?0:tsize; ! 294: if (opnd->sym_o == 0) return; /* no relocation */ ! 295: switch( cur_csect_name ){ ! 296: case C_TEXT: ! 297: rtsize += rel_cmd(&r, opnd, size, offset, rtout, pcrel); ! 298: break; ! 299: case C_DATA: ! 300: rdsize += rel_cmd(&r, opnd, size, offset - tz, rdout, pcrel); ! 301: break; ! 302: case C_DATA1: ! 303: rdsize += rel_cmd(&r, opnd, size, offset - tz, rdout, pcrel); ! 304: break; ! 305: case C_DATA2: ! 306: rdsize += rel_cmd(&r, opnd, size, offset - tz, rdout, pcrel); ! 307: break; ! 308: } ! 309: /* else ignore bss segment */ ! 310: } /* end Put_Rel */ ! 311: ! 312: ! 313: /* rel_cmd - Generate a relocation command and output */ ! 314: ! 315: rel_cmd(rp, opnd, size, offset, file, pcrel) ! 316: register struct reloc* rp; ! 317: struct oper *opnd; ! 318: subop_t size; ! 319: long offset; ! 320: FILE *file; ! 321: { ! 322: register struct sym_bkt *sp; /* pointer to symbol */ ! 323: static char zed[ sizeof *rp ] = {0}; ! 324: ! 325: sp = opnd->sym_o; ! 326: if (pass == 2) { ! 327: *rp = *(struct reloc *)zed; /* zero the whole structure */ ! 328: /* rp->r.r_extern = 0; */ ! 329: if (!(sp->attr_s & S_DEF) && (sp->attr_s & S_EXT)) { ! 330: rp->r.r_extern = 1; ! 331: rp->rsymbol = sp; ! 332: } ! 333: else switch( sp->csect_s ){ ! 334: case C_TEXT: ! 335: rp->r.r_symbolnum = N_TEXT; ! 336: break; ! 337: default: ! 338: rp->r.r_symbolnum = (rflag)?N_TEXT:N_DATA; ! 339: break; ! 340: case C_BSS: ! 341: rp->r.r_symbolnum = N_BSS; ! 342: break; ! 343: case C_UNDEF: ! 344: prog_error(E_RELOCATE); ! 345: } ! 346: rp->r.r_address = offset; ! 347: rp->r.r_length = (size==SUBOP_L)?2:(size==SUBOP_B)?0:1; ! 348: rp->r.r_pcrel = pcrel; ! 349: fwrite(rp, sizeof *rp, 1, file); ! 350: } ! 351: return(sizeof *rp); ! 352: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.