summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2014-07-15 17:17:30 +0000
committerSimon Atanasyan <simon@atanasyan.com>2014-07-15 17:17:30 +0000
commit64c0ac2b35df65e38c966089f9a7ab9075bf7f58 (patch)
treec2093bee27114d037493703dc539241db0ab021e /lld/lib/ReaderWriter
parentbc94c94be40d289948b4043fe4d973295061e484 (diff)
downloadbcm5719-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.cpp9
-rw-r--r--lld/lib/ReaderWriter/LinkerScript.cpp42
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 )"))
OpenPOWER on IntegriCloud