[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
//===- ErrorHandler.cpp ---------------------------------------------------===//
|
2015-08-06 23:08:23 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2015-08-06 23:08:23 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
#include "lld/Common/ErrorHandler.h"
|
2017-10-14 02:22:55 +08:00
|
|
|
|
|
|
|
#include "lld/Common/Threads.h"
|
2015-08-06 23:08:23 +08:00
|
|
|
|
|
|
|
#include "llvm/ADT/Twine.h"
|
2018-05-23 04:20:25 +08:00
|
|
|
#include "llvm/IR/DiagnosticInfo.h"
|
|
|
|
#include "llvm/IR/DiagnosticPrinter.h"
|
2016-11-11 03:39:05 +08:00
|
|
|
#include "llvm/Support/ManagedStatic.h"
|
2015-08-06 23:08:23 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2016-11-24 02:34:28 +08:00
|
|
|
#include <mutex>
|
2015-08-06 23:08:23 +08:00
|
|
|
|
2016-10-27 21:32:32 +08:00
|
|
|
#if !defined(_MSC_VER) && !defined(__MINGW32__)
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2016-07-07 22:06:38 +08:00
|
|
|
using namespace llvm;
|
2017-03-24 08:15:37 +08:00
|
|
|
using namespace lld;
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
|
2016-11-24 02:34:28 +08:00
|
|
|
// The functions defined in this file can be called from multiple threads,
|
|
|
|
// but outs() or errs() are not thread-safe. We protect them using a mutex.
|
|
|
|
static std::mutex Mu;
|
|
|
|
|
2017-03-31 03:13:47 +08:00
|
|
|
// Prints "\n" or does nothing, depending on Msg contents of
|
|
|
|
// the previous call of this function.
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
|
2017-03-31 03:13:47 +08:00
|
|
|
// True if the previous error message contained "\n".
|
|
|
|
// We want to separate multi-line error messages with a newline.
|
|
|
|
static bool Flag;
|
|
|
|
|
|
|
|
if (Flag)
|
|
|
|
*ErrorOS << "\n";
|
2017-07-20 05:40:26 +08:00
|
|
|
Flag = StringRef(Msg.str()).contains('\n');
|
2017-03-31 03:13:47 +08:00
|
|
|
}
|
|
|
|
|
2017-10-28 02:04:49 +08:00
|
|
|
ErrorHandler &lld::errorHandler() {
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
static ErrorHandler Handler;
|
|
|
|
return Handler;
|
|
|
|
}
|
|
|
|
|
2017-10-28 02:04:49 +08:00
|
|
|
void lld::exitLld(int Val) {
|
2018-08-25 02:36:42 +08:00
|
|
|
// Delete any temporary file, while keeping the memory mapping open.
|
|
|
|
if (errorHandler().OutputBuffer)
|
|
|
|
errorHandler().OutputBuffer->discard();
|
2017-11-14 02:06:43 +08:00
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
// Dealloc/destroy ManagedStatic variables before calling
|
|
|
|
// _exit(). In a non-LTO build, this is a nop. In an LTO
|
|
|
|
// build allows us to get the output of -time-passes.
|
|
|
|
llvm_shutdown();
|
|
|
|
|
|
|
|
outs().flush();
|
|
|
|
errs().flush();
|
|
|
|
_exit(Val);
|
|
|
|
}
|
|
|
|
|
2018-05-23 04:20:25 +08:00
|
|
|
void lld::diagnosticHandler(const DiagnosticInfo &DI) {
|
|
|
|
SmallString<128> S;
|
|
|
|
raw_svector_ostream OS(S);
|
|
|
|
DiagnosticPrinterRawOStream DP(OS);
|
|
|
|
DI.print(DP);
|
2018-07-03 05:01:43 +08:00
|
|
|
switch (DI.getSeverity()) {
|
|
|
|
case DS_Error:
|
|
|
|
error(S);
|
|
|
|
break;
|
|
|
|
case DS_Warning:
|
|
|
|
warn(S);
|
|
|
|
break;
|
|
|
|
case DS_Remark:
|
|
|
|
case DS_Note:
|
|
|
|
message(S);
|
|
|
|
break;
|
|
|
|
}
|
2018-05-23 04:20:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void lld::checkError(Error E) {
|
|
|
|
handleAllErrors(std::move(E),
|
|
|
|
[&](ErrorInfoBase &EIB) { error(EIB.message()); });
|
|
|
|
}
|
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
|
|
|
|
*ErrorOS << LogName << ": ";
|
|
|
|
if (ColorDiagnostics) {
|
2016-11-26 04:27:32 +08:00
|
|
|
ErrorOS->changeColor(C, true);
|
|
|
|
*ErrorOS << S;
|
|
|
|
ErrorOS->resetColor();
|
|
|
|
} else {
|
2016-11-26 04:37:16 +08:00
|
|
|
*ErrorOS << S;
|
2016-11-26 04:27:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
void ErrorHandler::log(const Twine &Msg) {
|
|
|
|
if (Verbose) {
|
2017-02-22 07:22:56 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(Mu);
|
2017-12-12 05:57:31 +08:00
|
|
|
*ErrorOS << LogName << ": " << Msg << "\n";
|
2017-02-22 07:22:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
void ErrorHandler::message(const Twine &Msg) {
|
2017-02-22 07:22:56 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(Mu);
|
|
|
|
outs() << Msg << "\n";
|
|
|
|
outs().flush();
|
2016-02-26 02:56:01 +08:00
|
|
|
}
|
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
void ErrorHandler::warn(const Twine &Msg) {
|
|
|
|
if (FatalWarnings) {
|
2016-07-04 21:43:12 +08:00
|
|
|
error(Msg);
|
2016-11-24 02:34:28 +08:00
|
|
|
return;
|
|
|
|
}
|
2017-03-31 03:13:47 +08:00
|
|
|
|
2016-11-24 02:34:28 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(Mu);
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
newline(ErrorOS, Msg);
|
2016-11-26 04:27:32 +08:00
|
|
|
print("warning: ", raw_ostream::MAGENTA);
|
|
|
|
*ErrorOS << Msg << "\n";
|
2016-07-04 21:43:12 +08:00
|
|
|
}
|
2015-09-25 02:55:33 +08:00
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
void ErrorHandler::error(const Twine &Msg) {
|
2016-11-24 02:34:28 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(Mu);
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
newline(ErrorOS, Msg);
|
2016-11-24 02:34:28 +08:00
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
if (ErrorLimit == 0 || ErrorCount < ErrorLimit) {
|
2016-11-26 04:27:32 +08:00
|
|
|
print("error: ", raw_ostream::RED);
|
|
|
|
*ErrorOS << Msg << "\n";
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
} else if (ErrorCount == ErrorLimit) {
|
2016-11-26 04:27:32 +08:00
|
|
|
print("error: ", raw_ostream::RED);
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
*ErrorOS << ErrorLimitExceededMsg << "\n";
|
|
|
|
if (ExitEarly)
|
2016-11-24 02:15:37 +08:00
|
|
|
exitLld(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
++ErrorCount;
|
2015-08-06 23:08:23 +08:00
|
|
|
}
|
|
|
|
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
void ErrorHandler::fatal(const Twine &Msg) {
|
2017-03-31 03:13:47 +08:00
|
|
|
error(Msg);
|
2016-10-27 21:32:32 +08:00
|
|
|
exitLld(1);
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
}
|