[lld] r226274 - [ELF] Add --as-needed.
Rui Ueyama
ruiu at google.com
Fri Jan 16 06:27:02 PST 2015
Author: ruiu
Date: Fri Jan 16 08:27:01 2015
New Revision: 226274
URL: http://llvm.org/viewvc/llvm-project?rev=226274&view=rev
Log:
[ELF] Add --as-needed.
The previous default behavior of LLD is --as-needed. LLD linked
against a DSO only if the DSO file was actually used to link an
executable (i.e. at least one symbol was resolved using the shared
library file.)
In this patch I added a boolean flag to FileNode for --as-needed.
I also added an accessor to DSO name to shared library file class.
Added:
lld/trunk/test/elf/as-needed.test
Modified:
lld/trunk/include/lld/Core/Node.h
lld/trunk/include/lld/Core/SharedLibraryFile.h
lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
lld/trunk/lib/Driver/GnuLdDriver.cpp
lld/trunk/lib/Driver/TODO.rst
lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
lld/trunk/lib/ReaderWriter/MachO/File.h
lld/trunk/test/elf/Mips/dynsym-table-1.test
Modified: lld/trunk/include/lld/Core/Node.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Node.h?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Node.h (original)
+++ lld/trunk/include/lld/Core/Node.h Fri Jan 16 08:27:01 2015
@@ -57,9 +57,7 @@ private:
class FileNode : public Node {
public:
explicit FileNode(std::unique_ptr<File> f)
- : Node(Node::Kind::File), _file(std::move(f)) {}
-
- virtual ~FileNode() {}
+ : Node(Node::Kind::File), _file(std::move(f)), _asNeeded(false) {}
static inline bool classof(const Node *a) {
return a->kind() == Node::Kind::File;
@@ -67,8 +65,12 @@ public:
File *getFile() { return _file.get(); }
+ void setAsNeeded(bool val) { _asNeeded = val; }
+ bool asNeeded() const { return _asNeeded; }
+
protected:
std::unique_ptr<File> _file;
+ bool _asNeeded;
};
} // namespace lld
Modified: lld/trunk/include/lld/Core/SharedLibraryFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SharedLibraryFile.h?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/SharedLibraryFile.h (original)
+++ lld/trunk/include/lld/Core/SharedLibraryFile.h Fri Jan 16 08:27:01 2015
@@ -31,6 +31,11 @@ public:
/// symbol. Otherwise return nullptr.
virtual const SharedLibraryAtom *exports(StringRef name,
bool dataSymbolOnly) const = 0;
+
+ // Returns DSO name. It's the soname (ELF), the install name (MachO) or
+ // the import name (Windows).
+ virtual StringRef getDSOName() const = 0;
+
protected:
/// only subclasses of SharedLibraryFile can be instantiated
explicit SharedLibraryFile(StringRef path) : File(path, kindSharedLibrary) {}
Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Fri Jan 16 08:27:01 2015
@@ -297,17 +297,14 @@ public:
class Attributes {
public:
Attributes()
- : _isWholeArchive(false), _asNeeded(false), _isDashlPrefix(false),
- _isSysRooted(false) {}
+ : _isWholeArchive(false), _isDashlPrefix(false), _isSysRooted(false) {}
void setWholeArchive(bool isWholeArchive) {
_isWholeArchive = isWholeArchive;
}
- void setAsNeeded(bool asNeeded) { _asNeeded = asNeeded; }
void setDashlPrefix(bool isDashlPrefix) { _isDashlPrefix = isDashlPrefix; }
void setSysRooted(bool isSysRooted) { _isSysRooted = isSysRooted; }
bool _isWholeArchive;
- bool _asNeeded;
bool _isDashlPrefix;
bool _isSysRooted;
};
Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Fri Jan 16 08:27:01 2015
@@ -259,7 +259,6 @@ evaluateLinkerScript(ELFLinkingContext &
// TODO : Propagate Set WholeArchive/dashlPrefix
ELFLinkingContext::Attributes attr;
attr.setSysRooted(sysroot);
- attr.setAsNeeded(path._asNeeded);
attr.setDashlPrefix(path._isDashlPrefix);
ErrorOr<StringRef> pathOrErr = path._isDashlPrefix
@@ -357,6 +356,7 @@ bool GnuLdDriver::parse(int argc, const
int numfiles = 0;
ELFLinkingContext::Attributes attributes;
+ bool asNeeded = false;
bool _outputOptionSet = false;
@@ -516,11 +516,11 @@ bool GnuLdDriver::parse(int argc, const
break;
case OPT_as_needed:
- attributes.setAsNeeded(true);
+ asNeeded = true;
break;
case OPT_no_as_needed:
- attributes.setAsNeeded(false);
+ asNeeded = false;
break;
case OPT_defsym: {
@@ -612,7 +612,9 @@ bool GnuLdDriver::parse(int argc, const
for (std::unique_ptr<File> &file : files) {
if (ctx->logInputFiles())
diagnostics << file->path() << "\n";
- ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
+ auto node = llvm::make_unique<FileNode>(std::move(file));
+ node->setAsNeeded(asNeeded);
+ ctx->getNodes().push_back(std::move(node));
}
numfiles += files.size();
break;
Modified: lld/trunk/lib/Driver/TODO.rst
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/TODO.rst?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/lib/Driver/TODO.rst (original)
+++ lld/trunk/lib/Driver/TODO.rst Fri Jan 16 08:27:01 2015
@@ -41,7 +41,6 @@ Missing Options
* -y,--trace-symbol
* -z (keywords need to be implemented)
* --accept-unknown-input-arch,--no-accept-unknown-input-arch
-* --as-needed,--no-as-needed
* -Bdynamic,-dy,-call_shared
* -Bgroup
* -dn,-non_shared
Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h Fri Jan 16 08:27:01 2015
@@ -55,6 +55,8 @@ public:
*this, name, _soname, sym->second._symbol);
}
+ StringRef getDSOName() const override { return _soname; }
+
protected:
std::error_code doParse() override {
std::error_code ec;
Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Fri Jan 16 08:27:01 2015
@@ -14,6 +14,7 @@
#include "TargetLayout.h"
#include "lld/Core/Instrumentation.h"
#include "lld/Core/Parallel.h"
+#include "lld/Core/SharedLibraryFile.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/ADT/StringSet.h"
@@ -143,6 +144,9 @@ protected:
LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable;
llvm::StringSet<> _soNeeded;
/// @}
+
+private:
+ static StringRef maybeGetSOName(Node *node);
};
//===----------------------------------------------------------------------===//
@@ -177,6 +181,17 @@ void OutputELFWriter<ELFT>::buildStaticS
_symtab->addSymbol(a, ELF::SHN_UNDEF);
}
+// Returns the DSO name for a given input file if it's a shared library
+// file and not marked as --as-needed.
+template <class ELFT>
+StringRef OutputELFWriter<ELFT>::maybeGetSOName(Node *node) {
+ if (auto *fnode = dyn_cast<FileNode>(node))
+ if (!fnode->asNeeded())
+ if (auto *file = dyn_cast<SharedLibraryFile>(fnode->getFile()))
+ return file->getDSOName();
+ return "";
+}
+
template <class ELFT>
void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable");
@@ -189,6 +204,11 @@ void OutputELFWriter<ELFT>::buildDynamic
if (isNeededTagRequired(sla))
_soNeeded.insert(sla->loadName());
}
+ for (const std::unique_ptr<Node> &node : _context.getNodes()) {
+ StringRef soname = maybeGetSOName(node.get());
+ if (!soname.empty())
+ _soNeeded.insert(soname);
+ }
// Never mark the dynamic linker as DT_NEEDED
_soNeeded.erase(sys::path::filename(_context.getInterpreter()));
for (const auto &loadName : _soNeeded) {
Modified: lld/trunk/lib/ReaderWriter/MachO/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/File.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/File.h Fri Jan 16 08:27:01 2015
@@ -273,6 +273,8 @@ public:
}
}
+ StringRef getDSOName() const override { return _installName; }
+
std::error_code doParse() override {
// Convert binary file to normalized mach-o.
auto normFile = normalized::readBinary(_mb, _ctx->arch());
Modified: lld/trunk/test/elf/Mips/dynsym-table-1.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/dynsym-table-1.test?rev=226274&r1=226273&r2=226274&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/dynsym-table-1.test (original)
+++ lld/trunk/test/elf/Mips/dynsym-table-1.test Fri Jan 16 08:27:01 2015
@@ -10,7 +10,7 @@
# RUN: yaml2obj -format=elf -docnum 3 %s > %t-main.o
# RUN: lld -flavor gnu -target mipsel -shared -o %t-bar.so %t-bar.o
# RUN: lld -flavor gnu -target mipsel -shared -o %t-foo.so %t-foo.o %t-bar.so
-# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe \
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe --as-needed \
# RUN: %t-main.o %t-foo.so %t-bar.so
# RUN: llvm-readobj -dt -dynamic-table %t.exe | FileCheck %s
Added: lld/trunk/test/elf/as-needed.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/as-needed.test?rev=226274&view=auto
==============================================================================
--- lld/trunk/test/elf/as-needed.test (added)
+++ lld/trunk/test/elf/as-needed.test Fri Jan 16 08:27:01 2015
@@ -0,0 +1,15 @@
+RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared.x86-64 \
+RUN: --as-needed %p/Inputs/shared.so-x86-64 %p/Inputs/libifunc.x86-64.so \
+RUN: -o %t1 -e main --allow-shlib-undefined
+RUN: llvm-readobj -dynamic-table %t1 | FileCheck %s -check-prefix AS_NEEDED
+
+AS_NEEDED: NEEDED SharedLibrary (shared.so-x86-64)
+AS_NEEDED-NOT: NEEDED SharedLibrary (libifunc.x86-64.so)
+
+RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared.x86-64 \
+RUN: %p/Inputs/shared.so-x86-64 %p/Inputs/libifunc.x86-64.so \
+RUN: -o %t2 -e main --allow-shlib-undefined
+RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s -check-prefix NO_AS_NEEDED
+
+NO_AS_NEEDED: NEEDED SharedLibrary (shared.so-x86-64)
+NO_AS_NEEDED: NEEDED SharedLibrary (libifunc.x86-64.so)
More information about the llvm-commits
mailing list