[ELF] - Move members of LinkerScript to LinkerScriptBase. NFC.
That moves all members that s possible to move for now (all which does not depend on ELFT templating). After that change LinkerScript contains only 8 methods in total, and I believe it is possible to move them all after tweaking other parts of linker. And we will be able to have single class for linkerscript at the end. llvm-svn: 297735
This commit is contained in:
parent
23e6a02450
commit
a2a1ef1abc
|
@ -104,8 +104,7 @@ uint64_t LinkerScriptBase::getOutputSectionSize(StringRef Name) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
void LinkerScriptBase::setDot(Expr E, const Twine &Loc, bool InSec) {
|
||||||
void LinkerScript<ELFT>::setDot(Expr E, const Twine &Loc, bool InSec) {
|
|
||||||
uint64_t Val = E();
|
uint64_t Val = E();
|
||||||
if (Val < Dot) {
|
if (Val < Dot) {
|
||||||
if (InSec)
|
if (InSec)
|
||||||
|
@ -123,8 +122,7 @@ void LinkerScript<ELFT>::setDot(Expr E, const Twine &Loc, bool InSec) {
|
||||||
// Sets value of a symbol. Two kinds of symbols are processed: synthetic
|
// Sets value of a symbol. Two kinds of symbols are processed: synthetic
|
||||||
// symbols, whose value is an offset from beginning of section and regular
|
// symbols, whose value is an offset from beginning of section and regular
|
||||||
// symbols whose value is absolute.
|
// symbols whose value is absolute.
|
||||||
template <class ELFT>
|
void LinkerScriptBase::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
|
||||||
void LinkerScript<ELFT>::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
|
|
||||||
if (Cmd->Name == ".") {
|
if (Cmd->Name == ".") {
|
||||||
setDot(Cmd->Expression, Cmd->Location, InSec);
|
setDot(Cmd->Expression, Cmd->Location, InSec);
|
||||||
return;
|
return;
|
||||||
|
@ -191,7 +189,7 @@ static StringRef basename(InputSectionBase *S) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> bool LinkerScript<ELFT>::shouldKeep(InputSectionBase *S) {
|
bool LinkerScriptBase::shouldKeep(InputSectionBase *S) {
|
||||||
for (InputSectionDescription *ID : Opt.KeptSections)
|
for (InputSectionDescription *ID : Opt.KeptSections)
|
||||||
if (ID->FilePat.match(basename(S)))
|
if (ID->FilePat.match(basename(S)))
|
||||||
for (SectionPattern &P : ID->SectionPatterns)
|
for (SectionPattern &P : ID->SectionPatterns)
|
||||||
|
@ -248,8 +246,7 @@ static void sortSections(InputSectionBase **Begin, InputSectionBase **End,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute and remember which sections the InputSectionDescription matches.
|
// Compute and remember which sections the InputSectionDescription matches.
|
||||||
template <class ELFT>
|
void LinkerScriptBase::computeInputSections(InputSectionDescription *I) {
|
||||||
void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
|
|
||||||
// Collects all sections that satisfy constraints of I
|
// Collects all sections that satisfy constraints of I
|
||||||
// and attach them to I.
|
// and attach them to I.
|
||||||
for (SectionPattern &Pat : I->SectionPatterns) {
|
for (SectionPattern &Pat : I->SectionPatterns) {
|
||||||
|
@ -306,9 +303,8 @@ void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase *> V) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
std::vector<InputSectionBase *>
|
std::vector<InputSectionBase *>
|
||||||
LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
|
LinkerScriptBase::createInputSectionList(OutputSectionCommand &OutCmd) {
|
||||||
std::vector<InputSectionBase *> Ret;
|
std::vector<InputSectionBase *> Ret;
|
||||||
|
|
||||||
for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) {
|
for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) {
|
||||||
|
@ -406,8 +402,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory &Factory) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add sections that didn't match any sections command.
|
// Add sections that didn't match any sections command.
|
||||||
template <class ELFT>
|
void LinkerScriptBase::addOrphanSections(OutputSectionFactory &Factory) {
|
||||||
void LinkerScript<ELFT>::addOrphanSections(OutputSectionFactory &Factory) {
|
|
||||||
for (InputSectionBase *S : InputSections)
|
for (InputSectionBase *S : InputSections)
|
||||||
if (S->Live && !S->OutSec)
|
if (S->Live && !S->OutSec)
|
||||||
Factory.addInputSec(S, getOutputSectionName(S->Name));
|
Factory.addInputSec(S, getOutputSectionName(S->Name));
|
||||||
|
@ -417,7 +412,7 @@ static bool isTbss(OutputSection *Sec) {
|
||||||
return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
|
return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void LinkerScript<ELFT>::output(InputSection *S) {
|
void LinkerScriptBase::output(InputSection *S) {
|
||||||
if (!AlreadyOutputIS.insert(S).second)
|
if (!AlreadyOutputIS.insert(S).second)
|
||||||
return;
|
return;
|
||||||
bool IsTbss = isTbss(CurOutSec);
|
bool IsTbss = isTbss(CurOutSec);
|
||||||
|
@ -451,7 +446,7 @@ template <class ELFT> void LinkerScript<ELFT>::output(InputSection *S) {
|
||||||
Dot = Pos;
|
Dot = Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void LinkerScript<ELFT>::flush() {
|
void LinkerScriptBase::flush() {
|
||||||
assert(CurOutSec);
|
assert(CurOutSec);
|
||||||
if (!AlreadyOutputOS.insert(CurOutSec).second)
|
if (!AlreadyOutputOS.insert(CurOutSec).second)
|
||||||
return;
|
return;
|
||||||
|
@ -459,7 +454,7 @@ template <class ELFT> void LinkerScript<ELFT>::flush() {
|
||||||
output(I);
|
output(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void LinkerScript<ELFT>::switchTo(OutputSection *Sec) {
|
void LinkerScriptBase::switchTo(OutputSection *Sec) {
|
||||||
if (CurOutSec == Sec)
|
if (CurOutSec == Sec)
|
||||||
return;
|
return;
|
||||||
if (AlreadyOutputOS.count(Sec))
|
if (AlreadyOutputOS.count(Sec))
|
||||||
|
@ -478,7 +473,7 @@ template <class ELFT> void LinkerScript<ELFT>::switchTo(OutputSection *Sec) {
|
||||||
CurOutSec->LMAOffset = LMAOffset();
|
CurOutSec->LMAOffset = LMAOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) {
|
void LinkerScriptBase::process(BaseCommand &Base) {
|
||||||
// This handles the assignments to symbol or to a location counter (.)
|
// This handles the assignments to symbol or to a location counter (.)
|
||||||
if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) {
|
if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) {
|
||||||
assignSymbol(AssignCmd, true);
|
assignSymbol(AssignCmd, true);
|
||||||
|
@ -533,9 +528,8 @@ findSection(StringRef Name, const std::vector<OutputSection *> &Sections) {
|
||||||
// This function searches for a memory region to place the given output
|
// This function searches for a memory region to place the given output
|
||||||
// section in. If found, a pointer to the appropriate memory region is
|
// section in. If found, a pointer to the appropriate memory region is
|
||||||
// returned. Otherwise, a nullptr is returned.
|
// returned. Otherwise, a nullptr is returned.
|
||||||
template <class ELFT>
|
MemoryRegion *LinkerScriptBase::findMemoryRegion(OutputSectionCommand *Cmd,
|
||||||
MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand *Cmd,
|
OutputSection *Sec) {
|
||||||
OutputSection *Sec) {
|
|
||||||
// If a memory region name was specified in the output section command,
|
// If a memory region name was specified in the output section command,
|
||||||
// then try to find that region first.
|
// then try to find that region first.
|
||||||
if (!Cmd->MemoryRegionName.empty()) {
|
if (!Cmd->MemoryRegionName.empty()) {
|
||||||
|
@ -568,8 +562,7 @@ MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand *Cmd,
|
||||||
|
|
||||||
// This function assigns offsets to input sections and an output section
|
// This function assigns offsets to input sections and an output section
|
||||||
// for a single sections command (e.g. ".text { *(.text); }").
|
// for a single sections command (e.g. ".text { *(.text); }").
|
||||||
template <class ELFT>
|
void LinkerScriptBase::assignOffsets(OutputSectionCommand *Cmd) {
|
||||||
void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) {
|
|
||||||
OutputSection *Sec = findSection(Cmd->Name, *OutputSections);
|
OutputSection *Sec = findSection(Cmd->Name, *OutputSections);
|
||||||
if (!Sec)
|
if (!Sec)
|
||||||
return;
|
return;
|
||||||
|
@ -606,7 +599,7 @@ void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) {
|
||||||
[this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); });
|
[this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void LinkerScript<ELFT>::removeEmptyCommands() {
|
void LinkerScriptBase::removeEmptyCommands() {
|
||||||
// It is common practice to use very generic linker scripts. So for any
|
// It is common practice to use very generic linker scripts. So for any
|
||||||
// given run some of the output sections in the script will be empty.
|
// given run some of the output sections in the script will be empty.
|
||||||
// We could create corresponding empty output sections, but that would
|
// We could create corresponding empty output sections, but that would
|
||||||
|
@ -630,7 +623,7 @@ static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() {
|
void LinkerScriptBase::adjustSectionsBeforeSorting() {
|
||||||
// If the output section contains only symbol assignments, create a
|
// If the output section contains only symbol assignments, create a
|
||||||
// corresponding output section. The bfd linker seems to only create them if
|
// corresponding output section. The bfd linker seems to only create them if
|
||||||
// '.' is assigned to, but creating these section should not have any bad
|
// '.' is assigned to, but creating these section should not have any bad
|
||||||
|
@ -655,7 +648,7 @@ template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void LinkerScript<ELFT>::adjustSectionsAfterSorting() {
|
void LinkerScriptBase::adjustSectionsAfterSorting() {
|
||||||
placeOrphanSections();
|
placeOrphanSections();
|
||||||
|
|
||||||
// If output section command doesn't specify any segments,
|
// If output section command doesn't specify any segments,
|
||||||
|
@ -731,7 +724,7 @@ static bool shouldSkip(const BaseCommand &Cmd) {
|
||||||
// determine whether a new output command should be added before or
|
// determine whether a new output command should be added before or
|
||||||
// after another commands. For the details, look at shouldSkip
|
// after another commands. For the details, look at shouldSkip
|
||||||
// function.
|
// function.
|
||||||
template <class ELFT> void LinkerScript<ELFT>::placeOrphanSections() {
|
void LinkerScriptBase::placeOrphanSections() {
|
||||||
// The OutputSections are already in the correct order.
|
// The OutputSections are already in the correct order.
|
||||||
// This loops creates or moves commands as needed so that they are in the
|
// This loops creates or moves commands as needed so that they are in the
|
||||||
// correct order.
|
// correct order.
|
||||||
|
@ -786,8 +779,7 @@ template <class ELFT> void LinkerScript<ELFT>::placeOrphanSections() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
void LinkerScriptBase::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
|
||||||
void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
|
|
||||||
// Assign addresses as instructed by linker script SECTIONS sub-commands.
|
// Assign addresses as instructed by linker script SECTIONS sub-commands.
|
||||||
Dot = 0;
|
Dot = 0;
|
||||||
switchTo(Aether);
|
switchTo(Aether);
|
||||||
|
@ -819,7 +811,7 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates program headers as instructed by PHDRS linker script command.
|
// Creates program headers as instructed by PHDRS linker script command.
|
||||||
template <class ELFT> std::vector<PhdrEntry> LinkerScript<ELFT>::createPhdrs() {
|
std::vector<PhdrEntry> LinkerScriptBase::createPhdrs() {
|
||||||
std::vector<PhdrEntry> Ret;
|
std::vector<PhdrEntry> Ret;
|
||||||
|
|
||||||
// Process PHDRS and FILEHDR keywords because they are not
|
// Process PHDRS and FILEHDR keywords because they are not
|
||||||
|
@ -854,7 +846,7 @@ template <class ELFT> std::vector<PhdrEntry> LinkerScript<ELFT>::createPhdrs() {
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() {
|
bool LinkerScriptBase::ignoreInterpSection() {
|
||||||
// Ignore .interp section in case we have PHDRS specification
|
// Ignore .interp section in case we have PHDRS specification
|
||||||
// and PT_INTERP isn't listed.
|
// and PT_INTERP isn't listed.
|
||||||
return !Opt.PhdrsCommands.empty() &&
|
return !Opt.PhdrsCommands.empty() &&
|
||||||
|
@ -863,7 +855,7 @@ template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() {
|
||||||
}) == Opt.PhdrsCommands.end();
|
}) == Opt.PhdrsCommands.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> uint32_t LinkerScript<ELFT>::getFiller(StringRef Name) {
|
uint32_t LinkerScriptBase::getFiller(StringRef Name) {
|
||||||
for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
|
for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
|
||||||
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
|
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
|
||||||
if (Cmd->Name == Name)
|
if (Cmd->Name == Name)
|
||||||
|
@ -905,7 +897,7 @@ void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) {
|
||||||
writeInt<ELFT>(Buf + Data->Offset, Data->Expression(), Data->Size);
|
writeInt<ELFT>(Buf + Data->Offset, Data->Expression(), Data->Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) {
|
bool LinkerScriptBase::hasLMA(StringRef Name) {
|
||||||
for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
|
for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
|
||||||
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
|
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
|
||||||
if (Cmd->LMAExpr && Cmd->Name == Name)
|
if (Cmd->LMAExpr && Cmd->Name == Name)
|
||||||
|
@ -917,7 +909,7 @@ template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) {
|
||||||
// SECTIONS commands. Sections are laid out as the same order as they
|
// SECTIONS commands. Sections are laid out as the same order as they
|
||||||
// were in the script. If a given name did not appear in the script,
|
// were in the script. If a given name did not appear in the script,
|
||||||
// it returns INT_MAX, so that it will be laid out at end of file.
|
// it returns INT_MAX, so that it will be laid out at end of file.
|
||||||
template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) {
|
int LinkerScriptBase::getSectionIndex(StringRef Name) {
|
||||||
for (int I = 0, E = Opt.Commands.size(); I != E; ++I)
|
for (int I = 0, E = Opt.Commands.size(); I != E; ++I)
|
||||||
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()))
|
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()))
|
||||||
if (Cmd->Name == Name)
|
if (Cmd->Name == Name)
|
||||||
|
@ -960,8 +952,7 @@ OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
|
||||||
// Returns indices of ELF headers containing specific section, identified
|
// Returns indices of ELF headers containing specific section, identified
|
||||||
// by Name. Each index is a zero based number of ELF header listed within
|
// by Name. Each index is a zero based number of ELF header listed within
|
||||||
// PHDRS {} script block.
|
// PHDRS {} script block.
|
||||||
template <class ELFT>
|
std::vector<size_t> LinkerScriptBase::getPhdrIndices(StringRef SectionName) {
|
||||||
std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) {
|
|
||||||
for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
|
for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
|
||||||
auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
|
auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
|
||||||
if (!Cmd || Cmd->Name != SectionName)
|
if (!Cmd || Cmd->Name != SectionName)
|
||||||
|
@ -975,8 +966,7 @@ std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
size_t LinkerScriptBase::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
|
||||||
size_t LinkerScript<ELFT>::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
|
|
||||||
size_t I = 0;
|
size_t I = 0;
|
||||||
for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
|
for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
|
||||||
if (Cmd.Name == PhdrName)
|
if (Cmd.Name == PhdrName)
|
||||||
|
|
|
@ -229,6 +229,24 @@ extern ScriptConfiguration *ScriptConfig;
|
||||||
class LinkerScriptBase {
|
class LinkerScriptBase {
|
||||||
protected:
|
protected:
|
||||||
~LinkerScriptBase() = default;
|
~LinkerScriptBase() = default;
|
||||||
|
|
||||||
|
void assignSymbol(SymbolAssignment *Cmd, bool InSec = false);
|
||||||
|
void computeInputSections(InputSectionDescription *);
|
||||||
|
void setDot(Expr E, const Twine &Loc, bool InSec = false);
|
||||||
|
|
||||||
|
std::vector<InputSectionBase *>
|
||||||
|
createInputSectionList(OutputSectionCommand &Cmd);
|
||||||
|
|
||||||
|
std::vector<size_t> getPhdrIndices(StringRef SectionName);
|
||||||
|
size_t getPhdrIndex(const Twine &Loc, StringRef PhdrName);
|
||||||
|
|
||||||
|
MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd, OutputSection *Sec);
|
||||||
|
|
||||||
|
void switchTo(OutputSection *Sec);
|
||||||
|
void flush();
|
||||||
|
void output(InputSection *Sec);
|
||||||
|
void process(BaseCommand &Base);
|
||||||
|
|
||||||
OutputSection *Aether;
|
OutputSection *Aether;
|
||||||
|
|
||||||
// "ScriptConfig" is a bit too long, so define a short name for it.
|
// "ScriptConfig" is a bit too long, so define a short name for it.
|
||||||
|
@ -237,6 +255,13 @@ protected:
|
||||||
uint64_t Dot;
|
uint64_t Dot;
|
||||||
uint64_t ThreadBssOffset = 0;
|
uint64_t ThreadBssOffset = 0;
|
||||||
|
|
||||||
|
std::function<uint64_t()> LMAOffset;
|
||||||
|
OutputSection *CurOutSec = nullptr;
|
||||||
|
MemoryRegion *CurMemRegion = nullptr;
|
||||||
|
|
||||||
|
llvm::DenseSet<OutputSection *> AlreadyOutputOS;
|
||||||
|
llvm::DenseSet<InputSectionBase *> AlreadyOutputIS;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool hasPhdrsCommands() { return !Opt.PhdrsCommands.empty(); }
|
bool hasPhdrsCommands() { return !Opt.PhdrsCommands.empty(); }
|
||||||
uint64_t getDot() { return Dot; }
|
uint64_t getDot() { return Dot; }
|
||||||
|
@ -249,15 +274,6 @@ public:
|
||||||
virtual OutputSection *getSymbolSection(StringRef S) = 0;
|
virtual OutputSection *getSymbolSection(StringRef S) = 0;
|
||||||
|
|
||||||
std::vector<OutputSection *> *OutputSections;
|
std::vector<OutputSection *> *OutputSections;
|
||||||
};
|
|
||||||
|
|
||||||
// This is a runner of the linker script.
|
|
||||||
template <class ELFT> class LinkerScript final : public LinkerScriptBase {
|
|
||||||
public:
|
|
||||||
LinkerScript();
|
|
||||||
~LinkerScript();
|
|
||||||
|
|
||||||
void processCommands(OutputSectionFactory &Factory);
|
|
||||||
void addOrphanSections(OutputSectionFactory &Factory);
|
void addOrphanSections(OutputSectionFactory &Factory);
|
||||||
void removeEmptyCommands();
|
void removeEmptyCommands();
|
||||||
void adjustSectionsBeforeSorting();
|
void adjustSectionsBeforeSorting();
|
||||||
|
@ -267,44 +283,29 @@ public:
|
||||||
bool ignoreInterpSection();
|
bool ignoreInterpSection();
|
||||||
|
|
||||||
uint32_t getFiller(StringRef Name);
|
uint32_t getFiller(StringRef Name);
|
||||||
void writeDataBytes(StringRef Name, uint8_t *Buf);
|
|
||||||
bool hasLMA(StringRef Name);
|
bool hasLMA(StringRef Name);
|
||||||
bool shouldKeep(InputSectionBase *S);
|
bool shouldKeep(InputSectionBase *S);
|
||||||
void assignOffsets(OutputSectionCommand *Cmd);
|
void assignOffsets(OutputSectionCommand *Cmd);
|
||||||
void placeOrphanSections();
|
void placeOrphanSections();
|
||||||
void assignAddresses(std::vector<PhdrEntry> &Phdrs);
|
void assignAddresses(std::vector<PhdrEntry> &Phdrs);
|
||||||
|
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 addSymbol(SymbolAssignment *Cmd);
|
||||||
|
void discard(ArrayRef<InputSectionBase *> V);
|
||||||
|
void processCommands(OutputSectionFactory &Factory);
|
||||||
|
|
||||||
uint64_t getSymbolValue(const Twine &Loc, StringRef S) override;
|
uint64_t getSymbolValue(const Twine &Loc, StringRef S) override;
|
||||||
bool isDefined(StringRef S) override;
|
bool isDefined(StringRef S) override;
|
||||||
bool isAbsolute(StringRef S) override;
|
bool isAbsolute(StringRef S) override;
|
||||||
OutputSection *getSymbolSection(StringRef S) override;
|
OutputSection *getSymbolSection(StringRef S) override;
|
||||||
|
|
||||||
int getSectionIndex(StringRef Name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void assignSymbol(SymbolAssignment *Cmd, bool InSec = false);
|
|
||||||
void addSymbol(SymbolAssignment *Cmd);
|
|
||||||
void computeInputSections(InputSectionDescription *);
|
|
||||||
void setDot(Expr E, const Twine &Loc, bool InSec = false);
|
|
||||||
|
|
||||||
void discard(ArrayRef<InputSectionBase *> V);
|
|
||||||
|
|
||||||
std::vector<InputSectionBase *>
|
|
||||||
createInputSectionList(OutputSectionCommand &Cmd);
|
|
||||||
|
|
||||||
std::vector<size_t> getPhdrIndices(StringRef SectionName);
|
|
||||||
size_t getPhdrIndex(const Twine &Loc, StringRef PhdrName);
|
|
||||||
|
|
||||||
MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd, OutputSection *Sec);
|
|
||||||
|
|
||||||
std::function<uint64_t()> LMAOffset;
|
|
||||||
OutputSection *CurOutSec = nullptr;
|
|
||||||
MemoryRegion *CurMemRegion = nullptr;
|
|
||||||
void switchTo(OutputSection *Sec);
|
|
||||||
void flush();
|
|
||||||
void output(InputSection *Sec);
|
|
||||||
void process(BaseCommand &Base);
|
|
||||||
llvm::DenseSet<OutputSection *> AlreadyOutputOS;
|
|
||||||
llvm::DenseSet<InputSectionBase *> AlreadyOutputIS;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Variable template is a C++14 feature, so we can't template
|
// Variable template is a C++14 feature, so we can't template
|
||||||
|
|
Loading…
Reference in New Issue