diff options
author | Simon Atanasyan <simon@atanasyan.com> | 2014-07-15 17:17:30 +0000 |
---|---|---|
committer | Simon Atanasyan <simon@atanasyan.com> | 2014-07-15 17:17:30 +0000 |
commit | 64c0ac2b35df65e38c966089f9a7ab9075bf7f58 (patch) | |
tree | c2093bee27114d037493703dc539241db0ab021e /lld/lib/ReaderWriter | |
parent | bc94c94be40d289948b4043fe4d973295061e484 (diff) | |
download | bcm5719-llvm-64c0ac2b35df65e38c966089f9a7ab9075bf7f58.tar.gz bcm5719-llvm-64c0ac2b35df65e38c966089f9a7ab9075bf7f58.zip |
[ELF] Implement parsing `-l` prefixed items in the `GROUP` linker script command.
There are two forms of `-l` prefixed expression:
* -l<libname>
* -l:<filename>
In the first case a linker should construct a full library name
`lib + libname + .[so|a]` and search this library as usual. In the second case
a linker should use the `<filename>` as is and search this file through library
search directories.
The patch reviewed by Shankar Easwaran.
llvm-svn: 213077
Diffstat (limited to 'lld/lib/ReaderWriter')
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp | 9 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/LinkerScript.cpp | 42 |
2 files changed, 45 insertions, 6 deletions
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 )")) |