summaryrefslogtreecommitdiffstats
path: root/lld/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib')
-rw-r--r--lld/lib/Driver/GnuLdInputGraph.cpp1
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp9
-rw-r--r--lld/lib/ReaderWriter/LinkerScript.cpp42
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 )"))
OpenPOWER on IntegriCloud