forked from OSchip/llvm-project
[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:
parent
009833d377
commit
a8dba48762
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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>;
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue