LEFT | RIGHT |
1 // Inferno utils/8l/asm.c | 1 // Inferno utils/8l/asm.c |
2 // http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c | 2 // http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c |
3 // | 3 // |
4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. | 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. |
5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) |
6 // Portions Copyright © 1997-1999 Vita Nuova Limited | 6 // Portions Copyright © 1997-1999 Vita Nuova Limited |
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com) | 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com) |
8 // Portions Copyright © 2004,2006 Bruce Ellis | 8 // Portions Copyright © 2004,2006 Bruce Ellis |
9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) |
10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 return; | 105 return; |
106 | 106 |
107 case 256 + R_386_PLT32: | 107 case 256 + R_386_PLT32: |
108 r->type = R_PCREL; | 108 r->type = R_PCREL; |
109 r->add += 4; | 109 r->add += 4; |
110 if(targ->type == SDYNIMPORT) { | 110 if(targ->type == SDYNIMPORT) { |
111 addpltsym(ctxt, targ); | 111 addpltsym(ctxt, targ); |
112 r->sym = linklookup(ctxt, ".plt", 0); | 112 r->sym = linklookup(ctxt, ".plt", 0); |
113 r->add += targ->plt; | 113 r->add += targ->plt; |
114 } | 114 } |
115 » » return; | 115 » » return;»» |
116 | 116 » |
117 case 256 + R_386_GOT32: | 117 case 256 + R_386_GOT32: |
118 if(targ->type != SDYNIMPORT) { | 118 if(targ->type != SDYNIMPORT) { |
119 // have symbol | 119 // have symbol |
120 // turn MOVL of GOT entry into LEAL of symbol itself | 120 // turn MOVL of GOT entry into LEAL of symbol itself |
121 if(r->off < 2 || s->p[r->off-2] != 0x8b) { | 121 if(r->off < 2 || s->p[r->off-2] != 0x8b) { |
122 diag("unexpected GOT reloc for non-dynamic symbo
l %s", targ->name); | 122 diag("unexpected GOT reloc for non-dynamic symbo
l %s", targ->name); |
123 return; | 123 return; |
124 } | 124 } |
125 s->p[r->off-2] = 0x8d; | 125 s->p[r->off-2] = 0x8d; |
126 r->type = R_GOTOFF; | 126 r->type = R_GOTOFF; |
127 return; | 127 return; |
128 } | 128 } |
129 addgotsym(ctxt, targ); | 129 addgotsym(ctxt, targ); |
130 r->type = R_CONST; // write r->add during relocsym | 130 r->type = R_CONST; // write r->add during relocsym |
131 r->sym = S; | 131 r->sym = S; |
132 r->add += targ->got; | 132 r->add += targ->got; |
133 return; | 133 return; |
134 | 134 » |
135 case 256 + R_386_GOTOFF: | 135 case 256 + R_386_GOTOFF: |
136 r->type = R_GOTOFF; | 136 r->type = R_GOTOFF; |
137 return; | 137 return; |
138 | 138 » |
139 case 256 + R_386_GOTPC: | 139 case 256 + R_386_GOTPC: |
140 r->type = R_PCREL; | 140 r->type = R_PCREL; |
141 r->sym = linklookup(ctxt, ".got", 0); | 141 r->sym = linklookup(ctxt, ".got", 0); |
142 r->add += 4; | 142 r->add += 4; |
143 return; | 143 return; |
144 | 144 |
145 case 256 + R_386_32: | 145 case 256 + R_386_32: |
146 if(targ->type == SDYNIMPORT) | 146 if(targ->type == SDYNIMPORT) |
147 diag("unexpected R_386_32 relocation for dynamic symbol
%s", targ->name); | 147 diag("unexpected R_386_32 relocation for dynamic symbol
%s", targ->name); |
148 r->type = R_ADDR; | 148 r->type = R_ADDR; |
149 return; | 149 return; |
150 | 150 » |
151 case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 0: | 151 case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 0: |
152 r->type = R_ADDR; | 152 r->type = R_ADDR; |
153 if(targ->type == SDYNIMPORT) | 153 if(targ->type == SDYNIMPORT) |
154 diag("unexpected reloc for dynamic symbol %s", targ->nam
e); | 154 diag("unexpected reloc for dynamic symbol %s", targ->nam
e); |
155 return; | 155 return; |
156 | 156 » |
157 case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 1: | 157 case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 1: |
158 if(targ->type == SDYNIMPORT) { | 158 if(targ->type == SDYNIMPORT) { |
159 addpltsym(ctxt, targ); | 159 addpltsym(ctxt, targ); |
160 r->sym = linklookup(ctxt, ".plt", 0); | 160 r->sym = linklookup(ctxt, ".plt", 0); |
161 r->add = targ->plt; | 161 r->add = targ->plt; |
162 r->type = R_PCREL; | 162 r->type = R_PCREL; |
163 return; | 163 return; |
164 } | 164 } |
165 r->type = R_PCREL; | 165 r->type = R_PCREL; |
166 return; | 166 return; |
167 | 167 » |
168 case 512 + MACHO_FAKE_GOTPCREL: | 168 case 512 + MACHO_FAKE_GOTPCREL: |
169 if(targ->type != SDYNIMPORT) { | 169 if(targ->type != SDYNIMPORT) { |
170 // have symbol | 170 // have symbol |
171 // turn MOVL of GOT entry into LEAL of symbol itself | 171 // turn MOVL of GOT entry into LEAL of symbol itself |
172 if(r->off < 2 || s->p[r->off-2] != 0x8b) { | 172 if(r->off < 2 || s->p[r->off-2] != 0x8b) { |
173 diag("unexpected GOT reloc for non-dynamic symbo
l %s", targ->name); | 173 diag("unexpected GOT reloc for non-dynamic symbo
l %s", targ->name); |
174 return; | 174 return; |
175 } | 175 } |
176 s->p[r->off-2] = 0x8d; | 176 s->p[r->off-2] = 0x8d; |
177 r->type = R_PCREL; | 177 r->type = R_PCREL; |
178 return; | 178 return; |
179 } | 179 } |
180 addgotsym(ctxt, targ); | 180 addgotsym(ctxt, targ); |
181 r->sym = linklookup(ctxt, ".got", 0); | 181 r->sym = linklookup(ctxt, ".got", 0); |
182 r->add += targ->got; | 182 r->add += targ->got; |
183 r->type = R_PCREL; | 183 r->type = R_PCREL; |
184 return; | 184 return; |
185 } | 185 } |
186 | 186 » |
187 // Handle references to ELF symbols from our own object files. | 187 // Handle references to ELF symbols from our own object files. |
188 if(targ->type != SDYNIMPORT) | 188 if(targ->type != SDYNIMPORT) |
189 return; | 189 return; |
190 | 190 |
191 switch(r->type) { | 191 switch(r->type) { |
192 case R_CALL: | 192 case R_CALL: |
193 case R_PCREL: | 193 case R_PCREL: |
194 addpltsym(ctxt, targ); | 194 addpltsym(ctxt, targ); |
195 r->sym = linklookup(ctxt, ".plt", 0); | 195 r->sym = linklookup(ctxt, ".plt", 0); |
196 r->add = targ->plt; | 196 r->add = targ->plt; |
197 return; | 197 return; |
198 | 198 » |
199 case R_ADDR: | 199 case R_ADDR: |
200 if(s->type != SDATA) | 200 if(s->type != SDATA) |
201 break; | 201 break; |
202 if(iself) { | 202 if(iself) { |
203 adddynsym(ctxt, targ); | 203 adddynsym(ctxt, targ); |
204 rel = linklookup(ctxt, ".rel", 0); | 204 rel = linklookup(ctxt, ".rel", 0); |
205 addaddrplus(ctxt, rel, s, r->off); | 205 addaddrplus(ctxt, rel, s, r->off); |
206 adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_386_32)
); | 206 adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_386_32)
); |
207 r->type = R_CONST; // write r->add during relocsym | 207 r->type = R_CONST; // write r->add during relocsym |
208 r->sym = S; | 208 r->sym = S; |
(...skipping 17 matching lines...) Expand all Loading... |
226 s->sub = got->sub; | 226 s->sub = got->sub; |
227 got->sub = s; | 227 got->sub = s; |
228 s->value = got->size; | 228 s->value = got->size; |
229 adduint32(ctxt, got, 0); | 229 adduint32(ctxt, got, 0); |
230 adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), ta
rg->dynid); | 230 adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), ta
rg->dynid); |
231 r->type = 256; // ignore during relocsym | 231 r->type = 256; // ignore during relocsym |
232 return; | 232 return; |
233 } | 233 } |
234 break; | 234 break; |
235 } | 235 } |
236 | 236 » |
237 ctxt->cursym = s; | 237 ctxt->cursym = s; |
238 diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)",
targ->name, r->type, targ->type); | 238 diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)",
targ->name, r->type, targ->type); |
239 } | 239 } |
240 | 240 |
241 int | 241 int |
242 elfreloc1(Reloc *r, vlong sectoff) | 242 elfreloc1(Reloc *r, vlong sectoff) |
243 { | 243 { |
244 int32 elfsym; | 244 int32 elfsym; |
245 | 245 |
246 LPUT(sectoff); | 246 LPUT(sectoff); |
(...skipping 10 matching lines...) Expand all Loading... |
257 return -1; | 257 return -1; |
258 break; | 258 break; |
259 | 259 |
260 case R_CALL: | 260 case R_CALL: |
261 case R_PCREL: | 261 case R_PCREL: |
262 if(r->siz == 4) | 262 if(r->siz == 4) |
263 LPUT(R_386_PC32 | elfsym<<8); | 263 LPUT(R_386_PC32 | elfsym<<8); |
264 else | 264 else |
265 return -1; | 265 return -1; |
266 break; | 266 break; |
267 | 267 » |
268 case R_TLS_LE: | 268 case R_TLS_LE: |
269 case R_TLS_IE: | 269 case R_TLS_IE: |
270 if(r->siz == 4) | 270 if(r->siz == 4) |
271 LPUT(R_386_TLS_LE | elfsym<<8); | 271 LPUT(R_386_TLS_LE | elfsym<<8); |
272 else | 272 else |
273 return -1; | 273 return -1; |
274 } | 274 } |
275 | 275 |
276 return 0; | 276 return 0; |
277 } | 277 } |
278 | 278 |
279 int | 279 int |
280 machoreloc1(Reloc *r, vlong sectoff) | 280 machoreloc1(Reloc *r, vlong sectoff) |
281 { | 281 { |
282 uint32 v; | 282 uint32 v; |
283 LSym *rs; | 283 LSym *rs; |
284 | 284 » |
285 rs = r->xsym; | 285 rs = r->xsym; |
286 | 286 |
287 if(rs->type == SHOSTOBJ) { | 287 if(rs->type == SHOSTOBJ) { |
288 if(rs->dynid < 0) { | 288 if(rs->dynid < 0) { |
289 diag("reloc %d to non-macho symbol %s type=%d", r->type,
rs->name, rs->type); | 289 diag("reloc %d to non-macho symbol %s type=%d", r->type,
rs->name, rs->type); |
290 return -1; | 290 return -1; |
291 } | 291 } |
292 » » v = rs->dynid; | 292 » » v = rs->dynid;» » » |
293 v |= 1<<27; // external relocation | 293 v |= 1<<27; // external relocation |
294 } else { | 294 } else { |
295 v = rs->sect->extnum; | 295 v = rs->sect->extnum; |
296 if(v == 0) { | 296 if(v == 0) { |
297 diag("reloc %d to symbol %s in non-macho section %s type
=%d", r->type, rs->name, rs->sect->name, rs->type); | 297 diag("reloc %d to symbol %s in non-macho section %s type
=%d", r->type, rs->name, rs->sect->name, rs->type); |
298 return -1; | 298 return -1; |
299 } | 299 } |
300 } | 300 } |
301 | 301 |
302 switch(r->type) { | 302 switch(r->type) { |
303 default: | 303 default: |
304 return -1; | 304 return -1; |
305 case R_ADDR: | 305 case R_ADDR: |
306 v |= MACHO_GENERIC_RELOC_VANILLA<<28; | 306 v |= MACHO_GENERIC_RELOC_VANILLA<<28; |
307 break; | 307 break; |
308 case R_CALL: | 308 case R_CALL: |
309 case R_PCREL: | 309 case R_PCREL: |
310 v |= 1<<24; // pc-relative bit | 310 v |= 1<<24; // pc-relative bit |
311 v |= MACHO_GENERIC_RELOC_VANILLA<<28; | 311 v |= MACHO_GENERIC_RELOC_VANILLA<<28; |
312 break; | 312 break; |
313 } | 313 } |
314 | 314 » |
315 switch(r->siz) { | 315 switch(r->siz) { |
316 default: | 316 default: |
317 return -1; | 317 return -1; |
318 case 1: | 318 case 1: |
319 v |= 0<<25; | 319 v |= 0<<25; |
320 break; | 320 break; |
321 case 2: | 321 case 2: |
322 v |= 1<<25; | 322 v |= 1<<25; |
323 break; | 323 break; |
324 case 4: | 324 case 4: |
(...skipping 23 matching lines...) Expand all Loading... |
348 *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got
", 0)); | 348 *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got
", 0)); |
349 return 0; | 349 return 0; |
350 } | 350 } |
351 return -1; | 351 return -1; |
352 } | 352 } |
353 | 353 |
354 void | 354 void |
355 elfsetupplt(void) | 355 elfsetupplt(void) |
356 { | 356 { |
357 LSym *plt, *got; | 357 LSym *plt, *got; |
358 | 358 » |
359 plt = linklookup(ctxt, ".plt", 0); | 359 plt = linklookup(ctxt, ".plt", 0); |
360 got = linklookup(ctxt, ".got.plt", 0); | 360 got = linklookup(ctxt, ".got.plt", 0); |
361 if(plt->size == 0) { | 361 if(plt->size == 0) { |
362 // pushl got+4 | 362 // pushl got+4 |
363 adduint8(ctxt, plt, 0xff); | 363 adduint8(ctxt, plt, 0xff); |
364 adduint8(ctxt, plt, 0x35); | 364 adduint8(ctxt, plt, 0x35); |
365 addaddrplus(ctxt, plt, got, 4); | 365 addaddrplus(ctxt, plt, got, 4); |
366 | 366 » » |
367 // jmp *got+8 | 367 // jmp *got+8 |
368 adduint8(ctxt, plt, 0xff); | 368 adduint8(ctxt, plt, 0xff); |
369 adduint8(ctxt, plt, 0x25); | 369 adduint8(ctxt, plt, 0x25); |
370 addaddrplus(ctxt, plt, got, 8); | 370 addaddrplus(ctxt, plt, got, 8); |
371 | 371 |
372 // zero pad | 372 // zero pad |
373 adduint32(ctxt, plt, 0); | 373 adduint32(ctxt, plt, 0); |
374 | 374 » » |
375 // assume got->size == 0 too | 375 // assume got->size == 0 too |
376 addaddrplus(ctxt, got, linklookup(ctxt, ".dynamic", 0), 0); | 376 addaddrplus(ctxt, got, linklookup(ctxt, ".dynamic", 0), 0); |
377 adduint32(ctxt, got, 0); | 377 adduint32(ctxt, got, 0); |
378 adduint32(ctxt, got, 0); | 378 adduint32(ctxt, got, 0); |
379 } | 379 } |
380 } | 380 } |
381 | 381 |
382 static void | 382 static void |
383 addpltsym(Link *ctxt, LSym *s) | 383 addpltsym(Link *ctxt, LSym *s) |
384 { | 384 { |
385 LSym *plt, *got, *rel; | 385 LSym *plt, *got, *rel; |
386 | 386 » |
387 if(s->plt >= 0) | 387 if(s->plt >= 0) |
388 return; | 388 return; |
389 | 389 |
390 adddynsym(ctxt, s); | 390 adddynsym(ctxt, s); |
391 | 391 » |
392 if(iself) { | 392 if(iself) { |
393 plt = linklookup(ctxt, ".plt", 0); | 393 plt = linklookup(ctxt, ".plt", 0); |
394 got = linklookup(ctxt, ".got.plt", 0); | 394 got = linklookup(ctxt, ".got.plt", 0); |
395 rel = linklookup(ctxt, ".rel.plt", 0); | 395 rel = linklookup(ctxt, ".rel.plt", 0); |
396 if(plt->size == 0) | 396 if(plt->size == 0) |
397 elfsetupplt(); | 397 elfsetupplt(); |
398 | 398 » » |
399 // jmpq *got+size | 399 // jmpq *got+size |
400 adduint8(ctxt, plt, 0xff); | 400 adduint8(ctxt, plt, 0xff); |
401 adduint8(ctxt, plt, 0x25); | 401 adduint8(ctxt, plt, 0x25); |
402 addaddrplus(ctxt, plt, got, got->size); | 402 addaddrplus(ctxt, plt, got, got->size); |
403 | 403 » » |
404 // add to got: pointer to current pos in plt | 404 // add to got: pointer to current pos in plt |
405 addaddrplus(ctxt, got, plt, plt->size); | 405 addaddrplus(ctxt, got, plt, plt->size); |
406 | 406 » » |
407 // pushl $x | 407 // pushl $x |
408 adduint8(ctxt, plt, 0x68); | 408 adduint8(ctxt, plt, 0x68); |
409 adduint32(ctxt, plt, rel->size); | 409 adduint32(ctxt, plt, rel->size); |
410 | 410 » » |
411 // jmp .plt | 411 // jmp .plt |
412 adduint8(ctxt, plt, 0xe9); | 412 adduint8(ctxt, plt, 0xe9); |
413 adduint32(ctxt, plt, -(plt->size+4)); | 413 adduint32(ctxt, plt, -(plt->size+4)); |
414 | 414 » » |
415 // rel | 415 // rel |
416 addaddrplus(ctxt, rel, got, got->size-4); | 416 addaddrplus(ctxt, rel, got, got->size-4); |
417 adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT)); | 417 adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT)); |
418 | 418 » » |
419 s->plt = plt->size - 16; | 419 s->plt = plt->size - 16; |
420 } else if(HEADTYPE == Hdarwin) { | 420 } else if(HEADTYPE == Hdarwin) { |
421 // Same laziness as in 6l. | 421 // Same laziness as in 6l. |
422 | 422 » » |
423 LSym *plt; | 423 LSym *plt; |
424 | 424 |
425 plt = linklookup(ctxt, ".plt", 0); | 425 plt = linklookup(ctxt, ".plt", 0); |
426 | 426 |
427 addgotsym(ctxt, s); | 427 addgotsym(ctxt, s); |
428 | 428 |
429 adduint32(ctxt, linklookup(ctxt, ".linkedit.plt", 0), s->dynid); | 429 adduint32(ctxt, linklookup(ctxt, ".linkedit.plt", 0), s->dynid); |
430 | 430 |
431 // jmpq *got+size(IP) | 431 // jmpq *got+size(IP) |
432 s->plt = plt->size; | 432 s->plt = plt->size; |
433 | 433 |
434 adduint8(ctxt, plt, 0xff); | 434 adduint8(ctxt, plt, 0xff); |
435 adduint8(ctxt, plt, 0x25); | 435 adduint8(ctxt, plt, 0x25); |
436 addaddrplus(ctxt, plt, linklookup(ctxt, ".got", 0), s->got); | 436 addaddrplus(ctxt, plt, linklookup(ctxt, ".got", 0), s->got); |
437 } else { | 437 } else { |
438 diag("addpltsym: unsupported binary format"); | 438 diag("addpltsym: unsupported binary format"); |
439 } | 439 } |
440 } | 440 } |
441 | 441 |
442 static void | 442 static void |
443 addgotsym(Link *ctxt, LSym *s) | 443 addgotsym(Link *ctxt, LSym *s) |
444 { | 444 { |
445 LSym *got, *rel; | 445 LSym *got, *rel; |
446 | 446 » |
447 if(s->got >= 0) | 447 if(s->got >= 0) |
448 return; | 448 return; |
449 | 449 » |
450 adddynsym(ctxt, s); | 450 adddynsym(ctxt, s); |
451 got = linklookup(ctxt, ".got", 0); | 451 got = linklookup(ctxt, ".got", 0); |
452 s->got = got->size; | 452 s->got = got->size; |
453 adduint32(ctxt, got, 0); | 453 adduint32(ctxt, got, 0); |
454 | 454 » |
455 if(iself) { | 455 if(iself) { |
456 rel = linklookup(ctxt, ".rel", 0); | 456 rel = linklookup(ctxt, ".rel", 0); |
457 addaddrplus(ctxt, rel, got, s->got); | 457 addaddrplus(ctxt, rel, got, s->got); |
458 adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_GLOB_DAT)); | 458 adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_GLOB_DAT)); |
459 } else if(HEADTYPE == Hdarwin) { | 459 } else if(HEADTYPE == Hdarwin) { |
460 adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), s->dynid); | 460 adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), s->dynid); |
461 } else { | 461 } else { |
462 diag("addgotsym: unsupported binary format"); | 462 diag("addgotsym: unsupported binary format"); |
463 } | 463 } |
464 } | 464 } |
465 | 465 |
466 void | 466 void |
467 adddynsym(Link *ctxt, LSym *s) | 467 adddynsym(Link *ctxt, LSym *s) |
468 { | 468 { |
469 LSym *d; | 469 LSym *d; |
470 int t; | 470 int t; |
471 char *name; | 471 char *name; |
472 | 472 » |
473 if(s->dynid >= 0) | 473 if(s->dynid >= 0) |
474 return; | 474 return; |
475 | 475 » |
476 if(iself) { | 476 if(iself) { |
477 s->dynid = nelfsym++; | 477 s->dynid = nelfsym++; |
478 | 478 » » |
479 d = linklookup(ctxt, ".dynsym", 0); | 479 d = linklookup(ctxt, ".dynsym", 0); |
480 | 480 |
481 /* name */ | 481 /* name */ |
482 name = s->extname; | 482 name = s->extname; |
483 adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), nam
e)); | 483 adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), nam
e)); |
484 | 484 » » |
485 /* value */ | 485 /* value */ |
486 if(s->type == SDYNIMPORT) | 486 if(s->type == SDYNIMPORT) |
487 adduint32(ctxt, d, 0); | 487 adduint32(ctxt, d, 0); |
488 else | 488 else |
489 addaddr(ctxt, d, s); | 489 addaddr(ctxt, d, s); |
490 | 490 » » |
491 /* size */ | 491 /* size */ |
492 adduint32(ctxt, d, 0); | 492 adduint32(ctxt, d, 0); |
493 | 493 » |
494 /* type */ | 494 /* type */ |
495 t = STB_GLOBAL << 4; | 495 t = STB_GLOBAL << 4; |
496 if(s->cgoexport && (s->type&SMASK) == STEXT) | 496 if(s->cgoexport && (s->type&SMASK) == STEXT) |
497 t |= STT_FUNC; | 497 t |= STT_FUNC; |
498 else | 498 else |
499 t |= STT_OBJECT; | 499 t |= STT_OBJECT; |
500 adduint8(ctxt, d, t); | 500 adduint8(ctxt, d, t); |
501 adduint8(ctxt, d, 0); | 501 adduint8(ctxt, d, 0); |
502 | 502 » |
503 /* shndx */ | 503 /* shndx */ |
504 if(s->type == SDYNIMPORT) | 504 if(s->type == SDYNIMPORT) |
505 adduint16(ctxt, d, SHN_UNDEF); | 505 adduint16(ctxt, d, SHN_UNDEF); |
506 else { | 506 else { |
507 switch(s->type) { | 507 switch(s->type) { |
508 default: | 508 default: |
509 case STEXT: | 509 case STEXT: |
510 t = 11; | 510 t = 11; |
511 break; | 511 break; |
512 case SRODATA: | 512 case SRODATA: |
(...skipping 14 matching lines...) Expand all Loading... |
527 // already taken care of | 527 // already taken care of |
528 } else { | 528 } else { |
529 diag("adddynsym: unsupported binary format"); | 529 diag("adddynsym: unsupported binary format"); |
530 } | 530 } |
531 } | 531 } |
532 | 532 |
533 void | 533 void |
534 adddynlib(char *lib) | 534 adddynlib(char *lib) |
535 { | 535 { |
536 LSym *s; | 536 LSym *s; |
537 | 537 » |
538 if(!needlib(lib)) | 538 if(!needlib(lib)) |
539 return; | 539 return; |
540 | 540 » |
541 if(iself) { | 541 if(iself) { |
542 s = linklookup(ctxt, ".dynstr", 0); | 542 s = linklookup(ctxt, ".dynstr", 0); |
543 if(s->size == 0) | 543 if(s->size == 0) |
544 addstring(s, ""); | 544 addstring(s, ""); |
545 elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addst
ring(s, lib)); | 545 elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addst
ring(s, lib)); |
546 } else if(HEADTYPE == Hdarwin) { | 546 } else if(HEADTYPE == Hdarwin) { |
547 machoadddynlib(lib); | 547 machoadddynlib(lib); |
548 } else if(HEADTYPE != Hwindows) { | 548 } else if(HEADTYPE != Hwindows) { |
549 diag("adddynlib: unsupported binary format"); | 549 diag("adddynlib: unsupported binary format"); |
550 } | 550 } |
(...skipping 15 matching lines...) Expand all Loading... |
566 if(iself) | 566 if(iself) |
567 asmbelfsetup(); | 567 asmbelfsetup(); |
568 | 568 |
569 sect = segtext.sect; | 569 sect = segtext.sect; |
570 cseek(sect->vaddr - segtext.vaddr + segtext.fileoff); | 570 cseek(sect->vaddr - segtext.vaddr + segtext.fileoff); |
571 codeblk(sect->vaddr, sect->len); | 571 codeblk(sect->vaddr, sect->len); |
572 for(sect = sect->next; sect != nil; sect = sect->next) { | 572 for(sect = sect->next; sect != nil; sect = sect->next) { |
573 cseek(sect->vaddr - segtext.vaddr + segtext.fileoff); | 573 cseek(sect->vaddr - segtext.vaddr + segtext.fileoff); |
574 datblk(sect->vaddr, sect->len); | 574 datblk(sect->vaddr, sect->len); |
575 } | 575 } |
576 | 576 » |
577 if(segrodata.filelen > 0) { | 577 if(segrodata.filelen > 0) { |
578 if(debug['v']) | 578 if(debug['v']) |
579 Bprint(&bso, "%5.2f rodatblk\n", cputime()); | 579 Bprint(&bso, "%5.2f rodatblk\n", cputime()); |
580 Bflush(&bso); | 580 Bflush(&bso); |
581 | 581 |
582 cseek(segrodata.fileoff); | 582 cseek(segrodata.fileoff); |
583 datblk(segrodata.vaddr, segrodata.filelen); | 583 datblk(segrodata.vaddr, segrodata.filelen); |
584 } | 584 } |
585 | 585 |
586 if(debug['v']) | 586 if(debug['v']) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 if(iself) { | 639 if(iself) { |
640 if(debug['v']) | 640 if(debug['v']) |
641 Bprint(&bso, "%5.2f elfsym\n", cputime()
); | 641 Bprint(&bso, "%5.2f elfsym\n", cputime()
); |
642 asmelfsym(); | 642 asmelfsym(); |
643 cflush(); | 643 cflush(); |
644 cwrite(elfstrdat, elfstrsize); | 644 cwrite(elfstrdat, elfstrsize); |
645 | 645 |
646 if(debug['v']) | 646 if(debug['v']) |
647 Bprint(&bso, "%5.2f dwarf\n", cputime())
; | 647 Bprint(&bso, "%5.2f dwarf\n", cputime())
; |
648 dwarfemitdebugsections(); | 648 dwarfemitdebugsections(); |
649 | 649 » » » » |
650 if(linkmode == LinkExternal) | 650 if(linkmode == LinkExternal) |
651 elfemitreloc(); | 651 elfemitreloc(); |
652 } | 652 } |
653 break; | 653 break; |
654 case Hplan9: | 654 case Hplan9: |
655 asmplan9sym(); | 655 asmplan9sym(); |
656 cflush(); | 656 cflush(); |
657 | 657 |
658 sym = linklookup(ctxt, "pclntab", 0); | 658 sym = linklookup(ctxt, "pclntab", 0); |
659 if(sym != nil) { | 659 if(sym != nil) { |
660 lcsize = sym->np; | 660 lcsize = sym->np; |
661 for(i=0; i < lcsize; i++) | 661 for(i=0; i < lcsize; i++) |
662 cput(sym->p[i]); | 662 cput(sym->p[i]); |
663 | 663 » » » » |
664 cflush(); | 664 cflush(); |
665 } | 665 } |
666 break; | 666 break; |
667 case Hwindows: | 667 case Hwindows: |
668 if(debug['v']) | 668 if(debug['v']) |
669 Bprint(&bso, "%5.2f dwarf\n", cputime()); | 669 Bprint(&bso, "%5.2f dwarf\n", cputime()); |
670 dwarfemitdebugsections(); | 670 dwarfemitdebugsections(); |
671 break; | 671 break; |
672 case Hdarwin: | 672 case Hdarwin: |
673 if(linkmode == LinkExternal) | 673 if(linkmode == LinkExternal) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 | 728 |
729 if(r <= 0) | 729 if(r <= 0) |
730 return v; | 730 return v; |
731 v += r - 1; | 731 v += r - 1; |
732 c = v % r; | 732 c = v % r; |
733 if(c < 0) | 733 if(c < 0) |
734 c += r; | 734 c += r; |
735 v -= c; | 735 v -= c; |
736 return v; | 736 return v; |
737 } | 737 } |
LEFT | RIGHT |