Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -569,7 +569,7 @@ std::unique_ptr TI(createTarget()); Target = TI.get(); LinkerScript LS; - Script::X = &LS; + ScriptBase = Script::X = &LS; Config->Rela = ELFT::Is64Bits || Config->EMachine == EM_X86_64; Config->Mips64EL = Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -123,6 +123,14 @@ unsigned Flags; }; +class LinkerScriptBase { +public: + virtual uint64_t getOutputSectionAddress(StringRef Name) = 0; + virtual uint64_t getOutputSectionSize(StringRef Name) = 0; + virtual uint64_t getHeaderSize() = 0; + virtual uint64_t getSymbolValue(StringRef S) = 0; +}; + // ScriptConfiguration holds linker script parse results. struct ScriptConfiguration { // Used to create symbol assignments outside SECTIONS command. @@ -145,7 +153,7 @@ extern ScriptConfiguration *ScriptConfig; // This is a runner of the linker script. -template class LinkerScript { +template class LinkerScript final : public LinkerScriptBase { typedef typename ELFT::uint uintX_t; public: @@ -163,9 +171,10 @@ void assignAddresses(); int compareSections(StringRef A, StringRef B); bool hasPhdrsCommands(); - uintX_t getOutputSectionAddress(StringRef Name); - uintX_t getOutputSectionSize(StringRef Name); - uintX_t getHeaderSize(); + uint64_t getOutputSectionAddress(StringRef Name) override; + uint64_t getOutputSectionSize(StringRef Name) override; + uint64_t getHeaderSize() override; + uint64_t getSymbolValue(StringRef S) override; std::vector *> *OutputSections; @@ -193,6 +202,8 @@ template struct Script { static LinkerScript *X; }; template LinkerScript *Script::X; +extern LinkerScriptBase *ScriptBase; + } // namespace elf } // namespace lld Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -41,6 +41,7 @@ using namespace lld; using namespace lld::elf; +LinkerScriptBase *elf::ScriptBase; ScriptConfiguration *elf::ScriptConfig; template @@ -556,8 +557,7 @@ } template -typename ELFT::uint -LinkerScript::getOutputSectionAddress(StringRef Name) { +uint64_t LinkerScript::getOutputSectionAddress(StringRef Name) { for (OutputSectionBase *Sec : *OutputSections) if (Sec->getName() == Name) return Sec->getVA(); @@ -566,7 +566,7 @@ } template -typename ELFT::uint LinkerScript::getOutputSectionSize(StringRef Name) { +uint64_t LinkerScript::getOutputSectionSize(StringRef Name) { for (OutputSectionBase *Sec : *OutputSections) if (Sec->getName() == Name) return Sec->getSize(); @@ -574,11 +574,17 @@ return 0; } -template -typename ELFT::uint LinkerScript::getHeaderSize() { +template uint64_t LinkerScript::getHeaderSize() { return Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); } +template uint64_t LinkerScript::getSymbolValue(StringRef S) { + if (SymbolBody *B = Symtab::X->find(S)) + return B->getVA(); + error("symbol not found: " + S); + return 0; +} + // Returns indices of ELF headers containing specific section, identified // by Name. Each index is a zero based number of ELF header listed within // PHDRS {} script block. @@ -1099,74 +1105,7 @@ static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { if (S == ".") return Dot; - - switch (Config->EKind) { - case ELF32LEKind: - if (SymbolBody *B = Symtab::X->find(S)) - return B->getVA(); - break; - case ELF32BEKind: - if (SymbolBody *B = Symtab::X->find(S)) - return B->getVA(); - break; - case ELF64LEKind: - if (SymbolBody *B = Symtab::X->find(S)) - return B->getVA(); - break; - case ELF64BEKind: - if (SymbolBody *B = Symtab::X->find(S)) - return B->getVA(); - break; - default: - llvm_unreachable("unsupported target"); - } - error("symbol not found: " + S); - return 0; -} - -static uint64_t getSectionSize(StringRef Name) { - switch (Config->EKind) { - case ELF32LEKind: - return Script::X->getOutputSectionSize(Name); - case ELF32BEKind: - return Script::X->getOutputSectionSize(Name); - case ELF64LEKind: - return Script::X->getOutputSectionSize(Name); - case ELF64BEKind: - return Script::X->getOutputSectionSize(Name); - default: - llvm_unreachable("unsupported target"); - } -} - -static uint64_t getSectionAddress(StringRef Name) { - switch (Config->EKind) { - case ELF32LEKind: - return Script::X->getOutputSectionAddress(Name); - case ELF32BEKind: - return Script::X->getOutputSectionAddress(Name); - case ELF64LEKind: - return Script::X->getOutputSectionAddress(Name); - case ELF64BEKind: - return Script::X->getOutputSectionAddress(Name); - default: - llvm_unreachable("unsupported target"); - } -} - -static uint64_t getHeaderSize() { - switch (Config->EKind) { - case ELF32LEKind: - return Script::X->getHeaderSize(); - case ELF32BEKind: - return Script::X->getHeaderSize(); - case ELF64LEKind: - return Script::X->getHeaderSize(); - case ELF64BEKind: - return Script::X->getHeaderSize(); - default: - llvm_unreachable("unsupported target"); - } + return ScriptBase->getSymbolValue(S); } SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { @@ -1314,7 +1253,8 @@ expect("("); StringRef Name = next(); expect(")"); - return [=](uint64_t Dot) { return getSectionAddress(Name); }; + return + [=](uint64_t Dot) { return ScriptBase->getOutputSectionAddress(Name); }; } if (Tok == "ASSERT") return readAssert(); @@ -1366,10 +1306,10 @@ expect("("); StringRef Name = next(); expect(")"); - return [=](uint64_t Dot) { return getSectionSize(Name); }; + return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; } if (Tok == "SIZEOF_HEADERS") - return [=](uint64_t Dot) { return getHeaderSize(); }; + return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; // Tok is a literal number. uint64_t V;