[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