diff --git a/lld/Common/Strings.cpp b/lld/Common/Strings.cpp --- a/lld/Common/Strings.cpp +++ b/lld/Common/Strings.cpp @@ -31,6 +31,16 @@ return demangle(name); } +StringMatcher::StringMatcher(ArrayRef> pat) { + for (std::pair p : pat) { + Expected pat = GlobPattern::create(p.first, p.second); + if (!pat) + error(toString(pat.takeError())); + else + patterns.push_back(*pat); + } +} + StringMatcher::StringMatcher(ArrayRef pat) { for (StringRef s : pat) { Expected pat = GlobPattern::create(s); diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -156,7 +156,15 @@ struct InputSectionDescription : BaseCommand { InputSectionDescription(StringRef filePattern) - : BaseCommand(InputSectionKind), filePat(filePattern) {} + : BaseCommand(InputSectionKind), filePat(filePattern) { + bool ForceExactMatch = false; + // Do not glob filename inside double quotes. + if (filePattern.startswith("\"")) { + filePattern = filePattern.substr(1, filePattern.size() - 2); + ForceExactMatch = true; + } + filePat = StringMatcher(std::make_pair(filePattern, ForceExactMatch)); + } static bool classof(const BaseCommand *c) { return c->kind == InputSectionKind; diff --git a/lld/include/lld/Common/Strings.h b/lld/include/lld/Common/Strings.h --- a/lld/include/lld/Common/Strings.h +++ b/lld/include/lld/Common/Strings.h @@ -32,6 +32,7 @@ public: StringMatcher() = default; explicit StringMatcher(llvm::ArrayRef pat); + explicit StringMatcher(llvm::ArrayRef> pat); bool match(llvm::StringRef s) const; diff --git a/lld/test/ELF/linkerscript/filename-spec.s b/lld/test/ELF/linkerscript/filename-spec.s --- a/lld/test/ELF/linkerscript/filename-spec.s +++ b/lld/test/ELF/linkerscript/filename-spec.s @@ -30,12 +30,12 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ # RUN: %p/Inputs/filename-spec.s -o %t.dir/filename-spec2.o -# RUN: echo "SECTIONS{.foo :{ %/t.dir/filename-spec2.o(.foo) %/t.dir/filename-spec1.o(.foo) }}" > %t5.script +# RUN: echo "SECTIONS{.foo :{ \"%/t.dir/filename-spec2.o\"(.foo) \"%/t.dir/filename-spec1.o\"(.foo) }}" > %t5.script # RUN: ld.lld -o %t5 --script %t5.script \ # RUN: %/t.dir/filename-spec1.o %/t.dir/filename-spec2.o # RUN: llvm-objdump -s %t5 | FileCheck --check-prefix=SECONDFIRST %s -# RUN: echo "SECTIONS{.foo :{ %/t.dir/filename-spec1.o(.foo) %/t.dir/filename-spec2.o(.foo) }}" > %t6.script +# RUN: echo "SECTIONS{.foo :{ \"%/t.dir/filename-spec1.o\"(.foo) \"%/t.dir/filename-spec2.o\"(.foo) }}" > %t6.script # RUN: ld.lld -o %t6 --script %t6.script \ # RUN: %/t.dir/filename-spec1.o %/t.dir/filename-spec2.o # RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTY %s diff --git a/llvm/include/llvm/Support/GlobPattern.h b/llvm/include/llvm/Support/GlobPattern.h --- a/llvm/include/llvm/Support/GlobPattern.h +++ b/llvm/include/llvm/Support/GlobPattern.h @@ -28,7 +28,7 @@ class GlobPattern { public: - static Expected create(StringRef Pat); + static Expected create(StringRef Pat, bool ForceExactMatch = true); bool match(StringRef S) const; private: diff --git a/llvm/lib/Support/GlobPattern.cpp b/llvm/lib/Support/GlobPattern.cpp --- a/llvm/lib/Support/GlobPattern.cpp +++ b/llvm/lib/Support/GlobPattern.cpp @@ -105,12 +105,12 @@ } } -Expected GlobPattern::create(StringRef S) { +Expected GlobPattern::create(StringRef S, bool ForceExactMatch) { GlobPattern Pat; - // S doesn't contain any metacharacter, + // S should be matched "as is" or doesn't contain any metacharacter, // so the regular string comparison should work. - if (!hasWildcard(S)) { + if (ForceExactMatch || !hasWildcard(S)) { Pat.Exact = S; return Pat; }