diff --git a/lld/ELF/ScriptLexer.cpp b/lld/ELF/ScriptLexer.cpp index 9d31b2b22651..40528f0cd7f6 100644 --- a/lld/ELF/ScriptLexer.cpp +++ b/lld/ELF/ScriptLexer.cpp @@ -27,15 +27,32 @@ //===----------------------------------------------------------------------===// #include "ScriptLexer.h" +#include "Config.h" #include "lld/Common/ErrorHandler.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include using namespace llvm; using namespace lld; using namespace lld::elf; +ScriptLexer::Buffer::Buffer(MemoryBufferRef mb) + : s(mb.getBuffer()), filename(mb.getBufferIdentifier()), + begin(mb.getBufferStart()) { + if (config->sysroot == "") + return; + StringRef path = filename; + for (; !path.empty(); path = sys::path::parent_path(path)) { + if (!sys::fs::equivalent(config->sysroot, path)) + continue; + isUnderSysroot = true; + return; + } +} + ScriptLexer::ScriptLexer(MemoryBufferRef mb) : curBuf(mb), mbs(1, mb) { activeFilenames.insert(mb.getBufferIdentifier()); } diff --git a/lld/ELF/ScriptLexer.h b/lld/ELF/ScriptLexer.h index 0c12b984c9e1..ffd84411f22a 100644 --- a/lld/ELF/ScriptLexer.h +++ b/lld/ELF/ScriptLexer.h @@ -25,10 +25,12 @@ protected: StringRef s, filename; const char *begin = nullptr; size_t lineNumber = 1; + // True if the script is opened as an absolute path under the --sysroot + // directory. + bool isUnderSysroot = false; + Buffer() = default; - Buffer(MemoryBufferRef mb) - : s(mb.getBuffer()), filename(mb.getBufferIdentifier()), - begin(mb.getBufferStart()) {} + Buffer(MemoryBufferRef mb); }; // The current buffer and parent buffers due to INCLUDE. Buffer curBuf; diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index c03373387709..714e290578ce 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -48,16 +48,6 @@ namespace { class ScriptParser final : ScriptLexer { public: ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) { - // Initialize IsUnderSysroot - if (config->sysroot == "") - return; - StringRef path = mb.getBufferIdentifier(); - for (; !path.empty(); path = sys::path::parent_path(path)) { - if (!sys::fs::equivalent(config->sysroot, path)) - continue; - isUnderSysroot = true; - return; - } } void readLinkerScript(); @@ -135,9 +125,6 @@ private: std::pair, SmallVector> readSymbols(); - // True if a script being read is in the --sysroot directory. - bool isUnderSysroot = false; - // If we are currently parsing a PROVIDE|PROVIDE_HIDDEN command, // then this member is set to the PROVIDE symbol name. std::optional activeProvideSym; @@ -319,7 +306,7 @@ void ScriptParser::readNoCrossRefs(bool to) { } void ScriptParser::addFile(StringRef s) { - if (isUnderSysroot && s.starts_with("/")) { + if (curBuf.isUnderSysroot && s.starts_with("/")) { SmallString<128> pathData; StringRef path = (config->sysroot + s).toStringRef(pathData); if (sys::fs::exists(path)) diff --git a/lld/test/ELF/linkerscript/group.s b/lld/test/ELF/linkerscript/group.s index 643dd6fc5377..8cfe1631a8c8 100644 --- a/lld/test/ELF/linkerscript/group.s +++ b/lld/test/ELF/linkerscript/group.s @@ -24,7 +24,8 @@ # RUN: echo 'GROUP(AS_NEEDED("a.o"))INPUT(/libb.a)' > %t.dir/3a.t # RUN: ld.lld 3.t --sysroot=%t.dir # RUN: llvm-nm a.out | FileCheck %s -# RUN: not ld.lld 3i.t --sysroot=%t.dir 2>&1 | FileCheck %s --check-prefix=CANNOT_OPEN -DFILE=/libb.a +# RUN: ld.lld 3i.t --sysroot=%t.dir +# RUN: llvm-nm a.out | FileCheck %s # RUN: echo 'GROUP("%t.dir/4a.t")INPUT(/libb.a)' > 4.t # RUN: echo 'GROUP(AS_NEEDED("a.o"))' > %t.dir/4a.t