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.cpp59
1 files changed, 54 insertions, 5 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 1e0e855171d..f43f99debe4 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -16,6 +16,7 @@
#include "LinkerScript.h"
#include "Config.h"
#include "Driver.h"
+#include "InputSection.h"
#include "SymbolTable.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -23,17 +24,23 @@
#include "llvm/Support/StringSaver.h"
using namespace llvm;
+using namespace llvm::object;
using namespace lld;
using namespace lld::elf2;
LinkerScript *elf2::Script;
-StringRef LinkerScript::getOutputSection(StringRef S) {
- return Sections.lookup(S);
+template <class ELFT>
+StringRef LinkerScript::getOutputSection(InputSectionBase<ELFT> *S) {
+ for (SectionRule &R : Sections)
+ if (R.match(S))
+ return R.Dest;
+ return "";
}
-bool LinkerScript::isDiscarded(StringRef S) {
- return Sections.lookup(S) == "/DISCARD/";
+template <class ELFT>
+bool LinkerScript::isDiscarded(InputSectionBase<ELFT> *S) {
+ return getOutputSection(S) == "/DISCARD/";
}
// A compartor to sort output sections. Returns -1 or 1 if both
@@ -48,6 +55,33 @@ int LinkerScript::compareSections(StringRef A, StringRef B) {
return I < J ? -1 : 1;
}
+// Returns true if S matches T. S may contain a meta character '*'
+// which matches zero or more occurrences of any character.
+static bool matchStr(StringRef S, StringRef T) {
+ for (;;) {
+ if (S.empty())
+ return T.empty();
+ if (S[0] == '*') {
+ S = S.substr(1);
+ if (S.empty())
+ // Fast path. If a pattern is '*', it matches anything.
+ return true;
+ for (size_t I = 0, E = T.size(); I < E; ++I)
+ if (matchStr(S, T.substr(I)))
+ return true;
+ return false;
+ }
+ if (T.empty() || S[0] != T[0])
+ return false;
+ S = S.substr(1);
+ T = T.substr(1);
+ }
+}
+
+template <class ELFT> bool SectionRule::match(InputSectionBase<ELFT> *S) {
+ return matchStr(SectionPattern, S->getSectionName());
+}
+
class elf2::ScriptParser {
public:
ScriptParser(BumpPtrAllocator *A, StringRef S, bool B)
@@ -352,7 +386,7 @@ void ScriptParser::readOutputSectionDescription() {
next(); // Skip input file name.
expect("(");
while (!Error && !skip(")"))
- Script->Sections[next()] = OutSec;
+ Script->Sections.push_back({OutSec, next()});
}
}
@@ -370,3 +404,18 @@ void LinkerScript::read(MemoryBufferRef MB) {
StringRef Path = MB.getBufferIdentifier();
ScriptParser(&Alloc, MB.getBuffer(), isUnderSysroot(Path)).run();
}
+
+template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF32LE> *);
+template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF32BE> *);
+template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF64LE> *);
+template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF64BE> *);
+
+template bool LinkerScript::isDiscarded(InputSectionBase<ELF32LE> *);
+template bool LinkerScript::isDiscarded(InputSectionBase<ELF32BE> *);
+template bool LinkerScript::isDiscarded(InputSectionBase<ELF64LE> *);
+template bool LinkerScript::isDiscarded(InputSectionBase<ELF64BE> *);
+
+template bool SectionRule::match(InputSectionBase<ELF32LE> *);
+template bool SectionRule::match(InputSectionBase<ELF32BE> *);
+template bool SectionRule::match(InputSectionBase<ELF64LE> *);
+template bool SectionRule::match(InputSectionBase<ELF64BE> *);
OpenPOWER on IntegriCloud