LEFT | RIGHT |
(no file at all) | |
1 // Inferno utils/5l/asm.c | 1 // Inferno utils/5l/asm.c |
2 // http://code.google.com/p/inferno-os/source/browse/utils/5l/asm.c | 2 // http://code.google.com/p/inferno-os/source/browse/utils/5l/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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 void | 150 void |
151 doelf(void) | 151 doelf(void) |
152 { | 152 { |
153 Sym *s, *shstrtab, *dynstr; | 153 Sym *s, *shstrtab, *dynstr; |
154 | 154 |
155 if(!iself) | 155 if(!iself) |
156 return; | 156 return; |
157 | 157 |
158 /* predefine strings we need for section headers */ | 158 /* predefine strings we need for section headers */ |
159 shstrtab = lookup(".shstrtab", 0); | 159 shstrtab = lookup(".shstrtab", 0); |
160 » shstrtab->type = SELFDATA; | 160 » shstrtab->type = SELFROSECT; |
161 shstrtab->reachable = 1; | 161 shstrtab->reachable = 1; |
162 | 162 |
163 elfstr[ElfStrEmpty] = addstring(shstrtab, ""); | 163 elfstr[ElfStrEmpty] = addstring(shstrtab, ""); |
164 elfstr[ElfStrText] = addstring(shstrtab, ".text"); | 164 elfstr[ElfStrText] = addstring(shstrtab, ".text"); |
165 elfstr[ElfStrData] = addstring(shstrtab, ".data"); | 165 elfstr[ElfStrData] = addstring(shstrtab, ".data"); |
166 elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); | 166 elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); |
167 addstring(shstrtab, ".rodata"); | 167 addstring(shstrtab, ".rodata"); |
168 addstring(shstrtab, ".gosymtab"); | 168 addstring(shstrtab, ".gosymtab"); |
169 addstring(shstrtab, ".gopclntab"); | 169 addstring(shstrtab, ".gopclntab"); |
170 if(!debug['s']) {······· | 170 if(!debug['s']) {······· |
171 elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab"); | 171 elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab"); |
172 elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab"); | 172 elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab"); |
173 } | 173 } |
174 elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab"); | 174 elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab"); |
175 | 175 |
176 if(!debug['d']) { /* -d suppresses dynamic loader format */ | 176 if(!debug['d']) { /* -d suppresses dynamic loader format */ |
177 elfstr[ElfStrInterp] = addstring(shstrtab, ".interp"); | 177 elfstr[ElfStrInterp] = addstring(shstrtab, ".interp"); |
178 elfstr[ElfStrHash] = addstring(shstrtab, ".hash"); | 178 elfstr[ElfStrHash] = addstring(shstrtab, ".hash"); |
179 elfstr[ElfStrGot] = addstring(shstrtab, ".got"); | 179 elfstr[ElfStrGot] = addstring(shstrtab, ".got"); |
180 elfstr[ElfStrGotPlt] = addstring(shstrtab, ".got.plt"); | 180 elfstr[ElfStrGotPlt] = addstring(shstrtab, ".got.plt"); |
181 elfstr[ElfStrDynamic] = addstring(shstrtab, ".dynamic"); | 181 elfstr[ElfStrDynamic] = addstring(shstrtab, ".dynamic"); |
182 elfstr[ElfStrDynsym] = addstring(shstrtab, ".dynsym"); | 182 elfstr[ElfStrDynsym] = addstring(shstrtab, ".dynsym"); |
183 elfstr[ElfStrDynstr] = addstring(shstrtab, ".dynstr"); | 183 elfstr[ElfStrDynstr] = addstring(shstrtab, ".dynstr"); |
184 elfstr[ElfStrRel] = addstring(shstrtab, ".rel"); | 184 elfstr[ElfStrRel] = addstring(shstrtab, ".rel"); |
185 elfstr[ElfStrRelPlt] = addstring(shstrtab, ".rel.plt"); | 185 elfstr[ElfStrRelPlt] = addstring(shstrtab, ".rel.plt"); |
186 elfstr[ElfStrPlt] = addstring(shstrtab, ".plt"); | 186 elfstr[ElfStrPlt] = addstring(shstrtab, ".plt"); |
187 | 187 |
188 /* interpreter string */ | 188 /* interpreter string */ |
| 189 if(interpreter == nil) |
| 190 interpreter = linuxdynld; |
189 s = lookup(".interp", 0); | 191 s = lookup(".interp", 0); |
| 192 s->type = SELFROSECT; |
190 s->reachable = 1; | 193 s->reachable = 1; |
191 » » s->type = SELFDATA;» // TODO: rodata | 194 » » addstring(s, interpreter); |
192 | 195 |
193 /* dynamic symbol table - first entry all zeros */ | 196 /* dynamic symbol table - first entry all zeros */ |
194 s = lookup(".dynsym", 0); | 197 s = lookup(".dynsym", 0); |
195 » » s->type = SELFDATA; | 198 » » s->type = SELFROSECT; |
196 s->reachable = 1; | 199 s->reachable = 1; |
197 s->value += ELF32SYMSIZE; | 200 s->value += ELF32SYMSIZE; |
198 | 201 |
199 /* dynamic string table */ | 202 /* dynamic string table */ |
200 s = lookup(".dynstr", 0); | 203 s = lookup(".dynstr", 0); |
201 » » s->type = SELFDATA; | 204 » » s->type = SELFROSECT; |
202 s->reachable = 1; | 205 s->reachable = 1; |
203 if(s->size == 0) | 206 if(s->size == 0) |
204 addstring(s, ""); | 207 addstring(s, ""); |
205 dynstr = s; | 208 dynstr = s; |
206 | 209 |
207 /* relocation table */ | 210 /* relocation table */ |
208 s = lookup(".rel", 0); | 211 s = lookup(".rel", 0); |
209 s->reachable = 1; | 212 s->reachable = 1; |
210 » » s->type = SELFDATA; | 213 » » s->type = SELFROSECT; |
211 | 214 |
212 /* global offset table */ | 215 /* global offset table */ |
213 s = lookup(".got", 0); | 216 s = lookup(".got", 0); |
214 s->reachable = 1; | 217 s->reachable = 1; |
215 » » s->type = SELFDATA; | 218 » » s->type = SELFSECT; // writable |
216 ················ | 219 ················ |
217 /* hash */ | 220 /* hash */ |
218 s = lookup(".hash", 0); | 221 s = lookup(".hash", 0); |
219 s->reachable = 1; | 222 s->reachable = 1; |
220 » » s->type = SELFDATA; | 223 » » s->type = SELFROSECT; |
221 | 224 |
222 /* got.plt */ | 225 /* got.plt */ |
223 s = lookup(".got.plt", 0); | 226 s = lookup(".got.plt", 0); |
224 s->reachable = 1; | 227 s->reachable = 1; |
225 » » s->type = SDATA;» // writable, so not SELFDATA | 228 » » s->type = SELFSECT; // writable |
226 ················ | 229 ················ |
227 s = lookup(".plt", 0); | 230 s = lookup(".plt", 0); |
228 s->reachable = 1; | 231 s->reachable = 1; |
229 » » s->type = SELFDATA; | 232 » » s->type = SELFROSECT; |
230 | 233 |
231 s = lookup(".rel.plt", 0); | 234 s = lookup(".rel.plt", 0); |
232 s->reachable = 1; | 235 s->reachable = 1; |
233 » » s->type = SELFDATA; | 236 » » s->type = SELFROSECT; |
234 ················ | 237 ················ |
235 elfsetupplt(); | 238 elfsetupplt(); |
236 | 239 |
237 /* define dynamic elf table */ | 240 /* define dynamic elf table */ |
238 s = lookup(".dynamic", 0); | 241 s = lookup(".dynamic", 0); |
239 s->reachable = 1; | 242 s->reachable = 1; |
240 » » s->type = SELFDATA; | 243 » » s->type = SELFROSECT; |
241 | 244 |
242 /* | 245 /* |
243 * .dynamic table | 246 * .dynamic table |
244 */ | 247 */ |
245 elfwritedynentsym(s, DT_HASH, lookup(".hash", 0)); | 248 elfwritedynentsym(s, DT_HASH, lookup(".hash", 0)); |
246 elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0)); | 249 elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0)); |
247 elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); | 250 elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); |
248 elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0)); | 251 elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0)); |
249 elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0)); | 252 elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0)); |
250 elfwritedynentsym(s, DT_REL, lookup(".rel", 0)); | 253 elfwritedynentsym(s, DT_REL, lookup(".rel", 0)); |
(...skipping 16 matching lines...) Expand all Loading... |
267 return addr - segdata.vaddr + segdata.fileoff; | 270 return addr - segdata.vaddr + segdata.fileoff; |
268 if(addr >= segtext.vaddr) | 271 if(addr >= segtext.vaddr) |
269 return addr - segtext.vaddr + segtext.fileoff; | 272 return addr - segtext.vaddr + segtext.fileoff; |
270 diag("datoff %#x", addr); | 273 diag("datoff %#x", addr); |
271 return 0; | 274 return 0; |
272 } | 275 } |
273 | 276 |
274 void | 277 void |
275 shsym(Elf64_Shdr *sh, Sym *s) | 278 shsym(Elf64_Shdr *sh, Sym *s) |
276 { | 279 { |
277 » sh->addr = symaddr(s); | 280 » vlong addr; |
278 » sh->off = datoff(sh->addr); | 281 » addr = symaddr(s); |
| 282 » if(sh->flags&SHF_ALLOC) |
| 283 » » sh->addr = addr; |
| 284 » sh->off = datoff(addr); |
279 sh->size = s->size; | 285 sh->size = s->size; |
280 } | 286 } |
281 | 287 |
282 void | 288 void |
283 phsh(Elf64_Phdr *ph, Elf64_Shdr *sh) | 289 phsh(Elf64_Phdr *ph, Elf64_Shdr *sh) |
284 { | 290 { |
285 ph->vaddr = sh->addr; | 291 ph->vaddr = sh->addr; |
286 ph->paddr = ph->vaddr; | 292 ph->paddr = ph->vaddr; |
287 ph->off = sh->off; | 293 ph->off = sh->off; |
288 ph->filesz = sh->size; | 294 ph->filesz = sh->size; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 datblk(segdata.vaddr, segdata.filelen); | 330 datblk(segdata.vaddr, segdata.filelen); |
325 | 331 |
326 /* output read-only data in text segment */ | 332 /* output read-only data in text segment */ |
327 sect = segtext.sect->next; | 333 sect = segtext.sect->next; |
328 cseek(sect->vaddr - segtext.vaddr + segtext.fileoff); | 334 cseek(sect->vaddr - segtext.vaddr + segtext.fileoff); |
329 datblk(sect->vaddr, sect->len); | 335 datblk(sect->vaddr, sect->len); |
330 | 336 |
331 if(iself) { | 337 if(iself) { |
332 /* index of elf text section; needed by asmelfsym, double-checke
d below */ | 338 /* index of elf text section; needed by asmelfsym, double-checke
d below */ |
333 /* !debug['d'] causes extra sections before the .text section */ | 339 /* !debug['d'] causes extra sections before the .text section */ |
334 » » elftextsh = 1; | 340 » » elftextsh = 2; |
335 if(!debug['d']) { | 341 if(!debug['d']) { |
336 elftextsh += 10; | 342 elftextsh += 10; |
337 if(elfverneed) | 343 if(elfverneed) |
338 elftextsh += 2; | 344 elftextsh += 2; |
339 } | 345 } |
340 } | 346 } |
341 | 347 |
342 /* output symbol table */ | 348 /* output symbol table */ |
343 symsize = 0; | 349 symsize = 0; |
344 lcsize = 0; | 350 lcsize = 0; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 o = segtext.fileoff - pph->off; | 485 o = segtext.fileoff - pph->off; |
480 segtext.fileoff -= o; | 486 segtext.fileoff -= o; |
481 segtext.filelen += o; | 487 segtext.filelen += o; |
482 | 488 |
483 if(!debug['d']) { | 489 if(!debug['d']) { |
484 /* interpreter for dynamic linking */ | 490 /* interpreter for dynamic linking */ |
485 sh = newElfShdr(elfstr[ElfStrInterp]); | 491 sh = newElfShdr(elfstr[ElfStrInterp]); |
486 sh->type = SHT_PROGBITS; | 492 sh->type = SHT_PROGBITS; |
487 sh->flags = SHF_ALLOC; | 493 sh->flags = SHF_ALLOC; |
488 sh->addralign = 1; | 494 sh->addralign = 1; |
489 » » » if(interpreter == nil) | 495 » » » shsym(sh, lookup(".interp", 0)); |
490 » » » » interpreter = linuxdynld; | |
491 » » » elfinterp(sh, startva, interpreter); | |
492 | 496 |
493 ph = newElfPhdr(); | 497 ph = newElfPhdr(); |
494 ph->type = PT_INTERP; | 498 ph->type = PT_INTERP; |
495 ph->flags = PF_R; | 499 ph->flags = PF_R; |
496 phsh(ph, sh); | 500 phsh(ph, sh); |
497 } | 501 } |
498 | 502 |
499 elfphload(&segtext); | 503 elfphload(&segtext); |
500 elfphload(&segdata); | 504 elfphload(&segdata); |
501 | 505 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 ph->align = 4; | 576 ph->align = 4; |
573 } | 577 } |
574 */ | 578 */ |
575 } | 579 } |
576 | 580 |
577 ph = newElfPhdr(); | 581 ph = newElfPhdr(); |
578 ph->type = PT_GNU_STACK; | 582 ph->type = PT_GNU_STACK; |
579 ph->flags = PF_W+PF_R; | 583 ph->flags = PF_W+PF_R; |
580 ph->align = 4; | 584 ph->align = 4; |
581 | 585 |
| 586 sh = newElfShstrtab(elfstr[ElfStrShstrtab]); |
| 587 sh->type = SHT_STRTAB; |
| 588 sh->addralign = 1; |
| 589 shsym(sh, lookup(".shstrtab", 0)); |
| 590 |
582 if(elftextsh != eh->shnum) | 591 if(elftextsh != eh->shnum) |
583 diag("elftextsh = %d, want %d", elftextsh, eh->shnum); | 592 diag("elftextsh = %d, want %d", elftextsh, eh->shnum); |
584 for(sect=segtext.sect; sect!=nil; sect=sect->next) | 593 for(sect=segtext.sect; sect!=nil; sect=sect->next) |
585 elfshbits(sect); | 594 elfshbits(sect); |
586 for(sect=segdata.sect; sect!=nil; sect=sect->next) | 595 for(sect=segdata.sect; sect!=nil; sect=sect->next) |
587 elfshbits(sect); | 596 elfshbits(sect); |
588 | 597 |
589 if (!debug['s']) { | 598 if (!debug['s']) { |
590 sh = newElfShdr(elfstr[ElfStrSymtab]); | 599 sh = newElfShdr(elfstr[ElfStrSymtab]); |
591 sh->type = SHT_SYMTAB; | 600 sh->type = SHT_SYMTAB; |
592 sh->off = symo; | 601 sh->off = symo; |
593 sh->size = symsize; | 602 sh->size = symsize; |
594 sh->addralign = 4; | 603 sh->addralign = 4; |
595 sh->entsize = 16; | 604 sh->entsize = 16; |
596 sh->link = eh->shnum; // link to strtab | 605 sh->link = eh->shnum; // link to strtab |
597 | 606 |
598 sh = newElfShdr(elfstr[ElfStrStrtab]); | 607 sh = newElfShdr(elfstr[ElfStrStrtab]); |
599 sh->type = SHT_STRTAB; | 608 sh->type = SHT_STRTAB; |
600 sh->off = symo+symsize; | 609 sh->off = symo+symsize; |
601 sh->size = elfstrsize; | 610 sh->size = elfstrsize; |
602 sh->addralign = 1; | 611 sh->addralign = 1; |
603 | 612 |
604 // dwarfaddelfheaders(); | 613 // dwarfaddelfheaders(); |
605 } | 614 } |
606 | 615 |
607 sh = newElfShstrtab(elfstr[ElfStrShstrtab]); | |
608 sh->type = SHT_STRTAB; | |
609 sh->addralign = 1; | |
610 shsym(sh, lookup(".shstrtab", 0)); | |
611 | |
612 /* Main header */ | 616 /* Main header */ |
613 eh->ident[EI_MAG0] = '\177'; | 617 eh->ident[EI_MAG0] = '\177'; |
614 eh->ident[EI_MAG1] = 'E'; | 618 eh->ident[EI_MAG1] = 'E'; |
615 eh->ident[EI_MAG2] = 'L'; | 619 eh->ident[EI_MAG2] = 'L'; |
616 eh->ident[EI_MAG3] = 'F'; | 620 eh->ident[EI_MAG3] = 'F'; |
617 eh->ident[EI_CLASS] = ELFCLASS32; | 621 eh->ident[EI_CLASS] = ELFCLASS32; |
618 eh->ident[EI_DATA] = ELFDATA2LSB; | 622 eh->ident[EI_DATA] = ELFDATA2LSB; |
619 eh->ident[EI_VERSION] = EV_CURRENT; | 623 eh->ident[EI_VERSION] = EV_CURRENT; |
620 | 624 |
621 eh->type = ET_EXEC; | 625 eh->type = ET_EXEC; |
622 eh->machine = EM_ARM; | 626 eh->machine = EM_ARM; |
623 eh->version = EV_CURRENT; | 627 eh->version = EV_CURRENT; |
624 eh->entry = entryvalue(); | 628 eh->entry = entryvalue(); |
625 | 629 |
626 if(pph != nil) { | 630 if(pph != nil) { |
627 pph->filesz = eh->phnum * eh->phentsize; | 631 pph->filesz = eh->phnum * eh->phentsize; |
628 pph->memsz = pph->filesz; | 632 pph->memsz = pph->filesz; |
629 } | 633 } |
630 | 634 |
631 cseek(0); | 635 cseek(0); |
632 a = 0; | 636 a = 0; |
633 a += elfwritehdr(); | 637 a += elfwritehdr(); |
634 a += elfwritephdrs(); | 638 a += elfwritephdrs(); |
635 a += elfwriteshdrs(); | 639 a += elfwriteshdrs(); |
636 cflush(); | 640 cflush(); |
637 » » if(a+elfwriteinterp() > ELFRESERVE) | 641 » » if(a > ELFRESERVE)» |
638 diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); | 642 diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); |
639 break; | 643 break; |
640 } | 644 } |
641 cflush(); | 645 cflush(); |
642 if(debug['c']){ | 646 if(debug['c']){ |
643 print("textsize=%d\n", textsize); | 647 print("textsize=%d\n", textsize); |
644 print("datsize=%ulld\n", segdata.filelen); | 648 print("datsize=%ulld\n", segdata.filelen); |
645 print("bsssize=%ulld\n", segdata.len - segdata.filelen); | 649 print("bsssize=%ulld\n", segdata.len - segdata.filelen); |
646 print("symsize=%d\n", symsize); | 650 print("symsize=%d\n", symsize); |
647 print("lcsize=%d\n", lcsize); | 651 print("lcsize=%d\n", lcsize); |
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1818 put(s, s->name, 'T', s->value, s->size, s->version, 0); | 1822 put(s, s->name, 'T', s->value, s->size, s->version, 0); |
1819 | 1823 |
1820 for(h=0; h<NHASH; h++) { | 1824 for(h=0; h<NHASH; h++) { |
1821 for(s=hash[h]; s!=S; s=s->hash) { | 1825 for(s=hash[h]; s!=S; s=s->hash) { |
1822 if(s->hide) | 1826 if(s->hide) |
1823 continue; | 1827 continue; |
1824 switch(s->type) { | 1828 switch(s->type) { |
1825 case SCONST: | 1829 case SCONST: |
1826 case SRODATA: | 1830 case SRODATA: |
1827 case SDATA: | 1831 case SDATA: |
1828 » » » case SELFDATA: | 1832 » » » case SELFROSECT: |
1829 case STYPE: | 1833 case STYPE: |
1830 case SSTRING: | 1834 case SSTRING: |
1831 case SGOSTRING: | 1835 case SGOSTRING: |
1832 if(!s->reachable) | 1836 if(!s->reachable) |
1833 continue; | 1837 continue; |
1834 put(s, s->name, 'D', s->value, s->size, s->versi
on, s->gotype); | 1838 put(s, s->name, 'D', s->value, s->size, s->versi
on, s->gotype); |
1835 continue; | 1839 continue; |
1836 | 1840 |
1837 case SBSS: | 1841 case SBSS: |
1838 if(!s->reachable) | 1842 if(!s->reachable) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1871 if(debug['v'] || debug['n']) | 1875 if(debug['v'] || debug['n']) |
1872 Bprint(&bso, "symsize = %ud\n", symsize); | 1876 Bprint(&bso, "symsize = %ud\n", symsize); |
1873 Bflush(&bso); | 1877 Bflush(&bso); |
1874 } | 1878 } |
1875 | 1879 |
1876 void | 1880 void |
1877 setpersrc(Sym *s) | 1881 setpersrc(Sym *s) |
1878 { | 1882 { |
1879 USED(s); | 1883 USED(s); |
1880 } | 1884 } |
LEFT | RIGHT |