[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