OLD | NEW |
---|---|
1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// | 1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 if (AlignDiff == 0) | 212 if (AlignDiff == 0) |
213 return OffsetInFile; | 213 return OffsetInFile; |
214 Str.writeZeroPadding(AlignDiff); | 214 Str.writeZeroPadding(AlignDiff); |
215 OffsetInFile += AlignDiff; | 215 OffsetInFile += AlignDiff; |
216 return OffsetInFile; | 216 return OffsetInFile; |
217 } | 217 } |
218 | 218 |
219 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, | 219 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, |
220 bool IsInternal, Assembler *Asm) { | 220 bool IsInternal, Assembler *Asm) { |
221 assert(!SectionNumbersAssigned); | 221 assert(!SectionNumbersAssigned); |
222 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | |
223 constexpr Ice::TimerStackIdT StackID = Ice::GlobalContext::TSK_Funcs; | |
John
2016/03/07 22:40:39
No need to fully qualify these.
Karl
2016/03/08 21:52:47
Done.
| |
224 Ice::TimerIdT TimerID = 0; | |
225 bool TimeThisFunction = Ctx.getFlags().getTimeEachFunction(); | |
226 if (TimeThisFunction) { | |
227 TimerID = Ctx.getTimerID(StackID, FuncName); | |
228 Ctx.pushTimer(TimerID, StackID); | |
229 } | |
222 ELFTextSection *Section = nullptr; | 230 ELFTextSection *Section = nullptr; |
223 ELFRelocationSection *RelSection = nullptr; | 231 ELFRelocationSection *RelSection = nullptr; |
224 const bool FunctionSections = Ctx.getFlags().getFunctionSections(); | 232 const bool FunctionSections = Ctx.getFlags().getFunctionSections(); |
225 if (TextSections.empty() || FunctionSections) { | 233 if (TextSections.empty() || FunctionSections) { |
226 IceString SectionName = ".text"; | 234 IceString SectionName = ".text"; |
227 if (FunctionSections) | 235 if (FunctionSections) |
228 SectionName += "." + FuncName; | 236 SectionName += "." + FuncName; |
229 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; | 237 constexpr Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; |
230 const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes(); | 238 const Elf64_Xword ShAlign = 1 << Asm->getBundleAlignLog2Bytes(); |
231 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, | 239 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 if (!RelSection->isRela()) { | 271 if (!RelSection->isRela()) { |
264 // This is a non-rela section, so we need to update the instruction stream | 272 // This is a non-rela section, so we need to update the instruction stream |
265 // with the relocation addends. | 273 // with the relocation addends. |
266 for (const auto *Fixup : Fixups) { | 274 for (const auto *Fixup : Fixups) { |
267 Fixup->emitOffset(Asm); | 275 Fixup->emitOffset(Asm); |
268 } | 276 } |
269 } | 277 } |
270 RelSection->addRelocations(OffsetInSection, Asm->fixups()); | 278 RelSection->addRelocations(OffsetInSection, Asm->fixups()); |
271 } | 279 } |
272 Section->appendData(Str, Asm->getBufferView()); | 280 Section->appendData(Str, Asm->getBufferView()); |
281 if (TimeThisFunction) | |
282 Ctx.popTimer(TimerID, StackID); | |
273 } | 283 } |
274 | 284 |
275 namespace { | 285 namespace { |
276 | 286 |
277 ELFObjectWriter::SectionType | 287 ELFObjectWriter::SectionType |
278 classifyGlobalSection(const VariableDeclaration *Var) { | 288 classifyGlobalSection(const VariableDeclaration *Var) { |
279 if (Var->getIsConstant()) | 289 if (Var->getIsConstant()) |
280 return ELFObjectWriter::ROData; | 290 return ELFObjectWriter::ROData; |
281 if (Var->hasNonzeroInitializer()) | 291 if (Var->hasNonzeroInitializer()) |
282 return ELFObjectWriter::Data; | 292 return ELFObjectWriter::Data; |
(...skipping 13 matching lines...) Expand all Loading... | |
296 } | 306 } |
297 } | 307 } |
298 } | 308 } |
299 | 309 |
300 } // end of anonymous namespace | 310 } // end of anonymous namespace |
301 | 311 |
302 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, | 312 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, |
303 FixupKind RelocationKind, | 313 FixupKind RelocationKind, |
304 const IceString &SectionSuffix, | 314 const IceString &SectionSuffix, |
305 bool IsPIC) { | 315 bool IsPIC) { |
316 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | |
306 assert(!SectionNumbersAssigned); | 317 assert(!SectionNumbersAssigned); |
307 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; | 318 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; |
308 for (auto &SectionList : VarsBySection) | 319 for (auto &SectionList : VarsBySection) |
309 SectionList.reserve(Vars.size()); | 320 SectionList.reserve(Vars.size()); |
310 partitionGlobalsBySection(Vars, VarsBySection, | 321 partitionGlobalsBySection(Vars, VarsBySection, |
311 Ctx.getFlags().getTranslateOnly()); | 322 Ctx.getFlags().getTranslateOnly()); |
312 size_t I = 0; | 323 size_t I = 0; |
313 for (auto &SectionList : VarsBySection) { | 324 for (auto &SectionList : VarsBySection) { |
314 writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind, | 325 writeDataOfType(static_cast<SectionType>(I++), SectionList, RelocationKind, |
315 SectionSuffix, IsPIC); | 326 SectionSuffix, IsPIC); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 Reloc->getOffset()); | 446 Reloc->getOffset()); |
436 break; | 447 break; |
437 } | 448 } |
438 } | 449 } |
439 } | 450 } |
440 } | 451 } |
441 } | 452 } |
442 } | 453 } |
443 | 454 |
444 void ELFObjectWriter::writeInitialELFHeader() { | 455 void ELFObjectWriter::writeInitialELFHeader() { |
456 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | |
445 assert(!SectionNumbersAssigned); | 457 assert(!SectionNumbersAssigned); |
446 constexpr Elf64_Off DummySHOffset = 0; | 458 constexpr Elf64_Off DummySHOffset = 0; |
447 constexpr SizeT DummySHStrIndex = 0; | 459 constexpr SizeT DummySHStrIndex = 0; |
448 constexpr SizeT DummyNumSections = 0; | 460 constexpr SizeT DummyNumSections = 0; |
449 if (ELF64) { | 461 if (ELF64) { |
450 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, | 462 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, |
451 DummyNumSections); | 463 DummyNumSections); |
452 } else { | 464 } else { |
453 writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex, | 465 writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex, |
454 DummyNumSections); | 466 DummyNumSections); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 Str.writeLE16(0); // e_phnum | 508 Str.writeLE16(0); // e_phnum |
497 Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr) | 509 Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr) |
498 : sizeof(Elf32_Shdr)); // e_shentsize | 510 : sizeof(Elf32_Shdr)); // e_shentsize |
499 static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40, | 511 static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40, |
500 "Elf_Shdr sizes cannot be derived from sizeof"); | 512 "Elf_Shdr sizes cannot be derived from sizeof"); |
501 Str.writeLE16(static_cast<Elf64_Half>(NumSections)); // e_shnum | 513 Str.writeLE16(static_cast<Elf64_Half>(NumSections)); // e_shnum |
502 Str.writeLE16(static_cast<Elf64_Half>(SectHeaderStrIndex)); // e_shstrndx | 514 Str.writeLE16(static_cast<Elf64_Half>(SectHeaderStrIndex)); // e_shstrndx |
503 } | 515 } |
504 | 516 |
505 template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) { | 517 template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) { |
518 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | |
506 ConstantList Pool = Ctx.getConstantPool(Ty); | 519 ConstantList Pool = Ctx.getConstantPool(Ty); |
507 if (Pool.empty()) { | 520 if (Pool.empty()) { |
508 return; | 521 return; |
509 } | 522 } |
510 SizeT Align = typeAlignInBytes(Ty); | 523 SizeT Align = typeAlignInBytes(Ty); |
511 size_t EntSize = typeWidthInBytes(Ty); | 524 size_t EntSize = typeWidthInBytes(Ty); |
512 char Buf[20]; | 525 char Buf[20]; |
513 SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf)); | 526 SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf)); |
514 // Check that we write the full PrimType. | 527 // Check that we write the full PrimType. |
515 assert(WriteAmt == EntSize); | 528 assert(WriteAmt == EntSize); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
572 template void ELFObjectWriter::writeConstantPool<ConstantInteger32>(Type Ty); | 585 template void ELFObjectWriter::writeConstantPool<ConstantInteger32>(Type Ty); |
573 | 586 |
574 void ELFObjectWriter::writeAllRelocationSections() { | 587 void ELFObjectWriter::writeAllRelocationSections() { |
575 writeRelocationSections(RelTextSections); | 588 writeRelocationSections(RelTextSections); |
576 writeRelocationSections(RelDataSections); | 589 writeRelocationSections(RelDataSections); |
577 writeRelocationSections(RelRODataSections); | 590 writeRelocationSections(RelRODataSections); |
578 } | 591 } |
579 | 592 |
580 void ELFObjectWriter::writeJumpTable(const JumpTableData &JT, | 593 void ELFObjectWriter::writeJumpTable(const JumpTableData &JT, |
581 FixupKind RelocationKind, bool IsPIC) { | 594 FixupKind RelocationKind, bool IsPIC) { |
595 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | |
582 ELFDataSection *Section; | 596 ELFDataSection *Section; |
583 ELFRelocationSection *RelSection; | 597 ELFRelocationSection *RelSection; |
584 const Elf64_Xword PointerSize = typeWidthInBytes(getPointerType()); | 598 const Elf64_Xword PointerSize = typeWidthInBytes(getPointerType()); |
585 const Elf64_Xword ShAddralign = PointerSize; | 599 const Elf64_Xword ShAddralign = PointerSize; |
586 const Elf64_Xword ShEntsize = PointerSize; | 600 const Elf64_Xword ShEntsize = PointerSize; |
587 const IceString SectionName = MangleSectionName( | 601 const IceString SectionName = MangleSectionName( |
588 IsPIC ? ".data.rel.ro" : ".rodata", JT.getFunctionName() + "$jumptable"); | 602 IsPIC ? ".data.rel.ro" : ".rodata", JT.getFunctionName() + "$jumptable"); |
589 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC, | 603 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC, |
590 ShAddralign, ShEntsize); | 604 ShAddralign, ShEntsize); |
591 Section->setFileOffset(alignFileOffset(ShAddralign)); | 605 Section->setFileOffset(alignFileOffset(ShAddralign)); |
(...skipping 16 matching lines...) Expand all Loading... | |
608 NewFixup.set_position(Section->getCurrentSize()); | 622 NewFixup.set_position(Section->getCurrentSize()); |
609 NewFixup.set_kind(RelocationKind); | 623 NewFixup.set_kind(RelocationKind); |
610 constexpr bool SuppressMangling = true; | 624 constexpr bool SuppressMangling = true; |
611 NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName(), | 625 NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName(), |
612 SuppressMangling)); | 626 SuppressMangling)); |
613 RelSection->addRelocation(NewFixup); | 627 RelSection->addRelocation(NewFixup); |
614 Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset); | 628 Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset); |
615 } | 629 } |
616 } | 630 } |
617 | 631 |
618 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { | 632 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { |
Jim Stichnoth
2016/03/07 23:20:12
I think you need a TT_writeELF marker here as well
Karl
2016/03/08 21:52:47
Done.
| |
619 for (const Constant *S : UndefSyms) { | 633 for (const Constant *S : UndefSyms) { |
620 const auto *Sym = llvm::cast<ConstantRelocatable>(S); | 634 const auto *Sym = llvm::cast<ConstantRelocatable>(S); |
621 const IceString &Name = Sym->getName(); | 635 const IceString &Name = Sym->getName(); |
622 bool BadIntrinsic; | 636 bool BadIntrinsic; |
623 const Intrinsics::FullIntrinsicInfo *Info = | 637 const Intrinsics::FullIntrinsicInfo *Info = |
624 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); | 638 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); |
625 if (Info) | 639 if (Info) |
626 continue; | 640 continue; |
627 // Ignore BadIntrinsic, which is set if the name begins with "llvm." but | 641 // Ignore BadIntrinsic, which is set if the name begins with "llvm." but |
628 // doesn't match a known intrinsic. If we want this to turn into an error, | 642 // doesn't match a known intrinsic. If we want this to turn into an error, |
(...skipping 12 matching lines...) Expand all Loading... | |
641 RelSec->setSize(RelSec->getSectionDataSize()); | 655 RelSec->setSize(RelSec->getSectionDataSize()); |
642 if (ELF64) { | 656 if (ELF64) { |
643 RelSec->writeData<true>(Ctx, Str, SymTab); | 657 RelSec->writeData<true>(Ctx, Str, SymTab); |
644 } else { | 658 } else { |
645 RelSec->writeData<false>(Ctx, Str, SymTab); | 659 RelSec->writeData<false>(Ctx, Str, SymTab); |
646 } | 660 } |
647 } | 661 } |
648 } | 662 } |
649 | 663 |
650 void ELFObjectWriter::writeNonUserSections() { | 664 void ELFObjectWriter::writeNonUserSections() { |
665 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); | |
666 | |
651 // Write out the shstrtab now that all sections are known. | 667 // Write out the shstrtab now that all sections are known. |
652 ShStrTab->doLayout(); | 668 ShStrTab->doLayout(); |
653 ShStrTab->setSize(ShStrTab->getSectionDataSize()); | 669 ShStrTab->setSize(ShStrTab->getSectionDataSize()); |
654 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); | 670 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); |
655 ShStrTab->setFileOffset(ShStrTabOffset); | 671 ShStrTab->setFileOffset(ShStrTabOffset); |
656 Str.writeBytes(ShStrTab->getSectionData()); | 672 Str.writeBytes(ShStrTab->getSectionData()); |
657 | 673 |
658 SectionList AllSections; | 674 SectionList AllSections; |
659 assignSectionNumbersInfo(AllSections); | 675 assignSectionNumbersInfo(AllSections); |
660 | 676 |
(...skipping 29 matching lines...) Expand all Loading... | |
690 if (ELF64) { | 706 if (ELF64) { |
691 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 707 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
692 AllSections.size()); | 708 AllSections.size()); |
693 } else { | 709 } else { |
694 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 710 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
695 AllSections.size()); | 711 AllSections.size()); |
696 } | 712 } |
697 } | 713 } |
698 | 714 |
699 } // end of namespace Ice | 715 } // end of namespace Ice |
OLD | NEW |