diff options
Diffstat (limited to 'lld/lib')
| -rw-r--r-- | lld/lib/Driver/GnuLdInputGraph.cpp | 1 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp | 9 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/LinkerScript.cpp | 42 |
3 files changed, 46 insertions, 6 deletions
diff --git a/lld/lib/Driver/GnuLdInputGraph.cpp b/lld/lib/Driver/GnuLdInputGraph.cpp index f634c2eba58..ac85565d100 100644 --- a/lld/lib/Driver/GnuLdInputGraph.cpp +++ b/lld/lib/Driver/GnuLdInputGraph.cpp @@ -96,6 +96,7 @@ std::error_code ELFGNULdScript::parse(const LinkingContext &ctx, for (const script::Path &path : group->getPaths()) { // TODO : Propagate Set WholeArchive/dashlPrefix attributes.setAsNeeded(path._asNeeded); + attributes.setDashlPrefix(path._isDashlPrefix); auto inputNode = new ELFFileNode( _elfLinkingContext, _elfLinkingContext.allocateString(path._path), attributes); diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp index 23036bca9f9..fe33d403d10 100644 --- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -163,18 +163,23 @@ static void buildSearchPath(SmallString<128> &path, StringRef dir, } ErrorOr<StringRef> ELFLinkingContext::searchLibrary(StringRef libName) const { + bool hasColonPrefix = libName[0] == ':'; + Twine soName = + hasColonPrefix ? libName.drop_front() : Twine("lib", libName) + ".so"; + Twine archiveName = + hasColonPrefix ? libName.drop_front() : Twine("lib", libName) + ".a"; SmallString<128> path; for (StringRef dir : _inputSearchPaths) { // Search for dynamic library if (!_isStaticExecutable) { buildSearchPath(path, dir, _sysrootPath); - llvm::sys::path::append(path, Twine("lib") + libName + ".so"); + llvm::sys::path::append(path, soName); if (llvm::sys::fs::exists(path.str())) return StringRef(*new (_allocator) std::string(path.str())); } // Search for static libraries too buildSearchPath(path, dir, _sysrootPath); - llvm::sys::path::append(path, Twine("lib") + libName + ".a"); + llvm::sys::path::append(path, archiveName); if (llvm::sys::fs::exists(path.str())) return StringRef(*new (_allocator) std::string(path.str())); } diff --git a/lld/lib/ReaderWriter/LinkerScript.cpp b/lld/lib/ReaderWriter/LinkerScript.cpp index 796fa24a566..8ba5f47e5c4 100644 --- a/lld/lib/ReaderWriter/LinkerScript.cpp +++ b/lld/lib/ReaderWriter/LinkerScript.cpp @@ -24,6 +24,7 @@ void Token::dump(raw_ostream &os) const { break; CASE(eof) CASE(identifier) + CASE(libname) CASE(kw_as_needed) CASE(kw_entry) CASE(kw_group) @@ -118,6 +119,24 @@ void Lexer::lex(Token &tok) { _buffer = _buffer.drop_front(quotedStringEnd + 1); return; } + // -l<lib name> + if (_buffer.startswith("-l")) { + _buffer = _buffer.drop_front(2); + StringRef::size_type start = 0; + if (_buffer[start] == ':') + ++start; + if (!canStartName(_buffer[start])) + // Create 'unknown' token. + break; + auto libNameEnd = + std::find_if(_buffer.begin() + start + 1, _buffer.end(), + [=](char c) { return !canContinueName(c); }); + StringRef::size_type libNameLen = + std::distance(_buffer.begin(), libNameEnd); + tok = Token(_buffer.substr(0, libNameLen), Token::libname); + _buffer = _buffer.drop_front(libNameLen); + return; + } /// keyword or identifer. if (!canStartName(_buffer[0])) break; @@ -295,12 +314,17 @@ Group *Parser::parseGroup() { std::vector<Path> paths; - while (_tok._kind == Token::identifier || _tok._kind == Token::kw_as_needed) { + while (_tok._kind == Token::identifier || _tok._kind == Token::libname || + _tok._kind == Token::kw_as_needed) { switch (_tok._kind) { case Token::identifier: paths.push_back(Path(_tok._range)); consumeToken(); break; + case Token::libname: + paths.push_back(Path(_tok._range, false, true)); + consumeToken(); + break; case Token::kw_as_needed: if (!parseAsNeeded(paths)) return nullptr; @@ -325,9 +349,19 @@ bool Parser::parseAsNeeded(std::vector<Path> &paths) { if (!expectAndConsume(Token::l_paren, "expected (")) return false; - while (_tok._kind == Token::identifier) { - paths.push_back(Path(_tok._range, true)); - consumeToken(); + while (_tok._kind == Token::identifier || _tok._kind == Token::libname) { + switch (_tok._kind) { + case Token::identifier: + paths.push_back(Path(_tok._range, true, false)); + consumeToken(); + break; + case Token::libname: + paths.push_back(Path(_tok._range, true, true)); + consumeToken(); + break; + default: + llvm_unreachable("Invalid token."); + } } if (!expectAndConsume(Token::r_paren, "expected )")) |

