|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.