diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-01 20:59:20 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-01 20:59:20 +0000 |
commit | 80350c116f86dbb87e055a630b1b2be0c66b244b (patch) | |
tree | 022e6b2a1e0e5a03028fa465a30338d8f6dbbf48 /ELF/Writer.cpp | |
parent | cbb560c9ba3c378189c7a438bed9977b482410fb (diff) |
Notes
Diffstat (limited to 'ELF/Writer.cpp')
-rw-r--r-- | ELF/Writer.cpp | 82 |
1 files changed, 43 insertions, 39 deletions
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp index 77d6412f80ad..258d5e26ef7f 100644 --- a/ELF/Writer.cpp +++ b/ELF/Writer.cpp @@ -261,23 +261,26 @@ template <class ELFT> void Writer<ELFT>::run() { if (!Config->Relocatable) fixSectionAlignments(); Script->fabricateDefaultCommands(); + } else { + Script->synchronize(); } for (BaseCommand *Base : Script->Opt.Commands) if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) OutputSectionCommands.push_back(Cmd); + clearOutputSections(); // If -compressed-debug-sections is specified, we need to compress // .debug_* sections. Do it right now because it changes the size of // output sections. - parallelForEach(OutputSections.begin(), OutputSections.end(), - [](OutputSection *S) { S->maybeCompress<ELFT>(); }); + parallelForEach( + OutputSectionCommands.begin(), OutputSectionCommands.end(), + [](OutputSectionCommand *Cmd) { Cmd->maybeCompress<ELFT>(); }); if (Config->Relocatable) { assignFileOffsets(); } else { - Script->synchronize(); - Script->assignAddresses(Phdrs); + Script->assignAddresses(Phdrs, OutputSectionCommands); // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a // 0 sized region. This has to be done late since only after assignAddresses @@ -300,13 +303,13 @@ template <class ELFT> void Writer<ELFT>::run() { openFile(); if (ErrorCount) return; + if (!Config->OFormatBinary) { writeHeader(); writeSections(); } else { writeSectionsBinary(); } - clearOutputSections(); // Backfill .note.gnu.build-id section content. This is done at last // because the content is usually a hash value of the entire output file. @@ -613,27 +616,27 @@ bool elf::isRelroSection(const OutputSection *Sec) { // .got contains pointers to external symbols. They are resolved by // the dynamic linker when a module is loaded into memory, and after // that they are not expected to change. So, it can be in RELRO. - if (InX::Got && Sec == InX::Got->OutSec) + if (InX::Got && Sec == InX::Got->getParent()) return true; // .got.plt contains pointers to external function symbols. They are // by default resolved lazily, so we usually cannot put it into RELRO. // However, if "-z now" is given, the lazy symbol resolution is // disabled, which enables us to put it into RELRO. - if (Sec == InX::GotPlt->OutSec) + if (Sec == InX::GotPlt->getParent()) return Config->ZNow; // .dynamic section contains data for the dynamic linker, and // there's no need to write to it at runtime, so it's better to put // it into RELRO. - if (Sec == InX::Dynamic->OutSec) + if (Sec == InX::Dynamic->getParent()) return true; // .bss.rel.ro is used for copy relocations for read-only symbols. // Since the dynamic linker needs to process copy relocations, the // section cannot be read-only, but once initialized, they shouldn't // change. - if (Sec == InX::BssRelRo->OutSec) + if (Sec == InX::BssRelRo->getParent()) return true; // Sections with some special names are put into RELRO. This is a @@ -1112,9 +1115,9 @@ template <class ELFT> void Writer<ELFT>::sortSections() { static void applySynthetic(const std::vector<SyntheticSection *> &Sections, std::function<void(SyntheticSection *)> Fn) { for (SyntheticSection *SS : Sections) - if (SS && SS->OutSec && !SS->empty()) { + if (SS && SS->getParent() && !SS->empty()) { Fn(SS); - SS->OutSec->assignOffsets(); + SS->getParent()->assignOffsets(); } } @@ -1130,16 +1133,15 @@ static void removeUnusedSyntheticSections(std::vector<OutputSection *> &V) { SyntheticSection *SS = dyn_cast<SyntheticSection>(S); if (!SS) return; - if (!SS->empty() || !SS->OutSec) + OutputSection *OS = SS->getParent(); + if (!SS->empty() || !OS) continue; - - SS->OutSec->Sections.erase(std::find(SS->OutSec->Sections.begin(), - SS->OutSec->Sections.end(), SS)); + OS->Sections.erase(std::find(OS->Sections.begin(), OS->Sections.end(), SS)); SS->Live = false; // If there are no other sections in the output section, remove it from the // output. - if (SS->OutSec->Sections.empty()) - V.erase(std::find(V.begin(), V.end(), SS->OutSec)); + if (OS->Sections.empty()) + V.erase(std::find(V.begin(), V.end(), OS)); } } @@ -1427,8 +1429,8 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { // Add an entry for .dynamic. if (InX::DynSymTab) - AddHdr(PT_DYNAMIC, InX::Dynamic->OutSec->getPhdrFlags()) - ->add(InX::Dynamic->OutSec); + AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags()) + ->add(InX::Dynamic->getParent()); // PT_GNU_RELRO includes all sections that should be marked as // read-only by dynamic linker after proccessing relocations. @@ -1441,9 +1443,9 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr. if (!In<ELFT>::EhFrame->empty() && In<ELFT>::EhFrameHdr && - In<ELFT>::EhFrame->OutSec && In<ELFT>::EhFrameHdr->OutSec) - AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->OutSec->getPhdrFlags()) - ->add(In<ELFT>::EhFrameHdr->OutSec); + In<ELFT>::EhFrame->getParent() && In<ELFT>::EhFrameHdr->getParent()) + AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->getParent()->getPhdrFlags()) + ->add(In<ELFT>::EhFrameHdr->getParent()); // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes // the dynamic linker fill the segment with random data. @@ -1556,9 +1558,11 @@ static uint64_t setOffset(OutputSection *Sec, uint64_t Off) { template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() { uint64_t Off = 0; - for (OutputSection *Sec : OutputSections) + for (OutputSectionCommand *Cmd : OutputSectionCommands) { + OutputSection *Sec = Cmd->Sec; if (Sec->Flags & SHF_ALLOC) Off = setOffset(Sec, Off); + } FileSize = alignTo(Off, Config->Wordsize); } @@ -1568,11 +1572,12 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() { Off = setOffset(Out::ElfHeader, Off); Off = setOffset(Out::ProgramHeaders, Off); - for (OutputSection *Sec : OutputSections) - Off = setOffset(Sec, Off); + for (OutputSectionCommand *Cmd : OutputSectionCommands) + Off = setOffset(Cmd->Sec, Off); SectionHeaderOff = alignTo(Off, Config->Wordsize); - FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr); + FileSize = + SectionHeaderOff + (OutputSectionCommands.size() + 1) * sizeof(Elf_Shdr); } // Finalize the program headers. We call this function after we assign @@ -1695,16 +1700,15 @@ template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() { // Setup MIPS _gp_disp/__gnu_local_gp symbols which should // be equal to the _gp symbol's value. - if (Config->EMachine == EM_MIPS) { - if (!ElfSym::MipsGp->Value) { - // Find GP-relative section with the lowest address - // and use this address to calculate default _gp value. - uint64_t Gp = -1; - for (const OutputSection *OS : OutputSections) - if ((OS->Flags & SHF_MIPS_GPREL) && OS->Addr < Gp) - Gp = OS->Addr; - if (Gp != (uint64_t)-1) - ElfSym::MipsGp->Value = Gp + 0x7ff0; + if (Config->EMachine == EM_MIPS && !ElfSym::MipsGp->Value) { + // Find GP-relative section with the lowest address + // and use this address to calculate default _gp value. + for (const OutputSectionCommand *Cmd : OutputSectionCommands) { + OutputSection *OS = Cmd->Sec; + if (OS->Flags & SHF_MIPS_GPREL) { + ElfSym::MipsGp->Value = OS->Addr + 0x7ff0; + break; + } } } } @@ -1728,7 +1732,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { EHdr->e_phnum = Phdrs.size(); EHdr->e_shentsize = sizeof(Elf_Shdr); EHdr->e_shnum = OutputSectionCommands.size() + 1; - EHdr->e_shstrndx = InX::ShStrTab->OutSec->SectionIndex; + EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex; if (Config->EMachine == EM_ARM) // We don't currently use any features incompatible with EF_ARM_EABI_VER5, @@ -1804,7 +1808,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() { OutputSection *EhFrameHdr = (In<ELFT>::EhFrameHdr && !In<ELFT>::EhFrameHdr->empty()) - ? In<ELFT>::EhFrameHdr->OutSec + ? In<ELFT>::EhFrameHdr->getParent() : nullptr; // In -r or -emit-relocs mode, write the relocation sections first as in @@ -1832,7 +1836,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() { } template <class ELFT> void Writer<ELFT>::writeBuildId() { - if (!InX::BuildId || !InX::BuildId->OutSec) + if (!InX::BuildId || !InX::BuildId->getParent()) return; // Compute a hash of all sections of the output file. |