diff options
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 10 | ||||
| -rw-r--r-- | lld/ELF/LinkerScript.h | 16 | ||||
| -rw-r--r-- | lld/ELF/Strings.cpp | 30 | ||||
| -rw-r--r-- | lld/ELF/Strings.h | 12 |
4 files changed, 54 insertions, 14 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index b51cf80ca00..1169f838e19 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -936,7 +936,7 @@ private: std::vector<uint8_t> readOutputSectionFiller(StringRef Tok); std::vector<StringRef> readOutputSectionPhdrs(); InputSectionDescription *readInputSectionDescription(StringRef Tok); - Regex readFilePatterns(); + StringMatcher readFilePatterns(); std::vector<SectionPattern> readInputSectionsList(); InputSectionDescription *readInputSectionRules(StringRef FilePattern); unsigned readPhdrType(); @@ -1207,11 +1207,11 @@ static int precedence(StringRef Op) { .Default(-1); } -Regex ScriptParser::readFilePatterns() { +StringMatcher ScriptParser::readFilePatterns() { std::vector<StringRef> V; while (!Error && !consume(")")) V.push_back(next()); - return compileGlobPatterns(V); + return StringMatcher(std::move(V)); } SortSectionPolicy ScriptParser::readSortKind() { @@ -1236,7 +1236,7 @@ SortSectionPolicy ScriptParser::readSortKind() { std::vector<SectionPattern> ScriptParser::readInputSectionsList() { std::vector<SectionPattern> Ret; while (!Error && peek() != ")") { - Regex ExcludeFileRe; + StringMatcher ExcludeFileRe; if (consume("EXCLUDE_FILE")) { expect("("); ExcludeFileRe = readFilePatterns(); @@ -1247,7 +1247,7 @@ std::vector<SectionPattern> ScriptParser::readInputSectionsList() { V.push_back(next()); if (!V.empty()) - Ret.push_back({std::move(ExcludeFileRe), compileGlobPatterns(V)}); + Ret.push_back({std::move(ExcludeFileRe), StringMatcher(std::move(V))}); else setError("section pattern is expected"); } diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 8ab04ab91c4..0503a6c73cc 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -19,7 +19,6 @@ #include "llvm/ADT/MapVector.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Regex.h" #include <functional> namespace lld { @@ -115,9 +114,9 @@ struct OutputSectionCommand : BaseCommand { // It can optionally have negative match pattern for EXCLUDED_FILE command. // Also it may be surrounded with SORT() command, so contains sorting rules. struct SectionPattern { - SectionPattern(llvm::Regex &&Re1, llvm::Regex &&Re2) - : ExcludedFileRe(std::forward<llvm::Regex>(Re1)), - SectionRe(std::forward<llvm::Regex>(Re2)) {} + SectionPattern(StringMatcher &&Re1, StringMatcher &&Re2) + : ExcludedFileRe(std::forward<StringMatcher>(Re1)), + SectionRe(std::forward<StringMatcher>(Re2)) {} SectionPattern(SectionPattern &&Other) { std::swap(ExcludedFileRe, Other.ExcludedFileRe); @@ -126,18 +125,17 @@ struct SectionPattern { std::swap(SortInner, Other.SortInner); } - llvm::Regex ExcludedFileRe; - llvm::Regex SectionRe; + StringMatcher ExcludedFileRe; + StringMatcher SectionRe; SortSectionPolicy SortOuter; SortSectionPolicy SortInner; }; struct InputSectionDescription : BaseCommand { InputSectionDescription(StringRef FilePattern) - : BaseCommand(InputSectionKind), - FileRe(compileGlobPatterns({FilePattern})) {} + : BaseCommand(InputSectionKind), FileRe(FilePattern) {} static bool classof(const BaseCommand *C); - llvm::Regex FileRe; + StringMatcher FileRe; // Input sections that matches at least one of SectionPatterns // will be associated with this InputSectionDescription. diff --git a/lld/ELF/Strings.cpp b/lld/ELF/Strings.cpp index ffabd009c17..09459ab0e04 100644 --- a/lld/ELF/Strings.cpp +++ b/lld/ELF/Strings.cpp @@ -21,6 +21,36 @@ using namespace llvm; using namespace lld; using namespace lld::elf; +// Returns true if S matches T. S can contain glob meta-characters. +// The asterisk ('*') matches zero or more characters, and the question +// mark ('?') matches one character. +static bool globMatch(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 (globMatch(S, T.substr(I))) + return true; + return false; + } + if (T.empty() || (S[0] != T[0] && S[0] != '?')) + return false; + S = S.substr(1); + T = T.substr(1); + } +} + +bool StringMatcher::match(StringRef S) { + for (StringRef P : Patterns) + if (globMatch(P, S)) + return true; + return false; +} // If an input string is in the form of "foo.N" where N is a number, // return N. Otherwise, returns 65536, which is one greater than the // lowest priority. diff --git a/lld/ELF/Strings.h b/lld/ELF/Strings.h index 5b613253553..3194b996011 100644 --- a/lld/ELF/Strings.h +++ b/lld/ELF/Strings.h @@ -25,6 +25,18 @@ std::vector<uint8_t> parseHex(StringRef S); bool isValidCIdentifier(StringRef S); StringRef unquote(StringRef S); +class StringMatcher { +public: + StringMatcher() = default; + explicit StringMatcher(StringRef P) : Patterns({P}) {} + explicit StringMatcher(std::vector<StringRef> &&Pat) + : Patterns(std::move(Pat)) {} + + bool match(StringRef S); +private: + std::vector<StringRef> Patterns; +}; + // Returns a demangled C++ symbol name. If Name is not a mangled // name or the system does not provide __cxa_demangle function, // it returns an unmodified string. |

