Annotation of coherent/b/bin/ld386/pass2.c, revision 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.