Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -31,6 +31,7 @@ #include "InputSection.h" #include "LinkerScript.h" #include "Memory.h" +#include "OutputSections.h" #include "Strings.h" #include "SymbolTable.h" #include "Target.h" @@ -852,7 +853,7 @@ SymbolTable Symtab; elf::Symtab::X = &Symtab; Target = createTarget(); - ScriptBase = Script::X = make>(); + Script = make(); Config->MaxPageSize = getMaxPageSize(Args); Config->ImageBase = getImageBase(Args); Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -223,8 +223,6 @@ class LinkerScriptBase { protected: - ~LinkerScriptBase() = default; - void assignSymbol(SymbolAssignment *Cmd, bool InSec = false); void computeInputSections(InputSectionDescription *); void setDot(Expr E, const Twine &Loc, bool InSec = false); @@ -265,8 +263,8 @@ uint64_t getOutputSectionSize(StringRef S); void discard(ArrayRef V); - virtual ExprValue getSymbolValue(const Twine &Loc, StringRef S) = 0; - virtual bool isDefined(StringRef S) = 0; + ExprValue getSymbolValue(const Twine &Loc, StringRef S); + bool isDefined(StringRef S); std::vector *OutputSections; void addOrphanSections(OutputSectionFactory &Factory); @@ -285,28 +283,13 @@ void processNonSectionCommands(); void assignAddresses(std::vector &Phdrs); int getSectionIndex(StringRef Name); -}; - -// This is a runner of the linker script. -template class LinkerScript final : public LinkerScriptBase { -public: - LinkerScript(); - ~LinkerScript(); void writeDataBytes(StringRef Name, uint8_t *Buf); void addSymbol(SymbolAssignment *Cmd); void processCommands(OutputSectionFactory &Factory); - - ExprValue getSymbolValue(const Twine &Loc, StringRef S) override; - bool isDefined(StringRef S) override; }; -// Variable template is a C++14 feature, so we can't template -// a global variable. Use a struct to workaround. -template struct Script { static LinkerScript *X; }; -template LinkerScript *Script::X; - -extern LinkerScriptBase *ScriptBase; +extern LinkerScriptBase *Script; } // end namespace elf } // end namespace lld Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -127,7 +127,7 @@ static ExprValue bitNot(ExprValue A) { return ~A.getValue(); } static ExprValue minus(ExprValue A) { return -A.getValue(); } -LinkerScriptBase *elf::ScriptBase; +LinkerScriptBase *elf::Script; ScriptConfiguration *elf::ScriptConfig; template static SymbolBody *addRegular(SymbolAssignment *Cmd) { @@ -219,18 +219,47 @@ } } -template -void LinkerScript::addSymbol(SymbolAssignment *Cmd) { +static SymbolBody *findSymbol(StringRef S) { + switch (Config->EKind) { + case ELF32LEKind: + return Symtab::X->find(S); + case ELF32BEKind: + return Symtab::X->find(S); + case ELF64LEKind: + return Symtab::X->find(S); + case ELF64BEKind: + return Symtab::X->find(S); + default: + llvm_unreachable("unknown Config->EKind"); + } +} + +static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) { + switch (Config->EKind) { + case ELF32LEKind: + return addRegular(Cmd); + case ELF32BEKind: + return addRegular(Cmd); + case ELF64LEKind: + return addRegular(Cmd); + case ELF64BEKind: + return addRegular(Cmd); + default: + llvm_unreachable("unknown Config->EKind"); + } +} + +void LinkerScriptBase::addSymbol(SymbolAssignment *Cmd) { if (Cmd->Name == ".") return; // If a symbol was in PROVIDE(), we need to define it only when // it is a referenced undefined symbol. - SymbolBody *B = Symtab::X->find(Cmd->Name); + SymbolBody *B = findSymbol(Cmd->Name); if (Cmd->Provide && (!B || B->isDefined())) return; - Cmd->Sym = addRegular(Cmd); + Cmd->Sym = addRegularSymbol(Cmd); } bool SymbolAssignment::classof(const BaseCommand *C) { @@ -253,9 +282,6 @@ return C->Kind == BytesDataKind; } -template LinkerScript::LinkerScript() = default; -template LinkerScript::~LinkerScript() = default; - static StringRef basename(InputSectionBase *S) { if (S->File) return sys::path::filename(S->File->getName()); @@ -391,8 +417,7 @@ return Ret; } -template -void LinkerScript::processCommands(OutputSectionFactory &Factory) { +void LinkerScriptBase::processCommands(OutputSectionFactory &Factory) { // A symbol can be assigned before any section is mentioned in the linker // script. In an DSO, the symbol values are addresses, so the only important // section values are: @@ -936,30 +961,31 @@ return 0; } -template static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { - const endianness E = ELFT::TargetEndianness; + const endianness E = + (Config->EKind == ELF32LEKind || Config->EKind == ELF64LEKind) + ? llvm::support::endianness::little + : llvm::support::endianness::big; switch (Size) { case 1: *Buf = (uint8_t)Data; break; case 2: - write16(Buf, Data); + write16(Buf, Data, E); break; case 4: - write32(Buf, Data); + write32(Buf, Data, E); break; case 8: - write64(Buf, Data); + write64(Buf, Data, E); break; default: llvm_unreachable("unsupported Size argument"); } } -template -void LinkerScript::writeDataBytes(StringRef Name, uint8_t *Buf) { +void LinkerScriptBase::writeDataBytes(StringRef Name, uint8_t *Buf) { int I = getSectionIndex(Name); if (I == INT_MAX) return; @@ -967,8 +993,7 @@ auto *Cmd = dyn_cast(Opt.Commands[I].get()); for (const std::unique_ptr &Base : Cmd->Commands) if (auto *Data = dyn_cast(Base.get())) - writeInt(Buf + Data->Offset, Data->Expression().getValue(), - Data->Size); + writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size); } bool LinkerScriptBase::hasLMA(StringRef Name) { @@ -991,22 +1016,21 @@ return INT_MAX; } -template -ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) { +ExprValue LinkerScriptBase::getSymbolValue(const Twine &Loc, StringRef S) { if (S == ".") return {CurOutSec, Dot - CurOutSec->Addr}; - if (SymbolBody *B = Symtab::X->find(S)) { + if (SymbolBody *B = findSymbol(S)) { if (auto *D = dyn_cast(B)) return {D->Section, D->Value}; auto *C = cast(B); - return {In::Common, C->Offset}; + return {InX::Common, C->Offset}; } error(Loc + ": symbol not found: " + S); return 0; } -template bool LinkerScript::isDefined(StringRef S) { - return Symtab::X->find(S) != nullptr; +bool LinkerScriptBase::isDefined(StringRef S) { + return findSymbol(S) != nullptr; } // Returns indices of ELF headers containing specific section, identified @@ -1490,7 +1514,7 @@ return [=] { if (!E().getValue()) error(Msg); - return ScriptBase->getDot(); + return Script->getDot(); }; } @@ -1620,7 +1644,7 @@ Expr E = readExpr(); if (Op == "+=") { std::string Loc = getCurrentLocation(); - E = [=] { return add(ScriptBase->getSymbolValue(Loc, Name), E()); }; + E = [=] { return add(Script->getSymbolValue(Loc, Name), E()); }; } return new SymbolAssignment(Name, E, getCurrentLocation()); } @@ -1791,13 +1815,12 @@ if (Tok == "ADDR") { StringRef Name = readParenLiteral(); return [=]() -> ExprValue { - return {ScriptBase->getOutputSection(Location, Name), 0}; + return {Script->getOutputSection(Location, Name), 0}; }; } if (Tok == "LOADADDR") { StringRef Name = readParenLiteral(); - return - [=] { return ScriptBase->getOutputSection(Location, Name)->getLMA(); }; + return [=] { return Script->getOutputSection(Location, Name)->getLMA(); }; } if (Tok == "ASSERT") return readAssert(); @@ -1810,7 +1833,7 @@ return [=] { return alignTo(E().getValue(), E2().getValue()); }; } expect(")"); - return [=] { return alignTo(ScriptBase->getDot(), E().getValue()); }; + return [=] { return alignTo(Script->getDot(), E().getValue()); }; } if (Tok == "CONSTANT") { StringRef Name = readParenLiteral(); @@ -1818,7 +1841,7 @@ } if (Tok == "DEFINED") { StringRef Name = readParenLiteral(); - return [=] { return ScriptBase->isDefined(Name) ? 1 : 0; }; + return [=] { return Script->isDefined(Name) ? 1 : 0; }; } if (Tok == "SEGMENT_START") { expect("("); @@ -1834,13 +1857,13 @@ expect(","); readExpr(); expect(")"); - return [=] { return alignTo(ScriptBase->getDot(), E().getValue()); }; + return [=] { return alignTo(Script->getDot(), E().getValue()); }; } if (Tok == "DATA_SEGMENT_END") { expect("("); expect("."); expect(")"); - return [] { return ScriptBase->getDot(); }; + return [] { return Script->getDot(); }; } // GNU linkers implements more complicated logic to handle // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to @@ -1851,16 +1874,15 @@ expect(","); readExpr(); expect(")"); - return [] { return alignTo(ScriptBase->getDot(), Target->PageSize); }; + return [] { return alignTo(Script->getDot(), Target->PageSize); }; } if (Tok == "SIZEOF") { StringRef Name = readParenLiteral(); - return [=] { return ScriptBase->getOutputSectionSize(Name); }; + return [=] { return Script->getOutputSectionSize(Name); }; } if (Tok == "ALIGNOF") { StringRef Name = readParenLiteral(); - return - [=] { return ScriptBase->getOutputSection(Location, Name)->Alignment; }; + return [=] { return Script->getOutputSection(Location, Name)->Alignment; }; } if (Tok == "SIZEOF_HEADERS") return [=] { return elf::getHeaderSize(); }; @@ -1873,7 +1895,7 @@ // Tok is a symbol name. if (Tok != "." && !isValidCIdentifier(Tok)) setError("malformed number: " + Tok); - return [=] { return ScriptBase->getSymbolValue(Location, Tok); }; + return [=] { return Script->getSymbolValue(Location, Tok); }; } Expr ScriptParser::readTernary(Expr Cond) { @@ -2122,8 +2144,3 @@ void elf::readDynamicList(MemoryBufferRef MB) { ScriptParser(MB).readDynamicList(); } - -template class elf::LinkerScript; -template class elf::LinkerScript; -template class elf::LinkerScript; -template class elf::LinkerScript; Index: lld/trunk/ELF/MarkLive.cpp =================================================================== --- lld/trunk/ELF/MarkLive.cpp +++ lld/trunk/ELF/MarkLive.cpp @@ -246,7 +246,7 @@ scanEhFrameSection(*EH, Enqueue); if (Sec->Flags & SHF_LINK_ORDER) continue; - if (isReserved(Sec) || Script::X->shouldKeep(Sec)) + if (isReserved(Sec) || Script->shouldKeep(Sec)) Enqueue({Sec, 0}); else if (isValidCIdentifier(Sec->Name)) { CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec); Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -236,7 +236,7 @@ template void OutputSection::writeTo(uint8_t *Buf) { Loc = Buf; - if (uint32_t Filler = Script::X->getFiller(this->Name)) + if (uint32_t Filler = Script->getFiller(this->Name)) fill(Buf, this->Size, Filler); auto Fn = [=](InputSection *IS) { IS->writeTo(Buf); }; @@ -244,7 +244,7 @@ // Linker scripts may have BYTE()-family commands with which you // can write arbitrary bytes to the output. Process them if any. - Script::X->writeDataBytes(this->Name, Buf); + Script->writeDataBytes(this->Name, Buf); } static uint64_t getOutFlags(InputSectionBase *S) { Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -2199,7 +2199,7 @@ void MipsRldMapSection::writeTo(uint8_t *Buf) { // Apply filler from linker script. - uint64_t Filler = ScriptBase->getFiller(this->Name); + uint64_t Filler = Script->getFiller(this->Name); Filler = (Filler << 32) | Filler; memcpy(Buf, &Filler, getSize()); } Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -133,8 +133,7 @@ template static bool needsInterpSection() { return !Symtab::X->getSharedFiles().empty() && - !Config->DynamicLinker.empty() && - !Script::X->ignoreInterpSection(); + !Config->DynamicLinker.empty() && !Script->ignoreInterpSection(); } template void elf::writeResult() { Writer().run(); } @@ -228,21 +227,21 @@ addReservedSymbols(); // Create output sections. - Script::X->OutputSections = &OutputSections; + Script->OutputSections = &OutputSections; if (ScriptConfig->HasSections) { // If linker script contains SECTIONS commands, let it create sections. - Script::X->processCommands(Factory); + Script->processCommands(Factory); // Linker scripts may have left some input sections unassigned. // Assign such sections using the default rule. - Script::X->addOrphanSections(Factory); + Script->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::X->processCommands(Factory); + Script->processCommands(Factory); } if (Config->Discard != DiscardPolicy::All) @@ -263,11 +262,11 @@ assignFileOffsets(); } else { if (ScriptConfig->HasSections) { - Script::X->assignAddresses(Phdrs); + Script->assignAddresses(Phdrs); } else { fixSectionAlignments(); assignAddresses(); - Script::X->processNonSectionCommands(); + Script->processNonSectionCommands(); } // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a @@ -723,8 +722,8 @@ template static bool compareSections(const OutputSection *A, const OutputSection *B) { // For now, put sections mentioned in a linker script first. - int AIndex = Script::X->getSectionIndex(A->Name); - int BIndex = Script::X->getSectionIndex(B->Name); + int AIndex = Script->getSectionIndex(A->Name); + int BIndex = Script->getSectionIndex(B->Name); bool AInScript = AIndex != INT_MAX; bool BInScript = BIndex != INT_MAX; if (AInScript != BInScript) @@ -968,7 +967,7 @@ compareSectionsNonScript); return; } - Script::X->adjustSectionsBeforeSorting(); + Script->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 @@ -1001,7 +1000,7 @@ auto E = OutputSections.end(); auto NonScriptI = std::find_if(OutputSections.begin(), E, [](OutputSection *S) { - return Script::X->getSectionIndex(S->Name) == INT_MAX; + return Script->getSectionIndex(S->Name) == INT_MAX; }); while (NonScriptI != E) { auto BestPos = std::max_element( @@ -1031,7 +1030,7 @@ ++NonScriptI; } - Script::X->adjustSectionsAfterSorting(); + Script->adjustSectionsAfterSorting(); } static void applySynthetic(const std::vector &Sections, @@ -1152,8 +1151,7 @@ // 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::X->hasPhdrsCommands() ? Script::X->createPhdrs() - : createPhdrs(); + Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs(); addPtArmExid(Phdrs); fixHeaders(); } @@ -1306,7 +1304,7 @@ // different flags or is loaded at a discontiguous address using AT linker // script command. uintX_t NewFlags = computeFlags(Sec->getPhdrFlags()); - if (Script::X->hasLMA(Sec->Name) || Flags != NewFlags) { + if (Script->hasLMA(Sec->Name) || Flags != NewFlags) { Load = AddHdr(PT_LOAD, NewFlags); Flags = NewFlags; } @@ -1370,7 +1368,7 @@ PhdrEntry *Note = nullptr; for (OutputSection *Sec : OutputSections) { if (Sec->Type == SHT_NOTE) { - if (!Note || Script::X->hasLMA(Sec->Name)) + if (!Note || Script->hasLMA(Sec->Name)) Note = AddHdr(PT_NOTE, PF_R); Note->add(Sec); } else { @@ -1447,7 +1445,7 @@ Out::ElfHeader->Addr = Min; Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size; - if (ScriptBase->hasPhdrsCommands()) + if (Script->hasPhdrsCommands()) return true; if (FirstPTLoad->First)