Annotation of coherent/b/bin/ld386/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: #include "data.h"
                      7: 
                      8: void
                      9: loadmod( mp )
                     10: mod_t *  mp;
                     11: {
                     12:        static  char *name = "";
                     13:        static  FILE *inputf, *inputr, *inputs;
                     14:        int     segn;
                     15: 
                     16:        if (watch) {
                     17:                errCount--;
                     18:                mpmsg(mp, "loading" );  /* NODOC */
                     19:        }
                     20: 
                     21:        if (strcmp(name, mp->fname)) { /* avoid opening lib many times */
                     22:                if (*name) {
                     23:                        fclose(inputf);
                     24:                        fclose(inputr);
                     25:                        fclose(inputs);
                     26:                }
                     27:                name = mp->fname;
                     28: 
                     29:                if (((inputf = fopen(name, "r")) == NULL) ||
                     30:                    ((inputr = fopen(name, "r")) == NULL) ||
                     31:                    ((inputs = fopen(name, "r")) == NULL)) {
                     32:                        filemsg(name, "can't open"); /* NODOC */
                     33:                        exit(1);
                     34:                }
                     35:        }
                     36: 
                     37:        for (segn = 0; segn < S_BSSD; segn++) {
                     38:                char    *t;     /* actual text */
                     39:                seg_t   *isgp, *orsp;
                     40:                unsigned i, len;
                     41:                long    size;
                     42:                FILE    *ofp, *orp;
                     43: 
                     44:                isgp = mp->seg + segn;
                     45: 
                     46:                if (!isgp->size)
                     47:                        continue;
                     48: 
                     49:                len = isgp->size;
                     50:                if (len != isgp->size)
                     51:                        mpfatal(mp, "is corrupt");
                     52: 
                     53:                t = alloc(len + 4);
                     54:                fseek(inputf, isgp->daddr, 0 );
                     55:                if (1 != fread(t, len, 1, inputf))
                     56:                        mpfatal(mp, "Read error in pass2");
                     57: 
                     58:                orsp = oseg + segn;
                     59:                ofp  = outputf[segn];
                     60:                orp  = outputr[segn];
                     61:                size = (long)isgp->size;
                     62: 
                     63:                w_message("relocating seg#%d[%06lx]@%06lx to %06lx @ %ld",
                     64:                        segn,
                     65:                        size,
                     66:                        (long)isgp->vbase,
                     67:                        (long)orsp->vbase,
                     68:                        isgp->nreloc);
                     69: 
                     70:                if (isgp->nreloc)
                     71:                        fseek(inputr, isgp->relptr, 0);
                     72: 
                     73:                for (i = 0; i < isgp->nreloc; i++) {
                     74:                        char *ptr;
                     75:                        char *mtype;
                     76:                        sym_t   *s;
                     77:                        RELOC rel;
                     78:                        long relf, w;
                     79:                        int  commsw;
                     80:                        long    workl;
                     81:                        short   works;
                     82:                        
                     83:                        /* get reloc record */
                     84:                        if (1 != fread(&rel, RELSZ, 1, inputr))
                     85:                                mpfatal(mp, "Read error in pass 2");
                     86: 
                     87: 
                     88:                        w = rel.r_vaddr - isgp->vbase;
                     89:                        if ((w < 0) || (w > len)) {
                     90:                                mpmsg(mp, "relocation out of range %lx", w);
                     91:                                /* A relocation record points outside the
                     92:                                 * range of its segment. */
                     93:                                continue;
                     94:                        }
                     95:                        ptr = t + w;
                     96: 
                     97:                        s = mp->sym[(int)rel.r_symndx];
                     98:                        relf = s->value;
                     99:                        mtype = "rel";
                    100: 
                    101:                        if (reloc) {
                    102:                                RELOC orel;
                    103: 
                    104:                                orel.r_type  = rel.r_type;
                    105:                                orel.r_vaddr = w + orsp->vbase -
                    106:                                        aouth.text_start;
                    107:                                if (s->scnum)
                    108:                                        orel.r_symndx = s->scnum - 1;
                    109:                                else
                    110:                                        orel.r_symndx = s->symno;
                    111:                                if (1 != fwrite(&orel, sizeof(orel), 1, orp))
                    112:                                        fatal("Write error");   /* NODOC */
                    113:                        }
                    114:                                
                    115:                        /*
                    116:                         * This wierdness is to deal with a coff wierdness.
                    117:                         * If dealing with a common the text is incremented
                    118:                         * by the length of the common as seen in that
                    119:                         * module.
                    120:                         */
                    121:                        commsw = (s->scnum <= 0);
                    122:                        if (s->sclass == C_EXT) {
                    123:                                SYMENT sym;
                    124: 
                    125:                                fseek(inputs,
                    126:                                      mp->symptr + (rel.r_symndx * SYMESZ),
                    127:                                      0);
                    128:                                if (1 != fread(&sym, SYMESZ, 1, inputs))
                    129:                                        fatal("Read error");    /* NODOC */
                    130:                                if ((C_EXT == sym.n_sclass) &&
                    131:                                     sym.n_value &&
                    132:                                     !sym.n_scnum) {
                    133:                                        commsw = 1;
                    134:                                        relf -= sym.n_value;
                    135:                                }
                    136:                        }
                    137:                        if (!commsw && (s->mod == mp))
                    138:                                relf -= mp->seg[s->scnum - 1].vbase;
                    139: 
                    140:                        switch (rel.r_type) {
                    141:                        case R_PCRBYTE:
                    142:                                mtype = "pcrel";
                    143:                                relf -= orsp->vbase;
                    144:                        case R_RELBYTE:
                    145:                                w = *ptr;
                    146:                                *ptr = w + relf;
                    147:                                break;
                    148:                        case R_PCRWORD:
                    149:                                mtype = "pcrel";
                    150:                                relf -= orsp->vbase;
                    151:                        case R_RELWORD:
                    152:                        case R_DIR16:
                    153:                                memcpy(&works, ptr, 2);
                    154:                                w = works;
                    155:                                works += relf;
                    156:                                memcpy(ptr, &works, 2);
                    157:                                break;
                    158:                        case R_PCRLONG:
                    159:                                mtype = "pcrel";
                    160:                                relf -= orsp->vbase;
                    161:                        case R_RELLONG:
                    162:                        case R_DIR32:
                    163:                                memcpy(&workl, ptr, 4);
                    164:                                w = workl;
                    165:                                workl += relf;
                    166:                                memcpy(ptr, &workl, 4);
                    167:                                break;
                    168:                        default:
                    169:                                mpmsg(mp,
                    170:                                      "unknown relocation r_type $d", 
                    171:                                      rel.r_type);
                    172:                                /* Unknown type on COFF relocation record. */
                    173:                        }
                    174:                        w_message("%s(%d) %lx = %s(%d, %lx) + %lx",
                    175:                                mtype,
                    176:                                rel.r_type,
                    177:                                relf + w,
                    178:                                s->name,
                    179:                                s->symno,
                    180:                                s->value,
                    181:                                w);
                    182:                }
                    183: 
                    184:                orsp->vbase += size;
                    185:                if (1 != fwrite(t, len, 1, ofp))
                    186:                        fatal("Write error");   /* NODOC */
                    187:                free(t);
                    188:        }
                    189: }

unix.superglobalmegacorp.com

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