[lld] r276283 - [ELF] - Linkerscript: add InputSectionDescription command to LS parser.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 21 07:26:59 PDT 2016
Author: grimar
Date: Thu Jul 21 09:26:59 2016
New Revision: 276283
URL: http://llvm.org/viewvc/llvm-project?rev=276283&view=rev
Log:
[ELF] - Linkerscript: add InputSectionDescription command to LS parser.
This adds InputSectionDescription command to represent
the input section declaration.
This leads to next cleanup:
SectionRule removed.
ScriptConfiguration::Sections mamber removed.
LinkerScript<ELFT>::getOutputSection() removed.
Differential revision: https://reviews.llvm.org/D22617
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=276283&r1=276282&r2=276283&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Jul 21 09:26:59 2016
@@ -47,6 +47,10 @@ bool OutputSectionCommand::classof(const
return C->Kind == OutputSectionKind;
}
+bool InputSectionDescription::classof(const BaseCommand *C) {
+ return C->Kind == InputSectionKind;
+}
+
// This is an operator-precedence parser to parse and evaluate
// a linker script expression. For each linker script arithmetic
// expression (e.g. ". = . + 0x1000"), a new instance of ExprParser
@@ -195,16 +199,8 @@ uint64_t ExprParser::parseExpr1(uint64_t
uint64_t ExprParser::parseExpr() { return parseExpr1(parsePrimary(), 0); }
template <class ELFT>
-StringRef LinkerScript<ELFT>::getOutputSection(InputSectionBase<ELFT> *S) {
- for (SectionRule &R : Opt.Sections)
- if (globMatch(R.SectionPattern, S->getSectionName()))
- return R.Dest;
- return "";
-}
-
-template <class ELFT>
bool LinkerScript<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) {
- return !S || !S->Live || getOutputSection(S) == "/DISCARD/";
+ return !S || !S->Live;
}
template <class ELFT>
@@ -215,9 +211,17 @@ bool LinkerScript<ELFT>::shouldKeep(Inpu
return false;
}
+static bool match(StringRef Pattern, ArrayRef<StringRef> Arr) {
+ for (StringRef S : Arr)
+ if (globMatch(S, Pattern))
+ return true;
+ return false;
+}
+
template <class ELFT>
std::vector<OutputSectionBase<ELFT> *>
LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
+ typedef const std::unique_ptr<ObjectFile<ELFT>> ObjectFile;
std::vector<OutputSectionBase<ELFT> *> Result;
// Add input section to output section. If there is no output section yet,
@@ -234,18 +238,34 @@ LinkerScript<ELFT>::createSections(Outpu
// Select input sections matching rule and add them to corresponding
// output section. Section rules are processed in order they're listed
// in script, so correct input section order is maintained by design.
- for (SectionRule &R : Opt.Sections)
- for (const std::unique_ptr<ObjectFile<ELFT>> &F :
- Symtab<ELFT>::X->getObjectFiles())
- for (InputSectionBase<ELFT> *S : F->getSections())
- if (!isDiscarded(S) && !S->OutSec &&
- globMatch(R.SectionPattern, S->getSectionName()))
- // Add single input section to output section.
- AddInputSec(S, R.Dest);
+ for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
+ auto *OutCmd = dyn_cast<OutputSectionCommand>(Base.get());
+ if (!OutCmd)
+ continue;
+
+ for (const std::unique_ptr<BaseCommand> &Cmd : OutCmd->Commands) {
+ auto *InCmd = dyn_cast<InputSectionDescription>(Cmd.get());
+ if (!InCmd)
+ continue;
+
+ for (ObjectFile &F : Symtab<ELFT>::X->getObjectFiles()) {
+ for (InputSectionBase<ELFT> *S : F->getSections()) {
+ if (isDiscarded(S) || S->OutSec)
+ continue;
+
+ if (match(S->getSectionName(), InCmd->Patterns)) {
+ if (OutCmd->Name == "/DISCARD/")
+ S->Live = false;
+ else
+ AddInputSec(S, OutCmd->Name);
+ }
+ }
+ }
+ }
+ }
// Add all other input sections, which are not listed in script.
- for (const std::unique_ptr<ObjectFile<ELFT>> &F :
- Symtab<ELFT>::X->getObjectFiles())
+ for (ObjectFile &F : Symtab<ELFT>::X->getObjectFiles())
for (InputSectionBase<ELFT> *S : F->getSections())
if (!isDiscarded(S)) {
if (!S->OutSec)
@@ -735,17 +755,20 @@ void ScriptParser::readOutputSectionDesc
while (!Error && !skip("}")) {
StringRef Tok = next();
if (Tok == "*") {
+ auto *InCmd = new InputSectionDescription();
+ Cmd->Commands.emplace_back(InCmd);
expect("(");
while (!Error && !skip(")"))
- Opt.Sections.emplace_back(OutSec, next());
+ InCmd->Patterns.push_back(next());
} else if (Tok == "KEEP") {
expect("(");
expect("*");
expect("(");
+ auto *InCmd = new InputSectionDescription();
+ Cmd->Commands.emplace_back(InCmd);
while (!Error && !skip(")")) {
- StringRef Sec = next();
- Opt.Sections.emplace_back(OutSec, Sec);
- Opt.KeptSections.push_back(Sec);
+ Opt.KeptSections.push_back(peek());
+ InCmd->Patterns.push_back(next());
}
expect(")");
} else {
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=276283&r1=276282&r2=276283&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Thu Jul 21 09:26:59 2016
@@ -31,25 +31,13 @@ class ScriptParser;
template <class ELFT> class InputSectionBase;
template <class ELFT> class OutputSectionBase;
-// This class represents each rule in SECTIONS command.
-struct SectionRule {
- SectionRule(StringRef D, StringRef S)
- : Dest(D), SectionPattern(S) {}
-
- StringRef Dest;
-
- StringRef SectionPattern;
-};
-
-// This enum represents what we can observe in SECTIONS tag of script.
-// Each sections-command may of be one of the following:
-// (https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS)
-// * An ENTRY command.
-// * A symbol assignment.
-// * An output section description.
-// * An overlay description.
-// We support only AssignmentKind and OutputSectionKind for now.
-enum SectionsCommandKind { AssignmentKind, OutputSectionKind };
+// This enum is used to implement linker script SECTIONS command.
+// https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
+enum SectionsCommandKind {
+ AssignmentKind,
+ OutputSectionKind,
+ InputSectionKind
+};
struct BaseCommand {
BaseCommand(int K) : Kind(K) {}
@@ -70,10 +58,17 @@ struct OutputSectionCommand : BaseComman
: BaseCommand(OutputSectionKind), Name(Name) {}
static bool classof(const BaseCommand *C);
StringRef Name;
+ std::vector<std::unique_ptr<BaseCommand>> Commands;
std::vector<StringRef> Phdrs;
std::vector<uint8_t> Filler;
};
+struct InputSectionDescription : BaseCommand {
+ InputSectionDescription() : BaseCommand(InputSectionKind) {}
+ static bool classof(const BaseCommand *C);
+ std::vector<StringRef> Patterns;
+};
+
struct PhdrsCommand {
StringRef Name;
unsigned Type;
@@ -84,9 +79,6 @@ struct PhdrsCommand {
// ScriptConfiguration holds linker script parse results.
struct ScriptConfiguration {
- // SECTIONS commands.
- std::vector<SectionRule> Sections;
-
// Used to assign addresses to sections.
std::vector<std::unique_ptr<BaseCommand>> Commands;
@@ -114,7 +106,6 @@ public:
std::vector<OutputSectionBase<ELFT> *>
createSections(OutputSectionFactory<ELFT> &Factory);
- StringRef getOutputSection(InputSectionBase<ELFT> *S);
ArrayRef<uint8_t> getFiller(StringRef Name);
bool isDiscarded(InputSectionBase<ELFT> *S);
bool shouldKeep(InputSectionBase<ELFT> *S);
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=276283&r1=276282&r2=276283&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Jul 21 09:26:59 2016
@@ -90,10 +90,6 @@ private:
template <class ELFT>
StringRef elf::getOutputSectionName(InputSectionBase<ELFT> *S) {
- StringRef Dest = Script<ELFT>::X->getOutputSection(S);
- if (!Dest.empty())
- return Dest;
-
StringRef Name = S->getSectionName();
for (StringRef V : {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.",
".init_array.", ".fini_array.", ".ctors.", ".dtors.",
More information about the llvm-commits
mailing list