diff options
author | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
commit | 60b571e49a90d38697b3aca23020d9da42fc7d7f (patch) | |
tree | 99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/llvm/tools/lld/ELF/Writer.cpp | |
parent | bea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff) | |
download | FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.zip FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.tar.gz |
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release:
MFC r309142 (by emaste):
Add WITH_LLD_AS_LD build knob
If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not
capable of linking the world and kernel, but can self-host and link many
substantial applications. GNU ld continues to be used for the world and
kernel build, regardless of how this knob is set.
It is on by default for arm64, and off for all other CPU architectures.
Sponsored by: The FreeBSD Foundation
MFC r310840:
Reapply 310775, now it also builds correctly if lldb is disabled:
Move llvm-objdump from CLANG_EXTRAS to installed by default
We currently install three tools from binutils 2.17.50: as, ld, and
objdump. Work is underway to migrate to a permissively-licensed
tool-chain, with one goal being the retirement of binutils 2.17.50.
LLVM's llvm-objdump is intended to be compatible with GNU objdump
although it is currently missing some options and may have formatting
differences. Enable it by default for testing and further investigation.
It may later be changed to install as /usr/bin/objdump, it becomes a
fully viable replacement.
Reviewed by: emaste
Differential Revision: https://reviews.freebsd.org/D8879
MFC r312855 (by emaste):
Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC
Reported by: Dan McGregor <dan.mcgregor usask.ca>
MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines
Don't check struct rtentry on FreeBSD, it is an internal kernel structure.
On other systems it may be API structure for SIOCADDRT/SIOCDELRT.
Reviewed by: emaste, dim
MFC r314152 (by jkim):
Remove an assembler flag, which is redundant since r309124. The upstream
took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE.
http://llvm.org/viewvc/llvm-project?rev=273500&view=rev
Reviewed by: dim
MFC r314564:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
4.0.0 (branches/release_40 296509). The release will follow soon.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Also note that as of 4.0.0, lld should be able to link the base system
on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5).
Though please be aware that this is work in progress.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/4.0.0/docs/ReleaseNotes.html>
<http://releases.llvm.org/4.0.0/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/4.0.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for
their help.
Relnotes: yes
Exp-run: antoine
PR: 215969, 216008
MFC r314708:
For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov):
[SCEV] limit recursion depth of CompareSCEVComplexity
Summary:
CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled
loop) and runs almost infinite time.
Added cache of "equal" SCEV pairs to earlier cutoff of further
estimation. Recursion depth limit was also introduced as a parameter.
Reviewers: sanjoy
Subscribers: mzolotukhin, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D26389
This commit is the cause of excessive compile times on skein_block.c
(and possibly other files) during kernel builds on amd64.
We never saw the problematic behavior described in this upstream commit,
so for now it is better to revert it. An upstream bug has been filed
here: https://bugs.llvm.org/show_bug.cgi?id=32142
Reported by: mjg
MFC r314795:
Reapply r287232 from upstream llvm trunk (by Daniil Fukalov):
[SCEV] limit recursion depth of CompareSCEVComplexity
Summary:
CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled
loop) and runs almost infinite time.
Added cache of "equal" SCEV pairs to earlier cutoff of further
estimation. Recursion depth limit was also introduced as a parameter.
Reviewers: sanjoy
Subscribers: mzolotukhin, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D26389
Pull in r296992 from upstream llvm trunk (by Sanjoy Das):
[SCEV] Decrease the recursion threshold for CompareValueComplexity
Fixes PR32142.
r287232 accidentally increased the recursion threshold for
CompareValueComplexity from 2 to 32. This change reverses that
change by introducing a separate flag for CompareValueComplexity's
threshold.
The latter revision fixes the excessive compile times for skein_block.c.
MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines
Unbreak ARMv6 world.
The new compiler_rt library imported with clang 4.0.0 have several fatal
issues (non-functional __udivsi3 for example) with ARM specific instrict
functions. As temporary workaround, until upstream solve these problems,
disable all thumb[1][2] related feature.
MFC r315016:
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release.
We were already very close to the last release candidate, so this is a
pretty minor update.
Relnotes: yes
MFC r316005:
Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by
Weiming Zhao):
builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA.
Summary:
Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation
mode (-mthumb, -marm), it reflect's capability of given CPU.
Due to this:
- use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB
- use '.thumb' directive consistently in all affected files
- decorate all thumb functions using
DEFINE_COMPILERRT_THUMB_FUNCTION()
---------
Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 !
Reviewers: weimingz, rengolin, compnerd
Subscribers: aemerson, dim
Differential Revision: https://reviews.llvm.org/D30938
Discussed with: mmel
Diffstat (limited to 'contrib/llvm/tools/lld/ELF/Writer.cpp')
-rw-r--r-- | contrib/llvm/tools/lld/ELF/Writer.cpp | 1800 |
1 files changed, 1130 insertions, 670 deletions
diff --git a/contrib/llvm/tools/lld/ELF/Writer.cpp b/contrib/llvm/tools/lld/ELF/Writer.cpp index 387bec3..01f6f8e 100644 --- a/contrib/llvm/tools/lld/ELF/Writer.cpp +++ b/contrib/llvm/tools/lld/ELF/Writer.cpp @@ -10,21 +10,26 @@ #include "Writer.h" #include "Config.h" #include "LinkerScript.h" +#include "Memory.h" #include "OutputSections.h" #include "Relocations.h" #include "Strings.h" #include "SymbolTable.h" +#include "SyntheticSections.h" #include "Target.h" - #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/FileOutputBuffer.h" -#include "llvm/Support/StringSaver.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" +#include <climits> +#include <thread> using namespace llvm; using namespace llvm::ELF; using namespace llvm::object; +using namespace llvm::support; +using namespace llvm::support::endian; using namespace lld; using namespace lld::elf; @@ -40,32 +45,25 @@ public: typedef typename ELFT::Sym Elf_Sym; typedef typename ELFT::SymRange Elf_Sym_Range; typedef typename ELFT::Rela Elf_Rela; - Writer(SymbolTable<ELFT> &S) : Symtab(S) {} void run(); private: - // This describes a program header entry. - // Each contains type, access flags and range of output sections that will be - // placed in it. - struct Phdr { - Phdr(unsigned Type, unsigned Flags) { - H.p_type = Type; - H.p_flags = Flags; - } - Elf_Phdr H = {}; - OutputSectionBase<ELFT> *First = nullptr; - OutputSectionBase<ELFT> *Last = nullptr; - }; - + void createSyntheticSections(); void copyLocalSymbols(); void addReservedSymbols(); + void addInputSec(InputSectionBase<ELFT> *S); void createSections(); + void forEachRelSec(std::function<void(InputSectionBase<ELFT> &)> Fn); + void sortSections(); + void finalizeSections(); void addPredefinedSections(); - bool needsGot(); - void createPhdrs(); + std::vector<PhdrEntry> createPhdrs(); + void removeEmptyPTLoad(); + void addPtArmExid(std::vector<PhdrEntry> &Phdrs); void assignAddresses(); void assignFileOffsets(); + void assignFileOffsetsBinary(); void setPhdrs(); void fixHeaders(); void fixSectionAlignments(); @@ -73,214 +71,312 @@ private: void openFile(); void writeHeader(); void writeSections(); + void writeSectionsBinary(); void writeBuildId(); - bool needsInterpSection() const { - return !Symtab.getSharedFiles().empty() && !Config->DynamicLinker.empty(); - } - bool isOutputDynamic() const { - return !Symtab.getSharedFiles().empty() || Config->Pic; - } - - void addCommonSymbols(std::vector<DefinedCommon *> &Syms); std::unique_ptr<FileOutputBuffer> Buffer; - BumpPtrAllocator Alloc; - std::vector<OutputSectionBase<ELFT> *> OutputSections; - std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> OwningSections; + std::vector<OutputSectionBase *> OutputSections; + OutputSectionFactory<ELFT> Factory; void addRelIpltSymbols(); void addStartEndSymbols(); - void addStartStopSymbols(OutputSectionBase<ELFT> *Sec); + void addStartStopSymbols(OutputSectionBase *Sec); + uintX_t getEntryAddr(); + OutputSectionBase *findSection(StringRef Name); - SymbolTable<ELFT> &Symtab; - std::vector<Phdr> Phdrs; + std::vector<PhdrEntry> Phdrs; uintX_t FileSize; uintX_t SectionHeaderOff; + bool AllocateHeader = true; }; } // anonymous namespace -template <class ELFT> -StringRef elf::getOutputSectionName(InputSectionBase<ELFT> *S) { - StringRef Dest = Script<ELFT>::X->getOutputSection(S); - if (!Dest.empty()) - return Dest; - - StringRef Name = S->getSectionName(); - for (StringRef V : {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.", - ".init_array.", ".fini_array.", ".ctors.", ".dtors.", - ".tbss.", ".gcc_except_table.", ".tdata."}) - if (Name.startswith(V)) - return V.drop_back(); +StringRef elf::getOutputSectionName(StringRef Name) { + if (Config->Relocatable) + return Name; + + for (StringRef V : + {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.", + ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", + ".gcc_except_table.", ".tdata.", ".ARM.exidx."}) { + StringRef Prefix = V.drop_back(); + if (Name.startswith(V) || Name == Prefix) + return Prefix; + } + + // CommonSection is identified as "COMMON" in linker scripts. + // By default, it should go to .bss section. + if (Name == "COMMON") + return ".bss"; + + // ".zdebug_" is a prefix for ZLIB-compressed sections. + // Because we decompressed input sections, we want to remove 'z'. + if (Name.startswith(".zdebug_")) + return Saver.save(Twine(".") + Name.substr(2)); return Name; } -template <class ELFT> -void elf::reportDiscarded(InputSectionBase<ELFT> *IS, - const std::unique_ptr<elf::ObjectFile<ELFT>> &File) { - if (!Config->PrintGcSections || !IS || IS->Live) +template <class ELFT> void elf::reportDiscarded(InputSectionBase<ELFT> *IS) { + if (!Config->PrintGcSections) return; - errs() << "removing unused section from '" << IS->getSectionName() - << "' in file '" << File->getName() << "'\n"; + errs() << "removing unused section from '" << IS->Name << "' in file '" + << IS->getFile()->getName() << "'\n"; } -template <class ELFT> void elf::writeResult(SymbolTable<ELFT> *Symtab) { - typedef typename ELFT::uint uintX_t; - typedef typename ELFT::Ehdr Elf_Ehdr; +template <class ELFT> static bool needsInterpSection() { + return !Symtab<ELFT>::X->getSharedFiles().empty() && + !Config->DynamicLinker.empty() && + !Script<ELFT>::X->ignoreInterpSection(); +} - // Create singleton output sections. - OutputSection<ELFT> Bss(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - DynamicSection<ELFT> Dynamic; - EhOutputSection<ELFT> EhFrame; - GotSection<ELFT> Got; - InterpSection<ELFT> Interp; - PltSection<ELFT> Plt; - RelocationSection<ELFT> RelaDyn(Config->Rela ? ".rela.dyn" : ".rel.dyn", - Config->ZCombreloc); - StringTableSection<ELFT> DynStrTab(".dynstr", true); - StringTableSection<ELFT> ShStrTab(".shstrtab", false); - SymbolTableSection<ELFT> DynSymTab(DynStrTab); - VersionTableSection<ELFT> VerSym; - VersionNeedSection<ELFT> VerNeed; - - OutputSectionBase<ELFT> ElfHeader("", 0, SHF_ALLOC); - ElfHeader.setSize(sizeof(Elf_Ehdr)); - OutputSectionBase<ELFT> ProgramHeaders("", 0, SHF_ALLOC); - ProgramHeaders.updateAlignment(sizeof(uintX_t)); - - // Instantiate optional output sections if they are needed. - std::unique_ptr<BuildIdSection<ELFT>> BuildId; - std::unique_ptr<EhFrameHeader<ELFT>> EhFrameHdr; - std::unique_ptr<GnuHashTableSection<ELFT>> GnuHashTab; - std::unique_ptr<GotPltSection<ELFT>> GotPlt; - std::unique_ptr<HashTableSection<ELFT>> HashTab; - std::unique_ptr<RelocationSection<ELFT>> RelaPlt; - std::unique_ptr<StringTableSection<ELFT>> StrTab; - std::unique_ptr<SymbolTableSection<ELFT>> SymTabSec; - std::unique_ptr<OutputSection<ELFT>> MipsRldMap; - std::unique_ptr<VersionDefinitionSection<ELFT>> VerDef; - - if (Config->BuildId == BuildIdKind::Fnv1) - BuildId.reset(new BuildIdFnv1<ELFT>); - else if (Config->BuildId == BuildIdKind::Md5) - BuildId.reset(new BuildIdMd5<ELFT>); - else if (Config->BuildId == BuildIdKind::Sha1) - BuildId.reset(new BuildIdSha1<ELFT>); - else if (Config->BuildId == BuildIdKind::Hexstring) - BuildId.reset(new BuildIdHexstring<ELFT>); - - if (Config->EhFrameHdr) - EhFrameHdr.reset(new EhFrameHeader<ELFT>); - - if (Config->GnuHash) - GnuHashTab.reset(new GnuHashTableSection<ELFT>); - if (Config->SysvHash) - HashTab.reset(new HashTableSection<ELFT>); - StringRef S = Config->Rela ? ".rela.plt" : ".rel.plt"; - GotPlt.reset(new GotPltSection<ELFT>); - RelaPlt.reset(new RelocationSection<ELFT>(S, false /*Sort*/)); - if (!Config->StripAll) { - StrTab.reset(new StringTableSection<ELFT>(".strtab", false)); - SymTabSec.reset(new SymbolTableSection<ELFT>(*StrTab)); - } - if (Config->EMachine == EM_MIPS && !Config->Shared) { - // This is a MIPS specific section to hold a space within the data segment - // of executable file which is pointed to by the DT_MIPS_RLD_MAP entry. - // See "Dynamic section" in Chapter 5 in the following document: - // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - MipsRldMap.reset(new OutputSection<ELFT>(".rld_map", SHT_PROGBITS, - SHF_ALLOC | SHF_WRITE)); - MipsRldMap->setSize(sizeof(uintX_t)); - MipsRldMap->updateAlignment(sizeof(uintX_t)); - } - if (!Config->VersionDefinitions.empty()) - VerDef.reset(new VersionDefinitionSection<ELFT>()); - - Out<ELFT>::Bss = &Bss; - Out<ELFT>::BuildId = BuildId.get(); - Out<ELFT>::DynStrTab = &DynStrTab; - Out<ELFT>::DynSymTab = &DynSymTab; - Out<ELFT>::Dynamic = &Dynamic; - Out<ELFT>::EhFrame = &EhFrame; - Out<ELFT>::EhFrameHdr = EhFrameHdr.get(); - Out<ELFT>::GnuHashTab = GnuHashTab.get(); - Out<ELFT>::Got = &Got; - Out<ELFT>::GotPlt = GotPlt.get(); - Out<ELFT>::HashTab = HashTab.get(); - Out<ELFT>::Interp = &Interp; - Out<ELFT>::Plt = &Plt; - Out<ELFT>::RelaDyn = &RelaDyn; - Out<ELFT>::RelaPlt = RelaPlt.get(); - Out<ELFT>::ShStrTab = &ShStrTab; - Out<ELFT>::StrTab = StrTab.get(); - Out<ELFT>::SymTab = SymTabSec.get(); - Out<ELFT>::VerDef = VerDef.get(); - Out<ELFT>::VerSym = &VerSym; - Out<ELFT>::VerNeed = &VerNeed; - Out<ELFT>::MipsRldMap = MipsRldMap.get(); - Out<ELFT>::Opd = nullptr; - Out<ELFT>::OpdBuf = nullptr; - Out<ELFT>::TlsPhdr = nullptr; - Out<ELFT>::ElfHeader = &ElfHeader; - Out<ELFT>::ProgramHeaders = &ProgramHeaders; - - Writer<ELFT>(*Symtab).run(); +template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); } + +template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() { + auto I = std::remove_if(Phdrs.begin(), Phdrs.end(), [&](const PhdrEntry &P) { + if (P.p_type != PT_LOAD) + return false; + if (!P.First) + return true; + uintX_t Size = P.Last->Addr + P.Last->Size - P.First->Addr; + return Size == 0; + }); + Phdrs.erase(I, Phdrs.end()); } // The main function of the writer. template <class ELFT> void Writer<ELFT>::run() { - if (!Config->DiscardAll) + // Create linker-synthesized sections such as .got or .plt. + // Such sections are of type input section. + createSyntheticSections(); + + // We need to create some reserved symbols such as _end. Create them. + if (!Config->Relocatable) + addReservedSymbols(); + + // Some architectures use small displacements for jump instructions. + // It is linker's responsibility to create thunks containing long + // jump instructions if jump targets are too far. Create thunks. + if (Target->NeedsThunks) + forEachRelSec(createThunks<ELFT>); + + // Create output sections. + Script<ELFT>::X->OutputSections = &OutputSections; + if (ScriptConfig->HasSections) { + // If linker script contains SECTIONS commands, let it create sections. + Script<ELFT>::X->processCommands(Factory); + + // Linker scripts may have left some input sections unassigned. + // Assign such sections using the default rule. + Script<ELFT>::X->addOrphanSections(Factory); + } else { + // If linker script does not contain SECTIONS commands, create + // output sections by default rules. We still need to give the + // linker script a chance to run, because it might contain + // non-SECTIONS commands such as ASSERT. + createSections(); + Script<ELFT>::X->processCommands(Factory); + } + + if (Config->Discard != DiscardPolicy::All) copyLocalSymbols(); - addReservedSymbols(); - createSections(); - if (HasError) + + // Now that we have a complete set of output sections. This function + // completes section contents. For example, we need to add strings + // to the string table, and add entries to .got and .plt. + // finalizeSections does that. + finalizeSections(); + if (ErrorCount) return; if (Config->Relocatable) { assignFileOffsets(); } else { - createPhdrs(); - fixHeaders(); - if (ScriptConfig->DoLayout) { - Script<ELFT>::X->assignAddresses(OutputSections); + if (ScriptConfig->HasSections) { + Script<ELFT>::X->assignAddresses(Phdrs); } else { fixSectionAlignments(); assignAddresses(); } - assignFileOffsets(); + + // 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 + // we know the size of the sections. + removeEmptyPTLoad(); + + if (!Config->OFormatBinary) + assignFileOffsets(); + else + assignFileOffsetsBinary(); + setPhdrs(); fixAbsoluteSymbols(); } + // Write the result down to a file. openFile(); - if (HasError) + if (ErrorCount) return; - writeHeader(); - writeSections(); + if (!Config->OFormatBinary) { + writeHeader(); + writeSections(); + } else { + writeSectionsBinary(); + } + + // 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. writeBuildId(); - if (HasError) + if (ErrorCount) return; + if (auto EC = Buffer->commit()) error(EC, "failed to write to the output file"); + + // Flush the output streams and exit immediately. A full shutdown + // is a good test that we are keeping track of all allocated memory, + // but actually freeing it is a waste of time in a regular linker run. + if (Config->ExitEarly) + exitLld(0); } -template <class ELFT> -static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) { - if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore) - return; +// Initialize Out<ELFT> members. +template <class ELFT> void Writer<ELFT>::createSyntheticSections() { + // Initialize all pointers with NULL. This is needed because + // you can call lld::elf::main more than once as a library. + memset(&Out<ELFT>::First, 0, sizeof(Out<ELFT>)); - if (Config->Shared && Sym->symbol()->Visibility == STV_DEFAULT && - Config->UnresolvedSymbols != UnresolvedPolicy::NoUndef) - return; + // Create singleton output sections. + Out<ELFT>::Bss = + make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); + Out<ELFT>::BssRelRo = make<OutputSection<ELFT>>(".bss.rel.ro", SHT_NOBITS, + SHF_ALLOC | SHF_WRITE); + In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true); + In<ELFT>::Dynamic = make<DynamicSection<ELFT>>(); + Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>(); + In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>( + Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); + In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false); + + Out<ELFT>::ElfHeader = make<OutputSectionBase>("", 0, SHF_ALLOC); + Out<ELFT>::ElfHeader->Size = sizeof(Elf_Ehdr); + Out<ELFT>::ProgramHeaders = make<OutputSectionBase>("", 0, SHF_ALLOC); + Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t)); + + if (needsInterpSection<ELFT>()) { + In<ELFT>::Interp = createInterpSection<ELFT>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Interp); + } else { + In<ELFT>::Interp = nullptr; + } - std::string Msg = "undefined symbol: " + Sym->getName().str(); - if (Sym->File) - Msg += " in " + getFilename(Sym->File); - if (Config->UnresolvedSymbols == UnresolvedPolicy::Warn) - warning(Msg); - else - error(Msg); + if (!Config->Relocatable) + Symtab<ELFT>::X->Sections.push_back(createCommentSection<ELFT>()); + + if (Config->Strip != StripPolicy::All) { + In<ELFT>::StrTab = make<StringTableSection<ELFT>>(".strtab", false); + In<ELFT>::SymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::StrTab); + } + + if (Config->BuildId != BuildIdKind::None) { + In<ELFT>::BuildId = make<BuildIdSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::BuildId); + } + + InputSection<ELFT> *Common = createCommonSection<ELFT>(); + if (!Common->Data.empty()) { + In<ELFT>::Common = Common; + Symtab<ELFT>::X->Sections.push_back(Common); + } + + // Add MIPS-specific sections. + bool HasDynSymTab = !Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic; + if (Config->EMachine == EM_MIPS) { + if (!Config->Shared && HasDynSymTab) { + In<ELFT>::MipsRldMap = make<MipsRldMapSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::MipsRldMap); + } + if (auto *Sec = MipsAbiFlagsSection<ELFT>::create()) + Symtab<ELFT>::X->Sections.push_back(Sec); + if (auto *Sec = MipsOptionsSection<ELFT>::create()) + Symtab<ELFT>::X->Sections.push_back(Sec); + if (auto *Sec = MipsReginfoSection<ELFT>::create()) + Symtab<ELFT>::X->Sections.push_back(Sec); + } + + if (HasDynSymTab) { + In<ELFT>::DynSymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::DynStrTab); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::DynSymTab); + + In<ELFT>::VerSym = make<VersionTableSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::VerSym); + + if (!Config->VersionDefinitions.empty()) { + In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::VerDef); + } + + In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::VerNeed); + + if (Config->GnuHash) { + In<ELFT>::GnuHashTab = make<GnuHashTableSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::GnuHashTab); + } + + if (Config->SysvHash) { + In<ELFT>::HashTab = make<HashTableSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::HashTab); + } + + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Dynamic); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::DynStrTab); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::RelaDyn); + } + + // Add .got. MIPS' .got is so different from the other archs, + // it has its own class. + if (Config->EMachine == EM_MIPS) { + In<ELFT>::MipsGot = make<MipsGotSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::MipsGot); + } else { + In<ELFT>::Got = make<GotSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Got); + } + + In<ELFT>::GotPlt = make<GotPltSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::GotPlt); + In<ELFT>::IgotPlt = make<IgotPltSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::IgotPlt); + + if (Config->GdbIndex) { + In<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::GdbIndex); + } + + // We always need to add rel[a].plt to output if it has entries. + // Even for static linking it can contain R_[*]_IRELATIVE relocations. + In<ELFT>::RelaPlt = make<RelocationSection<ELFT>>( + Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::RelaPlt); + + // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure + // that the IRelative relocations are processed last by the dynamic loader + In<ELFT>::RelaIplt = make<RelocationSection<ELFT>>( + (Config->EMachine == EM_ARM) ? ".rel.dyn" : In<ELFT>::RelaPlt->Name, + false /*Sort*/); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::RelaIplt); + + In<ELFT>::Plt = make<PltSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Plt); + In<ELFT>::Iplt = make<IpltSection<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Iplt); + + if (Config->EhFrameHdr) { + In<ELFT>::EhFrameHdr = make<EhFrameHeader<ELFT>>(); + Symtab<ELFT>::X->Sections.push_back(In<ELFT>::EhFrameHdr); + } } template <class ELFT> @@ -297,7 +393,7 @@ static bool shouldKeepInSymtab(InputSectionBase<ELFT> *Sec, StringRef SymName, if (Sec == &InputSection<ELFT>::Discarded) return false; - if (Config->DiscardNone) + if (Config->Discard == DiscardPolicy::None) return true; // In ELF assembly .L symbols are normally discarded by the assembler. @@ -308,16 +404,22 @@ static bool shouldKeepInSymtab(InputSectionBase<ELFT> *Sec, StringRef SymName, if (!SymName.startswith(".L") && !SymName.empty()) return true; - if (Config->DiscardLocals) + if (Config->Discard == DiscardPolicy::Locals) return false; - return !(Sec->getSectionHdr()->sh_flags & SHF_MERGE); + return !Sec || !(Sec->Flags & SHF_MERGE); } template <class ELFT> static bool includeInSymtab(const SymbolBody &B) { if (!B.isLocal() && !B.symbol()->IsUsedInRegularObj) return false; + // If --retain-symbols-file is given, we'll keep only symbols listed in that + // file. + if (Config->Discard == DiscardPolicy::RetainFile && + !Config->RetainSymbolsFile.count(B.getName())) + return false; + if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B)) { // Always include absolute symbols. if (!D->Section) @@ -335,27 +437,25 @@ template <class ELFT> static bool includeInSymtab(const SymbolBody &B) { // Local symbols are not in the linker's symbol table. This function scans // each object file's symbol table to copy local symbols to the output. template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { - if (!Out<ELFT>::SymTab) + if (!In<ELFT>::SymTab) return; - for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F : - Symtab.getObjectFiles()) { - const char *StrTab = F->getStringTable().data(); + for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) { for (SymbolBody *B : F->getLocalSymbols()) { + if (!B->IsLocal) + fatal(toString(F) + + ": broken object: getLocalSymbols returns a non-local symbol"); auto *DR = dyn_cast<DefinedRegular<ELFT>>(B); + // No reason to keep local undefined symbol in symtab. if (!DR) continue; if (!includeInSymtab<ELFT>(*B)) continue; - StringRef SymName(StrTab + B->getNameOffset()); + InputSectionBase<ELFT> *Sec = DR->Section; - if (!shouldKeepInSymtab<ELFT>(Sec, SymName, *B)) + if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B)) continue; - ++Out<ELFT>::SymTab->NumLocals; - if (Config->Relocatable) - B->DynsymIndex = Out<ELFT>::SymTab->NumLocals; - F->KeptLocalSyms.push_back( - std::make_pair(DR, Out<ELFT>::SymTab->StrTabSec.addString(SymName))); + In<ELFT>::SymTab->addLocal(B); } } } @@ -376,136 +476,200 @@ static int getPPC64SectionRank(StringRef SectionName) { .Default(1); } -template <class ELFT> static bool isRelroSection(OutputSectionBase<ELFT> *Sec) { +// All sections with SHF_MIPS_GPREL flag should be grouped together +// because data in these sections is addressable with a gp relative address. +static int getMipsSectionRank(const OutputSectionBase *S) { + if ((S->Flags & SHF_MIPS_GPREL) == 0) + return 0; + if (S->getName() == ".got") + return 1; + return 2; +} + +template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) { if (!Config->ZRelro) return false; - typename ELFT::uint Flags = Sec->getFlags(); + uint64_t Flags = Sec->Flags; if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE)) return false; if (Flags & SHF_TLS) return true; - uint32_t Type = Sec->getType(); + uint32_t Type = Sec->Type; if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY || Type == SHT_PREINIT_ARRAY) return true; - if (Sec == Out<ELFT>::GotPlt) + if (Sec == In<ELFT>::GotPlt->OutSec) return Config->ZNow; - if (Sec == Out<ELFT>::Dynamic || Sec == Out<ELFT>::Got) + if (Sec == In<ELFT>::Dynamic->OutSec) + return true; + if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec) + return true; + if (Sec == Out<ELFT>::BssRelRo) return true; StringRef S = Sec->getName(); return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" || - S == ".eh_frame"; + S == ".eh_frame" || S == ".openbsd.randomdata"; } -// Output section ordering is determined by this function. template <class ELFT> -static bool compareSections(OutputSectionBase<ELFT> *A, - OutputSectionBase<ELFT> *B) { - typedef typename ELFT::uint uintX_t; - - int Comp = Script<ELFT>::X->compareSections(A->getName(), B->getName()); - if (Comp != 0) - return Comp < 0; - - uintX_t AFlags = A->getFlags(); - uintX_t BFlags = B->getFlags(); +static bool compareSectionsNonScript(const OutputSectionBase *A, + const OutputSectionBase *B) { + // Put .interp first because some loaders want to see that section + // on the first page of the executable file when loaded into memory. + bool AIsInterp = A->getName() == ".interp"; + bool BIsInterp = B->getName() == ".interp"; + if (AIsInterp != BIsInterp) + return AIsInterp; // Allocatable sections go first to reduce the total PT_LOAD size and // so debug info doesn't change addresses in actual code. - bool AIsAlloc = AFlags & SHF_ALLOC; - bool BIsAlloc = BFlags & SHF_ALLOC; + bool AIsAlloc = A->Flags & SHF_ALLOC; + bool BIsAlloc = B->Flags & SHF_ALLOC; if (AIsAlloc != BIsAlloc) return AIsAlloc; - // We don't have any special requirements for the relative order of - // two non allocatable sections. + // We don't have any special requirements for the relative order of two non + // allocatable sections. if (!AIsAlloc) return false; + // We want to put section specified by -T option first, so we + // can start assigning VA starting from them later. + auto AAddrSetI = Config->SectionStartMap.find(A->getName()); + auto BAddrSetI = Config->SectionStartMap.find(B->getName()); + bool AHasAddrSet = AAddrSetI != Config->SectionStartMap.end(); + bool BHasAddrSet = BAddrSetI != Config->SectionStartMap.end(); + if (AHasAddrSet != BHasAddrSet) + return AHasAddrSet; + if (AHasAddrSet) + return AAddrSetI->second < BAddrSetI->second; + // We want the read only sections first so that they go in the PT_LOAD // covering the program headers at the start of the file. - bool AIsWritable = AFlags & SHF_WRITE; - bool BIsWritable = BFlags & SHF_WRITE; + bool AIsWritable = A->Flags & SHF_WRITE; + bool BIsWritable = B->Flags & SHF_WRITE; if (AIsWritable != BIsWritable) return BIsWritable; - // For a corresponding reason, put non exec sections first (the program - // header PT_LOAD is not executable). - bool AIsExec = AFlags & SHF_EXECINSTR; - bool BIsExec = BFlags & SHF_EXECINSTR; - if (AIsExec != BIsExec) - return BIsExec; + if (!Config->SingleRoRx) { + // For a corresponding reason, put non exec sections first (the program + // header PT_LOAD is not executable). + // We only do that if we are not using linker scripts, since with linker + // scripts ro and rx sections are in the same PT_LOAD, so their relative + // order is not important. The same applies for -no-rosegment. + bool AIsExec = A->Flags & SHF_EXECINSTR; + bool BIsExec = B->Flags & SHF_EXECINSTR; + if (AIsExec != BIsExec) + return BIsExec; + } // If we got here we know that both A and B are in the same PT_LOAD. + bool AIsTls = A->Flags & SHF_TLS; + bool BIsTls = B->Flags & SHF_TLS; + bool AIsNoBits = A->Type == SHT_NOBITS; + bool BIsNoBits = B->Type == SHT_NOBITS; + + // The first requirement we have is to put (non-TLS) nobits sections last. The + // reason is that the only thing the dynamic linker will see about them is a + // p_memsz that is larger than p_filesz. Seeing that it zeros the end of the + // PT_LOAD, so that has to correspond to the nobits sections. + bool AIsNonTlsNoBits = AIsNoBits && !AIsTls; + bool BIsNonTlsNoBits = BIsNoBits && !BIsTls; + if (AIsNonTlsNoBits != BIsNonTlsNoBits) + return BIsNonTlsNoBits; + + // We place nobits RelRo sections before plain r/w ones, and non-nobits RelRo + // sections after r/w ones, so that the RelRo sections are contiguous. + bool AIsRelRo = isRelroSection<ELFT>(A); + bool BIsRelRo = isRelroSection<ELFT>(B); + if (AIsRelRo != BIsRelRo) + return AIsNonTlsNoBits ? AIsRelRo : BIsRelRo; + // The TLS initialization block needs to be a single contiguous block in a R/W - // PT_LOAD, so stick TLS sections directly before R/W sections. The TLS NOBITS - // sections are placed here as they don't take up virtual address space in the - // PT_LOAD. - bool AIsTls = AFlags & SHF_TLS; - bool BIsTls = BFlags & SHF_TLS; + // PT_LOAD, so stick TLS sections directly before the other RelRo R/W + // sections. The TLS NOBITS sections are placed here as they don't take up + // virtual address space in the PT_LOAD. if (AIsTls != BIsTls) return AIsTls; - // The next requirement we have is to put nobits sections last. The - // reason is that the only thing the dynamic linker will see about - // them is a p_memsz that is larger than p_filesz. Seeing that it - // zeros the end of the PT_LOAD, so that has to correspond to the - // nobits sections. - bool AIsNoBits = A->getType() == SHT_NOBITS; - bool BIsNoBits = B->getType() == SHT_NOBITS; + // Within the TLS initialization block, the non-nobits sections need to appear + // first. if (AIsNoBits != BIsNoBits) return BIsNoBits; - // We place RelRo section before plain r/w ones. - bool AIsRelRo = isRelroSection(A); - bool BIsRelRo = isRelroSection(B); - if (AIsRelRo != BIsRelRo) - return AIsRelRo; - // Some architectures have additional ordering restrictions for sections // within the same PT_LOAD. if (Config->EMachine == EM_PPC64) return getPPC64SectionRank(A->getName()) < getPPC64SectionRank(B->getName()); + if (Config->EMachine == EM_MIPS) + return getMipsSectionRank(A) < getMipsSectionRank(B); return false; } -// Until this function is called, common symbols do not belong to any section. -// This function adds them to end of BSS section. +// Output section ordering is determined by this function. template <class ELFT> -void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) { - if (Syms.empty()) - return; +static bool compareSections(const OutputSectionBase *A, + const OutputSectionBase *B) { + // For now, put sections mentioned in a linker script first. + int AIndex = Script<ELFT>::X->getSectionIndex(A->getName()); + int BIndex = Script<ELFT>::X->getSectionIndex(B->getName()); + bool AInScript = AIndex != INT_MAX; + bool BInScript = BIndex != INT_MAX; + if (AInScript != BInScript) + return AInScript; + // If both are in the script, use that order. + if (AInScript) + return AIndex < BIndex; + + return compareSectionsNonScript<ELFT>(A, B); +} - // Sort the common symbols by alignment as an heuristic to pack them better. - std::stable_sort(Syms.begin(), Syms.end(), - [](const DefinedCommon *A, const DefinedCommon *B) { - return A->Alignment > B->Alignment; - }); - - uintX_t Off = Out<ELFT>::Bss->getSize(); - for (DefinedCommon *C : Syms) { - Off = alignTo(Off, C->Alignment); - Out<ELFT>::Bss->updateAlignment(C->Alignment); - C->OffsetInBss = Off; - Off += C->Size; - } +// Program header entry +PhdrEntry::PhdrEntry(unsigned Type, unsigned Flags) { + p_type = Type; + p_flags = Flags; +} - Out<ELFT>::Bss->setSize(Off); +void PhdrEntry::add(OutputSectionBase *Sec) { + Last = Sec; + if (!First) + First = Sec; + p_align = std::max(p_align, Sec->Addralign); + if (p_type == PT_LOAD) + Sec->FirstInPtLoad = First; } template <class ELFT> -static Symbol *addOptionalSynthetic(SymbolTable<ELFT> &Table, StringRef Name, - OutputSectionBase<ELFT> *Sec, - typename ELFT::uint Val) { - SymbolBody *S = Table.find(Name); +static void addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec, + typename ELFT::uint Val, + uint8_t StOther = STV_HIDDEN) { + if (SymbolBody *S = Symtab<ELFT>::X->find(Name)) + if (!S->isInCurrentDSO()) + Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, StOther); +} + +template <class ELFT> +static Symbol *addRegular(StringRef Name, InputSectionBase<ELFT> *Sec, + typename ELFT::uint Value) { + // The linker generated symbols are added as STB_WEAK to allow user defined + // ones to override them. + return Symtab<ELFT>::X->addRegular(Name, STV_HIDDEN, STT_NOTYPE, Value, + /*Size=*/0, STB_WEAK, Sec, + /*File=*/nullptr); +} + +template <class ELFT> +static Symbol *addOptionalRegular(StringRef Name, InputSectionBase<ELFT> *IS, + typename ELFT::uint Value) { + SymbolBody *S = Symtab<ELFT>::X->find(Name); if (!S) return nullptr; - if (!S->isUndefined() && !S->isShared()) + if (S->isInCurrentDSO()) return S->symbol(); - return Table.addSynthetic(Name, Sec, Val); + return addRegular(Name, IS, Value); } // The beginning and the ending of .rel[a].plt section are marked @@ -515,14 +679,13 @@ static Symbol *addOptionalSynthetic(SymbolTable<ELFT> &Table, StringRef Name, // need these symbols, since IRELATIVE relocs are resolved through GOT // and PLT. For details, see http://www.airs.com/blog/archives/403. template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() { - if (isOutputDynamic() || !Out<ELFT>::RelaPlt) + if (In<ELFT>::DynSymTab) return; StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start"; - addOptionalSynthetic(Symtab, S, Out<ELFT>::RelaPlt, 0); + addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, 0); S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end"; - addOptionalSynthetic(Symtab, S, Out<ELFT>::RelaPlt, - DefinedSynthetic<ELFT>::SectionEnd); + addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1); } // The linker is expected to define some symbols depending on @@ -530,24 +693,28 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() { template <class ELFT> void Writer<ELFT>::addReservedSymbols() { if (Config->EMachine == EM_MIPS) { // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer - // so that it points to an absolute address which is relative to GOT. + // so that it points to an absolute address which by default is relative + // to GOT. Default offset is 0x7ff0. // See "Global Data Symbols" in Chapter 6 in the following document: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - Symtab.addSynthetic("_gp", Out<ELFT>::Got, MipsGPOffset); + ElfSym<ELFT>::MipsGp = + Symtab<ELFT>::X->addAbsolute("_gp", STV_HIDDEN, STB_LOCAL); // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between - // start of function and 'gp' pointer into GOT. - Symbol *Sym = - addOptionalSynthetic(Symtab, "_gp_disp", Out<ELFT>::Got, MipsGPOffset); - if (Sym) - ElfSym<ELFT>::MipsGpDisp = Sym->body(); + // start of function and 'gp' pointer into GOT. To simplify relocation + // calculation we assign _gp value to it and calculate corresponding + // relocations as relative to this value. + if (Symtab<ELFT>::X->find("_gp_disp")) + ElfSym<ELFT>::MipsGpDisp = + Symtab<ELFT>::X->addAbsolute("_gp_disp", STV_HIDDEN, STB_LOCAL); // The __gnu_local_gp is a magic symbol equal to the current value of 'gp' // pointer. This symbol is used in the code generated by .cpload pseudo-op // in case of using -mno-shared option. // https://sourceware.org/ml/binutils/2004-12/msg00094.html - addOptionalSynthetic(Symtab, "__gnu_local_gp", Out<ELFT>::Got, - MipsGPOffset); + if (Symtab<ELFT>::X->find("__gnu_local_gp")) + ElfSym<ELFT>::MipsLocalGp = + Symtab<ELFT>::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL); } // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol @@ -562,27 +729,35 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() { // an undefined symbol in the .o files. // Given that the symbol is effectively unused, we just create a dummy // hidden one to avoid the undefined symbol error. - if (!Config->Relocatable) - Symtab.addIgnored("_GLOBAL_OFFSET_TABLE_"); + Symtab<ELFT>::X->addIgnored("_GLOBAL_OFFSET_TABLE_"); // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For // static linking the linker is required to optimize away any references to // __tls_get_addr, so it's not defined anywhere. Create a hidden definition - // to avoid the undefined symbol error. - if (!isOutputDynamic()) - Symtab.addIgnored("__tls_get_addr"); + // to avoid the undefined symbol error. As usual special cases are ARM and + // MIPS - the libc for these targets defines __tls_get_addr itself because + // there are no TLS optimizations for these targets. + if (!In<ELFT>::DynSymTab && + (Config->EMachine != EM_MIPS && Config->EMachine != EM_ARM)) + Symtab<ELFT>::X->addIgnored("__tls_get_addr"); + + // If linker script do layout we do not need to create any standart symbols. + if (ScriptConfig->HasSections) + return; + + ElfSym<ELFT>::EhdrStart = Symtab<ELFT>::X->addIgnored("__ehdr_start"); auto Define = [this](StringRef S, DefinedRegular<ELFT> *&Sym1, DefinedRegular<ELFT> *&Sym2) { - Sym1 = Symtab.addIgnored(S, STV_DEFAULT); + Sym1 = Symtab<ELFT>::X->addIgnored(S, STV_DEFAULT); // The name without the underscore is not a reserved name, // so it is defined only when there is a reference against it. assert(S.startswith("_")); S = S.substr(1); - if (SymbolBody *B = Symtab.find(S)) + if (SymbolBody *B = Symtab<ELFT>::X->find(S)) if (B->isUndefined()) - Sym2 = Symtab.addAbsolute(S, STV_DEFAULT); + Sym2 = Symtab<ELFT>::X->addAbsolute(S, STV_DEFAULT); }; Define("_end", ElfSym<ELFT>::End, ElfSym<ELFT>::End2); @@ -592,65 +767,239 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() { // Sort input sections by section name suffixes for // __attribute__((init_priority(N))). -template <class ELFT> static void sortInitFini(OutputSectionBase<ELFT> *S) { +template <class ELFT> static void sortInitFini(OutputSectionBase *S) { if (S) reinterpret_cast<OutputSection<ELFT> *>(S)->sortInitFini(); } // Sort input sections by the special rule for .ctors and .dtors. -template <class ELFT> static void sortCtorsDtors(OutputSectionBase<ELFT> *S) { +template <class ELFT> static void sortCtorsDtors(OutputSectionBase *S) { if (S) reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors(); } -// Create output section objects and add them to OutputSections. -template <class ELFT> void Writer<ELFT>::createSections() { - // Create output sections for input object file sections. - std::vector<OutputSectionBase<ELFT> *> RegularSections; - OutputSectionFactory<ELFT> Factory; - for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F : - Symtab.getObjectFiles()) { - for (InputSectionBase<ELFT> *C : F->getSections()) { - if (isDiscarded(C)) { - reportDiscarded(C, F); +// Sort input sections using the list provided by --symbol-ordering-file. +template <class ELFT> +static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> OutputSections) { + if (Config->SymbolOrderingFile.empty()) + return; + + // Build a map from symbols to their priorities. Symbols that didn't + // appear in the symbol ordering file have the lowest priority 0. + // All explicitly mentioned symbols have negative (higher) priorities. + DenseMap<StringRef, int> SymbolOrder; + int Priority = -Config->SymbolOrderingFile.size(); + for (StringRef S : Config->SymbolOrderingFile) + SymbolOrder.insert({S, Priority++}); + + // Build a map from sections to their priorities. + DenseMap<InputSectionBase<ELFT> *, int> SectionOrder; + for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) { + for (SymbolBody *Body : File->getSymbols()) { + auto *D = dyn_cast<DefinedRegular<ELFT>>(Body); + if (!D || !D->Section) continue; - } - OutputSectionBase<ELFT> *Sec; - bool IsNew; - std::tie(Sec, IsNew) = Factory.create(C, getOutputSectionName(C)); - if (IsNew) { - OwningSections.emplace_back(Sec); - OutputSections.push_back(Sec); - RegularSections.push_back(Sec); - } - Sec->addSection(C); + int &Priority = SectionOrder[D->Section]; + Priority = std::min(Priority, SymbolOrder.lookup(D->getName())); } } - // If we have a .opd section (used under PPC64 for function descriptors), - // store a pointer to it here so that we can use it later when processing - // relocations. - Out<ELFT>::Opd = Factory.lookup(".opd", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC); + // Sort sections by priority. + for (OutputSectionBase *Base : OutputSections) + if (auto *Sec = dyn_cast<OutputSection<ELFT>>(Base)) + Sec->sort([&](InputSection<ELFT> *S) { return SectionOrder.lookup(S); }); +} + +template <class ELFT> +void Writer<ELFT>::forEachRelSec( + std::function<void(InputSectionBase<ELFT> &)> Fn) { + for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections) { + if (!IS->Live) + continue; + // Scan all relocations. Each relocation goes through a series + // of tests to determine if it needs special treatment, such as + // creating GOT, PLT, copy relocations, etc. + // Note that relocations for non-alloc sections are directly + // processed by InputSection::relocateNonAlloc. + if (!(IS->Flags & SHF_ALLOC)) + continue; + if (isa<InputSection<ELFT>>(IS) || isa<EhInputSection<ELFT>>(IS)) + Fn(*IS); + } +} + +template <class ELFT> +void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) { + if (!IS) + return; + + if (!IS->Live) { + reportDiscarded(IS); + return; + } + OutputSectionBase *Sec; + bool IsNew; + StringRef OutsecName = getOutputSectionName(IS->Name); + std::tie(Sec, IsNew) = Factory.create(IS, OutsecName); + if (IsNew) + OutputSections.push_back(Sec); + Sec->addSection(IS); +} + +template <class ELFT> void Writer<ELFT>::createSections() { + for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections) + addInputSec(IS); + + sortBySymbolsOrder<ELFT>(OutputSections); + sortInitFini<ELFT>(findSection(".init_array")); + sortInitFini<ELFT>(findSection(".fini_array")); + sortCtorsDtors<ELFT>(findSection(".ctors")); + sortCtorsDtors<ELFT>(findSection(".dtors")); + + for (OutputSectionBase *Sec : OutputSections) + Sec->assignOffsets(); +} + +template <class ELFT> +static bool canSharePtLoad(const OutputSectionBase &S1, + const OutputSectionBase &S2) { + if (!(S1.Flags & SHF_ALLOC) || !(S2.Flags & SHF_ALLOC)) + return false; + + bool S1IsWrite = S1.Flags & SHF_WRITE; + bool S2IsWrite = S2.Flags & SHF_WRITE; + if (S1IsWrite != S2IsWrite) + return false; + + if (!S1IsWrite) + return true; // RO and RX share a PT_LOAD with linker scripts. + return (S1.Flags & SHF_EXECINSTR) == (S2.Flags & SHF_EXECINSTR); +} + +template <class ELFT> void Writer<ELFT>::sortSections() { + // Don't sort if using -r. It is not necessary and we want to preserve the + // relative order for SHF_LINK_ORDER sections. + if (Config->Relocatable) + return; + if (!ScriptConfig->HasSections) { + std::stable_sort(OutputSections.begin(), OutputSections.end(), + compareSectionsNonScript<ELFT>); + return; + } + Script<ELFT>::X->adjustSectionsBeforeSorting(); + + // The order of the sections in the script is arbitrary and may not agree with + // compareSectionsNonScript. This means that we cannot easily define a + // strict weak ordering. To see why, consider a comparison of a section in the + // script and one not in the script. We have a two simple options: + // * Make them equivalent (a is not less than b, and b is not less than a). + // The problem is then that equivalence has to be transitive and we can + // have sections a, b and c with only b in a script and a less than c + // which breaks this property. + // * Use compareSectionsNonScript. Given that the script order doesn't have + // to match, we can end up with sections a, b, c, d where b and c are in the + // script and c is compareSectionsNonScript less than b. In which case d + // can be equivalent to c, a to b and d < a. As a concrete example: + // .a (rx) # not in script + // .b (rx) # in script + // .c (ro) # in script + // .d (ro) # not in script + // + // The way we define an order then is: + // * First put script sections at the start and sort the script and + // non-script sections independently. + // * Move each non-script section to its preferred position. We try + // to put each section in the last position where it it can share + // a PT_LOAD. + + std::stable_sort(OutputSections.begin(), OutputSections.end(), + compareSections<ELFT>); - Out<ELFT>::Dynamic->PreInitArraySec = Factory.lookup( - ".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE | SHF_ALLOC); - Out<ELFT>::Dynamic->InitArraySec = - Factory.lookup(".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC); - Out<ELFT>::Dynamic->FiniArraySec = - Factory.lookup(".fini_array", SHT_FINI_ARRAY, SHF_WRITE | SHF_ALLOC); + auto I = OutputSections.begin(); + auto E = OutputSections.end(); + auto NonScriptI = + std::find_if(OutputSections.begin(), E, [](OutputSectionBase *S) { + return Script<ELFT>::X->getSectionIndex(S->getName()) == INT_MAX; + }); + while (NonScriptI != E) { + auto BestPos = std::max_element( + I, NonScriptI, [&](OutputSectionBase *&A, OutputSectionBase *&B) { + bool ACanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *A); + bool BCanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *B); + if (ACanSharePtLoad != BCanSharePtLoad) + return BCanSharePtLoad; + + bool ACmp = compareSectionsNonScript<ELFT>(*NonScriptI, A); + bool BCmp = compareSectionsNonScript<ELFT>(*NonScriptI, B); + if (ACmp != BCmp) + return BCmp; // FIXME: missing test + + size_t PosA = &A - &OutputSections[0]; + size_t PosB = &B - &OutputSections[0]; + return ACmp ? PosA > PosB : PosA < PosB; + }); + + // max_element only returns NonScriptI if the range is empty. If the range + // is not empty we should consider moving the the element forward one + // position. + if (BestPos != NonScriptI && + !compareSectionsNonScript<ELFT>(*NonScriptI, *BestPos)) + ++BestPos; + std::rotate(BestPos, NonScriptI, NonScriptI + 1); + ++NonScriptI; + } - // Sort section contents for __attribute__((init_priority(N)). - sortInitFini(Out<ELFT>::Dynamic->InitArraySec); - sortInitFini(Out<ELFT>::Dynamic->FiniArraySec); - sortCtorsDtors(Factory.lookup(".ctors", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC)); - sortCtorsDtors(Factory.lookup(".dtors", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC)); + Script<ELFT>::X->adjustSectionsAfterSorting(); +} + +template <class ELFT> +static void +finalizeSynthetic(const std::vector<SyntheticSection<ELFT> *> &Sections) { + for (SyntheticSection<ELFT> *SS : Sections) + if (SS && SS->OutSec && !SS->empty()) { + SS->finalize(); + SS->OutSec->Size = 0; + SS->OutSec->assignOffsets(); + } +} + +// We need to add input synthetic sections early in createSyntheticSections() +// to make them visible from linkescript side. But not all sections are always +// required to be in output. For example we don't need dynamic section content +// sometimes. This function filters out such unused sections from output. +template <class ELFT> +static void removeUnusedSyntheticSections(std::vector<OutputSectionBase *> &V) { + // Input synthetic sections are placed after all regular ones. We iterate over + // them all and exit at first non-synthetic. + for (InputSectionBase<ELFT> *S : llvm::reverse(Symtab<ELFT>::X->Sections)) { + SyntheticSection<ELFT> *SS = dyn_cast<SyntheticSection<ELFT>>(S); + if (!SS) + return; + if (!SS->empty() || !SS->OutSec) + continue; + + OutputSection<ELFT> *OutSec = cast<OutputSection<ELFT>>(SS->OutSec); + OutSec->Sections.erase( + std::find(OutSec->Sections.begin(), OutSec->Sections.end(), SS)); + // If there is no other sections in output section, remove it from output. + if (OutSec->Sections.empty()) + V.erase(std::find(V.begin(), V.end(), OutSec)); + } +} + +// Create output section objects and add them to OutputSections. +template <class ELFT> void Writer<ELFT>::finalizeSections() { + Out<ELFT>::DebugInfo = findSection(".debug_info"); + Out<ELFT>::PreinitArray = findSection(".preinit_array"); + Out<ELFT>::InitArray = findSection(".init_array"); + Out<ELFT>::FiniArray = findSection(".fini_array"); // The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop // symbols for sections, so that the runtime can get the start and end // addresses of each section by section name. Add such symbols. if (!Config->Relocatable) { addStartEndSymbols(); - for (OutputSectionBase<ELFT> *Sec : RegularSections) + for (OutputSectionBase *Sec : OutputSections) addStartStopSymbols(Sec); } @@ -658,16 +1007,12 @@ template <class ELFT> void Writer<ELFT>::createSections() { // It should be okay as no one seems to care about the type. // Even the author of gold doesn't remember why gold behaves that way. // https://sourceware.org/ml/binutils/2002-03/msg00360.html - if (isOutputDynamic()) - Symtab.addSynthetic("_DYNAMIC", Out<ELFT>::Dynamic, 0); + if (In<ELFT>::DynSymTab) + addRegular("_DYNAMIC", In<ELFT>::Dynamic, 0); // Define __rel[a]_iplt_{start,end} symbols if needed. addRelIpltSymbols(); - // Add scripted symbols with zero values now. - // Real values will be assigned later - Script<ELFT>::X->addScriptedSymbols(); - if (!Out<ELFT>::EhFrame->empty()) { OutputSections.push_back(Out<ELFT>::EhFrame); Out<ELFT>::EhFrame->finalize(); @@ -675,190 +1020,104 @@ template <class ELFT> void Writer<ELFT>::createSections() { // Scan relocations. This must be done after every symbol is declared so that // we can correctly decide if a dynamic relocation is needed. - for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F : - Symtab.getObjectFiles()) { - for (InputSectionBase<ELFT> *C : F->getSections()) { - if (isDiscarded(C)) - continue; - if (auto *S = dyn_cast<InputSection<ELFT>>(C)) { - scanRelocations(*S); - continue; - } - if (auto *S = dyn_cast<EhInputSection<ELFT>>(C)) - if (S->RelocSection) - scanRelocations(*S, *S->RelocSection); - } - } - - for (OutputSectionBase<ELFT> *Sec : OutputSections) - Sec->assignOffsets(); + forEachRelSec(scanRelocations<ELFT>); // Now that we have defined all possible symbols including linker- // synthesized ones. Visit all symbols to give the finishing touches. - std::vector<DefinedCommon *> CommonSymbols; - for (Symbol *S : Symtab.getSymbols()) { + for (Symbol *S : Symtab<ELFT>::X->getSymbols()) { SymbolBody *Body = S->body(); - // We only report undefined symbols in regular objects. This means that we - // will accept an undefined reference in bitcode if it can be optimized out. - if (S->IsUsedInRegularObj && Body->isUndefined() && !S->isWeak()) - reportUndefined<ELFT>(Symtab, Body); - - if (auto *C = dyn_cast<DefinedCommon>(Body)) - CommonSymbols.push_back(C); - if (!includeInSymtab<ELFT>(*Body)) continue; - if (Out<ELFT>::SymTab) - Out<ELFT>::SymTab->addSymbol(Body); + if (In<ELFT>::SymTab) + In<ELFT>::SymTab->addGlobal(Body); - if (isOutputDynamic() && S->includeInDynsym()) { - Out<ELFT>::DynSymTab->addSymbol(Body); + if (In<ELFT>::DynSymTab && S->includeInDynsym()) { + In<ELFT>::DynSymTab->addGlobal(Body); if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body)) if (SS->file()->isNeeded()) - Out<ELFT>::VerNeed->addSymbol(SS); + In<ELFT>::VerNeed->addSymbol(SS); } } // Do not proceed if there was an undefined symbol. - if (HasError) + if (ErrorCount) return; - addCommonSymbols(CommonSymbols); - // So far we have added sections from input object files. // This function adds linker-created Out<ELFT>::* sections. addPredefinedSections(); + removeUnusedSyntheticSections<ELFT>(OutputSections); - std::stable_sort(OutputSections.begin(), OutputSections.end(), - compareSections<ELFT>); + sortSections(); unsigned I = 1; - for (OutputSectionBase<ELFT> *Sec : OutputSections) { + for (OutputSectionBase *Sec : OutputSections) { Sec->SectionIndex = I++; - Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName())); + Sec->ShName = In<ELFT>::ShStrTab->addString(Sec->getName()); } - // Finalizers fix each section's size. - // .dynsym is finalized early since that may fill up .gnu.hash. - if (isOutputDynamic()) - Out<ELFT>::DynSymTab->finalize(); + // Binary and relocatable output does not have PHDRS. + // The headers have to be created before finalize as that can influence the + // image base and the dynamic section on mips includes the image base. + if (!Config->Relocatable && !Config->OFormatBinary) { + Phdrs = Script<ELFT>::X->hasPhdrsCommands() ? Script<ELFT>::X->createPhdrs() + : createPhdrs(); + addPtArmExid(Phdrs); + fixHeaders(); + } // Fill other section headers. The dynamic table is finalized // at the end because some tags like RELSZ depend on result - // of finalizing other sections. The dynamic string table is - // finalized once the .dynamic finalizer has added a few last - // strings. See DynamicSection::finalize() - for (OutputSectionBase<ELFT> *Sec : OutputSections) - if (Sec != Out<ELFT>::DynStrTab && Sec != Out<ELFT>::Dynamic) - Sec->finalize(); - - if (isOutputDynamic()) - Out<ELFT>::Dynamic->finalize(); - - // Now that all output offsets are fixed. Finalize mergeable sections - // to fix their maps from input offsets to output offsets. - for (OutputSectionBase<ELFT> *Sec : OutputSections) - Sec->finalizePieces(); -} - -template <class ELFT> bool Writer<ELFT>::needsGot() { - if (!Out<ELFT>::Got->empty()) - return true; - - // We add the .got section to the result for dynamic MIPS target because - // its address and properties are mentioned in the .dynamic section. - if (Config->EMachine == EM_MIPS) - return true; - - // If we have a relocation that is relative to GOT (such as GOTOFFREL), - // we need to emit a GOT even if it's empty. - return Out<ELFT>::Got->HasGotOffRel; + // of finalizing other sections. + for (OutputSectionBase *Sec : OutputSections) + Sec->finalize(); + + // Dynamic section must be the last one in this list and dynamic + // symbol table section (DynSymTab) must be the first one. + finalizeSynthetic<ELFT>( + {In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab, + In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab, + In<ELFT>::VerDef, In<ELFT>::DynStrTab, In<ELFT>::GdbIndex, + In<ELFT>::Got, In<ELFT>::MipsGot, In<ELFT>::IgotPlt, + In<ELFT>::GotPlt, In<ELFT>::RelaDyn, In<ELFT>::RelaIplt, + In<ELFT>::RelaPlt, In<ELFT>::Plt, In<ELFT>::Iplt, + In<ELFT>::Plt, In<ELFT>::EhFrameHdr, In<ELFT>::VerSym, + In<ELFT>::VerNeed, In<ELFT>::Dynamic}); } -// This function add Out<ELFT>::* sections to OutputSections. template <class ELFT> void Writer<ELFT>::addPredefinedSections() { - auto Add = [&](OutputSectionBase<ELFT> *C) { - if (C) - OutputSections.push_back(C); - }; - - // A core file does not usually contain unmodified segments except - // the first page of the executable. Add the build ID section to beginning of - // the file so that the section is included in the first page. - if (Out<ELFT>::BuildId) - OutputSections.insert(OutputSections.begin(), Out<ELFT>::BuildId); - - // Add .interp at first because some loaders want to see that section - // on the first page of the executable file when loaded into memory. - if (needsInterpSection()) - OutputSections.insert(OutputSections.begin(), Out<ELFT>::Interp); - - // This order is not the same as the final output order - // because we sort the sections using their attributes below. - Add(Out<ELFT>::SymTab); - Add(Out<ELFT>::ShStrTab); - Add(Out<ELFT>::StrTab); - if (isOutputDynamic()) { - Add(Out<ELFT>::DynSymTab); - - bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0; - if (Out<ELFT>::VerDef || HasVerNeed) - Add(Out<ELFT>::VerSym); - Add(Out<ELFT>::VerDef); - if (HasVerNeed) - Add(Out<ELFT>::VerNeed); - - Add(Out<ELFT>::GnuHashTab); - Add(Out<ELFT>::HashTab); - Add(Out<ELFT>::Dynamic); - Add(Out<ELFT>::DynStrTab); - if (Out<ELFT>::RelaDyn->hasRelocs()) - Add(Out<ELFT>::RelaDyn); - Add(Out<ELFT>::MipsRldMap); - } - - // We always need to add rel[a].plt to output if it has entries. - // Even during static linking it can contain R_[*]_IRELATIVE relocations. - if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) { - Add(Out<ELFT>::RelaPlt); - Out<ELFT>::RelaPlt->Static = !isOutputDynamic(); - } - - if (needsGot()) - Add(Out<ELFT>::Got); - if (Out<ELFT>::GotPlt && !Out<ELFT>::GotPlt->empty()) - Add(Out<ELFT>::GotPlt); - if (!Out<ELFT>::Plt->empty()) - Add(Out<ELFT>::Plt); - if (!Out<ELFT>::EhFrame->empty()) - Add(Out<ELFT>::EhFrameHdr); - if (Out<ELFT>::Bss->getSize() > 0) - Add(Out<ELFT>::Bss); + if (Out<ELFT>::Bss->Size > 0) + OutputSections.push_back(Out<ELFT>::Bss); + if (Out<ELFT>::BssRelRo->Size > 0) + OutputSections.push_back(Out<ELFT>::BssRelRo); + + auto OS = dyn_cast_or_null<OutputSection<ELFT>>(findSection(".ARM.exidx")); + if (OS && !OS->Sections.empty() && !Config->Relocatable) + OS->addSection(make<ARMExidxSentinelSection<ELFT>>()); + + addInputSec(In<ELFT>::SymTab); + addInputSec(In<ELFT>::ShStrTab); + addInputSec(In<ELFT>::StrTab); } // The linker is expected to define SECNAME_start and SECNAME_end // symbols for a few sections. This function defines them. template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { - auto Define = [&](StringRef Start, StringRef End, - OutputSectionBase<ELFT> *OS) { - if (OS) { - this->Symtab.addSynthetic(Start, OS, 0); - this->Symtab.addSynthetic(End, OS, DefinedSynthetic<ELFT>::SectionEnd); - } else { - addOptionalSynthetic(this->Symtab, Start, - (OutputSectionBase<ELFT> *)nullptr, 0); - addOptionalSynthetic(this->Symtab, End, - (OutputSectionBase<ELFT> *)nullptr, 0); - } + auto Define = [&](StringRef Start, StringRef End, OutputSectionBase *OS) { + // These symbols resolve to the image base if the section does not exist. + // A special value -1 indicates end of the section. + addOptionalSynthetic<ELFT>(Start, OS, 0); + addOptionalSynthetic<ELFT>(End, OS, OS ? -1 : 0); }; Define("__preinit_array_start", "__preinit_array_end", - Out<ELFT>::Dynamic->PreInitArraySec); - Define("__init_array_start", "__init_array_end", - Out<ELFT>::Dynamic->InitArraySec); - Define("__fini_array_start", "__fini_array_end", - Out<ELFT>::Dynamic->FiniArraySec); + Out<ELFT>::PreinitArray); + Define("__init_array_start", "__init_array_end", Out<ELFT>::InitArray); + Define("__fini_array_start", "__fini_array_end", Out<ELFT>::FiniArray); + + if (OutputSectionBase *Sec = findSection(".ARM.exidx")) + Define("__exidx_start", "__exidx_end", Sec); } // If a section name is valid as a C identifier (which is rare because of @@ -867,189 +1126,271 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { // respectively. This is not requested by the ELF standard, but GNU ld and // gold provide the feature, and used by many programs. template <class ELFT> -void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) { +void Writer<ELFT>::addStartStopSymbols(OutputSectionBase *Sec) { StringRef S = Sec->getName(); if (!isValidCIdentifier(S)) return; - StringSaver Saver(Alloc); - StringRef Start = Saver.save("__start_" + S); - StringRef Stop = Saver.save("__stop_" + S); - if (SymbolBody *B = Symtab.find(Start)) - if (B->isUndefined()) - Symtab.addSynthetic(Start, Sec, 0); - if (SymbolBody *B = Symtab.find(Stop)) - if (B->isUndefined()) - Symtab.addSynthetic(Stop, Sec, DefinedSynthetic<ELFT>::SectionEnd); + addOptionalSynthetic<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT); + addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT); } -template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) { - if (!(Sec->getFlags() & SHF_ALLOC)) +template <class ELFT> +OutputSectionBase *Writer<ELFT>::findSection(StringRef Name) { + for (OutputSectionBase *Sec : OutputSections) + if (Sec->getName() == Name) + return Sec; + return nullptr; +} + +template <class ELFT> static bool needsPtLoad(OutputSectionBase *Sec) { + if (!(Sec->Flags & SHF_ALLOC)) return false; // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is // responsible for allocating space for them, not the PT_LOAD that // contains the TLS initialization image. - if (Sec->getFlags() & SHF_TLS && Sec->getType() == SHT_NOBITS) + if (Sec->Flags & SHF_TLS && Sec->Type == SHT_NOBITS) return false; return true; } -static uint32_t toPhdrFlags(uint64_t Flags) { - uint32_t Ret = PF_R; - if (Flags & SHF_WRITE) - Ret |= PF_W; - if (Flags & SHF_EXECINSTR) - Ret |= PF_X; - return Ret; +// Linker scripts are responsible for aligning addresses. Unfortunately, most +// linker scripts are designed for creating two PT_LOADs only, one RX and one +// RW. This means that there is no alignment in the RO to RX transition and we +// cannot create a PT_LOAD there. +template <class ELFT> +static typename ELFT::uint computeFlags(typename ELFT::uint F) { + if (Config->OMagic) + return PF_R | PF_W | PF_X; + if (Config->SingleRoRx && !(F & PF_W)) + return F | PF_X; + return F; } // Decide which program headers to create and which sections to include in each // one. -template <class ELFT> void Writer<ELFT>::createPhdrs() { - auto AddHdr = [this](unsigned Type, unsigned Flags) { - return &*Phdrs.emplace(Phdrs.end(), Type, Flags); - }; - - auto AddSec = [](Phdr &Hdr, OutputSectionBase<ELFT> *Sec) { - Hdr.Last = Sec; - if (!Hdr.First) - Hdr.First = Sec; - Hdr.H.p_align = std::max<uintX_t>(Hdr.H.p_align, Sec->getAlignment()); +template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() { + std::vector<PhdrEntry> Ret; + auto AddHdr = [&](unsigned Type, unsigned Flags) -> PhdrEntry * { + Ret.emplace_back(Type, Flags); + return &Ret.back(); }; // The first phdr entry is PT_PHDR which describes the program header itself. - Phdr &Hdr = *AddHdr(PT_PHDR, PF_R); - AddSec(Hdr, Out<ELFT>::ProgramHeaders); + PhdrEntry &Hdr = *AddHdr(PT_PHDR, PF_R); + Hdr.add(Out<ELFT>::ProgramHeaders); // PT_INTERP must be the second entry if exists. - if (needsInterpSection()) { - Phdr &Hdr = *AddHdr(PT_INTERP, toPhdrFlags(Out<ELFT>::Interp->getFlags())); - AddSec(Hdr, Out<ELFT>::Interp); + if (OutputSectionBase *Sec = findSection(".interp")) { + PhdrEntry &Hdr = *AddHdr(PT_INTERP, Sec->getPhdrFlags()); + Hdr.add(Sec); } // Add the first PT_LOAD segment for regular output sections. - uintX_t Flags = PF_R; - Phdr *Load = AddHdr(PT_LOAD, Flags); - AddSec(*Load, Out<ELFT>::ElfHeader); - AddSec(*Load, Out<ELFT>::ProgramHeaders); - - Phdr TlsHdr(PT_TLS, PF_R); - Phdr RelRo(PT_GNU_RELRO, PF_R); - Phdr Note(PT_NOTE, PF_R); - for (OutputSectionBase<ELFT> *Sec : OutputSections) { - if (!(Sec->getFlags() & SHF_ALLOC)) + uintX_t Flags = computeFlags<ELFT>(PF_R); + PhdrEntry *Load = AddHdr(PT_LOAD, Flags); + + PhdrEntry TlsHdr(PT_TLS, PF_R); + PhdrEntry RelRo(PT_GNU_RELRO, PF_R); + PhdrEntry Note(PT_NOTE, PF_R); + for (OutputSectionBase *Sec : OutputSections) { + if (!(Sec->Flags & SHF_ALLOC)) break; // If we meet TLS section then we create TLS header - // and put all TLS sections inside for futher use when + // and put all TLS sections inside for further use when // assign addresses. - if (Sec->getFlags() & SHF_TLS) - AddSec(TlsHdr, Sec); + if (Sec->Flags & SHF_TLS) + TlsHdr.add(Sec); if (!needsPtLoad<ELFT>(Sec)) continue; - // If flags changed then we want new load segment. - uintX_t NewFlags = toPhdrFlags(Sec->getFlags()); - if (Flags != NewFlags) { + // Segments are contiguous memory regions that has the same attributes + // (e.g. executable or writable). There is one phdr for each segment. + // Therefore, we need to create a new phdr when the next section has + // different flags or is loaded at a discontiguous address using AT linker + // script command. + uintX_t NewFlags = computeFlags<ELFT>(Sec->getPhdrFlags()); + if (Script<ELFT>::X->hasLMA(Sec->getName()) || Flags != NewFlags) { Load = AddHdr(PT_LOAD, NewFlags); Flags = NewFlags; } - AddSec(*Load, Sec); + Load->add(Sec); - if (isRelroSection(Sec)) - AddSec(RelRo, Sec); - if (Sec->getType() == SHT_NOTE) - AddSec(Note, Sec); + if (isRelroSection<ELFT>(Sec)) + RelRo.add(Sec); + if (Sec->Type == SHT_NOTE) + Note.add(Sec); } // Add the TLS segment unless it's empty. if (TlsHdr.First) - Phdrs.push_back(std::move(TlsHdr)); + Ret.push_back(std::move(TlsHdr)); // Add an entry for .dynamic. - if (isOutputDynamic()) { - Phdr &H = *AddHdr(PT_DYNAMIC, toPhdrFlags(Out<ELFT>::Dynamic->getFlags())); - AddSec(H, Out<ELFT>::Dynamic); + if (In<ELFT>::DynSymTab) { + PhdrEntry &H = + *AddHdr(PT_DYNAMIC, In<ELFT>::Dynamic->OutSec->getPhdrFlags()); + H.add(In<ELFT>::Dynamic->OutSec); } // PT_GNU_RELRO includes all sections that should be marked as // read-only by dynamic linker after proccessing relocations. if (RelRo.First) - Phdrs.push_back(std::move(RelRo)); + Ret.push_back(std::move(RelRo)); // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr. - if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) { - Phdr &Hdr = *AddHdr(PT_GNU_EH_FRAME, - toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags())); - AddSec(Hdr, Out<ELFT>::EhFrameHdr); + if (!Out<ELFT>::EhFrame->empty() && In<ELFT>::EhFrameHdr) { + PhdrEntry &Hdr = + *AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->OutSec->getPhdrFlags()); + Hdr.add(In<ELFT>::EhFrameHdr->OutSec); + } + + // PT_OPENBSD_RANDOMIZE specifies the location and size of a part of the + // memory image of the program that must be filled with random data before any + // code in the object is executed. + if (OutputSectionBase *Sec = findSection(".openbsd.randomdata")) { + PhdrEntry &Hdr = *AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags()); + Hdr.add(Sec); } // PT_GNU_STACK is a special section to tell the loader to make the // pages for the stack non-executable. - if (!Config->ZExecStack) - AddHdr(PT_GNU_STACK, PF_R | PF_W); + if (!Config->ZExecstack) { + PhdrEntry &Hdr = *AddHdr(PT_GNU_STACK, PF_R | PF_W); + if (Config->ZStackSize != uint64_t(-1)) + Hdr.p_memsz = Config->ZStackSize; + } + + // PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable + // is expected to perform W^X violations, such as calling mprotect(2) or + // mmap(2) with PROT_WRITE | PROT_EXEC, which is prohibited by default on + // OpenBSD. + if (Config->ZWxneeded) + AddHdr(PT_OPENBSD_WXNEEDED, PF_X); if (Note.First) - Phdrs.push_back(std::move(Note)); + Ret.push_back(std::move(Note)); + return Ret; +} - Out<ELFT>::ProgramHeaders->setSize(sizeof(Elf_Phdr) * Phdrs.size()); +template <class ELFT> +void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry> &Phdrs) { + if (Config->EMachine != EM_ARM) + return; + auto I = std::find_if( + OutputSections.begin(), OutputSections.end(), + [](OutputSectionBase *Sec) { return Sec->Type == SHT_ARM_EXIDX; }); + if (I == OutputSections.end()) + return; + + // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME + PhdrEntry ARMExidx(PT_ARM_EXIDX, PF_R); + ARMExidx.add(*I); + Phdrs.push_back(ARMExidx); } -// The first section of each PT_LOAD and the first section after PT_GNU_RELRO -// have to be page aligned so that the dynamic linker can set the permissions. +// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the +// first section after PT_GNU_RELRO have to be page aligned so that the dynamic +// linker can set the permissions. template <class ELFT> void Writer<ELFT>::fixSectionAlignments() { - for (const Phdr &P : Phdrs) - if (P.H.p_type == PT_LOAD) + for (const PhdrEntry &P : Phdrs) + if (P.p_type == PT_LOAD && P.First) P.First->PageAlign = true; - for (const Phdr &P : Phdrs) { - if (P.H.p_type != PT_GNU_RELRO) + for (const PhdrEntry &P : Phdrs) { + if (P.p_type != PT_GNU_RELRO) continue; + if (P.First) + P.First->PageAlign = true; // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we // have to align it to a page. auto End = OutputSections.end(); auto I = std::find(OutputSections.begin(), End, P.Last); if (I == End || (I + 1) == End) continue; - OutputSectionBase<ELFT> *Sec = *(I + 1); - if (needsPtLoad(Sec)) + OutputSectionBase *Sec = *(I + 1); + if (needsPtLoad<ELFT>(Sec)) Sec->PageAlign = true; } } +template <class ELFT> +void elf::allocateHeaders(MutableArrayRef<PhdrEntry> Phdrs, + ArrayRef<OutputSectionBase *> OutputSections) { + auto FirstPTLoad = + std::find_if(Phdrs.begin(), Phdrs.end(), + [](const PhdrEntry &E) { return E.p_type == PT_LOAD; }); + if (FirstPTLoad == Phdrs.end()) + return; + if (FirstPTLoad->First) + for (OutputSectionBase *Sec : OutputSections) + if (Sec->FirstInPtLoad == FirstPTLoad->First) + Sec->FirstInPtLoad = Out<ELFT>::ElfHeader; + FirstPTLoad->First = Out<ELFT>::ElfHeader; + if (!FirstPTLoad->Last) + FirstPTLoad->Last = Out<ELFT>::ProgramHeaders; +} + // We should set file offsets and VAs for elf header and program headers // sections. These are special, we do not include them into output sections // list, but have them to simplify the code. template <class ELFT> void Writer<ELFT>::fixHeaders() { - uintX_t BaseVA = ScriptConfig->DoLayout ? 0 : Config->ImageBase; - Out<ELFT>::ElfHeader->setVA(BaseVA); - uintX_t Off = Out<ELFT>::ElfHeader->getSize(); - Out<ELFT>::ProgramHeaders->setVA(Off + BaseVA); + Out<ELFT>::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size(); + // If the script has SECTIONS, assignAddresses will compute the values. + if (ScriptConfig->HasSections) + return; + + uintX_t HeaderSize = getHeaderSize<ELFT>(); + // When -T<section> option is specified, lower the base to make room for those + // sections. + if (!Config->SectionStartMap.empty()) { + uint64_t Min = -1; + for (const auto &P : Config->SectionStartMap) + Min = std::min(Min, P.second); + if (HeaderSize < Min) + Min -= HeaderSize; + else + AllocateHeader = false; + if (Min < Config->ImageBase) + Config->ImageBase = alignDown(Min, Config->MaxPageSize); + } + + if (AllocateHeader) + allocateHeaders<ELFT>(Phdrs, OutputSections); + + uintX_t BaseVA = Config->ImageBase; + Out<ELFT>::ElfHeader->Addr = BaseVA; + Out<ELFT>::ProgramHeaders->Addr = BaseVA + Out<ELFT>::ElfHeader->Size; } // Assign VAs (addresses at run-time) to output sections. template <class ELFT> void Writer<ELFT>::assignAddresses() { - uintX_t VA = Config->ImageBase + Out<ELFT>::ElfHeader->getSize() + - Out<ELFT>::ProgramHeaders->getSize(); - + uintX_t VA = Config->ImageBase; + if (AllocateHeader) + VA += getHeaderSize<ELFT>(); uintX_t ThreadBssOffset = 0; - for (OutputSectionBase<ELFT> *Sec : OutputSections) { - uintX_t Alignment = Sec->getAlignment(); + for (OutputSectionBase *Sec : OutputSections) { + uintX_t Alignment = Sec->Addralign; if (Sec->PageAlign) - Alignment = std::max<uintX_t>(Alignment, Target->PageSize); + Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize); + + auto I = Config->SectionStartMap.find(Sec->getName()); + if (I != Config->SectionStartMap.end()) + VA = I->second; // We only assign VAs to allocated sections. if (needsPtLoad<ELFT>(Sec)) { VA = alignTo(VA, Alignment); - Sec->setVA(VA); - VA += Sec->getSize(); - } else if (Sec->getFlags() & SHF_TLS && Sec->getType() == SHT_NOBITS) { + Sec->Addr = VA; + VA += Sec->Size; + } else if (Sec->Flags & SHF_TLS && Sec->Type == SHT_NOBITS) { uintX_t TVA = VA + ThreadBssOffset; TVA = alignTo(TVA, Alignment); - Sec->setVA(TVA); - ThreadBssOffset = TVA - VA + Sec->getSize(); + Sec->Addr = TVA; + ThreadBssOffset = TVA - VA + Sec->Size; } } } @@ -1059,38 +1400,50 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() { // virtual address (modulo the page size) so that the loader can load // executables without any address adjustment. template <class ELFT, class uintX_t> -static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase<ELFT> *Sec) { - uintX_t Alignment = Sec->getAlignment(); - if (Sec->PageAlign) - Alignment = std::max<uintX_t>(Alignment, Target->PageSize); - Off = alignTo(Off, Alignment); - - // Relocatable output does not have program headers - // and does not need any other offset adjusting. - if (Config->Relocatable || !(Sec->getFlags() & SHF_ALLOC)) - return Off; - return alignTo(Off, Target->PageSize, Sec->getVA()); +static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) { + OutputSectionBase *First = Sec->FirstInPtLoad; + // If the section is not in a PT_LOAD, we just have to align it. + if (!First) + return alignTo(Off, Sec->Addralign); + + // The first section in a PT_LOAD has to have congruent offset and address + // module the page size. + if (Sec == First) + return alignTo(Off, Config->MaxPageSize, Sec->Addr); + + // If two sections share the same PT_LOAD the file offset is calculated + // using this formula: Off2 = Off1 + (VA2 - VA1). + return First->Offset + Sec->Addr - First->Addr; +} + +template <class ELFT, class uintX_t> +void setOffset(OutputSectionBase *Sec, uintX_t &Off) { + if (Sec->Type == SHT_NOBITS) { + Sec->Offset = Off; + return; + } + + Off = getFileAlignment<ELFT>(Off, Sec); + Sec->Offset = Off; + Off += Sec->Size; +} + +template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() { + uintX_t Off = 0; + for (OutputSectionBase *Sec : OutputSections) + if (Sec->Flags & SHF_ALLOC) + setOffset<ELFT>(Sec, Off); + FileSize = alignTo(Off, sizeof(uintX_t)); } // Assign file offsets to output sections. template <class ELFT> void Writer<ELFT>::assignFileOffsets() { uintX_t Off = 0; + setOffset<ELFT>(Out<ELFT>::ElfHeader, Off); + setOffset<ELFT>(Out<ELFT>::ProgramHeaders, Off); - auto Set = [&](OutputSectionBase<ELFT> *Sec) { - if (Sec->getType() == SHT_NOBITS) { - Sec->setFileOffset(Off); - return; - } - - Off = getFileAlignment<ELFT>(Off, Sec); - Sec->setFileOffset(Off); - Off += Sec->getSize(); - }; - - Set(Out<ELFT>::ElfHeader); - Set(Out<ELFT>::ProgramHeaders); - for (OutputSectionBase<ELFT> *Sec : OutputSections) - Set(Sec); + for (OutputSectionBase *Sec : OutputSections) + setOffset<ELFT>(Sec, Off); SectionHeaderOff = alignTo(Off, sizeof(uintX_t)); FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr); @@ -1099,50 +1452,62 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() { // Finalize the program headers. We call this function after we assign // file offsets and VAs to all sections. template <class ELFT> void Writer<ELFT>::setPhdrs() { - for (Phdr &P : Phdrs) { - Elf_Phdr &H = P.H; - OutputSectionBase<ELFT> *First = P.First; - OutputSectionBase<ELFT> *Last = P.Last; + for (PhdrEntry &P : Phdrs) { + OutputSectionBase *First = P.First; + OutputSectionBase *Last = P.Last; if (First) { - H.p_filesz = Last->getFileOff() - First->getFileOff(); - if (Last->getType() != SHT_NOBITS) - H.p_filesz += Last->getSize(); - H.p_memsz = Last->getVA() + Last->getSize() - First->getVA(); - H.p_offset = First->getFileOff(); - H.p_vaddr = First->getVA(); + P.p_filesz = Last->Offset - First->Offset; + if (Last->Type != SHT_NOBITS) + P.p_filesz += Last->Size; + P.p_memsz = Last->Addr + Last->Size - First->Addr; + P.p_offset = First->Offset; + P.p_vaddr = First->Addr; + if (!P.HasLMA) + P.p_paddr = First->getLMA(); } - if (H.p_type == PT_LOAD) - H.p_align = Target->PageSize; - else if (H.p_type == PT_GNU_RELRO) - H.p_align = 1; - H.p_paddr = H.p_vaddr; + if (P.p_type == PT_LOAD) + P.p_align = Config->MaxPageSize; + else if (P.p_type == PT_GNU_RELRO) + P.p_align = 1; // The TLS pointer goes after PT_TLS. At least glibc will align it, // so round up the size to make sure the offsets are correct. - if (H.p_type == PT_TLS) { - Out<ELFT>::TlsPhdr = &H; - H.p_memsz = alignTo(H.p_memsz, H.p_align); + if (P.p_type == PT_TLS) { + Out<ELFT>::TlsPhdr = &P; + if (P.p_memsz) + P.p_memsz = alignTo(P.p_memsz, P.p_align); } } } -static uint32_t getMipsEFlags(bool Is64Bits) { - // FIXME: In fact ELF flags depends on ELF flags of input object files - // and selected emulation. For now just use hard coded values. - if (Is64Bits) - return EF_MIPS_CPIC | EF_MIPS_PIC | EF_MIPS_ARCH_64R2; - - uint32_t V = EF_MIPS_CPIC | EF_MIPS_ABI_O32 | EF_MIPS_ARCH_32R2; - if (Config->Shared) - V |= EF_MIPS_PIC; - return V; -} +// The entry point address is chosen in the following ways. +// +// 1. the '-e' entry command-line option; +// 2. the ENTRY(symbol) command in a linker control script; +// 3. the value of the symbol start, if present; +// 4. the address of the first byte of the .text section, if present; +// 5. the address 0. +template <class ELFT> typename ELFT::uint Writer<ELFT>::getEntryAddr() { + // Case 1, 2 or 3. As a special case, if the symbol is actually + // a number, we'll use that number as an address. + if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Entry)) + return B->getVA<ELFT>(); + uint64_t Addr; + if (!Config->Entry.getAsInteger(0, Addr)) + return Addr; + + // Case 4 + if (OutputSectionBase *Sec = findSection(".text")) { + if (Config->WarnMissingEntry) + warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" + + utohexstr(Sec->Addr)); + return Sec->Addr; + } -template <class ELFT> static typename ELFT::uint getEntryAddr() { - if (Symbol *S = Config->EntrySym) - return S->body()->getVA<ELFT>(); - if (Config->EntryAddr != uint64_t(-1)) - return Config->EntryAddr; + // Case 5 + if (Config->WarnMissingEntry) + warn("cannot find entry symbol " + Config->Entry + + "; not setting start address"); return 0; } @@ -1164,6 +1529,10 @@ static uint16_t getELFType() { // to each section. This function fixes some predefined absolute // symbol values that depend on section address and size. template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() { + // __ehdr_start is the location of program headers. + if (ElfSym<ELFT>::EhdrStart) + ElfSym<ELFT>::EhdrStart->Value = Out<ELFT>::ProgramHeaders->Addr; + auto Set = [](DefinedRegular<ELFT> *S1, DefinedRegular<ELFT> *S2, uintX_t V) { if (S1) S1->Value = V; @@ -1174,45 +1543,66 @@ template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() { // _etext is the first location after the last read-only loadable segment. // _edata is the first location after the last read-write loadable segment. // _end is the first location after the uninitialized data region. - for (Phdr &P : Phdrs) { - Elf_Phdr &H = P.H; - if (H.p_type != PT_LOAD) + for (PhdrEntry &P : Phdrs) { + if (P.p_type != PT_LOAD) continue; - Set(ElfSym<ELFT>::End, ElfSym<ELFT>::End2, H.p_vaddr + H.p_memsz); + Set(ElfSym<ELFT>::End, ElfSym<ELFT>::End2, P.p_vaddr + P.p_memsz); - uintX_t Val = H.p_vaddr + H.p_filesz; - if (H.p_flags & PF_W) + uintX_t Val = P.p_vaddr + P.p_filesz; + if (P.p_flags & PF_W) Set(ElfSym<ELFT>::Edata, ElfSym<ELFT>::Edata2, Val); else Set(ElfSym<ELFT>::Etext, ElfSym<ELFT>::Etext2, Val); } + + // 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<ELFT>::MipsGp->Value) { + // Find GP-relative section with the lowest address + // and use this address to calculate default _gp value. + uintX_t Gp = -1; + for (const OutputSectionBase * OS : OutputSections) + if ((OS->Flags & SHF_MIPS_GPREL) && OS->Addr < Gp) + Gp = OS->Addr; + if (Gp != (uintX_t)-1) + ElfSym<ELFT>::MipsGp->Value = Gp + 0x7ff0; + } + if (ElfSym<ELFT>::MipsGpDisp) + ElfSym<ELFT>::MipsGpDisp->Value = ElfSym<ELFT>::MipsGp->Value; + if (ElfSym<ELFT>::MipsLocalGp) + ElfSym<ELFT>::MipsLocalGp->Value = ElfSym<ELFT>::MipsGp->Value; + } } template <class ELFT> void Writer<ELFT>::writeHeader() { uint8_t *Buf = Buffer->getBufferStart(); memcpy(Buf, "\177ELF", 4); - auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf); - // Write the ELF header. auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Buf); EHdr->e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; EHdr->e_ident[EI_DATA] = getELFEncoding<ELFT>(); EHdr->e_ident[EI_VERSION] = EV_CURRENT; - EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI(); + EHdr->e_ident[EI_OSABI] = Config->OSABI; EHdr->e_type = getELFType(); - EHdr->e_machine = FirstObj.EMachine; + EHdr->e_machine = Config->EMachine; EHdr->e_version = EV_CURRENT; - EHdr->e_entry = getEntryAddr<ELFT>(); + EHdr->e_entry = getEntryAddr(); EHdr->e_shoff = SectionHeaderOff; EHdr->e_ehsize = sizeof(Elf_Ehdr); EHdr->e_phnum = Phdrs.size(); EHdr->e_shentsize = sizeof(Elf_Shdr); EHdr->e_shnum = OutputSections.size() + 1; - EHdr->e_shstrndx = Out<ELFT>::ShStrTab->SectionIndex; + EHdr->e_shstrndx = In<ELFT>::ShStrTab->OutSec->SectionIndex; - if (Config->EMachine == EM_MIPS) - EHdr->e_flags = getMipsEFlags(ELFT::Is64Bits); + if (Config->EMachine == EM_ARM) + // We don't currently use any features incompatible with EF_ARM_EABI_VER5, + // but we don't have any firm guarantees of conformance. Linux AArch64 + // kernels (as of 2016) require an EABI version to be set. + EHdr->e_flags = EF_ARM_EABI_VER5; + else if (Config->EMachine == EM_MIPS) + EHdr->e_flags = getMipsEFlags<ELFT>(); if (!Config->Relocatable) { EHdr->e_phoff = sizeof(Elf_Ehdr); @@ -1221,63 +1611,133 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { // Write the program header table. auto *HBuf = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff); - for (Phdr &P : Phdrs) - *HBuf++ = P.H; + for (PhdrEntry &P : Phdrs) { + HBuf->p_type = P.p_type; + HBuf->p_flags = P.p_flags; + HBuf->p_offset = P.p_offset; + HBuf->p_vaddr = P.p_vaddr; + HBuf->p_paddr = P.p_paddr; + HBuf->p_filesz = P.p_filesz; + HBuf->p_memsz = P.p_memsz; + HBuf->p_align = P.p_align; + ++HBuf; + } // Write the section header table. Note that the first table entry is null. auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff); - for (OutputSectionBase<ELFT> *Sec : OutputSections) - Sec->writeHeaderTo(++SHdrs); + for (OutputSectionBase *Sec : OutputSections) + Sec->writeHeaderTo<ELFT>(++SHdrs); } +// Removes a given file asynchronously. This is a performance hack, +// so remove this when operating systems are improved. +// +// On Linux (and probably on other Unix-like systems), unlink(2) is a +// noticeably slow system call. As of 2016, unlink takes 250 +// milliseconds to remove a 1 GB file on ext4 filesystem on my machine. +// +// To create a new result file, we first remove existing file. So, if +// you repeatedly link a 1 GB program in a regular compile-link-debug +// cycle, every cycle wastes 250 milliseconds only to remove a file. +// Since LLD can link a 1 GB binary in about 5 seconds, that waste +// actually counts. +// +// This function spawns a background thread to call unlink. +// The calling thread returns almost immediately. +static void unlinkAsync(StringRef Path) { + if (!Config->Threads || !sys::fs::exists(Config->OutputFile)) + return; + + // First, rename Path to avoid race condition. We cannot remove + // Path from a different thread because we are now going to create + // Path as a new file. If we do that in a different thread, the new + // thread can remove the new file. + SmallString<128> TempPath; + if (sys::fs::createUniqueFile(Path + "tmp%%%%%%%%", TempPath)) + return; + if (sys::fs::rename(Path, TempPath)) { + sys::fs::remove(TempPath); + return; + } + + // Remove TempPath in background. + std::thread([=] { ::remove(TempPath.str().str().c_str()); }).detach(); +} + +// Open a result file. template <class ELFT> void Writer<ELFT>::openFile() { + unlinkAsync(Config->OutputFile); ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr = FileOutputBuffer::create(Config->OutputFile, FileSize, FileOutputBuffer::F_executable); + if (auto EC = BufferOrErr.getError()) error(EC, "failed to open " + Config->OutputFile); else Buffer = std::move(*BufferOrErr); } +template <class ELFT> void Writer<ELFT>::writeSectionsBinary() { + uint8_t *Buf = Buffer->getBufferStart(); + for (OutputSectionBase *Sec : OutputSections) + if (Sec->Flags & SHF_ALLOC) + Sec->writeTo(Buf + Sec->Offset); +} + // Write section contents to a mmap'ed file. template <class ELFT> void Writer<ELFT>::writeSections() { uint8_t *Buf = Buffer->getBufferStart(); - // PPC64 needs to process relocations in the .opd section before processing - // relocations in code-containing sections. - if (OutputSectionBase<ELFT> *Sec = Out<ELFT>::Opd) { - Out<ELFT>::OpdBuf = Buf + Sec->getFileOff(); - Sec->writeTo(Buf + Sec->getFileOff()); + // PPC64 needs to process relocations in the .opd section + // before processing relocations in code-containing sections. + Out<ELFT>::Opd = findSection(".opd"); + if (Out<ELFT>::Opd) { + Out<ELFT>::OpdBuf = Buf + Out<ELFT>::Opd->Offset; + Out<ELFT>::Opd->writeTo(Buf + Out<ELFT>::Opd->Offset); } - for (OutputSectionBase<ELFT> *Sec : OutputSections) - if (Sec != Out<ELFT>::Opd) - Sec->writeTo(Buf + Sec->getFileOff()); + OutputSectionBase *EhFrameHdr = + In<ELFT>::EhFrameHdr ? In<ELFT>::EhFrameHdr->OutSec : nullptr; + for (OutputSectionBase *Sec : OutputSections) + if (Sec != Out<ELFT>::Opd && Sec != EhFrameHdr) + Sec->writeTo(Buf + Sec->Offset); + + // The .eh_frame_hdr depends on .eh_frame section contents, therefore + // it should be written after .eh_frame is written. + if (!Out<ELFT>::EhFrame->empty() && EhFrameHdr) + EhFrameHdr->writeTo(Buf + EhFrameHdr->Offset); } template <class ELFT> void Writer<ELFT>::writeBuildId() { - if (!Out<ELFT>::BuildId) + if (!In<ELFT>::BuildId || !In<ELFT>::BuildId->OutSec) return; - // Compute a hash of all sections except .debug_* sections. - // We skip debug sections because they tend to be very large - // and their contents are very likely to be the same as long as - // other sections are the same. + // Compute a hash of all sections of the output file. uint8_t *Start = Buffer->getBufferStart(); - uint8_t *Last = Start; - std::vector<ArrayRef<uint8_t>> Regions; - for (OutputSectionBase<ELFT> *Sec : OutputSections) { - uint8_t *End = Start + Sec->getFileOff(); - if (!Sec->getName().startswith(".debug_")) - Regions.push_back({Last, End}); - Last = End; - } - Regions.push_back({Last, Start + FileSize}); - Out<ELFT>::BuildId->writeBuildId(Regions); + uint8_t *End = Start + FileSize; + In<ELFT>::BuildId->writeBuildId({Start, End}); } -template void elf::writeResult<ELF32LE>(SymbolTable<ELF32LE> *Symtab); -template void elf::writeResult<ELF32BE>(SymbolTable<ELF32BE> *Symtab); -template void elf::writeResult<ELF64LE>(SymbolTable<ELF64LE> *Symtab); -template void elf::writeResult<ELF64BE>(SymbolTable<ELF64BE> *Symtab); +template void elf::writeResult<ELF32LE>(); +template void elf::writeResult<ELF32BE>(); +template void elf::writeResult<ELF64LE>(); +template void elf::writeResult<ELF64BE>(); + +template void elf::allocateHeaders<ELF32LE>(MutableArrayRef<PhdrEntry>, + ArrayRef<OutputSectionBase *>); +template void elf::allocateHeaders<ELF32BE>(MutableArrayRef<PhdrEntry>, + ArrayRef<OutputSectionBase *>); +template void elf::allocateHeaders<ELF64LE>(MutableArrayRef<PhdrEntry>, + ArrayRef<OutputSectionBase *>); +template void elf::allocateHeaders<ELF64BE>(MutableArrayRef<PhdrEntry>, + ArrayRef<OutputSectionBase *>); + +template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase *); +template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase *); +template bool elf::isRelroSection<ELF64LE>(const OutputSectionBase *); +template bool elf::isRelroSection<ELF64BE>(const OutputSectionBase *); + +template void elf::reportDiscarded<ELF32LE>(InputSectionBase<ELF32LE> *); +template void elf::reportDiscarded<ELF32BE>(InputSectionBase<ELF32BE> *); +template void elf::reportDiscarded<ELF64LE>(InputSectionBase<ELF64LE> *); +template void elf::reportDiscarded<ELF64BE>(InputSectionBase<ELF64BE> *); |