Index: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h =================================================================== --- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h +++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h @@ -268,6 +268,9 @@ return true; } + // Retrieve search path list. + StringRefVector getSearchPaths() { return _inputSearchPaths; }; + // By default, the linker would merge sections that are read only with // segments that have read and execute permissions. When the user specifies a // flag --rosegment, a separate segment needs to be created. Index: lld/trunk/lib/Driver/GnuLdDriver.cpp =================================================================== --- lld/trunk/lib/Driver/GnuLdDriver.cpp +++ lld/trunk/lib/Driver/GnuLdDriver.cpp @@ -280,11 +280,16 @@ if (!script) return LinkerScriptReaderError::parse_error; // Evaluate script commands. - // Currently we only recognize GROUP() command. - for (const script::Command *c : script->_commands) + // Currently we only recognize this subset of linker script commands: + // - GROUP() + // - SEARCH_DIR() + for (const script::Command *c : script->_commands) { if (auto *group = dyn_cast(c)) if (std::error_code ec = evaluateLinkerScriptGroup(ctx, path, group, diag)) return ec; + if (auto *searchDir = dyn_cast(c)) + ctx.addSearchPath(searchDir->getSearchPath()); + } return std::error_code(); } Index: lld/trunk/unittests/DriverTests/GnuLdDriverTest.cpp =================================================================== --- lld/trunk/unittests/DriverTests/GnuLdDriverTest.cpp +++ lld/trunk/unittests/DriverTests/GnuLdDriverTest.cpp @@ -177,3 +177,17 @@ EXPECT_EQ("/y", cast(nodes[2].get())->getFile()->path()); EXPECT_EQ(2, cast(nodes[3].get())->getSize()); } + +TEST_F(GnuLdParserTest, LinkerScriptSearchDir) { + parse("ld", "a.o", nullptr); + std::unique_ptr mb = MemoryBuffer::getMemBuffer( + "SEARCH_DIR(\"/foo/bar\")", "foo.so"); + std::string s; + raw_string_ostream out(s); + std::error_code ec = GnuLdDriver::evalLinkerScript( + *_context, std::move(mb), out); + EXPECT_FALSE(ec); + std::vector searchPaths = _context->getSearchPaths(); + EXPECT_EQ((size_t)2, searchPaths.size()); + EXPECT_EQ("/foo/bar", searchPaths[1]); +}