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