LEFT | RIGHT |
1 /* | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 » Copyright © 2010 Wei guangjing. | 2 // Use of this source code is governed by a BSD-style |
3 » Portions Copyright © 2010 The Go Authors. | 3 // license that can be found in the LICENSE file. |
4 | |
5 Permission is hereby granted, free of charge, to any person obtaining a copy | |
6 of this software and associated documentation files (the "Software"), to deal | |
7 in the Software without restriction, including without limitation the rights | |
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
9 copies of the Software, and to permit persons to whom the Software is | |
10 furnished to do so, subject to the following conditions: | |
11 | |
12 The above copyright notice and this permission notice shall be included in | |
13 all copies or substantial portions of the Software. | |
14 | |
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
21 THE SOFTWARE. | |
22 */ | |
23 | 4 |
24 #include "l.h" | 5 #include "l.h" |
25 #include "lib.h" | 6 #include "lib.h" |
26 #include "../ld/pe.h" | 7 #include "../ld/pe.h" |
27 | 8 |
28 #define IMAGE_SCN_MEM_DISCARDABLE 0x2000000 | 9 #define IMAGE_SCN_MEM_DISCARDABLE 0x2000000 |
29 | 10 |
30 #define IMAGE_SYM_UNDEFINED 0 | 11 #define IMAGE_SYM_UNDEFINED 0 |
31 #define IMAGE_SYM_ABSOLUTE (-1) | 12 #define IMAGE_SYM_ABSOLUTE (-1) |
32 #define IMAGE_SYM_DEBUG (-2) | 13 #define IMAGE_SYM_DEBUG (-2) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 uint16 sectnum; | 83 uint16 sectnum; |
103 uint16 type; | 84 uint16 type; |
104 uint8 sclass; | 85 uint8 sclass; |
105 uint8 aux; | 86 uint8 aux; |
106 Sym* sym; | 87 Sym* sym; |
107 }; | 88 }; |
108 | 89 |
109 struct PeSect { | 90 struct PeSect { |
110 char* name; | 91 char* name; |
111 uchar* base; | 92 uchar* base; |
112 » uint64» size; | 93 » uint64 size; |
113 Sym* sym; | 94 Sym* sym; |
114 IMAGE_SECTION_HEADER sh; | 95 IMAGE_SECTION_HEADER sh; |
115 }; | 96 }; |
116 | 97 |
117 struct PeObj { | 98 struct PeObj { |
118 Biobuf *f; | 99 Biobuf *f; |
119 char *name; | 100 char *name; |
120 uint32 base; | 101 uint32 base; |
121 ········ | 102 ········ |
122 PeSect *sect; | 103 PeSect *sect; |
123 » uint» » nsect; | 104 » uint» nsect; |
124 PeSym *pesym; | 105 PeSym *pesym; |
125 uint npesym; | 106 uint npesym; |
126 ········ | 107 ········ |
127 IMAGE_FILE_HEADER fh; | 108 IMAGE_FILE_HEADER fh; |
128 » uchar* snames; | 109 » char* snames; |
129 }; | 110 }; |
130 | 111 |
131 static int map(PeObj *obj, PeSect *sect); | 112 static int map(PeObj *obj, PeSect *sect); |
132 static int readsym(PeObj *obj, int i, PeSym **sym, char *pn); | 113 static int readsym(PeObj *obj, int i, PeSym **sym); |
133 | 114 |
134 void | 115 void |
135 ldpe(Biobuf *f, char *pkg, int64 len, char *pn) | 116 ldpe(Biobuf *f, char *pkg, int64 len, char *pn) |
136 { | 117 { |
137 char *name; | 118 char *name; |
138 int32 base; | 119 int32 base; |
139 » int i, j, numaux; | 120 » int i, j, l, numaux; |
140 » uint32 l; | |
141 PeObj *obj; | 121 PeObj *obj; |
142 PeSect *sect, *rsect; | 122 PeSect *sect, *rsect; |
143 IMAGE_SECTION_HEADER sh; | 123 IMAGE_SECTION_HEADER sh; |
144 uchar symbuf[18]; | 124 uchar symbuf[18]; |
145 Sym *s; | 125 Sym *s; |
146 Reloc *r, *rp; | 126 Reloc *r, *rp; |
147 PeSym *sym; | 127 PeSym *sym; |
148 ········ | 128 ········ |
149 if(debug['v']) | 129 if(debug['v']) |
150 Bprint(&bso, "%5.2f ldpe %s\n", cputime(), pn); | 130 Bprint(&bso, "%5.2f ldpe %s\n", cputime(), pn); |
151 ········ | 131 ········ |
152 version++; | 132 version++; |
153 base = Boffset(f); | 133 base = Boffset(f); |
154 ········ | 134 ········ |
155 obj = mal(sizeof *obj); | 135 obj = mal(sizeof *obj); |
156 obj->f = f; | 136 obj->f = f; |
157 obj->base = base; | 137 obj->base = base; |
158 obj->name = pn; | 138 obj->name = pn; |
159 // read header | 139 // read header |
160 if(Bread(f, &obj->fh, sizeof obj->fh) != sizeof obj->fh) | 140 if(Bread(f, &obj->fh, sizeof obj->fh) != sizeof obj->fh) |
161 goto bad; | 141 goto bad; |
162 // load section list | 142 // load section list |
163 obj->sect = mal(obj->fh.NumberOfSections*sizeof obj->sect[0]); | 143 obj->sect = mal(obj->fh.NumberOfSections*sizeof obj->sect[0]); |
164 obj->nsect = obj->fh.NumberOfSections; | 144 obj->nsect = obj->fh.NumberOfSections; |
165 for(i=0; i < obj->fh.NumberOfSections; i++) { | 145 for(i=0; i < obj->fh.NumberOfSections; i++) { |
166 if(Bread(f, &obj->sect[i].sh, sizeof sh) != sizeof sh) | 146 if(Bread(f, &obj->sect[i].sh, sizeof sh) != sizeof sh) |
167 goto bad; | 147 goto bad; |
168 obj->sect[i].size = obj->sect[i].sh.SizeOfRawData; | 148 obj->sect[i].size = obj->sect[i].sh.SizeOfRawData; |
169 » » obj->sect[i].name = obj->sect[i].sh.Name; | 149 » » obj->sect[i].name = (char*)obj->sect[i].sh.Name; |
170 » » // TODO riase error if found .cormeta .rsrc | 150 » » // TODO return error if found .cormeta .rsrc |
171 } | 151 } |
172 // load string table | 152 // load string table |
173 Bseek(f, base+obj->fh.PointerToSymbolTable+18*obj->fh.NumberOfSymbols, 0
); | 153 Bseek(f, base+obj->fh.PointerToSymbolTable+18*obj->fh.NumberOfSymbols, 0
); |
174 if(Bread(f, &l, sizeof l) != sizeof l)· | 154 if(Bread(f, &l, sizeof l) != sizeof l)· |
175 goto bad; | 155 goto bad; |
176 obj->snames = mal(l); | 156 obj->snames = mal(l); |
177 Bseek(f, base+obj->fh.PointerToSymbolTable+18*obj->fh.NumberOfSymbols, 0
); | 157 Bseek(f, base+obj->fh.PointerToSymbolTable+18*obj->fh.NumberOfSymbols, 0
); |
178 if(Bread(f, obj->snames, l) != l) | 158 if(Bread(f, obj->snames, l) != l) |
179 goto bad; | 159 goto bad; |
180 // read symbols | 160 // read symbols |
181 obj->pesym = mal(obj->fh.NumberOfSymbols*sizeof obj->pesym[0]); | 161 obj->pesym = mal(obj->fh.NumberOfSymbols*sizeof obj->pesym[0]); |
182 obj->npesym = obj->fh.NumberOfSymbols; | 162 obj->npesym = obj->fh.NumberOfSymbols; |
183 Bseek(f, base+obj->fh.PointerToSymbolTable, 0); | 163 Bseek(f, base+obj->fh.PointerToSymbolTable, 0); |
184 numaux = 0; | |
185 for(i=0; i<obj->fh.NumberOfSymbols; i+=numaux+1) { | 164 for(i=0; i<obj->fh.NumberOfSymbols; i+=numaux+1) { |
186 Bseek(f, base+obj->fh.PointerToSymbolTable+sizeof(symbuf)*i, 0); | 165 Bseek(f, base+obj->fh.PointerToSymbolTable+sizeof(symbuf)*i, 0); |
187 if(Bread(f, symbuf, sizeof symbuf) != sizeof symbuf) | 166 if(Bread(f, symbuf, sizeof symbuf) != sizeof symbuf) |
188 goto bad; | 167 goto bad; |
| 168 ················ |
189 if((symbuf[0] == 0) && (symbuf[1] == 0) && | 169 if((symbuf[0] == 0) && (symbuf[1] == 0) && |
190 (symbuf[2] == 0) && (symbuf[3] == 0)) { | 170 (symbuf[2] == 0) && (symbuf[3] == 0)) { |
191 l = le32(&symbuf[4]); | 171 l = le32(&symbuf[4]); |
192 » » » obj->pesym[i].name = &obj->snames[l]; | 172 » » » obj->pesym[i].name = (char*)&obj->snames[l]; |
193 } else { | 173 } else { |
194 » » » obj->pesym[i].name = strdup(symbuf); | 174 » » » obj->pesym[i].name = strdup((char*)symbuf); |
195 } | 175 } |
196 obj->pesym[i].value = le32(&symbuf[8]); | 176 obj->pesym[i].value = le32(&symbuf[8]); |
197 obj->pesym[i].sectnum = le16(&symbuf[12]); | 177 obj->pesym[i].sectnum = le16(&symbuf[12]); |
198 obj->pesym[i].sclass = symbuf[16]; | 178 obj->pesym[i].sclass = symbuf[16]; |
199 obj->pesym[i].aux = symbuf[17]; | 179 obj->pesym[i].aux = symbuf[17]; |
200 obj->pesym[i].type = le16(&symbuf[14]); | 180 obj->pesym[i].type = le16(&symbuf[14]); |
201 » » numaux = obj->pesym[i].aux; if (numaux < 0) numaux = 0; | 181 » » numaux = obj->pesym[i].aux; |
| 182 » » if (numaux < 0) |
| 183 » » » numaux = 0; |
202 } | 184 } |
203 // create symbols for mapped sections | 185 // create symbols for mapped sections |
204 for(i=0; i<obj->nsect; i++) { | 186 for(i=0; i<obj->nsect; i++) { |
205 sect = &obj->sect[i]; | 187 sect = &obj->sect[i]; |
206 » » if(sect->sh.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) | 188 » » if(sect->sh.Characteristics&IMAGE_SCN_MEM_DISCARDABLE) |
207 continue; | 189 continue; |
208 if(map(obj, sect) < 0) | 190 if(map(obj, sect) < 0) |
209 goto bad; | 191 goto bad; |
210 ················ | 192 ················ |
211 name = smprint("%s(%s)", pn, sect->name); | 193 name = smprint("%s(%s)", pn, sect->name); |
212 s = lookup(name, version); | 194 s = lookup(name, version); |
213 free(name); | 195 free(name); |
214 » » switch(sect->sh.Characteristics&(IMAGE_SCN_CNT_UNINITIALIZED_DAT
A|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SC
N_CNT_CODE|IMAGE_SCN_MEM_EXECUTE)) { | 196 » » switch(sect->sh.Characteristics&(IMAGE_SCN_CNT_UNINITIALIZED_DAT
A|IMAGE_SCN_CNT_INITIALIZED_DATA| |
| 197 » » » IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_COD
E|IMAGE_SCN_MEM_EXECUTE)) { |
215 case IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ:
//.rdata | 198 case IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ:
//.rdata |
216 s->type = SRODATA; | 199 s->type = SRODATA; |
217 break; | 200 break; |
218 case IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_MEM_READ
|IMAGE_SCN_MEM_WRITE: //.bss | 201 case IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_MEM_READ
|IMAGE_SCN_MEM_WRITE: //.bss |
219 case IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ|I
MAGE_SCN_MEM_WRITE: //.data | 202 case IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ|I
MAGE_SCN_MEM_WRITE: //.data |
220 s->type = SDATA; | 203 s->type = SDATA; |
221 break; | 204 break; |
222 » » » case IMAGE_SCN_CNT_CODE |IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN
_MEM_READ: //.text | 205 » » » case IMAGE_SCN_CNT_CODE|IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_
MEM_READ: //.text |
223 s->type = STEXT; | 206 s->type = STEXT; |
224 break; | 207 break; |
225 default: | 208 default: |
226 werrstr("unexpected flags for PE section %s", se
ct->name); | 209 werrstr("unexpected flags for PE section %s", se
ct->name); |
227 goto bad; | 210 goto bad; |
228 } | 211 } |
229 s->p = sect->base; | 212 s->p = sect->base; |
230 s->np = sect->size; | 213 s->np = sect->size; |
231 s->size = sect->size; | 214 s->size = sect->size; |
232 if(s->type == STEXT) { | 215 if(s->type == STEXT) { |
233 if(etextp) | 216 if(etextp) |
234 etextp->next = s; | 217 etextp->next = s; |
235 else | 218 else |
236 textp = s; | 219 textp = s; |
237 etextp = s; | 220 etextp = s; |
238 } | 221 } |
239 sect->sym = s; | 222 sect->sym = s; |
240 } | 223 } |
241 ········ | 224 ········ |
242 // load relocations | 225 // load relocations |
243 for(i=0; i<obj->nsect; i++) { | 226 for(i=0; i<obj->nsect; i++) { |
244 rsect = &obj->sect[i]; | 227 rsect = &obj->sect[i]; |
245 if(rsect->sym == 0 || rsect->sh.NumberOfRelocations == 0) | 228 if(rsect->sym == 0 || rsect->sh.NumberOfRelocations == 0) |
246 » » » » continue; | 229 » » » continue; |
247 if(rsect->sh.Characteristics&IMAGE_SCN_MEM_DISCARDABLE) | 230 if(rsect->sh.Characteristics&IMAGE_SCN_MEM_DISCARDABLE) |
248 continue; | 231 continue; |
249 r = mal(rsect->sh.NumberOfRelocations*sizeof r[0]); | 232 r = mal(rsect->sh.NumberOfRelocations*sizeof r[0]); |
250 Bseek(f, obj->base+rsect->sh.PointerToRelocations, 0); | 233 Bseek(f, obj->base+rsect->sh.PointerToRelocations, 0); |
251 for(j=0; j<rsect->sh.NumberOfRelocations; j++) { | 234 for(j=0; j<rsect->sh.NumberOfRelocations; j++) { |
252 rp = &r[j]; | 235 rp = &r[j]; |
253 if(Bread(f, symbuf, 10) != 10) | 236 if(Bread(f, symbuf, 10) != 10) |
254 goto bad; | 237 goto bad; |
255 ························ | 238 ························ |
256 uint32 rva, symindex; | 239 uint32 rva, symindex; |
257 uint16 type; | 240 uint16 type; |
258 rva = le32(&symbuf[0]); | 241 rva = le32(&symbuf[0]); |
259 symindex = le32(&symbuf[4]); | 242 symindex = le32(&symbuf[4]); |
260 type = le16(&symbuf[8]); | 243 type = le16(&symbuf[8]); |
261 » » » if(readsym(obj, symindex, &sym, pn) < 0) | 244 » » » if(readsym(obj, symindex, &sym) < 0) |
262 goto bad; | 245 goto bad; |
263 if(sym->sym == nil) { | 246 if(sym->sym == nil) { |
264 » » » » werrstr("reloc of invalid sym %s idx=%d type=%d"
, sym->name, sym->sclass, sym->type); | 247 » » » » werrstr("reloc of invalid sym %s idx=%d type=%d"
, sym->name, symindex, sym->type); |
265 goto bad; | 248 goto bad; |
266 } | 249 } |
267 rp->sym = sym->sym; | 250 rp->sym = sym->sym; |
268 rp->siz = 4; | 251 rp->siz = 4; |
269 rp->off = rva; | 252 rp->off = rva; |
270 switch(type) { | 253 switch(type) { |
271 default: | 254 default: |
272 diag("%s: unknown relocation type %d;",
pn, type); | 255 diag("%s: unknown relocation type %d;",
pn, type); |
273 case IMAGE_REL_I386_REL32: | 256 case IMAGE_REL_I386_REL32: |
274 rp->type = D_PCREL; | 257 rp->type = D_PCREL; |
275 rp->add = 0; | 258 rp->add = 0; |
276 break; | 259 break; |
277 case IMAGE_REL_I386_DIR32: | 260 case IMAGE_REL_I386_DIR32: |
278 rp->type = D_ADDR; | 261 rp->type = D_ADDR; |
279 // load addend from image | 262 // load addend from image |
280 rp->add = le32(rsect->base+rp->off); | 263 rp->add = le32(rsect->base+rp->off); |
281 break; | 264 break; |
282 } | 265 } |
283 } | 266 } |
284 qsort(r, rsect->sh.NumberOfRelocations, sizeof r[0], rbyoff); | 267 qsort(r, rsect->sh.NumberOfRelocations, sizeof r[0], rbyoff); |
285 ················ | 268 ················ |
286 s = rsect->sym; | 269 s = rsect->sym; |
287 s->r = r; | 270 s->r = r; |
288 s->nr = rsect->sh.NumberOfRelocations; | 271 s->nr = rsect->sh.NumberOfRelocations; |
289 } | 272 } |
290 ········ | 273 ········ |
291 // enter sub-symbols into symbol table. | 274 // enter sub-symbols into symbol table. |
| 275 // frist 2 entry is file name. |
292 for(i=2; i<obj->npesym; i++) { | 276 for(i=2; i<obj->npesym; i++) { |
293 if(obj->pesym[i].name == 0) | 277 if(obj->pesym[i].name == 0) |
294 continue; | 278 continue; |
295 if(obj->pesym[i].name[0] == '.') //skip section | 279 if(obj->pesym[i].name[0] == '.') //skip section |
296 continue; | 280 continue; |
297 if(obj->pesym[i].sectnum > 0) { | 281 if(obj->pesym[i].sectnum > 0) { |
298 sect = &obj->sect[obj->pesym[i].sectnum-1]; | 282 sect = &obj->sect[obj->pesym[i].sectnum-1]; |
299 if(sect->sym == 0) | 283 if(sect->sym == 0) |
300 continue; | 284 continue; |
301 } | 285 } |
302 » » if(readsym(obj, i, &sym, pn) < 0) | 286 » » if(readsym(obj, i, &sym) < 0) |
303 goto bad; | 287 goto bad; |
304 ········ | 288 ········ |
305 s = sym->sym; | 289 s = sym->sym; |
306 if(sym->sectnum == 0) {// extern | 290 if(sym->sectnum == 0) {// extern |
307 if(s->type == SDYNIMPORT) | 291 if(s->type == SDYNIMPORT) |
308 s->plt = -2; // flag for dynimport in PE object
files. | 292 s->plt = -2; // flag for dynimport in PE object
files. |
309 continue; | 293 continue; |
310 } else if (sym->sectnum > 0) { | 294 } else if (sym->sectnum > 0) { |
311 sect = &obj->sect[sym->sectnum-1]; | 295 sect = &obj->sect[sym->sectnum-1]; |
312 if(sect->sym == 0) | 296 if(sect->sym == 0) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 } | 333 } |
350 | 334 |
351 static int | 335 static int |
352 map(PeObj *obj, PeSect *sect) | 336 map(PeObj *obj, PeSect *sect) |
353 { | 337 { |
354 if(sect->base != nil) | 338 if(sect->base != nil) |
355 return 0; | 339 return 0; |
356 | 340 |
357 sect->base = mal(sect->sh.SizeOfRawData); | 341 sect->base = mal(sect->sh.SizeOfRawData); |
358 werrstr("short read"); | 342 werrstr("short read"); |
359 » if(Bseek(obj->f, obj->base+sect->sh.PointerToRawData, 0) < 0 || Bread(ob
j->f, sect->base, sect->sh.SizeOfRawData) != sect->sh.SizeOfRawData) | 343 » if(Bseek(obj->f, obj->base+sect->sh.PointerToRawData, 0) < 0 || |
| 344 » » » Bread(obj->f, sect->base, sect->sh.SizeOfRawData) != sec
t->sh.SizeOfRawData) |
360 return -1; | 345 return -1; |
361 ········ | 346 ········ |
362 return 0; | 347 return 0; |
363 } | 348 } |
364 | 349 |
365 static int | 350 static int |
366 readsym(PeObj *obj, int i, PeSym **y, char* pn) | 351 readsym(PeObj *obj, int i, PeSym **y) |
367 { | 352 { |
368 Sym *s; | 353 Sym *s; |
369 PeSym *sym; | 354 PeSym *sym; |
370 » char* name; | 355 » char *name, *p; |
371 | 356 |
372 if(i >= obj->npesym || i < 0) { | 357 if(i >= obj->npesym || i < 0) { |
373 werrstr("invalid pe symbol index"); | 358 werrstr("invalid pe symbol index"); |
374 return -1; | 359 return -1; |
375 } | 360 } |
376 | 361 |
377 sym = &obj->pesym[i]; | 362 sym = &obj->pesym[i]; |
378 *y = sym; | 363 *y = sym; |
379 s = nil; | 364 s = nil; |
380 ········ | 365 ········ |
381 » if(sym->sclass == IMAGE_SYM_CLASS_STATIC && sym->value == 0) { // sectio
n | 366 » name = sym->name; |
382 » » » PeSect *sect; | 367 » if(sym->sclass == IMAGE_SYM_CLASS_STATIC && sym->value == 0) // section |
383 » » » sect = &obj->sect[sym->sectnum-1]; | 368 » » name = obj->sect[sym->sectnum-1].sym->name; |
384 » » » name = sect->sym->name; | |
385 » } | |
386 | |
387 if(strncmp(sym->name, "__imp__", 6) == 0) | 369 if(strncmp(sym->name, "__imp__", 6) == 0) |
388 » » » name = &sym->name[7]; // __imp__Name => Name | 370 » » name = &sym->name[7]; // __imp__Name => Name |
389 else if(sym->name[0] == '_')· | 371 else if(sym->name[0] == '_')· |
390 » » » name = &sym->name[1]; // _Name => Name | 372 » » name = &sym->name[1]; // _Name => Name |
| 373 » // remove last @XXX |
| 374 » p = strchr(name, '@'); |
| 375 » if(p) |
| 376 » » *p = 0; |
391 ········ | 377 ········ |
392 switch(sym->type) { | 378 switch(sym->type) { |
393 default: | 379 default: |
394 » » » werrstr("%s: invalid symbol type %d", sym->name, sym->sc
lass); | 380 » » werrstr("%s: invalid symbol type %d", sym->name, sym->type); |
395 » » » return -1; | 381 » » return -1; |
396 case IMAGE_SYM_DTYPE_FUNCTION: | 382 case IMAGE_SYM_DTYPE_FUNCTION: |
397 case IMAGE_SYM_DTYPE_NULL: | 383 case IMAGE_SYM_DTYPE_NULL: |
398 switch(sym->sclass) { | 384 switch(sym->sclass) { |
399 case IMAGE_SYM_CLASS_EXTERNAL: //global | 385 case IMAGE_SYM_CLASS_EXTERNAL: //global |
400 » » » » » s = lookup(name, 0); | 386 » » » s = lookup(name, 0); |
401 » » » » break; | 387 » » » break; |
402 case IMAGE_SYM_CLASS_NULL: | 388 case IMAGE_SYM_CLASS_NULL: |
403 case IMAGE_SYM_CLASS_STATIC: | 389 case IMAGE_SYM_CLASS_STATIC: |
404 » » » » s = lookup(name, version); | 390 » » » s = lookup(name, version); |
405 break; | 391 break; |
406 default: | 392 default: |
407 werrstr("%s: invalid symbol binding %d", sym->name, sym-
>sclass); | 393 werrstr("%s: invalid symbol binding %d", sym->name, sym-
>sclass); |
408 return -1; | 394 return -1; |
409 } | 395 } |
410 break; | 396 break; |
411 » »······· | 397 » } |
412 » } | 398 |
413 if(s != nil && s->type == 0 && !(sym->sclass == IMAGE_SYM_CLASS_STATIC &
& sym->value == 0)) | 399 if(s != nil && s->type == 0 && !(sym->sclass == IMAGE_SYM_CLASS_STATIC &
& sym->value == 0)) |
414 s->type = SXREF; | 400 s->type = SXREF; |
415 sym->sym = s; | 401 sym->sym = s; |
416 | 402 |
417 return 0; | 403 return 0; |
418 } | 404 } |
LEFT | RIGHT |