Annotation of researchv9/cmd/sun/as/rel.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.