Annotation of coherent/d/bin/load/pass2.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * ld/pass2.c
                      3:  * Pass 2
                      4:  * Read, relocate and output segments of module
                      5:  */
                      6: 
                      7: #include "data.h"
                      8: 
                      9: void
                     10: loadmod( mp )
                     11: mod_t *  mp;
                     12: {
                     13:        seg_t   *isgp, *irsp, *osgp, *orsp;
                     14:        sym_t   *sp;
                     15:        int     opcode, relseg;
                     16:        int     segn;
                     17:        uaddr_t addr, bias;
                     18:        unsigned int    symno;
                     19:        FILE    *ifp, *irfp, *ofp, *orfp;
                     20:        static  FILE    *inputf[NLSEG];
                     21:        static  char    *fname = NULL;
                     22: 
                     23:        if ( watch )
                     24:                mpmsg( mp, "loading" );
                     25: 
                     26:        for ( segn = 0; segn < NLSEG; segn++ ) {
                     27: 
                     28:                if ( (segn != L_REL) && (outputf[segn] == NULL) )
                     29:                        continue;
                     30: 
                     31:                if ( fname != mp->fname ) {
                     32: 
                     33:                        if ( fname != NULL )
                     34:                                fclose( inputf[segn] );
                     35: 
                     36:                        if (( inputf[segn] = fopen(mp->fname, "r")) == NULL ) {
                     37:                                filemsg(mp->fname, "can't open (pass 2)");
                     38:                                exit(1);
                     39:                        }
                     40:                }
                     41: 
                     42:                fseek( inputf[segn], mp->seg[segn].daddr, 0 );
                     43: 
                     44:                if ( watch && (mp->seg[segn].size != 0) )
                     45:                        message("relocating seg#%d[%06lo]@%06lo to %06lo",
                     46:                                segn, (long)mp->seg[segn].size,
                     47:                                (long)mp->seg[segn].vbase,
                     48:                                (long)oseg[segn].vbase);
                     49:        }
                     50: 
                     51:        fname = mp->fname;
                     52:        irfp  = inputf[L_REL];
                     53:        irsp  = &mp->seg[L_REL];
                     54:        orfp  = outputf[L_REL];
                     55:        orsp  = &oseg[L_REL];
                     56: 
                     57:        while ( (opcode = getbyte(irfp, irsp)) != EOF ) {
                     58: 
                     59:                addr = getaddr( irfp, irsp );
                     60: 
                     61:                /*
                     62:                 * Find segment in which it address lies
                     63:                 */
                     64:                for (segn=0, isgp=&mp->seg[0]; segn < L_SYM; segn++, isgp++) {
                     65:                        if ( (addr >= isgp->vbase)
                     66:                          && (addr < isgp->vbase+isgp->size) )
                     67:                                break;
                     68:                }
                     69: 
                     70:                if ( (segn == L_BSSI)
                     71:                  || (segn == L_BSSD)
                     72:                  || (segn == L_SYM) ) {
                     73:                        mpmsg( mp, "bad relocation address %06lo", (long)addr);
                     74:                        continue;
                     75:                }
                     76: 
                     77:                ifp  = inputf[segn];
                     78:                ofp  = outputf[segn];
                     79:                osgp = &oseg[segn];
                     80: 
                     81:                /*
                     82:                 * Put unrelocated stuff
                     83:                 */
                     84:                while ( isgp->vbase < addr )
                     85:                        putbyte( getbyte(ifp, isgp), ofp, osgp );
                     86: 
                     87:                bias = 0;
                     88: 
                     89:                switch ( relseg = (opcode & LR_SEG) ) {
                     90: 
                     91:                case L_SYM:
                     92:                        /*
                     93:                         * Symbolic reference:
                     94:                         *      L_SYM[+LR_PCR+LR_WORD],addr-16,symno-16,offset
                     95:                         */
                     96:                        symno = getsymno( irfp, irsp );
                     97: 
                     98:                        if ( symno >= mp->nsym ) {
                     99:                                mpmsg( mp, "bad reloc. sym. no. %d", symno );
                    100:                        }
                    101: 
                    102:                        else if ( (sp = mp->sym[symno]) == NULL ) {
                    103:                                mpmsg( mp, "symbol %d not kept", symno );
                    104:                        }
                    105:                        
                    106:                        /*
                    107:                         * Symbolic reference not resolved.
                    108:                         */
                    109:                        else if ( sp->s.ls_type == (L_GLOBAL|L_REF) ) {
                    110:                                if ( orfp != NULL ) {
                    111:                                        putbyte( opcode, orfp, orsp );
                    112:                                        putaddr( osgp->vbase, orfp, orsp );
                    113:                                        putsymno( sp->symno, orfp, orsp );
                    114:                                }
                    115:                        }
                    116:                        
                    117:                        /*
                    118:                         * Convert symbolic reference to segment reference.
                    119:                         */
                    120:                        else {
                    121:                                bias = sp->s.ls_addr;
                    122: 
                    123:                                if ( orfp != NULL ) {
                    124:                                        putbyte(sp->s.ls_type&LR_SEG
                    125:                                                |opcode&~LR_SEG,
                    126:                                                orfp, orsp);
                    127:                                        putaddr( osgp->vbase, orfp, orsp );
                    128: 
                    129:                                        /*
                    130:                                         * Keep segment size correct
                    131:                                         */
                    132:                                        orsp->size -= sizeof(short);
                    133:                                }
                    134:                        }
                    135:                        break;
                    136: 
                    137:                case L_SHRI:
                    138:                case L_PRVI:
                    139:                case L_BSSI:
                    140:                case L_SHRD:
                    141:                case L_PRVD:
                    142:                case L_BSSD:
                    143:                        bias    = oseg[relseg].vbase
                    144:                                - mp->seg[relseg].vbase;
                    145:                        /* no break */
                    146: 
                    147:                case L_ABS:
                    148:                        if ( orfp != NULL ) {
                    149:                                putbyte( opcode, orfp, orsp );
                    150:                                putaddr( osgp->vbase, orfp, orsp );
                    151:                        }
                    152:                        break;
                    153: 
                    154:                default:
                    155:                        goto BadCode;
                    156:                }
                    157: 
                    158:                if ( opcode & LR_PCR )
                    159:                        bias += isgp->vbase - osgp->vbase;
                    160: 
                    161:                switch ( opcode & LR_OP ) {
                    162: 
                    163:                default:
                    164:                BadCode:
                    165:                        mpmsg( mp, "bad relocation opcode %03o", opcode );
                    166:                        break;
                    167: 
                    168:                case LR_BYTE:
                    169:                        bias += getbyte( ifp, isgp );
                    170:                        putbyte( (char)bias, ofp, osgp );
                    171:                        break;
                    172: 
                    173:                case LR_WORD:
                    174:                        bias += getword( ifp, isgp );
                    175:                        putword( (short)bias, ofp, osgp );
                    176:                        break;
                    177:                }
                    178:        }
                    179: 
                    180:        /*
                    181:         * Copy remainder of segments.
                    182:         */
                    183:        for ( segn = 0; segn < L_SYM; segn++ )
                    184:                if ( (ofp = outputf[segn]) != NULL )
                    185:                        copyseg(inputf[segn], &mp->seg[segn], ofp, &oseg[segn]);
                    186: 
                    187:        /*
                    188:         * Adjust bss bases (others done by copyseg).
                    189:         */
                    190:        oseg[L_BSSD].vbase += mp->seg[L_BSSD].size;
                    191:        oseg[L_BSSI].vbase += mp->seg[L_BSSI].size;
                    192: }
                    193: 
                    194: /*
                    195:  * I/O routines
                    196:  */
                    197: void
                    198: putstruc( p, s, fp, sgp )
                    199: register char  *p;
                    200: register unsigned int  s;
                    201: register FILE  *fp;
                    202: register seg_t *sgp;
                    203: {
                    204:        while ( s-- )
                    205:                putbyte( *p++, fp, sgp );
                    206: }
                    207: 
                    208: unsigned short
                    209: getword( fp, sgp )
                    210: FILE   *fp;
                    211: seg_t  *sgp;
                    212: {
                    213:        return( (worder == LOHI) ? getlohi(fp,sgp) : gethilo(fp,sgp) );
                    214: }
                    215: 
                    216: unsigned short
                    217: getlohi( fp, sgp )
                    218: FILE   *fp;
                    219: seg_t  *sgp;
                    220: {
                    221:        register unsigned char  b;
                    222: 
                    223:        b = getbyte( fp, sgp );
                    224:        return( (getbyte(fp,sgp) << 8) | b );
                    225: }
                    226: 
                    227: unsigned short
                    228: gethilo( fp, sgp )
                    229: FILE   *fp;
                    230: seg_t  *sgp;
                    231: {
                    232:        register unsigned char  b;
                    233: 
                    234:        b = getbyte(fp, sgp);
                    235:        return( (b << 8) | getbyte(fp,sgp) );
                    236: }
                    237: 
                    238: int
                    239: getbyte( fp, sgp )
                    240: FILE   *fp;
                    241: seg_t  *sgp;
                    242: {
                    243:        if ( sgp->size == 0 )
                    244:                return( EOF );
                    245: 
                    246:        else {
                    247:                sgp->size--;
                    248:                sgp->vbase++;
                    249:                return( getc(fp) );
                    250:        }
                    251: }
                    252: 
                    253: void
                    254: putword( w, fp, sgp )
                    255: unsigned short w;
                    256: FILE   *fp;
                    257: seg_t  *sgp;
                    258: {
                    259:        if ( worder == LOHI )
                    260:                putlohi( w, fp, sgp );
                    261: 
                    262:        else
                    263:                puthilo( w, fp, sgp );
                    264: }
                    265: 
                    266: void
                    267: putlohi( w, fp, sgp )
                    268: unsigned short w;
                    269: FILE   *fp;
                    270: seg_t  *sgp;
                    271: {
                    272:        putbyte( w & 0377, fp, sgp );
                    273:        putbyte( w >>8, fp, sgp );
                    274: }
                    275: 
                    276: void
                    277: puthilo( w, fp, sgp )
                    278: unsigned short w;
                    279: FILE   *fp;
                    280: seg_t  *sgp;
                    281: {
                    282:        putbyte( w >> 8, fp, sgp );
                    283:        putbyte( w & 0377, fp, sgp );
                    284: }
                    285: 
                    286: void
                    287: putbyte( b, fp, sgp )
                    288: unsigned char  b;
                    289: FILE   *fp;
                    290: seg_t  *sgp;
                    291: {
                    292:        sgp->vbase++;
                    293:        putc( b, fp );
                    294: }
                    295: 
                    296: /*
                    297:  * Copy a segment.
                    298:  * Watch out for EOF before the expected size.
                    299:  */
                    300: copyseg(ifp, isgp, ofp, osgp) FILE *ifp, *ofp; seg_t *isgp, *osgp;
                    301: {
                    302:        register int b;
                    303:        register fsize_t n;
                    304: 
                    305:        for (n = isgp->size; n > 0; n--) {
                    306:                if ((b = getc(ifp)) == EOF)
                    307:                        break;
                    308:                putc(b, ofp);
                    309:        }
                    310:        while (n-- > 0)
                    311:                putc(0, ofp);
                    312:        n = isgp->size;
                    313:        isgp->vbase += n;
                    314:        osgp->vbase += n;
                    315: }

unix.superglobalmegacorp.com

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