[ELF] - Combine LinkerScriptBase and LinkerScript<ELFT>

Patch removes templated linkerscript class.

Unfortunately that required 2 additional static methods
findSymbol() and addRegularSymbol() because code
depends on Symtab<ELFT>::X

Differential revision: https://reviews.llvm.org/D30982

llvm-svn: 298241
This commit is contained in:
George Rimar 2017-03-20 10:09:58 +00:00
parent 009833d377
commit a8dba48762
7 changed files with 86 additions and 87 deletions

View File

@ -31,6 +31,7 @@
#include "InputSection.h" #include "InputSection.h"
#include "LinkerScript.h" #include "LinkerScript.h"
#include "Memory.h" #include "Memory.h"
#include "OutputSections.h"
#include "Strings.h" #include "Strings.h"
#include "SymbolTable.h" #include "SymbolTable.h"
#include "Target.h" #include "Target.h"
@ -852,7 +853,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
SymbolTable<ELFT> Symtab; SymbolTable<ELFT> Symtab;
elf::Symtab<ELFT>::X = &Symtab; elf::Symtab<ELFT>::X = &Symtab;
Target = createTarget(); Target = createTarget();
ScriptBase = Script<ELFT>::X = make<LinkerScript<ELFT>>(); Script = make<LinkerScriptBase>();
Config->MaxPageSize = getMaxPageSize(Args); Config->MaxPageSize = getMaxPageSize(Args);
Config->ImageBase = getImageBase(Args); Config->ImageBase = getImageBase(Args);

View File

@ -127,7 +127,7 @@ static ExprValue bitOr(ExprValue A, ExprValue B) {
static ExprValue bitNot(ExprValue A) { return ~A.getValue(); } static ExprValue bitNot(ExprValue A) { return ~A.getValue(); }
static ExprValue minus(ExprValue A) { return -A.getValue(); } static ExprValue minus(ExprValue A) { return -A.getValue(); }
LinkerScriptBase *elf::ScriptBase; LinkerScriptBase *elf::Script;
ScriptConfiguration *elf::ScriptConfig; ScriptConfiguration *elf::ScriptConfig;
template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) { template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
@ -219,18 +219,47 @@ void LinkerScriptBase::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
} }
} }
template <class ELFT> static SymbolBody *findSymbol(StringRef S) {
void LinkerScript<ELFT>::addSymbol(SymbolAssignment *Cmd) { switch (Config->EKind) {
case ELF32LEKind:
return Symtab<ELF32LE>::X->find(S);
case ELF32BEKind:
return Symtab<ELF32BE>::X->find(S);
case ELF64LEKind:
return Symtab<ELF64LE>::X->find(S);
case ELF64BEKind:
return Symtab<ELF64BE>::X->find(S);
default:
llvm_unreachable("unknown Config->EKind");
}
}
static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) {
switch (Config->EKind) {
case ELF32LEKind:
return addRegular<ELF32LE>(Cmd);
case ELF32BEKind:
return addRegular<ELF32BE>(Cmd);
case ELF64LEKind:
return addRegular<ELF64LE>(Cmd);
case ELF64BEKind:
return addRegular<ELF64BE>(Cmd);
default:
llvm_unreachable("unknown Config->EKind");
}
}
void LinkerScriptBase::addSymbol(SymbolAssignment *Cmd) {
if (Cmd->Name == ".") if (Cmd->Name == ".")
return; return;
// If a symbol was in PROVIDE(), we need to define it only when // If a symbol was in PROVIDE(), we need to define it only when
// it is a referenced undefined symbol. // it is a referenced undefined symbol.
SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); SymbolBody *B = findSymbol(Cmd->Name);
if (Cmd->Provide && (!B || B->isDefined())) if (Cmd->Provide && (!B || B->isDefined()))
return; return;
Cmd->Sym = addRegular<ELFT>(Cmd); Cmd->Sym = addRegularSymbol(Cmd);
} }
bool SymbolAssignment::classof(const BaseCommand *C) { bool SymbolAssignment::classof(const BaseCommand *C) {
@ -253,9 +282,6 @@ bool BytesDataCommand::classof(const BaseCommand *C) {
return C->Kind == BytesDataKind; return C->Kind == BytesDataKind;
} }
template <class ELFT> LinkerScript<ELFT>::LinkerScript() = default;
template <class ELFT> LinkerScript<ELFT>::~LinkerScript() = default;
static StringRef basename(InputSectionBase *S) { static StringRef basename(InputSectionBase *S) {
if (S->File) if (S->File)
return sys::path::filename(S->File->getName()); return sys::path::filename(S->File->getName());
@ -391,8 +417,7 @@ LinkerScriptBase::createInputSectionList(OutputSectionCommand &OutCmd) {
return Ret; return Ret;
} }
template <class ELFT> void LinkerScriptBase::processCommands(OutputSectionFactory &Factory) {
void LinkerScript<ELFT>::processCommands(OutputSectionFactory &Factory) {
// A symbol can be assigned before any section is mentioned in the linker // 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 // script. In an DSO, the symbol values are addresses, so the only important
// section values are: // section values are:
@ -936,30 +961,31 @@ uint32_t LinkerScriptBase::getFiller(StringRef Name) {
return 0; return 0;
} }
template <class ELFT>
static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { 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) { switch (Size) {
case 1: case 1:
*Buf = (uint8_t)Data; *Buf = (uint8_t)Data;
break; break;
case 2: case 2:
write16<E>(Buf, Data); write16(Buf, Data, E);
break; break;
case 4: case 4:
write32<E>(Buf, Data); write32(Buf, Data, E);
break; break;
case 8: case 8:
write64<E>(Buf, Data); write64(Buf, Data, E);
break; break;
default: default:
llvm_unreachable("unsupported Size argument"); llvm_unreachable("unsupported Size argument");
} }
} }
template <class ELFT> void LinkerScriptBase::writeDataBytes(StringRef Name, uint8_t *Buf) {
void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) {
int I = getSectionIndex(Name); int I = getSectionIndex(Name);
if (I == INT_MAX) if (I == INT_MAX)
return; return;
@ -967,8 +993,7 @@ void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) {
auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()); auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get());
for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)
if (auto *Data = dyn_cast<BytesDataCommand>(Base.get())) if (auto *Data = dyn_cast<BytesDataCommand>(Base.get()))
writeInt<ELFT>(Buf + Data->Offset, Data->Expression().getValue(), writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
Data->Size);
} }
bool LinkerScriptBase::hasLMA(StringRef Name) { bool LinkerScriptBase::hasLMA(StringRef Name) {
@ -991,22 +1016,21 @@ int LinkerScriptBase::getSectionIndex(StringRef Name) {
return INT_MAX; return INT_MAX;
} }
template <class ELFT> ExprValue LinkerScriptBase::getSymbolValue(const Twine &Loc, StringRef S) {
ExprValue LinkerScript<ELFT>::getSymbolValue(const Twine &Loc, StringRef S) {
if (S == ".") if (S == ".")
return {CurOutSec, Dot - CurOutSec->Addr}; return {CurOutSec, Dot - CurOutSec->Addr};
if (SymbolBody *B = Symtab<ELFT>::X->find(S)) { if (SymbolBody *B = findSymbol(S)) {
if (auto *D = dyn_cast<DefinedRegular>(B)) if (auto *D = dyn_cast<DefinedRegular>(B))
return {D->Section, D->Value}; return {D->Section, D->Value};
auto *C = cast<DefinedCommon>(B); auto *C = cast<DefinedCommon>(B);
return {In<ELFT>::Common, C->Offset}; return {InX::Common, C->Offset};
} }
error(Loc + ": symbol not found: " + S); error(Loc + ": symbol not found: " + S);
return 0; return 0;
} }
template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) { bool LinkerScriptBase::isDefined(StringRef S) {
return Symtab<ELFT>::X->find(S) != nullptr; return findSymbol(S) != nullptr;
} }
// Returns indices of ELF headers containing specific section, identified // Returns indices of ELF headers containing specific section, identified
@ -1490,7 +1514,7 @@ Expr ScriptParser::readAssert() {
return [=] { return [=] {
if (!E().getValue()) if (!E().getValue())
error(Msg); error(Msg);
return ScriptBase->getDot(); return Script->getDot();
}; };
} }
@ -1620,7 +1644,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
Expr E = readExpr(); Expr E = readExpr();
if (Op == "+=") { if (Op == "+=") {
std::string Loc = getCurrentLocation(); 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()); return new SymbolAssignment(Name, E, getCurrentLocation());
} }
@ -1791,13 +1815,12 @@ Expr ScriptParser::readPrimary() {
if (Tok == "ADDR") { if (Tok == "ADDR") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
return [=]() -> ExprValue { return [=]() -> ExprValue {
return {ScriptBase->getOutputSection(Location, Name), 0}; return {Script->getOutputSection(Location, Name), 0};
}; };
} }
if (Tok == "LOADADDR") { if (Tok == "LOADADDR") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
return return [=] { return Script->getOutputSection(Location, Name)->getLMA(); };
[=] { return ScriptBase->getOutputSection(Location, Name)->getLMA(); };
} }
if (Tok == "ASSERT") if (Tok == "ASSERT")
return readAssert(); return readAssert();
@ -1810,7 +1833,7 @@ Expr ScriptParser::readPrimary() {
return [=] { return alignTo(E().getValue(), E2().getValue()); }; return [=] { return alignTo(E().getValue(), E2().getValue()); };
} }
expect(")"); expect(")");
return [=] { return alignTo(ScriptBase->getDot(), E().getValue()); }; return [=] { return alignTo(Script->getDot(), E().getValue()); };
} }
if (Tok == "CONSTANT") { if (Tok == "CONSTANT") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
@ -1818,7 +1841,7 @@ Expr ScriptParser::readPrimary() {
} }
if (Tok == "DEFINED") { if (Tok == "DEFINED") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
return [=] { return ScriptBase->isDefined(Name) ? 1 : 0; }; return [=] { return Script->isDefined(Name) ? 1 : 0; };
} }
if (Tok == "SEGMENT_START") { if (Tok == "SEGMENT_START") {
expect("("); expect("(");
@ -1834,13 +1857,13 @@ Expr ScriptParser::readPrimary() {
expect(","); expect(",");
readExpr(); readExpr();
expect(")"); expect(")");
return [=] { return alignTo(ScriptBase->getDot(), E().getValue()); }; return [=] { return alignTo(Script->getDot(), E().getValue()); };
} }
if (Tok == "DATA_SEGMENT_END") { if (Tok == "DATA_SEGMENT_END") {
expect("("); expect("(");
expect("."); expect(".");
expect(")"); expect(")");
return [] { return ScriptBase->getDot(); }; return [] { return Script->getDot(); };
} }
// GNU linkers implements more complicated logic to handle // GNU linkers implements more complicated logic to handle
// DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to
@ -1851,16 +1874,15 @@ Expr ScriptParser::readPrimary() {
expect(","); expect(",");
readExpr(); readExpr();
expect(")"); expect(")");
return [] { return alignTo(ScriptBase->getDot(), Target->PageSize); }; return [] { return alignTo(Script->getDot(), Target->PageSize); };
} }
if (Tok == "SIZEOF") { if (Tok == "SIZEOF") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
return [=] { return ScriptBase->getOutputSectionSize(Name); }; return [=] { return Script->getOutputSectionSize(Name); };
} }
if (Tok == "ALIGNOF") { if (Tok == "ALIGNOF") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
return return [=] { return Script->getOutputSection(Location, Name)->Alignment; };
[=] { return ScriptBase->getOutputSection(Location, Name)->Alignment; };
} }
if (Tok == "SIZEOF_HEADERS") if (Tok == "SIZEOF_HEADERS")
return [=] { return elf::getHeaderSize(); }; return [=] { return elf::getHeaderSize(); };
@ -1873,7 +1895,7 @@ Expr ScriptParser::readPrimary() {
// Tok is a symbol name. // Tok is a symbol name.
if (Tok != "." && !isValidCIdentifier(Tok)) if (Tok != "." && !isValidCIdentifier(Tok))
setError("malformed number: " + Tok); setError("malformed number: " + Tok);
return [=] { return ScriptBase->getSymbolValue(Location, Tok); }; return [=] { return Script->getSymbolValue(Location, Tok); };
} }
Expr ScriptParser::readTernary(Expr Cond) { Expr ScriptParser::readTernary(Expr Cond) {
@ -2122,8 +2144,3 @@ void elf::readVersionScript(MemoryBufferRef MB) {
void elf::readDynamicList(MemoryBufferRef MB) { void elf::readDynamicList(MemoryBufferRef MB) {
ScriptParser(MB).readDynamicList(); ScriptParser(MB).readDynamicList();
} }
template class elf::LinkerScript<ELF32LE>;
template class elf::LinkerScript<ELF32BE>;
template class elf::LinkerScript<ELF64LE>;
template class elf::LinkerScript<ELF64BE>;

View File

@ -223,8 +223,6 @@ extern ScriptConfiguration *ScriptConfig;
class LinkerScriptBase { class LinkerScriptBase {
protected: protected:
~LinkerScriptBase() = default;
void assignSymbol(SymbolAssignment *Cmd, bool InSec = false); void assignSymbol(SymbolAssignment *Cmd, bool InSec = false);
void computeInputSections(InputSectionDescription *); void computeInputSections(InputSectionDescription *);
void setDot(Expr E, const Twine &Loc, bool InSec = false); void setDot(Expr E, const Twine &Loc, bool InSec = false);
@ -265,8 +263,8 @@ public:
uint64_t getOutputSectionSize(StringRef S); uint64_t getOutputSectionSize(StringRef S);
void discard(ArrayRef<InputSectionBase *> V); void discard(ArrayRef<InputSectionBase *> V);
virtual ExprValue getSymbolValue(const Twine &Loc, StringRef S) = 0; ExprValue getSymbolValue(const Twine &Loc, StringRef S);
virtual bool isDefined(StringRef S) = 0; bool isDefined(StringRef S);
std::vector<OutputSection *> *OutputSections; std::vector<OutputSection *> *OutputSections;
void addOrphanSections(OutputSectionFactory &Factory); void addOrphanSections(OutputSectionFactory &Factory);
@ -285,28 +283,13 @@ public:
void processNonSectionCommands(); void processNonSectionCommands();
void assignAddresses(std::vector<PhdrEntry> &Phdrs); void assignAddresses(std::vector<PhdrEntry> &Phdrs);
int getSectionIndex(StringRef Name); int getSectionIndex(StringRef Name);
};
// This is a runner of the linker script.
template <class ELFT> class LinkerScript final : public LinkerScriptBase {
public:
LinkerScript();
~LinkerScript();
void writeDataBytes(StringRef Name, uint8_t *Buf); void writeDataBytes(StringRef Name, uint8_t *Buf);
void addSymbol(SymbolAssignment *Cmd); void addSymbol(SymbolAssignment *Cmd);
void processCommands(OutputSectionFactory &Factory); 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 extern LinkerScriptBase *Script;
// a global variable. Use a struct to workaround.
template <class ELFT> struct Script { static LinkerScript<ELFT> *X; };
template <class ELFT> LinkerScript<ELFT> *Script<ELFT>::X;
extern LinkerScriptBase *ScriptBase;
} // end namespace elf } // end namespace elf
} // end namespace lld } // end namespace lld

View File

@ -246,7 +246,7 @@ template <class ELFT> void elf::markLive() {
scanEhFrameSection<ELFT>(*EH, Enqueue); scanEhFrameSection<ELFT>(*EH, Enqueue);
if (Sec->Flags & SHF_LINK_ORDER) if (Sec->Flags & SHF_LINK_ORDER)
continue; continue;
if (isReserved<ELFT>(Sec) || Script<ELFT>::X->shouldKeep(Sec)) if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec))
Enqueue({Sec, 0}); Enqueue({Sec, 0});
else if (isValidCIdentifier(Sec->Name)) { else if (isValidCIdentifier(Sec->Name)) {
CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec); CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);

View File

@ -236,7 +236,7 @@ void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) { template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
Loc = Buf; Loc = Buf;
if (uint32_t Filler = Script<ELFT>::X->getFiller(this->Name)) if (uint32_t Filler = Script->getFiller(this->Name))
fill(Buf, this->Size, Filler); fill(Buf, this->Size, Filler);
auto Fn = [=](InputSection *IS) { IS->writeTo<ELFT>(Buf); }; auto Fn = [=](InputSection *IS) { IS->writeTo<ELFT>(Buf); };
@ -244,7 +244,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
// Linker scripts may have BYTE()-family commands with which you // Linker scripts may have BYTE()-family commands with which you
// can write arbitrary bytes to the output. Process them if any. // can write arbitrary bytes to the output. Process them if any.
Script<ELFT>::X->writeDataBytes(this->Name, Buf); Script->writeDataBytes(this->Name, Buf);
} }
static uint64_t getOutFlags(InputSectionBase *S) { static uint64_t getOutFlags(InputSectionBase *S) {

View File

@ -2199,7 +2199,7 @@ MipsRldMapSection::MipsRldMapSection()
void MipsRldMapSection::writeTo(uint8_t *Buf) { void MipsRldMapSection::writeTo(uint8_t *Buf) {
// Apply filler from linker script. // Apply filler from linker script.
uint64_t Filler = ScriptBase->getFiller(this->Name); uint64_t Filler = Script->getFiller(this->Name);
Filler = (Filler << 32) | Filler; Filler = (Filler << 32) | Filler;
memcpy(Buf, &Filler, getSize()); memcpy(Buf, &Filler, getSize());
} }

View File

@ -133,8 +133,7 @@ StringRef elf::getOutputSectionName(StringRef Name) {
template <class ELFT> static bool needsInterpSection() { template <class ELFT> static bool needsInterpSection() {
return !Symtab<ELFT>::X->getSharedFiles().empty() && return !Symtab<ELFT>::X->getSharedFiles().empty() &&
!Config->DynamicLinker.empty() && !Config->DynamicLinker.empty() && !Script->ignoreInterpSection();
!Script<ELFT>::X->ignoreInterpSection();
} }
template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); } template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
@ -228,21 +227,21 @@ template <class ELFT> void Writer<ELFT>::run() {
addReservedSymbols(); addReservedSymbols();
// Create output sections. // Create output sections.
Script<ELFT>::X->OutputSections = &OutputSections; Script->OutputSections = &OutputSections;
if (ScriptConfig->HasSections) { if (ScriptConfig->HasSections) {
// If linker script contains SECTIONS commands, let it create sections. // If linker script contains SECTIONS commands, let it create sections.
Script<ELFT>::X->processCommands(Factory); Script->processCommands(Factory);
// Linker scripts may have left some input sections unassigned. // Linker scripts may have left some input sections unassigned.
// Assign such sections using the default rule. // Assign such sections using the default rule.
Script<ELFT>::X->addOrphanSections(Factory); Script->addOrphanSections(Factory);
} else { } else {
// If linker script does not contain SECTIONS commands, create // If linker script does not contain SECTIONS commands, create
// output sections by default rules. We still need to give the // output sections by default rules. We still need to give the
// linker script a chance to run, because it might contain // linker script a chance to run, because it might contain
// non-SECTIONS commands such as ASSERT. // non-SECTIONS commands such as ASSERT.
createSections(); createSections();
Script<ELFT>::X->processCommands(Factory); Script->processCommands(Factory);
} }
if (Config->Discard != DiscardPolicy::All) if (Config->Discard != DiscardPolicy::All)
@ -263,11 +262,11 @@ template <class ELFT> void Writer<ELFT>::run() {
assignFileOffsets(); assignFileOffsets();
} else { } else {
if (ScriptConfig->HasSections) { if (ScriptConfig->HasSections) {
Script<ELFT>::X->assignAddresses(Phdrs); Script->assignAddresses(Phdrs);
} else { } else {
fixSectionAlignments(); fixSectionAlignments();
assignAddresses(); assignAddresses();
Script<ELFT>::X->processNonSectionCommands(); Script->processNonSectionCommands();
} }
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
@ -723,8 +722,8 @@ static bool compareSectionsNonScript(const OutputSection *A,
template <class ELFT> template <class ELFT>
static bool compareSections(const OutputSection *A, const OutputSection *B) { static bool compareSections(const OutputSection *A, const OutputSection *B) {
// For now, put sections mentioned in a linker script first. // For now, put sections mentioned in a linker script first.
int AIndex = Script<ELFT>::X->getSectionIndex(A->Name); int AIndex = Script->getSectionIndex(A->Name);
int BIndex = Script<ELFT>::X->getSectionIndex(B->Name); int BIndex = Script->getSectionIndex(B->Name);
bool AInScript = AIndex != INT_MAX; bool AInScript = AIndex != INT_MAX;
bool BInScript = BIndex != INT_MAX; bool BInScript = BIndex != INT_MAX;
if (AInScript != BInScript) if (AInScript != BInScript)
@ -968,7 +967,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
compareSectionsNonScript<ELFT>); compareSectionsNonScript<ELFT>);
return; return;
} }
Script<ELFT>::X->adjustSectionsBeforeSorting(); Script->adjustSectionsBeforeSorting();
// The order of the sections in the script is arbitrary and may not agree with // The order of the sections in the script is arbitrary and may not agree with
// compareSectionsNonScript. This means that we cannot easily define a // compareSectionsNonScript. This means that we cannot easily define a
@ -1001,7 +1000,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
auto E = OutputSections.end(); auto E = OutputSections.end();
auto NonScriptI = auto NonScriptI =
std::find_if(OutputSections.begin(), E, [](OutputSection *S) { std::find_if(OutputSections.begin(), E, [](OutputSection *S) {
return Script<ELFT>::X->getSectionIndex(S->Name) == INT_MAX; return Script->getSectionIndex(S->Name) == INT_MAX;
}); });
while (NonScriptI != E) { while (NonScriptI != E) {
auto BestPos = std::max_element( auto BestPos = std::max_element(
@ -1031,7 +1030,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
++NonScriptI; ++NonScriptI;
} }
Script<ELFT>::X->adjustSectionsAfterSorting(); Script->adjustSectionsAfterSorting();
} }
static void applySynthetic(const std::vector<SyntheticSection *> &Sections, static void applySynthetic(const std::vector<SyntheticSection *> &Sections,
@ -1152,8 +1151,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// The headers have to be created before finalize as that can influence the // 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. // image base and the dynamic section on mips includes the image base.
if (!Config->Relocatable && !Config->OFormatBinary) { if (!Config->Relocatable && !Config->OFormatBinary) {
Phdrs = Script<ELFT>::X->hasPhdrsCommands() ? Script<ELFT>::X->createPhdrs() Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
: createPhdrs();
addPtArmExid(Phdrs); addPtArmExid(Phdrs);
fixHeaders(); fixHeaders();
} }
@ -1306,7 +1304,7 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
// different flags or is loaded at a discontiguous address using AT linker // different flags or is loaded at a discontiguous address using AT linker
// script command. // script command.
uintX_t NewFlags = computeFlags<ELFT>(Sec->getPhdrFlags()); uintX_t NewFlags = computeFlags<ELFT>(Sec->getPhdrFlags());
if (Script<ELFT>::X->hasLMA(Sec->Name) || Flags != NewFlags) { if (Script->hasLMA(Sec->Name) || Flags != NewFlags) {
Load = AddHdr(PT_LOAD, NewFlags); Load = AddHdr(PT_LOAD, NewFlags);
Flags = NewFlags; Flags = NewFlags;
} }
@ -1370,7 +1368,7 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
PhdrEntry *Note = nullptr; PhdrEntry *Note = nullptr;
for (OutputSection *Sec : OutputSections) { for (OutputSection *Sec : OutputSections) {
if (Sec->Type == SHT_NOTE) { if (Sec->Type == SHT_NOTE) {
if (!Note || Script<ELFT>::X->hasLMA(Sec->Name)) if (!Note || Script->hasLMA(Sec->Name))
Note = AddHdr(PT_NOTE, PF_R); Note = AddHdr(PT_NOTE, PF_R);
Note->add(Sec); Note->add(Sec);
} else { } else {
@ -1447,7 +1445,7 @@ bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs,
Out::ElfHeader->Addr = Min; Out::ElfHeader->Addr = Min;
Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size; Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
if (ScriptBase->hasPhdrsCommands()) if (Script->hasPhdrsCommands())
return true; return true;
if (FirstPTLoad->First) if (FirstPTLoad->First)