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 10 matching lines...) Expand all Loading... |
21 // all copies or substantial portions of the Software. | 21 // all copies or substantial portions of the Software. |
22 // | 22 // |
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
29 // THE SOFTWARE. | 29 // THE SOFTWARE. |
30 | 30 |
| 31 // Writing object files. |
| 32 |
31 #include "l.h" | 33 #include "l.h" |
32 #include "../ld/lib.h" | 34 #include "../ld/lib.h" |
33 #include "../ld/elf.h" | 35 #include "../ld/elf.h" |
34 #include "../ld/dwarf.h" | 36 #include "../ld/dwarf.h" |
35 #include "../ld/macho.h" | 37 #include "../ld/macho.h" |
36 #include "../ld/pe.h" | 38 #include "../ld/pe.h" |
37 | 39 |
38 #define Dbufslop 100 | 40 #define Dbufslop 100 |
39 | 41 |
40 char linuxdynld[] = "/lib/ld-linux.so.2"; | 42 char linuxdynld[] = "/lib/ld-linux.so.2"; |
41 char freebsddynld[] = "/usr/libexec/ld-elf.so.1"; | 43 char freebsddynld[] = "/usr/libexec/ld-elf.so.1"; |
42 uint32 symdatva = SYMDATVA; | 44 uint32 symdatva = SYMDATVA; |
43 | 45 |
44 int32 | 46 int32 |
45 entryvalue(void) | 47 entryvalue(void) |
46 { | 48 { |
47 char *a; | 49 char *a; |
48 Sym *s; | 50 Sym *s; |
49 | 51 |
50 a = INITENTRY; | 52 a = INITENTRY; |
51 if(*a >= '0' && *a <= '9') | 53 if(*a >= '0' && *a <= '9') |
52 return atolwhex(a); | 54 return atolwhex(a); |
53 s = lookup(a, 0); | 55 s = lookup(a, 0); |
54 if(s->type == 0) | 56 if(s->type == 0) |
55 return INITTEXT; | 57 return INITTEXT; |
56 » switch(s->type) { | 58 » if(s->type != STEXT) |
57 » case STEXT: | |
58 » » break; | |
59 » case SDATA: | |
60 » » if(dlm) | |
61 » » » return s->value+INITDAT; | |
62 » default: | |
63 diag("entry not text: %s", s->name); | 59 diag("entry not text: %s", s->name); |
64 } | |
65 return s->value; | 60 return s->value; |
66 } | 61 } |
67 | 62 |
68 void | 63 void |
69 wputl(ushort w) | 64 wputl(ushort w) |
70 { | 65 { |
71 cput(w); | 66 cput(w); |
72 cput(w>>8); | 67 cput(w>>8); |
73 } | 68 } |
74 | 69 |
(...skipping 22 matching lines...) Expand all Loading... |
97 cput(l>>24); | 92 cput(l>>24); |
98 } | 93 } |
99 | 94 |
100 void | 95 void |
101 vputl(uvlong l) | 96 vputl(uvlong l) |
102 { | 97 { |
103 lputl(l >> 32); | 98 lputl(l >> 32); |
104 lputl(l); | 99 lputl(l); |
105 } | 100 } |
106 | 101 |
107 void | |
108 strnput(char *s, int n) | |
109 { | |
110 for(; *s && n > 0; s++) { | |
111 cput(*s); | |
112 n--; | |
113 } | |
114 while(n > 0) { | |
115 cput(0); | |
116 n--; | |
117 } | |
118 } | |
119 | |
120 vlong | |
121 addstring(Sym *s, char *str) | |
122 { | |
123 int n, m; | |
124 vlong r; | |
125 Prog *p; | |
126 | |
127 if(s->type == 0) | |
128 s->type = SDATA; | |
129 s->reachable = 1; | |
130 r = s->size; | |
131 n = strlen(str)+1; | |
132 if(strcmp(s->name, ".shstrtab") == 0) | |
133 elfsetstring(str, r); | |
134 while(n > 0) { | |
135 m = n; | |
136 if(m > sizeof(p->to.scon)) | |
137 m = sizeof(p->to.scon); | |
138 p = newdata(s, s->size, m, D_EXTERN); | |
139 p->to.type = D_SCONST; | |
140 memmove(p->to.scon, str, m); | |
141 s->size += m; | |
142 str += m; | |
143 n -= m; | |
144 } | |
145 return r; | |
146 } | |
147 | |
148 vlong | |
149 adduintxx(Sym *s, uint64 v, int wid) | |
150 { | |
151 vlong r; | |
152 Prog *p; | |
153 | |
154 if(s->type == 0) | |
155 s->type = SDATA; | |
156 s->reachable = 1; | |
157 r = s->size; | |
158 p = newdata(s, s->size, wid, D_EXTERN); | |
159 s->size += wid; | |
160 p->to.type = D_CONST; | |
161 p->to.offset = v; | |
162 return r; | |
163 } | |
164 | |
165 vlong | |
166 adduint8(Sym *s, uint8 v) | |
167 { | |
168 return adduintxx(s, v, 1); | |
169 } | |
170 | |
171 vlong | |
172 adduint16(Sym *s, uint16 v) | |
173 { | |
174 return adduintxx(s, v, 2); | |
175 } | |
176 | |
177 vlong | |
178 adduint32(Sym *s, uint32 v) | |
179 { | |
180 return adduintxx(s, v, 4); | |
181 } | |
182 | |
183 vlong | |
184 adduint64(Sym *s, uint64 v) | |
185 { | |
186 return adduintxx(s, v, 8); | |
187 } | |
188 | |
189 vlong | |
190 addaddr(Sym *s, Sym *t) | |
191 { | |
192 vlong r; | |
193 Prog *p; | |
194 enum { Ptrsize = 4 }; | |
195 | |
196 if(s->type == 0) | |
197 s->type = SDATA; | |
198 s->reachable = 1; | |
199 r = s->size; | |
200 p = newdata(s, s->size, Ptrsize, D_EXTERN); | |
201 s->size += Ptrsize; | |
202 p->to.type = D_ADDR; | |
203 p->to.index = D_EXTERN; | |
204 p->to.offset = 0; | |
205 p->to.sym = t; | |
206 return r; | |
207 } | |
208 | |
209 vlong | |
210 addsize(Sym *s, Sym *t) | |
211 { | |
212 vlong r; | |
213 Prog *p; | |
214 enum { Ptrsize = 4 }; | |
215 | |
216 if(s->type == 0) | |
217 s->type = SDATA; | |
218 s->reachable = 1; | |
219 r = s->size; | |
220 p = newdata(s, s->size, Ptrsize, D_EXTERN); | |
221 s->size += Ptrsize; | |
222 p->to.type = D_SIZE; | |
223 p->to.index = D_EXTERN; | |
224 p->to.offset = 0; | |
225 p->to.sym = t; | |
226 return r; | |
227 } | |
228 | |
229 vlong | 102 vlong |
230 datoff(vlong addr) | 103 datoff(vlong addr) |
231 { | 104 { |
232 if(addr >= segdata.vaddr) | 105 if(addr >= segdata.vaddr) |
233 return addr - segdata.vaddr + segdata.fileoff; | 106 return addr - segdata.vaddr + segdata.fileoff; |
| 107 if(addr >= segtext.vaddr) |
| 108 return addr - segtext.vaddr + segtext.fileoff; |
234 diag("datoff %#llx", addr); | 109 diag("datoff %#llx", addr); |
235 return 0; | 110 return 0; |
236 } | 111 } |
237 | 112 |
238 enum { | 113 enum { |
239 ElfStrEmpty, | 114 ElfStrEmpty, |
240 ElfStrInterp, | 115 ElfStrInterp, |
241 ElfStrHash, | 116 ElfStrHash, |
242 ElfStrGot, | 117 ElfStrGot, |
243 ElfStrGotPlt, | 118 ElfStrGotPlt, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 doelf(void) | 152 doelf(void) |
278 { | 153 { |
279 Sym *s, *shstrtab, *dynamic, *dynstr, *d; | 154 Sym *s, *shstrtab, *dynamic, *dynstr, *d; |
280 int h, nsym, t; | 155 int h, nsym, t; |
281 | 156 |
282 if(!iself) | 157 if(!iself) |
283 return; | 158 return; |
284 | 159 |
285 /* predefine strings we need for section headers */ | 160 /* predefine strings we need for section headers */ |
286 shstrtab = lookup(".shstrtab", 0); | 161 shstrtab = lookup(".shstrtab", 0); |
| 162 shstrtab->type = SELFDATA; |
287 shstrtab->reachable = 1; | 163 shstrtab->reachable = 1; |
| 164 |
288 elfstr[ElfStrEmpty] = addstring(shstrtab, ""); | 165 elfstr[ElfStrEmpty] = addstring(shstrtab, ""); |
289 elfstr[ElfStrText] = addstring(shstrtab, ".text"); | 166 elfstr[ElfStrText] = addstring(shstrtab, ".text"); |
290 elfstr[ElfStrData] = addstring(shstrtab, ".data"); | 167 elfstr[ElfStrData] = addstring(shstrtab, ".data"); |
291 elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); | 168 elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); |
292 addstring(shstrtab, ".elfdata"); | 169 addstring(shstrtab, ".elfdata"); |
293 if(HEADTYPE == 8) | 170 if(HEADTYPE == 8) |
294 addstring(shstrtab, ".closure"); | 171 addstring(shstrtab, ".closure"); |
295 addstring(shstrtab, ".rodata"); | 172 addstring(shstrtab, ".rodata"); |
296 if(!debug['s']) { | 173 if(!debug['s']) { |
297 elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts"); | 174 elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts"); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 s = lookup(".dynamic", 0); | 225 s = lookup(".dynamic", 0); |
349 s->reachable = 1; | 226 s->reachable = 1; |
350 s->type = SELFDATA; | 227 s->type = SELFDATA; |
351 dynamic = s; | 228 dynamic = s; |
352 | 229 |
353 /* | 230 /* |
354 * relocation entries for dynimport symbols | 231 * relocation entries for dynimport symbols |
355 */ | 232 */ |
356 nsym = 1; // sym 0 is reserved | 233 nsym = 1; // sym 0 is reserved |
357 for(h=0; h<NHASH; h++) { | 234 for(h=0; h<NHASH; h++) { |
358 » » » for(s=hash[h]; s!=S; s=s->link) { | 235 » » » for(s=hash[h]; s!=S; s=s->hash) { |
359 if(!s->reachable || (s->type != STEXT && s->type
!= SDATA && s->type != SBSS) || s->dynimpname == nil) | 236 if(!s->reachable || (s->type != STEXT && s->type
!= SDATA && s->type != SBSS) || s->dynimpname == nil) |
360 continue; | 237 continue; |
361 | 238 |
362 if(!s->dynexport) { | 239 if(!s->dynexport) { |
363 d = lookup(".rel", 0); | 240 d = lookup(".rel", 0); |
364 addaddr(d, s); | 241 addaddr(d, s); |
365 adduint32(d, ELF32_R_INFO(nsym, R_386_32
)); | 242 adduint32(d, ELF32_R_INFO(nsym, R_386_32
)); |
366 } | 243 } |
367 | 244 |
368 nsym++; | 245 nsym++; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 ph->paddr = ph->vaddr; | 325 ph->paddr = ph->vaddr; |
449 ph->off = sh->off; | 326 ph->off = sh->off; |
450 ph->filesz = sh->size; | 327 ph->filesz = sh->size; |
451 ph->memsz = sh->size; | 328 ph->memsz = sh->size; |
452 ph->align = sh->addralign; | 329 ph->align = sh->addralign; |
453 } | 330 } |
454 | 331 |
455 void | 332 void |
456 asmb(void) | 333 asmb(void) |
457 { | 334 { |
458 Prog *p; | |
459 int32 v, magic; | 335 int32 v, magic; |
460 int a, dynsym; | 336 int a, dynsym; |
461 » uint32 va, fo, w, symo, startva, machlink, erodata; | 337 » uint32 va, fo, w, symo, startva, machlink; |
462 » uchar *op1; | |
463 ulong expectpc; | 338 ulong expectpc; |
464 ElfEhdr *eh; | 339 ElfEhdr *eh; |
465 ElfPhdr *ph, *pph; | 340 ElfPhdr *ph, *pph; |
466 ElfShdr *sh; | 341 ElfShdr *sh; |
467 Section *sect; | 342 Section *sect; |
468 | 343 |
469 if(debug['v']) | 344 if(debug['v']) |
470 Bprint(&bso, "%5.2f asmb\n", cputime()); | 345 Bprint(&bso, "%5.2f asmb\n", cputime()); |
471 Bflush(&bso); | 346 Bflush(&bso); |
472 | 347 |
473 seek(cout, HEADR, 0); | 348 seek(cout, HEADR, 0); |
474 pc = INITTEXT; | 349 pc = INITTEXT; |
475 » curp = firstp; | 350 » codeblk(pc, segtext.sect->len); |
476 » for(p = firstp; p != P; p = p->link) { | 351 » pc += segtext.sect->len; |
477 » » if(p->as == ATEXT) | 352 |
478 » » » curtext = p; | |
479 » » curp = p; | |
480 » » if(HEADTYPE == 8) { | |
481 » » » // native client | |
482 » » » expectpc = p->pc; | |
483 » » » p->pc = pc; | |
484 » » » asmins(p); | |
485 » » » if(p->pc != expectpc) { | |
486 » » » » Bflush(&bso); | |
487 » » » » diag("phase error %lux sb %lux in %s", p->pc, ex
pectpc, TNAME); | |
488 » » » } | |
489 » » » while(pc < p->pc) { | |
490 » » » » cput(0x90);» // nop | |
491 » » » » pc++; | |
492 » » » } | |
493 » » } | |
494 » » if(p->pc != pc) { | |
495 » » » Bflush(&bso); | |
496 » » » if(!debug['a']) | |
497 » » » » print("%P\n", curp); | |
498 » » » diag("phase error %lux sb %lux in %s", p->pc, pc, TNAME)
; | |
499 » » » pc = p->pc; | |
500 » » } | |
501 » » if(HEADTYPE != 8) { | |
502 » » » asmins(p); | |
503 » » » if(pc != p->pc) { | |
504 » » » » Bflush(&bso); | |
505 » » » » diag("asmins changed pc %lux sb %lux in %s", p->
pc, pc, TNAME); | |
506 » » » } | |
507 » » } | |
508 » » if(cbc < sizeof(and)) | |
509 » » » cflush(); | |
510 » » a = (andptr - and); | |
511 | |
512 » » if(debug['a']) { | |
513 » » » Bprint(&bso, pcstr, pc); | |
514 » » » for(op1 = and; op1 < andptr; op1++) | |
515 » » » » Bprint(&bso, "%.2ux", *op1 & 0xff); | |
516 » » » Bprint(&bso, "\t%P\n", curp); | |
517 » » } | |
518 » » if(dlm) { | |
519 » » » if(p->as == ATEXT) | |
520 » » » » reloca = nil; | |
521 » » » else if(reloca != nil) | |
522 » » » » diag("reloc failure: %P", curp); | |
523 » » } | |
524 » » memmove(cbp, and, a); | |
525 » » cbp += a; | |
526 » » pc += a; | |
527 » » cbc -= a; | |
528 » } | |
529 if(HEADTYPE == 8) { | 353 if(HEADTYPE == 8) { |
530 int32 etext; | 354 int32 etext; |
531 ················ | 355 ················ |
532 etext = rnd(segtext.vaddr + segtext.filelen, 4096); | 356 etext = rnd(segtext.vaddr + segtext.filelen, 4096); |
533 while(pc < etext) { | 357 while(pc < etext) { |
534 cput(0xf4); // hlt | 358 cput(0xf4); // hlt |
535 pc++; | 359 pc++; |
536 } | 360 } |
537 pc = segrodata.vaddr; | 361 pc = segrodata.vaddr; |
| 362 cflush(); |
538 } | 363 } |
539 cflush(); | |
540 | 364 |
541 /* output read-only data in text segment */ | 365 /* output read-only data in text segment */ |
542 » if(HEADTYPE == 8) { | 366 » sect = segtext.sect->next; |
543 » » // Native Client | 367 » datblk(pc, sect->vaddr + sect->len - pc); |
544 » » sect = segrodata.sect; | |
545 » » segrodata.fileoff = seek(cout, 0, 1); | |
546 » } else | |
547 » » sect = segtext.sect->next; | |
548 | |
549 » erodata = sect->vaddr + sect->len; | |
550 » for(v = pc; v < erodata; v += sizeof(buf)-Dbufslop) { | |
551 » » if(erodata-v > sizeof(buf)-Dbufslop) | |
552 » » » datblk(v, sizeof(buf)-Dbufslop, 1); | |
553 » » else | |
554 » » » datblk(v, erodata-v, 1); | |
555 » } | |
556 | 368 |
557 switch(HEADTYPE) { | 369 switch(HEADTYPE) { |
558 default: | 370 default: |
559 if(iself) | 371 if(iself) |
560 goto Elfseek; | 372 goto Elfseek; |
561 diag("unknown header type %d", HEADTYPE); | 373 diag("unknown header type %d", HEADTYPE); |
562 case 0: | 374 case 0: |
563 seek(cout, rnd(HEADR+textsize, 8192), 0); | 375 seek(cout, rnd(HEADR+textsize, 8192), 0); |
564 break; | 376 break; |
565 case 1: | 377 case 1: |
(...skipping 29 matching lines...) Expand all Loading... |
595 case 10: | 407 case 10: |
596 v = rnd(segtext.fileoff+segtext.filelen, INITRND); | 408 v = rnd(segtext.fileoff+segtext.filelen, INITRND); |
597 seek(cout, v, 0); | 409 seek(cout, v, 0); |
598 break; | 410 break; |
599 } | 411 } |
600 | 412 |
601 if(debug['v']) | 413 if(debug['v']) |
602 Bprint(&bso, "%5.2f datblk\n", cputime()); | 414 Bprint(&bso, "%5.2f datblk\n", cputime()); |
603 Bflush(&bso); | 415 Bflush(&bso); |
604 | 416 |
605 if(dlm){ | |
606 char buf[8]; | |
607 | |
608 ewrite(cout, buf, INITDAT-textsize); | |
609 textsize = INITDAT; | |
610 } | |
611 | |
612 segdata.fileoff = seek(cout, 0, 1); | 417 segdata.fileoff = seek(cout, 0, 1); |
613 » for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) { | 418 » datblk(INITDAT, segdata.filelen); |
614 » » if(datsize-v > sizeof(buf)-Dbufslop) | |
615 » » » datblk(v, sizeof(buf)-Dbufslop, 0); | |
616 » » else | |
617 » » » datblk(v, datsize-v, 0); | |
618 » } | |
619 | 419 |
620 machlink = 0; | 420 machlink = 0; |
621 if(HEADTYPE == 6) | 421 if(HEADTYPE == 6) |
622 machlink = domacholink(); | 422 machlink = domacholink(); |
623 | 423 |
624 symsize = 0; | 424 symsize = 0; |
625 spsize = 0; | 425 spsize = 0; |
626 lcsize = 0; | 426 lcsize = 0; |
627 symo = 0; | 427 symo = 0; |
628 if(!debug['s']) { | 428 if(!debug['s']) { |
629 if(debug['v']) | 429 if(debug['v']) |
630 Bprint(&bso, "%5.2f sym\n", cputime()); | 430 Bprint(&bso, "%5.2f sym\n", cputime()); |
631 Bflush(&bso); | 431 Bflush(&bso); |
632 switch(HEADTYPE) { | 432 switch(HEADTYPE) { |
633 default: | 433 default: |
634 if(iself) | 434 if(iself) |
635 goto Elfsym; | 435 goto Elfsym; |
636 case 0: | 436 case 0: |
637 » » » seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0); | 437 » » » seek(cout, rnd(HEADR+textsize, 8192)+segdata.filelen, 0)
; |
638 break; | 438 break; |
639 case 1: | 439 case 1: |
640 » » » seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); | 440 » » » seek(cout, rnd(HEADR+textsize, INITRND)+segdata.filelen,
0); |
641 break; | 441 break; |
642 case 2: | 442 case 2: |
643 » » » seek(cout, HEADR+textsize+datsize, 0); | 443 » » » seek(cout, HEADR+textsize+segdata.filelen, 0); |
644 » » » symo = HEADR+textsize+datsize; | 444 » » » symo = HEADR+textsize+segdata.filelen; |
645 break; | 445 break; |
646 case 3: | 446 case 3: |
647 case 4: | 447 case 4: |
648 debug['s'] = 1; | 448 debug['s'] = 1; |
649 » » » symo = HEADR+textsize+datsize; | 449 » » » symo = HEADR+textsize+segdata.filelen; |
650 break; | 450 break; |
651 case 6: | 451 case 6: |
652 » » » symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND
)+machlink; | 452 » » » symo = rnd(HEADR+textsize, INITRND)+rnd(segdata.filelen,
INITRND)+machlink; |
653 break; | 453 break; |
654 Elfsym: | 454 Elfsym: |
655 case 10: | 455 case 10: |
656 » » » symo = rnd(HEADR+textsize, INITRND)+datsize; | 456 » » » symo = rnd(HEADR+textsize, INITRND)+segdata.filelen; |
657 symo = rnd(symo, INITRND); | 457 symo = rnd(symo, INITRND); |
658 break; | 458 break; |
659 } | 459 } |
660 seek(cout, symo+8, 0); | 460 seek(cout, symo+8, 0); |
661 if(!debug['s']) | 461 if(!debug['s']) |
662 asmsym(); | 462 asmsym(); |
663 if(debug['v']) | 463 if(debug['v']) |
664 Bprint(&bso, "%5.2f sp\n", cputime()); | 464 Bprint(&bso, "%5.2f sp\n", cputime()); |
665 Bflush(&bso); | 465 Bflush(&bso); |
666 if(debug['v']) | 466 if(debug['v']) |
667 Bprint(&bso, "%5.2f pc\n", cputime()); | 467 Bprint(&bso, "%5.2f pc\n", cputime()); |
668 Bflush(&bso); | 468 Bflush(&bso); |
669 if(!debug['s']) | 469 if(!debug['s']) |
670 asmlc(); | 470 asmlc(); |
671 if(dlm) | |
672 asmdyn(); | |
673 if(HEADTYPE == 10 || (iself && !debug['s'])) | 471 if(HEADTYPE == 10 || (iself && !debug['s'])) |
674 strnput("", INITRND-(8+symsize+lcsize)%INITRND); | 472 strnput("", INITRND-(8+symsize+lcsize)%INITRND); |
675 cflush(); | 473 cflush(); |
676 seek(cout, symo, 0); | 474 seek(cout, symo, 0); |
677 lputl(symsize); | 475 lputl(symsize); |
678 lputl(lcsize); | 476 lputl(lcsize); |
679 cflush(); | 477 cflush(); |
680 if(HEADTYPE != 10 && !debug['s']) { | 478 if(HEADTYPE != 10 && !debug['s']) { |
681 seek(cout, symo+8+symsize+lcsize, 0); | 479 seek(cout, symo+8+symsize+lcsize, 0); |
682 if(debug['v']) | 480 if(debug['v']) |
683 Bprint(&bso, "%5.2f dwarf\n", cputime()); | 481 Bprint(&bso, "%5.2f dwarf\n", cputime()); |
684 dwarfemitdebugsections(); | 482 dwarfemitdebugsections(); |
685 } | 483 } |
686 } else if(dlm){ | |
687 seek(cout, HEADR+textsize+datsize, 0); | |
688 asmdyn(); | |
689 cflush(); | |
690 } | 484 } |
691 if(debug['v']) | 485 if(debug['v']) |
692 Bprint(&bso, "%5.2f headr\n", cputime()); | 486 Bprint(&bso, "%5.2f headr\n", cputime()); |
693 Bflush(&bso); | 487 Bflush(&bso); |
694 seek(cout, 0L, 0); | 488 seek(cout, 0L, 0); |
695 switch(HEADTYPE) { | 489 switch(HEADTYPE) { |
696 default: | 490 default: |
697 if(iself) | 491 if(iself) |
698 goto Elfput; | 492 goto Elfput; |
699 case 0: /* garbage */ | 493 case 0: /* garbage */ |
700 lput(0x160L<<16); /* magic and sections */ | 494 lput(0x160L<<16); /* magic and sections */ |
701 lput(0L); /* time and date */ | 495 lput(0L); /* time and date */ |
702 » » lput(rnd(HEADR+textsize, 4096)+datsize); | 496 » » lput(rnd(HEADR+textsize, 4096)+segdata.filelen); |
703 lput(symsize); /* nsyms */ | 497 lput(symsize); /* nsyms */ |
704 lput((0x38L<<16)|7L); /* size of optional hdr and flag
s */ | 498 lput((0x38L<<16)|7L); /* size of optional hdr and flag
s */ |
705 lput((0413<<16)|0437L); /* magic and version */ | 499 lput((0413<<16)|0437L); /* magic and version */ |
706 lput(rnd(HEADR+textsize, 4096)); /* sizes */ | 500 lput(rnd(HEADR+textsize, 4096)); /* sizes */ |
707 » » lput(datsize); | 501 » » lput(segdata.filelen); |
708 » » lput(bsssize); | 502 » » lput(segdata.len - segdata.filelen); |
709 lput(entryvalue()); /* va of entry */ | 503 lput(entryvalue()); /* va of entry */ |
710 lput(INITTEXT-HEADR); /* va of base of text */ | 504 lput(INITTEXT-HEADR); /* va of base of text */ |
711 lput(INITDAT); /* va of base of data */ | 505 lput(INITDAT); /* va of base of data */ |
712 » » lput(INITDAT+datsize);» » /* va of base of bss */ | 506 » » lput(INITDAT+segdata.filelen);» » /* va of base of bss */ |
713 lput(~0L); /* gp reg mask */ | 507 lput(~0L); /* gp reg mask */ |
714 lput(0L); | 508 lput(0L); |
715 lput(0L); | 509 lput(0L); |
716 lput(0L); | 510 lput(0L); |
717 lput(0L); | 511 lput(0L); |
718 lput(~0L); /* gp value ?? */ | 512 lput(~0L); /* gp value ?? */ |
719 break; | 513 break; |
720 lputl(0); /* x */ | 514 lputl(0); /* x */ |
721 case 1: /* unix coff */ | 515 case 1: /* unix coff */ |
722 /* | 516 /* |
723 * file header | 517 * file header |
724 */ | 518 */ |
725 lputl(0x0004014c); /* 4 sections, magic */ | 519 lputl(0x0004014c); /* 4 sections, magic */ |
726 lputl(0); /* unix time stamp */ | 520 lputl(0); /* unix time stamp */ |
727 lputl(0); /* symbol table */ | 521 lputl(0); /* symbol table */ |
728 lputl(0); /* nsyms */ | 522 lputl(0); /* nsyms */ |
729 lputl(0x0003001c); /* flags, sizeof a.out header */ | 523 lputl(0x0003001c); /* flags, sizeof a.out header */ |
730 /* | 524 /* |
731 * a.out header | 525 * a.out header |
732 */ | 526 */ |
733 lputl(0x10b); /* magic, version stamp */ | 527 lputl(0x10b); /* magic, version stamp */ |
734 lputl(rnd(textsize, INITRND)); /* text sizes */ | 528 lputl(rnd(textsize, INITRND)); /* text sizes */ |
735 » » lputl(datsize);»» » /* data sizes */ | 529 » » lputl(segdata.filelen);»» » /* data sizes */ |
736 » » lputl(bsssize);»» » /* bss sizes */ | 530 » » lputl(segdata.len - segdata.filelen);» » » /* bss s
izes */ |
737 lput(entryvalue()); /* va of entry */ | 531 lput(entryvalue()); /* va of entry */ |
738 lputl(INITTEXT); /* text start */ | 532 lputl(INITTEXT); /* text start */ |
739 lputl(INITDAT); /* data start */ | 533 lputl(INITDAT); /* data start */ |
740 /* | 534 /* |
741 * text section header | 535 * text section header |
742 */ | 536 */ |
743 s8put(".text"); | 537 s8put(".text"); |
744 lputl(HEADR); /* pa */ | 538 lputl(HEADR); /* pa */ |
745 lputl(HEADR); /* va */ | 539 lputl(HEADR); /* va */ |
746 lputl(textsize); /* text size */ | 540 lputl(textsize); /* text size */ |
747 lputl(HEADR); /* file offset */ | 541 lputl(HEADR); /* file offset */ |
748 lputl(0); /* relocation */ | 542 lputl(0); /* relocation */ |
749 lputl(0); /* line numbers */ | 543 lputl(0); /* line numbers */ |
750 lputl(0); /* relocation, line numbers */ | 544 lputl(0); /* relocation, line numbers */ |
751 lputl(0x20); /* flags text only */ | 545 lputl(0x20); /* flags text only */ |
752 /* | 546 /* |
753 * data section header | 547 * data section header |
754 */ | 548 */ |
755 s8put(".data"); | 549 s8put(".data"); |
756 lputl(INITDAT); /* pa */ | 550 lputl(INITDAT); /* pa */ |
757 lputl(INITDAT); /* va */ | 551 lputl(INITDAT); /* va */ |
758 » » lputl(datsize);»» » /* data size */ | 552 » » lputl(segdata.filelen);»» » /* data size */ |
759 lputl(HEADR+textsize); /* file offset */ | 553 lputl(HEADR+textsize); /* file offset */ |
760 lputl(0); /* relocation */ | 554 lputl(0); /* relocation */ |
761 lputl(0); /* line numbers */ | 555 lputl(0); /* line numbers */ |
762 lputl(0); /* relocation, line numbers */ | 556 lputl(0); /* relocation, line numbers */ |
763 lputl(0x40); /* flags data only */ | 557 lputl(0x40); /* flags data only */ |
764 /* | 558 /* |
765 * bss section header | 559 * bss section header |
766 */ | 560 */ |
767 s8put(".bss"); | 561 s8put(".bss"); |
768 » » lputl(INITDAT+datsize);»» /* pa */ | 562 » » lputl(INITDAT+segdata.filelen);»» /* pa */ |
769 » » lputl(INITDAT+datsize);»» /* va */ | 563 » » lputl(INITDAT+segdata.filelen);»» /* va */ |
770 » » lputl(bsssize);»» » /* bss size */ | 564 » » lputl(segdata.len - segdata.filelen);» » » /* bss s
ize */ |
771 lputl(0); /* file offset */ | 565 lputl(0); /* file offset */ |
772 lputl(0); /* relocation */ | 566 lputl(0); /* relocation */ |
773 lputl(0); /* line numbers */ | 567 lputl(0); /* line numbers */ |
774 lputl(0); /* relocation, line numbers */ | 568 lputl(0); /* relocation, line numbers */ |
775 lputl(0x80); /* flags bss only */ | 569 lputl(0x80); /* flags bss only */ |
776 /* | 570 /* |
777 * comment section header | 571 * comment section header |
778 */ | 572 */ |
779 s8put(".comment"); | 573 s8put(".comment"); |
780 lputl(0); /* pa */ | 574 lputl(0); /* pa */ |
781 lputl(0); /* va */ | 575 lputl(0); /* va */ |
782 lputl(symsize+lcsize); /* comment size */ | 576 lputl(symsize+lcsize); /* comment size */ |
783 » » lputl(HEADR+textsize+datsize);» /* file offset */ | 577 » » lputl(HEADR+textsize+segdata.filelen);» /* file offset */ |
784 » » lputl(HEADR+textsize+datsize);» /* offset of syms */ | 578 » » lputl(HEADR+textsize+segdata.filelen);» /* offset of syms */ |
785 » » lputl(HEADR+textsize+datsize+symsize);/* offset of line numbers
*/ | 579 » » lputl(HEADR+textsize+segdata.filelen+symsize);/* offset of line
numbers */ |
786 lputl(0); /* relocation, line numbers */ | 580 lputl(0); /* relocation, line numbers */ |
787 lputl(0x200); /* flags comment only */ | 581 lputl(0x200); /* flags comment only */ |
788 break; | 582 break; |
789 case 2: /* plan9 */ | 583 case 2: /* plan9 */ |
790 magic = 4*11*11+7; | 584 magic = 4*11*11+7; |
791 if(dlm) | |
792 magic |= 0x80000000; | |
793 lput(magic); /* magic */ | 585 lput(magic); /* magic */ |
794 lput(textsize); /* sizes */ | 586 lput(textsize); /* sizes */ |
795 » » lput(datsize); | 587 » » lput(segdata.filelen); |
796 » » lput(bsssize); | 588 » » lput(segdata.len - segdata.filelen); |
797 lput(symsize); /* nsyms */ | 589 lput(symsize); /* nsyms */ |
798 lput(entryvalue()); /* va of entry */ | 590 lput(entryvalue()); /* va of entry */ |
799 lput(spsize); /* sp offsets */ | 591 lput(spsize); /* sp offsets */ |
800 lput(lcsize); /* line offsets */ | 592 lput(lcsize); /* line offsets */ |
801 break; | 593 break; |
802 case 3: | 594 case 3: |
803 /* MS-DOS .COM */ | 595 /* MS-DOS .COM */ |
804 break; | 596 break; |
805 case 4: | 597 case 4: |
806 /* fake MS-DOS .EXE */ | 598 /* fake MS-DOS .EXE */ |
807 » » v = rnd(HEADR+textsize, INITRND)+datsize; | 599 » » v = rnd(HEADR+textsize, INITRND)+segdata.filelen; |
808 wputl(0x5A4D); /* 'MZ' */ | 600 wputl(0x5A4D); /* 'MZ' */ |
809 wputl(v % 512); /* bytes in last page */ | 601 wputl(v % 512); /* bytes in last page */ |
810 wputl(rnd(v, 512)/512); /* total number of pages */ | 602 wputl(rnd(v, 512)/512); /* total number of pages */ |
811 wputl(0x0000); /* number of reloc items */ | 603 wputl(0x0000); /* number of reloc items */ |
812 v = rnd(HEADR-(INITTEXT & 0xFFFF), 16); | 604 v = rnd(HEADR-(INITTEXT & 0xFFFF), 16); |
813 wputl(v/16); /* size of header */ | 605 wputl(v/16); /* size of header */ |
814 wputl(0x0000); /* minimum allocation */ | 606 wputl(0x0000); /* minimum allocation */ |
815 wputl(0xFFFF); /* maximum allocation */ | 607 wputl(0xFFFF); /* maximum allocation */ |
816 wputl(0x0000); /* initial ss value */ | 608 wputl(0x0000); /* initial ss value */ |
817 wputl(0x0100); /* initial sp value */ | 609 wputl(0x0100); /* initial sp value */ |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 cbc = sizeof(buf.cbuf); | 879 cbc = sizeof(buf.cbuf); |
1088 } | 880 } |
1089 | 881 |
1090 /* Current position in file */ | 882 /* Current position in file */ |
1091 vlong | 883 vlong |
1092 cpos(void) | 884 cpos(void) |
1093 { | 885 { |
1094 return seek(cout, 0, 1) + sizeof(buf.cbuf) - cbc; | 886 return seek(cout, 0, 1) + sizeof(buf.cbuf) - cbc; |
1095 } | 887 } |
1096 | 888 |
1097 void | |
1098 datblk(int32 s, int32 n, int32 rodata) | |
1099 { | |
1100 Prog *p; | |
1101 char *cast; | |
1102 int32 l, fl, j; | |
1103 int i, c; | |
1104 Adr *a; | |
1105 int32 base; | |
1106 ········ | |
1107 base = INITDAT; | |
1108 if(rodata) | |
1109 base = 0; | |
1110 | |
1111 memset(buf.dbuf, 0, n+Dbufslop); | |
1112 for(p = datap; p != P; p = p->link) { | |
1113 a = &p->from; | |
1114 if(rodata != (a->sym->type == SRODATA)) | |
1115 continue; | |
1116 | |
1117 l = a->sym->value + a->offset - s; | |
1118 if(l >= n) | |
1119 continue; | |
1120 | |
1121 c = a->scale; | |
1122 i = 0; | |
1123 if(l < 0) { | |
1124 if(l+c <= 0) | |
1125 continue; | |
1126 i = -l; | |
1127 l = 0; | |
1128 } | |
1129 | |
1130 curp = p; | |
1131 if(!a->sym->reachable) | |
1132 diag("unreachable symbol in datblk - %s", a->sym->name); | |
1133 if(a->sym->type == SMACHO) | |
1134 continue; | |
1135 | |
1136 if(p->as != AINIT && p->as != ADYNT) { | |
1137 for(j=l+(c-i)-1; j>=l; j--) | |
1138 if(buf.dbuf[j]) { | |
1139 print("%P\n", p); | |
1140 diag("multiple initialization"); | |
1141 break; | |
1142 } | |
1143 } | |
1144 switch(p->to.type) { | |
1145 case D_FCONST: | |
1146 switch(c) { | |
1147 default: | |
1148 case 4: | |
1149 fl = ieeedtof(&p->to.ieee); | |
1150 cast = (char*)&fl; | |
1151 for(; i<c; i++) { | |
1152 buf.dbuf[l] = cast[fnuxi4[i]]; | |
1153 l++; | |
1154 } | |
1155 break; | |
1156 case 8: | |
1157 cast = (char*)&p->to.ieee; | |
1158 for(; i<c; i++) { | |
1159 buf.dbuf[l] = cast[fnuxi8[i]]; | |
1160 l++; | |
1161 } | |
1162 break; | |
1163 } | |
1164 break; | |
1165 | |
1166 case D_SCONST: | |
1167 for(; i<c; i++) { | |
1168 buf.dbuf[l] = p->to.scon[i]; | |
1169 l++; | |
1170 } | |
1171 break; | |
1172 | |
1173 default: | |
1174 fl = p->to.offset; | |
1175 if(p->to.type == D_SIZE) | |
1176 fl += p->to.sym->size; | |
1177 if(p->to.type == D_ADDR) { | |
1178 if(p->to.index != D_STATIC && p->to.index != D_E
XTERN) | |
1179 diag("DADDR type%P", p); | |
1180 if(p->to.sym) { | |
1181 if(p->to.sym->type == SUNDEF) | |
1182 ckoff(p->to.sym, fl); | |
1183 fl += p->to.sym->value; | |
1184 if(p->to.sym->type != STEXT && p->to.sym
->type != SUNDEF && p->to.sym->type != SRODATA) | |
1185 fl += INITDAT; | |
1186 if(dlm) | |
1187 dynreloc(p->to.sym, l+s+INITDAT,
1); | |
1188 } | |
1189 } | |
1190 cast = (char*)&fl; | |
1191 switch(c) { | |
1192 default: | |
1193 diag("bad nuxi %d %d\n%P", c, i, curp); | |
1194 break; | |
1195 case 1: | |
1196 for(; i<c; i++) { | |
1197 buf.dbuf[l] = cast[inuxi1[i]]; | |
1198 l++; | |
1199 } | |
1200 break; | |
1201 case 2: | |
1202 for(; i<c; i++) { | |
1203 buf.dbuf[l] = cast[inuxi2[i]]; | |
1204 l++; | |
1205 } | |
1206 break; | |
1207 case 4: | |
1208 for(; i<c; i++) { | |
1209 buf.dbuf[l] = cast[inuxi4[i]]; | |
1210 l++; | |
1211 } | |
1212 break; | |
1213 } | |
1214 break; | |
1215 } | |
1216 } | |
1217 | |
1218 ewrite(cout, buf.dbuf, n); | |
1219 if(!debug['a']) | |
1220 return; | |
1221 | |
1222 /* | |
1223 * a second pass just to print the asm | |
1224 */ | |
1225 for(p = datap; p != P; p = p->link) { | |
1226 a = &p->from; | |
1227 if(rodata != (a->sym->type == SRODATA)) | |
1228 continue; | |
1229 | |
1230 l = a->sym->value + a->offset - s; | |
1231 if(l < 0 || l >= n) | |
1232 continue; | |
1233 | |
1234 c = a->scale; | |
1235 i = 0; | |
1236 | |
1237 switch(p->to.type) { | |
1238 case D_FCONST: | |
1239 switch(c) { | |
1240 default: | |
1241 case 4: | |
1242 fl = ieeedtof(&p->to.ieee); | |
1243 cast = (char*)&fl; | |
1244 Bprint(&bso, pcstr, l+s+base); | |
1245 for(j=0; j<c; j++) | |
1246 Bprint(&bso, "%.2ux", cast[fnuxi4[j]] &
0xff); | |
1247 Bprint(&bso, "\t%P\n", p); | |
1248 break; | |
1249 case 8: | |
1250 cast = (char*)&p->to.ieee; | |
1251 Bprint(&bso, pcstr, l+s+base); | |
1252 for(j=0; j<c; j++) | |
1253 Bprint(&bso, "%.2ux", cast[fnuxi8[j]] &
0xff); | |
1254 Bprint(&bso, "\t%P\n", p); | |
1255 break; | |
1256 } | |
1257 break; | |
1258 | |
1259 case D_SCONST: | |
1260 Bprint(&bso, pcstr, l+s+base); | |
1261 for(j=0; j<c; j++) | |
1262 Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff); | |
1263 Bprint(&bso, "\t%P\n", p); | |
1264 break; | |
1265 | |
1266 default: | |
1267 fl = p->to.offset; | |
1268 if(p->to.type == D_SIZE) | |
1269 fl += p->to.sym->size; | |
1270 if(p->to.type == D_ADDR) { | |
1271 if(p->to.index != D_STATIC && p->to.index != D_E
XTERN) | |
1272 diag("DADDR type%P", p); | |
1273 if(p->to.sym) { | |
1274 if(p->to.sym->type == SUNDEF) | |
1275 ckoff(p->to.sym, fl); | |
1276 fl += p->to.sym->value; | |
1277 if(p->to.sym->type != STEXT && p->to.sym
->type != SUNDEF && p->to.sym->type != SRODATA) | |
1278 fl += INITDAT; | |
1279 if(dlm) | |
1280 dynreloc(p->to.sym, l+s+base, 1)
; | |
1281 } | |
1282 } | |
1283 cast = (char*)&fl; | |
1284 switch(c) { | |
1285 default: | |
1286 diag("bad nuxi %d %d\n%P", c, i, p); | |
1287 break; | |
1288 case 1: | |
1289 Bprint(&bso, pcstr, l+s+base); | |
1290 for(j=0; j<c; j++) | |
1291 Bprint(&bso, "%.2ux", cast[inuxi1[j]] &
0xff); | |
1292 Bprint(&bso, "\t%P\n", p); | |
1293 break; | |
1294 case 2: | |
1295 Bprint(&bso, pcstr, l+s+base); | |
1296 for(j=0; j<c; j++) | |
1297 Bprint(&bso, "%.2ux", cast[inuxi2[j]] &
0xff); | |
1298 Bprint(&bso, "\t%P\n", p); | |
1299 break; | |
1300 case 4: | |
1301 Bprint(&bso, pcstr, l+s+base); | |
1302 for(j=0; j<c; j++) | |
1303 Bprint(&bso, "%.2ux", cast[inuxi4[j]] &
0xff); | |
1304 Bprint(&bso, "\t%P\n", p); | |
1305 break; | |
1306 } | |
1307 break; | |
1308 } | |
1309 } | |
1310 } | |
1311 | |
1312 int32 | 889 int32 |
1313 rnd(int32 v, int32 r) | 890 rnd(int32 v, int32 r) |
1314 { | 891 { |
1315 int32 c; | 892 int32 c; |
1316 | 893 |
1317 if(r <= 0) | 894 if(r <= 0) |
1318 return v; | 895 return v; |
1319 v += r - 1; | 896 v += r - 1; |
1320 c = v % r; | 897 c = v % r; |
1321 if(c < 0) | 898 if(c < 0) |
1322 c += r; | 899 c += r; |
1323 v -= c; | 900 v -= c; |
1324 return v; | 901 return v; |
1325 } | 902 } |
LEFT | RIGHT |