[lld] r189871 - [lld] handle the case of errors from createLinkerInput

Shankar Easwaran shankare at codeaurora.org
Tue Sep 3 15:44:37 PDT 2013


Author: shankare
Date: Tue Sep  3 17:44:37 2013
New Revision: 189871

URL: http://llvm.org/viewvc/llvm-project?rev=189871&view=rev
Log:
[lld] handle the case of errors from createLinkerInput

This changes the interface of createLinkerInput to use ErrorOr, so that
errors from the linker can be captured.

Also adds a convenience function for error strings to be returned from
file nodes.

Added:
    lld/trunk/test/elf/librarynotfound.test
Modified:
    lld/trunk/include/lld/Driver/CoreInputGraph.h
    lld/trunk/include/lld/Driver/DarwinInputGraph.h
    lld/trunk/include/lld/Driver/GnuLDInputGraph.h
    lld/trunk/include/lld/Driver/InputGraph.h
    lld/trunk/include/lld/Driver/WinLinkInputGraph.h
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/lib/Driver/CoreDriver.cpp
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/Driver/Driver.cpp
    lld/trunk/lib/Driver/GnuLdDriver.cpp
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
    lld/trunk/unittests/DriverTests/DriverTest.h

Modified: lld/trunk/include/lld/Driver/CoreInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/CoreInputGraph.h?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/CoreInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/CoreInputGraph.h Tue Sep  3 17:44:37 2013
@@ -34,7 +34,7 @@ public:
     return a->kind() == InputElement::Kind::File;
   }
 
-  virtual std::unique_ptr<lld::LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const lld::LinkingContext &);
 
   /// \brief validates the Input Element

Modified: lld/trunk/include/lld/Driver/DarwinInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/DarwinInputGraph.h?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/DarwinInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/DarwinInputGraph.h Tue Sep  3 17:44:37 2013
@@ -35,7 +35,7 @@ public:
     return a->kind() == InputElement::Kind::File;
   }
 
-  virtual std::unique_ptr<lld::LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const lld::LinkingContext &);
 
   /// \brief validates the Input Element

Modified: lld/trunk/include/lld/Driver/GnuLDInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/GnuLDInputGraph.h?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/GnuLDInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/GnuLDInputGraph.h Tue Sep  3 17:44:37 2013
@@ -26,10 +26,11 @@ namespace lld {
 class ELFFileNode : public FileNode {
 public:
   ELFFileNode(ELFLinkingContext &ctx, StringRef path,
-              std::vector<StringRef> searchPath,
-              bool isWholeArchive = false, bool asNeeded = false)
+              std::vector<StringRef> searchPath, bool isWholeArchive = false,
+              bool asNeeded = false, bool dashlPrefix = false)
       : FileNode(path), _elfLinkingContext(ctx),
-        _isWholeArchive(isWholeArchive), _asNeeded(asNeeded) {
+        _isWholeArchive(isWholeArchive), _asNeeded(asNeeded),
+        _isDashlPrefix(dashlPrefix) {
     std::copy(searchPath.begin(), searchPath.end(),
               std::back_inserter(_libraryPaths));
   }
@@ -38,17 +39,20 @@ public:
     return a->kind() == InputElement::Kind::File;
   }
 
-  virtual StringRef path(const LinkingContext &ctx) const;
+  virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const;
 
-  virtual std::unique_ptr<lld::LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const lld::LinkingContext &);
 
   /// \brief validates the Input Element
   virtual bool validate() { return true; }
 
+  /// \brief create an error string for printing purposes
+  virtual std::string errStr(llvm::error_code);
+
   /// \brief Dump the Input Element
   virtual bool dump(raw_ostream &diagnostics) {
-    diagnostics << "Name    : " << path(_elfLinkingContext) << "\n";
+    diagnostics << "Name    : " << *path(_elfLinkingContext) << "\n";
     diagnostics << "Type    : "
                 << "ELF File"
                 << "\n";
@@ -67,9 +71,11 @@ public:
   }
 
 private:
+  llvm::BumpPtrAllocator _alloc;
   ELFLinkingContext &_elfLinkingContext;
-  bool _isWholeArchive : 1;
-  bool _asNeeded : 1;
+  bool _isWholeArchive;
+  bool _asNeeded;
+  bool _isDashlPrefix;
   std::vector<StringRef> _libraryPaths;
 };
 
@@ -82,10 +88,10 @@ public:
     return a->kind() == InputElement::Kind::Control;
   }
 
-  virtual std::unique_ptr<lld::LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const lld::LinkingContext &) {
     // FIXME : create a linker input to handle groups
-    return nullptr;
+    return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
   }
 
   /// \brief Validate the options

Modified: lld/trunk/include/lld/Driver/InputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/InputGraph.h?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/InputGraph.h (original)
+++ lld/trunk/include/lld/Driver/InputGraph.h Tue Sep  3 17:44:37 2013
@@ -198,7 +198,7 @@ public:
   InputGraph::InputElementIterT end() { return _elements.end(); }
 
   /// \brief Create a lld::File node from the FileNode
-  virtual std::unique_ptr<LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const LinkingContext &targetInfo) = 0;
 
 private:
@@ -214,7 +214,9 @@ public:
   FileNode(StringRef path, int64_t ordinal = -1)
       : InputElement(InputElement::Kind::File, ordinal), _path(path) {}
 
-  virtual StringRef path(const LinkingContext &) const { return _path; }
+  virtual llvm::ErrorOr<StringRef> path(const LinkingContext &) const {
+    return _path;
+  }
 
   virtual ~FileNode() {}
 
@@ -223,8 +225,13 @@ public:
     return a->kind() == InputElement::Kind::File;
   }
 
+  /// \brief create an error string for printing purposes
+  virtual std::string errStr(llvm::error_code) {
+    llvm_unreachable("not handling errors");
+  }
+
   /// \brief Create a lld::File node from the FileNode
-  virtual std::unique_ptr<LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const LinkingContext &targetInfo) = 0;
 
 protected:
@@ -248,7 +255,7 @@ public:
     return true;
   }
 
-  virtual std::unique_ptr<lld::LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const lld::LinkingContext &) = 0;
 };
 

Modified: lld/trunk/include/lld/Driver/WinLinkInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/WinLinkInputGraph.h?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/WinLinkInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/WinLinkInputGraph.h Tue Sep  3 17:44:37 2013
@@ -35,9 +35,9 @@ public:
     return a->kind() == InputElement::Kind::File;
   }
 
-  virtual StringRef path(const LinkingContext &ctx) const;
+  virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const;
 
-  virtual std::unique_ptr<lld::LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const lld::LinkingContext &);
 
   /// \brief validates the Input Element
@@ -60,9 +60,9 @@ public:
     return a->kind() == InputElement::Kind::File;
   }
 
-  virtual StringRef path(const LinkingContext &ctx) const;
+  virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const;
 
-  virtual std::unique_ptr<lld::LinkerInput>
+  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
   createLinkerInput(const lld::LinkingContext &);
 
   /// \brief validates the Input Element

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Tue Sep  3 17:44:37 2013
@@ -153,8 +153,9 @@ public:
   virtual void setNoAllowDynamicLibraries() { _noAllowDynamicLibraries = true; }
 
   /// Searches directories for a match on the input File
-  StringRef searchLibrary(StringRef libName,
-                          const std::vector<StringRef> &searchPath) const;
+  llvm::ErrorOr<std::string>
+  searchLibrary(StringRef libName,
+                const std::vector<StringRef> &searchPath) const;
 
   /// Get the entry symbol name
   virtual StringRef entrySymbolName() const;

Modified: lld/trunk/lib/Driver/CoreDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/CoreDriver.cpp?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/lib/Driver/CoreDriver.cpp (original)
+++ lld/trunk/lib/Driver/CoreDriver.cpp Tue Sep  3 17:44:37 2013
@@ -67,9 +67,9 @@ public:
 
 namespace lld {
 
-std::unique_ptr<lld::LinkerInput>
+llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
 COREFileNode::createLinkerInput(const LinkingContext &info) {
-  return std::unique_ptr<LinkerInput>(new LinkerInput(path(info)));
+  return std::unique_ptr<LinkerInput>(new LinkerInput(*path(info)));
 }
 
 bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Tue Sep  3 17:44:37 2013
@@ -71,9 +71,9 @@ public:
 
 namespace lld {
 
-std::unique_ptr<lld::LinkerInput>
+llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
 MachOFileNode::createLinkerInput(const LinkingContext &ctx) {
-  return std::unique_ptr<LinkerInput>(new LinkerInput(path(ctx)));
+  return std::unique_ptr<LinkerInput>(new LinkerInput(*path(ctx)));
 }
 
 bool DarwinLdDriver::linkMachO(int argc, const char *argv[],

Modified: lld/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/Driver.cpp?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/lib/Driver/Driver.cpp (original)
+++ lld/trunk/lib/Driver/Driver.cpp Tue Sep  3 17:44:37 2013
@@ -55,7 +55,12 @@ bool Driver::link(const LinkingContext &
   for (auto &ie : inputGraph.inputElements()) {
     if (ie->kind() == InputElement::Kind::File) {
       FileNode *fileNode = (llvm::dyn_cast<FileNode>)(ie.get());
-      linkerInputs.push_back(std::move(fileNode->createLinkerInput(context)));
+      auto linkerInput = fileNode->createLinkerInput(context);
+      if (!linkerInput) {
+        llvm::outs() << fileNode->errStr(error_code(linkerInput)) << "\n";
+        return true;
+      }
+      linkerInputs.push_back(std::move(*fileNode->createLinkerInput(context)));
     }
   }
   for (const auto &input : linkerInputs) {

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Tue Sep  3 17:44:37 2013
@@ -71,18 +71,38 @@ public:
 
 } // namespace
 
-std::unique_ptr<lld::LinkerInput>
+llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
 ELFFileNode::createLinkerInput(const LinkingContext &ctx) {
-  std::unique_ptr<LinkerInput> inputFile(new LinkerInput(path(ctx)));
+  auto filePath = path(ctx);
+  if (!filePath &&
+      error_code(filePath) == llvm::errc::no_such_file_or_directory)
+    return make_error_code(llvm::errc::no_such_file_or_directory);
+  std::unique_ptr<LinkerInput> inputFile(new LinkerInput(*filePath));
   inputFile->setAsNeeded(_asNeeded);
   inputFile->setForceLoad(_isWholeArchive);
   return std::move(inputFile);
 }
 
-StringRef ELFFileNode::path(const LinkingContext &) const {
+llvm::ErrorOr<StringRef> ELFFileNode::path(const LinkingContext &) const {
+  if (!_isDashlPrefix)
+    return _path;
   return _elfLinkingContext.searchLibrary(_path, _libraryPaths);
 }
 
+std::string ELFFileNode::errStr(llvm::error_code errc) {
+  std::string errorMsg;
+  if (errc == llvm::errc::no_such_file_or_directory) {
+    if (_isDashlPrefix)
+      errorMsg = (Twine("Unable to find library -l") + _path).str();
+    else
+      errorMsg = (Twine("Unable to find file ") + _path).str();
+  }
+  else {
+    return "Unknown Error";
+  }
+  return std::move(errorMsg);
+}
+
 bool GnuLdDriver::linkELF(int argc, const char *argv[],
                           raw_ostream &diagnostics) {
   std::unique_ptr<ELFLinkingContext> options;
@@ -278,9 +298,9 @@ bool GnuLdDriver::parse(int argc, const
     case OPT_INPUT:
     case OPT_l: {
       std::unique_ptr<InputElement> inputFile =
-          std::move(std::unique_ptr<InputElement>(
-              new ELFFileNode(*ctx, inputArg->getValue(), searchPath,
-                              isWholeArchive, asNeeded)));
+          std::move(std::unique_ptr<InputElement>(new ELFFileNode(
+              *ctx, inputArg->getValue(), searchPath, isWholeArchive, asNeeded,
+              inputArg->getOption().getID() == OPT_l)));
       if (controlNodeStack.empty())
         inputGraph->addInputElement(std::move(inputFile));
       else

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Tue Sep  3 17:44:37 2013
@@ -210,17 +210,17 @@ std::unique_ptr<llvm::opt::InputArgList>
 
 } // namespace
 
-std::unique_ptr<lld::LinkerInput>
+llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
 PECOFFFileNode::createLinkerInput(const LinkingContext &ctx) {
-  return std::unique_ptr<LinkerInput>(new LinkerInput(path(ctx)));
+  return std::unique_ptr<LinkerInput>(new LinkerInput(*path(ctx)));
 }
 
-std::unique_ptr<lld::LinkerInput>
+llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
 PECOFFLibraryNode::createLinkerInput(const LinkingContext &ctx) {
-  return std::unique_ptr<LinkerInput>(new LinkerInput(path(ctx)));
+  return std::unique_ptr<LinkerInput>(new LinkerInput(*path(ctx)));
 }
 
-StringRef PECOFFFileNode::path(const LinkingContext &) const {
+llvm::ErrorOr<StringRef> PECOFFFileNode::path(const LinkingContext &) const {
   if (_path.endswith(".lib"))
     return _ctx.searchLibraryFile(_path);
   if (llvm::sys::path::extension(_path).empty())
@@ -228,7 +228,7 @@ StringRef PECOFFFileNode::path(const Lin
   return _path;
 }
 
-StringRef PECOFFLibraryNode::path(const LinkingContext &) const {
+llvm::ErrorOr<StringRef> PECOFFLibraryNode::path(const LinkingContext &) const {
   if (!_path.endswith(".lib"))
     return _ctx.searchLibraryFile(_ctx.allocateString(_path.str() + ".lib"));
   return _ctx.searchLibraryFile(_path);
@@ -484,7 +484,7 @@ bool WinLinkDriver::parse(int argc, cons
   // with ".exe".
   if (ctx.outputPath().empty()) {
     SmallString<128> firstInputFilePath =
-        (llvm::dyn_cast<FileNode>(&((inputGraph)[0])))->path(ctx);
+        *(llvm::dyn_cast<FileNode>(&((inputGraph)[0])))->path(ctx);
     (llvm::sys::path::replace_extension(firstInputFilePath, ".exe"));
     ctx.setOutputPath(ctx.allocateString(firstInputFilePath.str()));
   }

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Tue Sep  3 17:44:37 2013
@@ -140,7 +140,7 @@ ELFLinkingContext::create(llvm::Triple t
   }
 }
 
-StringRef ELFLinkingContext::searchLibrary(
+llvm::ErrorOr<std::string> ELFLinkingContext::searchLibrary(
     StringRef libName, const std::vector<StringRef> &searchPath) const {
   bool foundFile = false;
   StringRef pathref;
@@ -178,7 +178,10 @@ StringRef ELFLinkingContext::searchLibra
     if (foundFile)
       return (*(new (_alloc) std::string(pathref.str())));
   }
-  return libName;
+  if (!llvm::sys::fs::exists(libName))
+    return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
+
+  return std::string(libName);
 }
 
 std::unique_ptr<File> ELFLinkingContext::createUndefinedSymbolFile() {

Added: lld/trunk/test/elf/librarynotfound.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/librarynotfound.test?rev=189871&view=auto
==============================================================================
--- lld/trunk/test/elf/librarynotfound.test (added)
+++ lld/trunk/test/elf/librarynotfound.test Tue Sep  3 17:44:37 2013
@@ -0,0 +1,4 @@
+# Tests the functionality of library not found
+RUN: not lld -flavor gnu -lfn | FileCheck %s
+
+CHECK: Unable to find library -lfn

Modified: lld/trunk/unittests/DriverTests/DriverTest.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/DriverTest.h?rev=189871&r1=189870&r2=189871&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/DriverTest.h (original)
+++ lld/trunk/unittests/DriverTests/DriverTest.h Tue Sep  3 17:44:37 2013
@@ -36,7 +36,8 @@ protected:
   std::string inputFile(unsigned index) {
     const InputElement &inputElement = linkingContext()->inputGraph()[index];
     if (inputElement.kind() == InputElement::Kind::File)
-      return (llvm::dyn_cast<FileNode>(&inputElement))->path(*linkingContext());
+      return *(llvm::dyn_cast<FileNode>(&inputElement))
+                  ->path(*linkingContext());
     llvm_unreachable("not handling other types of input files");
   }
 





More information about the llvm-commits mailing list