summaryrefslogtreecommitdiffstats
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r--lld/ELF/LinkerScript.cpp55
1 files changed, 42 insertions, 13 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index ed47c74e7a9..17a5edeff8d 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -138,9 +138,10 @@ static bool compareByName(InputSectionBase<ELFT> *A,
}
template <class ELFT>
-std::vector<OutputSectionBase<ELFT> *>
-LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
- std::vector<OutputSectionBase<ELFT> *> Ret;
+void LinkerScript<ELFT>::createSections(
+ std::vector<OutputSectionBase<ELFT> *> *Out,
+ OutputSectionFactory<ELFT> &Factory) {
+ OutputSections = Out;
for (auto &P : getSectionMap()) {
std::vector<InputSectionBase<ELFT> *> Sections;
@@ -157,7 +158,7 @@ LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
if (I->Sort)
std::stable_sort(Sections.begin(), Sections.end(), compareByName<ELFT>);
for (InputSectionBase<ELFT> *S : Sections)
- addSection(Factory, Ret, S, OutputName);
+ addSection(Factory, *Out, S, OutputName);
}
// Add all other input sections, which are not listed in script.
@@ -165,17 +166,15 @@ LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
Symtab<ELFT>::X->getObjectFiles())
for (InputSectionBase<ELFT> *S : F->getSections())
if (!isDiscarded(S) && !S->OutSec)
- addSection(Factory, Ret, S, getOutputSectionName(S));
+ addSection(Factory, *Out, S, getOutputSectionName(S));
// Remove from the output all the sections which did not meet
// the optional constraints.
- return filter(Ret);
+ filter();
}
// Process ONLY_IF_RO and ONLY_IF_RW.
-template <class ELFT>
-std::vector<OutputSectionBase<ELFT> *>
-LinkerScript<ELFT>::filter(std::vector<OutputSectionBase<ELFT> *> &Sections) {
+template <class ELFT> void LinkerScript<ELFT>::filter() {
// In this loop, we remove output sections if they don't satisfy
// requested properties.
for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
@@ -186,10 +185,10 @@ LinkerScript<ELFT>::filter(std::vector<OutputSectionBase<ELFT> *> &Sections) {
if (Cmd->Constraint == ConstraintKind::NoConstraint)
continue;
- auto It = llvm::find_if(Sections, [&](OutputSectionBase<ELFT> *S) {
+ auto It = llvm::find_if(*OutputSections, [&](OutputSectionBase<ELFT> *S) {
return S->getName() == Cmd->Name;
});
- if (It == Sections.end())
+ if (It == OutputSections->end())
continue;
OutputSectionBase<ELFT> *Sec = *It;
@@ -198,9 +197,8 @@ LinkerScript<ELFT>::filter(std::vector<OutputSectionBase<ELFT> *> &Sections) {
bool RW = (Cmd->Constraint == ConstraintKind::ReadWrite);
if ((RO && Writable) || (RW && !Writable))
- Sections.erase(It);
+ OutputSections->erase(It);
}
- return Sections;
}
template <class ELFT>
@@ -396,6 +394,15 @@ template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
return !Opt.PhdrsCommands.empty();
}
+template <class ELFT>
+typename ELFT::uint LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
+ for (OutputSectionBase<ELFT> *Sec : *OutputSections)
+ if (Sec->getName() == Name)
+ return Sec->getSize();
+ error("undefined section " + Name);
+ 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.
@@ -838,6 +845,22 @@ static uint64_t getSymbolValue(StringRef S, uint64_t Dot) {
return 0;
}
+static uint64_t getSectionSize(StringRef Name) {
+ switch (Config->EKind) {
+ case ELF32LEKind:
+ return Script<ELF32LE>::X->getOutputSectionSize(Name);
+ case ELF32BEKind:
+ return Script<ELF32BE>::X->getOutputSectionSize(Name);
+ case ELF64LEKind:
+ return Script<ELF64LE>::X->getOutputSectionSize(Name);
+ case ELF64BEKind:
+ return Script<ELF64BE>::X->getOutputSectionSize(Name);
+ default:
+ llvm_unreachable("unsupported target");
+ }
+ return 0;
+}
+
SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
StringRef Op = next();
assert(Op == "=" || Op == "+=");
@@ -946,6 +969,12 @@ Expr ScriptParser::readPrimary() {
expect(")");
return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); };
}
+ if (Tok == "SIZEOF") {
+ expect("(");
+ StringRef Name = next();
+ expect(")");
+ return [=](uint64_t Dot) { return getSectionSize(Name); };
+ }
// Parse a symbol name or a number literal.
uint64_t V = 0;
OpenPOWER on IntegriCloud