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 TimerStackIdT StackID = GlobalContext::TSK_Funcs; |
| 224 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 Reloc->getOffset()); | 443 Reloc->getOffset()); |
433 break; | 444 break; |
434 } | 445 } |
435 } | 446 } |
436 } | 447 } |
437 } | 448 } |
438 } | 449 } |
439 } | 450 } |
440 | 451 |
441 void ELFObjectWriter::writeInitialELFHeader() { | 452 void ELFObjectWriter::writeInitialELFHeader() { |
| 453 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
442 assert(!SectionNumbersAssigned); | 454 assert(!SectionNumbersAssigned); |
443 constexpr Elf64_Off DummySHOffset = 0; | 455 constexpr Elf64_Off DummySHOffset = 0; |
444 constexpr SizeT DummySHStrIndex = 0; | 456 constexpr SizeT DummySHStrIndex = 0; |
445 constexpr SizeT DummyNumSections = 0; | 457 constexpr SizeT DummyNumSections = 0; |
446 if (ELF64) { | 458 if (ELF64) { |
447 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, | 459 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, |
448 DummyNumSections); | 460 DummyNumSections); |
449 } else { | 461 } else { |
450 writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex, | 462 writeELFHeaderInternal<false>(DummySHOffset, DummySHStrIndex, |
451 DummyNumSections); | 463 DummyNumSections); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 Str.writeLE16(0); // e_phnum | 505 Str.writeLE16(0); // e_phnum |
494 Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr) | 506 Str.writeLE16(IsELF64 ? sizeof(Elf64_Shdr) |
495 : sizeof(Elf32_Shdr)); // e_shentsize | 507 : sizeof(Elf32_Shdr)); // e_shentsize |
496 static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40, | 508 static_assert(sizeof(Elf64_Shdr) == 64 && sizeof(Elf32_Shdr) == 40, |
497 "Elf_Shdr sizes cannot be derived from sizeof"); | 509 "Elf_Shdr sizes cannot be derived from sizeof"); |
498 Str.writeLE16(static_cast<Elf64_Half>(NumSections)); // e_shnum | 510 Str.writeLE16(static_cast<Elf64_Half>(NumSections)); // e_shnum |
499 Str.writeLE16(static_cast<Elf64_Half>(SectHeaderStrIndex)); // e_shstrndx | 511 Str.writeLE16(static_cast<Elf64_Half>(SectHeaderStrIndex)); // e_shstrndx |
500 } | 512 } |
501 | 513 |
502 template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) { | 514 template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) { |
| 515 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
503 ConstantList Pool = Ctx.getConstantPool(Ty); | 516 ConstantList Pool = Ctx.getConstantPool(Ty); |
504 if (Pool.empty()) { | 517 if (Pool.empty()) { |
505 return; | 518 return; |
506 } | 519 } |
507 SizeT Align = typeAlignInBytes(Ty); | 520 SizeT Align = typeAlignInBytes(Ty); |
508 size_t EntSize = typeWidthInBytes(Ty); | 521 size_t EntSize = typeWidthInBytes(Ty); |
509 char Buf[20]; | 522 char Buf[20]; |
510 SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf)); | 523 SizeT WriteAmt = std::min(EntSize, llvm::array_lengthof(Buf)); |
511 // Check that we write the full PrimType. | 524 // Check that we write the full PrimType. |
512 assert(WriteAmt == EntSize); | 525 assert(WriteAmt == EntSize); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 template void ELFObjectWriter::writeConstantPool<ConstantInteger32>(Type Ty); | 582 template void ELFObjectWriter::writeConstantPool<ConstantInteger32>(Type Ty); |
570 | 583 |
571 void ELFObjectWriter::writeAllRelocationSections() { | 584 void ELFObjectWriter::writeAllRelocationSections() { |
572 writeRelocationSections(RelTextSections); | 585 writeRelocationSections(RelTextSections); |
573 writeRelocationSections(RelDataSections); | 586 writeRelocationSections(RelDataSections); |
574 writeRelocationSections(RelRODataSections); | 587 writeRelocationSections(RelRODataSections); |
575 } | 588 } |
576 | 589 |
577 void ELFObjectWriter::writeJumpTable(const JumpTableData &JT, | 590 void ELFObjectWriter::writeJumpTable(const JumpTableData &JT, |
578 FixupKind RelocationKind, bool IsPIC) { | 591 FixupKind RelocationKind, bool IsPIC) { |
| 592 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
579 ELFDataSection *Section; | 593 ELFDataSection *Section; |
580 ELFRelocationSection *RelSection; | 594 ELFRelocationSection *RelSection; |
581 const Elf64_Xword PointerSize = typeWidthInBytes(getPointerType()); | 595 const Elf64_Xword PointerSize = typeWidthInBytes(getPointerType()); |
582 const Elf64_Xword ShAddralign = PointerSize; | 596 const Elf64_Xword ShAddralign = PointerSize; |
583 const Elf64_Xword ShEntsize = PointerSize; | 597 const Elf64_Xword ShEntsize = PointerSize; |
584 const IceString SectionName = MangleSectionName( | 598 const IceString SectionName = MangleSectionName( |
585 IsPIC ? ".data.rel.ro" : ".rodata", JT.getFunctionName() + "$jumptable"); | 599 IsPIC ? ".data.rel.ro" : ".rodata", JT.getFunctionName() + "$jumptable"); |
586 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC, | 600 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, SHF_ALLOC, |
587 ShAddralign, ShEntsize); | 601 ShAddralign, ShEntsize); |
588 Section->setFileOffset(alignFileOffset(ShAddralign)); | 602 Section->setFileOffset(alignFileOffset(ShAddralign)); |
(...skipping 15 matching lines...) Expand all Loading... |
604 AssemblerFixup NewFixup; | 618 AssemblerFixup NewFixup; |
605 NewFixup.set_position(Section->getCurrentSize()); | 619 NewFixup.set_position(Section->getCurrentSize()); |
606 NewFixup.set_kind(RelocationKind); | 620 NewFixup.set_kind(RelocationKind); |
607 NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName())); | 621 NewFixup.set_value(Ctx.getConstantSym(TargetOffset, JT.getFunctionName())); |
608 RelSection->addRelocation(NewFixup); | 622 RelSection->addRelocation(NewFixup); |
609 Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset); | 623 Section->appendRelocationOffset(Str, RelSection->isRela(), TargetOffset); |
610 } | 624 } |
611 } | 625 } |
612 | 626 |
613 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { | 627 void ELFObjectWriter::setUndefinedSyms(const ConstantList &UndefSyms) { |
| 628 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
614 for (const Constant *S : UndefSyms) { | 629 for (const Constant *S : UndefSyms) { |
615 const auto *Sym = llvm::cast<ConstantRelocatable>(S); | 630 const auto *Sym = llvm::cast<ConstantRelocatable>(S); |
616 const IceString &Name = Sym->getName(); | 631 const IceString &Name = Sym->getName(); |
617 bool BadIntrinsic; | 632 bool BadIntrinsic; |
618 const Intrinsics::FullIntrinsicInfo *Info = | 633 const Intrinsics::FullIntrinsicInfo *Info = |
619 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); | 634 Ctx.getIntrinsicsInfo().find(Name, BadIntrinsic); |
620 if (Info) | 635 if (Info) |
621 continue; | 636 continue; |
622 // Ignore BadIntrinsic, which is set if the name begins with "llvm." but | 637 // Ignore BadIntrinsic, which is set if the name begins with "llvm." but |
623 // doesn't match a known intrinsic. If we want this to turn into an error, | 638 // doesn't match a known intrinsic. If we want this to turn into an error, |
(...skipping 11 matching lines...) Expand all Loading... |
635 RelSec->setSize(RelSec->getSectionDataSize()); | 650 RelSec->setSize(RelSec->getSectionDataSize()); |
636 if (ELF64) { | 651 if (ELF64) { |
637 RelSec->writeData<true>(Str, SymTab); | 652 RelSec->writeData<true>(Str, SymTab); |
638 } else { | 653 } else { |
639 RelSec->writeData<false>(Str, SymTab); | 654 RelSec->writeData<false>(Str, SymTab); |
640 } | 655 } |
641 } | 656 } |
642 } | 657 } |
643 | 658 |
644 void ELFObjectWriter::writeNonUserSections() { | 659 void ELFObjectWriter::writeNonUserSections() { |
| 660 TimerMarker Timer(TimerStack::TT_writeELF, &Ctx); |
| 661 |
645 // Write out the shstrtab now that all sections are known. | 662 // Write out the shstrtab now that all sections are known. |
646 ShStrTab->doLayout(); | 663 ShStrTab->doLayout(); |
647 ShStrTab->setSize(ShStrTab->getSectionDataSize()); | 664 ShStrTab->setSize(ShStrTab->getSectionDataSize()); |
648 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); | 665 Elf64_Off ShStrTabOffset = alignFileOffset(ShStrTab->getSectionAlign()); |
649 ShStrTab->setFileOffset(ShStrTabOffset); | 666 ShStrTab->setFileOffset(ShStrTabOffset); |
650 Str.writeBytes(ShStrTab->getSectionData()); | 667 Str.writeBytes(ShStrTab->getSectionData()); |
651 | 668 |
652 SectionList AllSections; | 669 SectionList AllSections; |
653 assignSectionNumbersInfo(AllSections); | 670 assignSectionNumbersInfo(AllSections); |
654 | 671 |
(...skipping 29 matching lines...) Expand all Loading... |
684 if (ELF64) { | 701 if (ELF64) { |
685 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 702 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
686 AllSections.size()); | 703 AllSections.size()); |
687 } else { | 704 } else { |
688 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 705 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
689 AllSections.size()); | 706 AllSections.size()); |
690 } | 707 } |
691 } | 708 } |
692 | 709 |
693 } // end of namespace Ice | 710 } // end of namespace Ice |
OLD | NEW |