Index: lld/Common/ErrorHandler.cpp =================================================================== --- lld/Common/ErrorHandler.cpp +++ lld/Common/ErrorHandler.cpp @@ -14,6 +14,7 @@ #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -216,6 +217,26 @@ exitLld(1); } +void ErrorHandler::error(const Twine &msg, ErrorTag tag, + ArrayRef args) { + error(msg); + if (errorHandlingScript.empty()) + return; + SmallVector scriptArgs(2 + args.size()); + scriptArgs[0] = errorHandlingScript; + switch (tag) { + case ErrorTag::LibNotFound: + scriptArgs[1] = "missing-lib"; + break; + default: + llvm_unreachable("unsupported ErrorTag"); + } + std::copy(args.begin(), args.end(), scriptArgs.begin() + 2); + int Res = llvm::sys::ExecuteAndWait(errorHandlingScript, scriptArgs); + if (Res < 0) + error("failed to call error handling script: " + errorHandlingScript); +} + void ErrorHandler::fatal(const Twine &msg) { error(msg); exitLld(1); Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -277,8 +277,10 @@ void LinkerDriver::addLibrary(StringRef name) { if (Optional path = searchLibrary(name)) addFile(*path, /*withLOption=*/true); - else - error("unable to find library -l" + name); + else { + error("unable to find library -l" + name, ErrorTag::LibNotFound, + {"missing-lib", name}); + } } // This function is called on startup. We need this for LTO since @@ -936,6 +938,10 @@ config->enableNewDtags = args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true); config->entry = args.getLastArgValue(OPT_entry); + + errorHandler().errorHandlingScript = + args.getLastArgValue(OPT_error_handling_script); + config->executeOnly = args.hasFlag(OPT_execute_only, OPT_no_execute_only, false); config->exportDynamic = Index: lld/ELF/Options.td =================================================================== --- lld/ELF/Options.td +++ lld/ELF/Options.td @@ -179,6 +179,9 @@ def error_unresolved_symbols: F<"error-unresolved-symbols">, HelpText<"Report unresolved symbols as errors">; +defm error_handling_script: EEq<"error-handling-script", + "Specify an error handling script">; + defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">; defm execute_only: BB<"execute-only", Index: lld/include/lld/Common/ErrorHandler.h =================================================================== --- lld/include/lld/Common/ErrorHandler.h +++ lld/include/lld/Common/ErrorHandler.h @@ -89,11 +89,14 @@ llvm::raw_ostream &outs(); llvm::raw_ostream &errs(); +enum class ErrorTag { LibNotFound }; + class ErrorHandler { public: uint64_t errorCount = 0; uint64_t errorLimit = 20; StringRef errorLimitExceededMsg = "too many errors emitted, stopping now"; + StringRef errorHandlingScript = ""; StringRef logName = "lld"; bool exitEarly = true; bool fatalWarnings = false; @@ -101,6 +104,7 @@ bool vsDiagnostics = false; void error(const Twine &msg); + void error(const Twine &msg, ErrorTag tag, ArrayRef args); LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg); void log(const Twine &msg); void message(const Twine &msg); @@ -118,6 +122,9 @@ ErrorHandler &errorHandler(); inline void error(const Twine &msg) { errorHandler().error(msg); } +inline void error(const Twine &msg, ErrorTag tag, ArrayRef args) { + errorHandler().error(msg, tag, args); +} inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg) { errorHandler().fatal(msg); }