[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
|
|
|
|
[Support] Move LLD's parallel algorithm wrappers to support
Essentially takes the lld/Common/Threads.h wrappers and moves them to
the llvm/Support/Paralle.h algorithm header.
The changes are:
- Remove policy parameter, since all clients use `par`.
- Rename the methods to `parallelSort` etc to match LLVM style, since
they are no longer C++17 pstl compatible.
- Move algorithms from llvm::parallel:: to llvm::, since they have
"parallel" in the name and are no longer overloads of the regular
algorithms.
- Add range overloads
- Use the sequential algorithm directly when 1 thread is requested
(skips task grouping)
- Fix the index type of parallelForEachN to size_t. Nobody in LLVM was
using any other parameter, and it made overload resolution hard for
for_each_n(par, 0, foo.size(), ...) because 0 is int, not size_t.
Remove Threads.h and update LLD for that.
This is a prerequisite for parallel public symbol processing in the PDB
library, which is in LLVM.
Reviewed By: MaskRay, aganea
Differential Revision: https://reviews.llvm.org/D79390
2020-05-05 11:03:19 +08:00
|
|
|
#include "llvm/Support/Parallel.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>
|
2019-07-17 22:54:02 +08:00
|
|
|
#include <regex>
|
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,
|
Make it possible to redirect not only errs() but also outs()
This change is for those who use lld as a library. Context:
https://reviews.llvm.org/D70287
This patch adds a new parmeter to lld::*::link() so that we can pass
an raw_ostream object representing stdout. Previously, lld::*::link()
took only an stderr object.
Justification for making stdoutOS and stderrOS mandatory: I wanted to
make link() functions to take stdout and stderr in that order.
However, if we change the function signature from
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stderrOS = llvm::errs());
to
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stdoutOS = llvm::outs(),
raw_ostream &stderrOS = llvm::errs());
, then the meaning of existing code that passes stderrOS silently
changes (stderrOS would be interpreted as stdoutOS). So, I chose to
make existing code not to compile, so that developers can fix their
code.
Differential Revision: https://reviews.llvm.org/D70292
2019-11-15 13:06:57 +08:00
|
|
|
// but lld::outs() or lld::errs() are not thread-safe. We protect them using a
|
|
|
|
// mutex.
|
2016-11-24 02:34:28 +08:00
|
|
|
static std::mutex mu;
|
|
|
|
|
2019-08-07 18:11:24 +08:00
|
|
|
// We want to separate multi-line messages with a newline. `sep` is "\n"
|
|
|
|
// if the last messages was multi-line. Otherwise "".
|
|
|
|
static StringRef sep;
|
|
|
|
|
|
|
|
static StringRef getSeparator(const Twine &msg) {
|
|
|
|
if (StringRef(msg.str()).contains('\n'))
|
|
|
|
return "\n";
|
|
|
|
return "";
|
2017-03-31 03:13:47 +08:00
|
|
|
}
|
|
|
|
|
Make it possible to redirect not only errs() but also outs()
This change is for those who use lld as a library. Context:
https://reviews.llvm.org/D70287
This patch adds a new parmeter to lld::*::link() so that we can pass
an raw_ostream object representing stdout. Previously, lld::*::link()
took only an stderr object.
Justification for making stdoutOS and stderrOS mandatory: I wanted to
make link() functions to take stdout and stderr in that order.
However, if we change the function signature from
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stderrOS = llvm::errs());
to
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stdoutOS = llvm::outs(),
raw_ostream &stderrOS = llvm::errs());
, then the meaning of existing code that passes stderrOS silently
changes (stderrOS would be interpreted as stdoutOS). So, I chose to
make existing code not to compile, so that developers can fix their
code.
Differential Revision: https://reviews.llvm.org/D70292
2019-11-15 13:06:57 +08:00
|
|
|
raw_ostream *lld::stdoutOS;
|
|
|
|
raw_ostream *lld::stderrOS;
|
|
|
|
|
|
|
|
raw_ostream &lld::outs() { return stdoutOS ? *stdoutOS : llvm::outs(); }
|
|
|
|
raw_ostream &lld::errs() { return stderrOS ? *stderrOS : llvm::errs(); }
|
|
|
|
|
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
|
|
|
|
2019-03-17 03:36:29 +08:00
|
|
|
// Dealloc/destroy ManagedStatic variables before calling _exit().
|
|
|
|
// In an LTO build, allows us to get the output of -time-passes.
|
|
|
|
// Ensures that the thread pool for the parallel algorithms is stopped to
|
|
|
|
// avoid intermittent crashes on Windows when exiting.
|
[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
|
|
|
llvm_shutdown();
|
|
|
|
|
2020-01-23 01:08:09 +08:00
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(mu);
|
|
|
|
lld::outs().flush();
|
|
|
|
lld::errs().flush();
|
|
|
|
}
|
[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
|
|
|
_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()); });
|
|
|
|
}
|
|
|
|
|
2019-08-02 13:04:27 +08:00
|
|
|
// This is for --vs-diagnostics.
|
|
|
|
//
|
|
|
|
// Normally, lld's error message starts with argv[0]. Therefore, it usually
|
|
|
|
// looks like this:
|
|
|
|
//
|
|
|
|
// ld.lld: error: ...
|
|
|
|
//
|
|
|
|
// This error message style is unfortunately unfriendly to Visual Studio
|
|
|
|
// IDE. VS interprets the first word of the first line as an error location
|
|
|
|
// and make it clickable, thus "ld.lld" in the above message would become a
|
|
|
|
// clickable text. When you click it, VS opens "ld.lld" executable file with
|
|
|
|
// a binary editor.
|
|
|
|
//
|
|
|
|
// As a workaround, we print out an error location instead of "ld.lld" if
|
|
|
|
// lld is running in VS diagnostics mode. As a result, error message will
|
|
|
|
// look like this:
|
|
|
|
//
|
|
|
|
// src/foo.c(35): error: ...
|
|
|
|
//
|
|
|
|
// This function returns an error location string. An error location is
|
|
|
|
// extracted from an error message using regexps.
|
2019-08-07 16:08:17 +08:00
|
|
|
std::string ErrorHandler::getLocation(const Twine &msg) {
|
|
|
|
if (!vsDiagnostics)
|
2020-01-29 03:23:46 +08:00
|
|
|
return std::string(logName);
|
2019-08-07 16:08:17 +08:00
|
|
|
|
|
|
|
static std::regex regexes[] = {
|
|
|
|
std::regex(
|
2019-08-09 16:29:03 +08:00
|
|
|
R"(^undefined (?:\S+ )?symbol:.*\n)"
|
|
|
|
R"(>>> referenced by .+\((\S+):(\d+)\))"),
|
|
|
|
std::regex(
|
|
|
|
R"(^undefined (?:\S+ )?symbol:.*\n>>> referenced by (\S+):(\d+))"),
|
2019-07-17 22:54:02 +08:00
|
|
|
std::regex(R"(^undefined symbol:.*\n>>> referenced by (.*):)"),
|
|
|
|
std::regex(
|
|
|
|
R"(^duplicate symbol: .*\n>>> defined in (\S+)\n>>> defined in.*)"),
|
2019-08-09 16:29:03 +08:00
|
|
|
std::regex(
|
|
|
|
R"(^duplicate symbol: .*\n>>> defined at .+\((\S+):(\d+)\))"),
|
|
|
|
std::regex(R"(^duplicate symbol: .*\n>>> defined at (\S+):(\d+))"),
|
|
|
|
std::regex(
|
|
|
|
R"(.*\n>>> defined in .*\n>>> referenced by .+\((\S+):(\d+)\))"),
|
2019-08-07 16:08:17 +08:00
|
|
|
std::regex(R"(.*\n>>> defined in .*\n>>> referenced by (\S+):(\d+))"),
|
2019-07-17 22:54:02 +08:00
|
|
|
std::regex(R"((\S+):(\d+): unclosed quote)"),
|
|
|
|
};
|
|
|
|
|
2019-08-07 16:08:17 +08:00
|
|
|
std::string str = msg.str();
|
|
|
|
for (std::regex &re : regexes) {
|
|
|
|
std::smatch m;
|
|
|
|
if (!std::regex_search(str, m, re))
|
|
|
|
continue;
|
2019-07-17 22:54:02 +08:00
|
|
|
|
2019-08-07 16:08:17 +08:00
|
|
|
assert(m.size() == 2 || m.size() == 3);
|
|
|
|
if (m.size() == 2)
|
|
|
|
return m.str(1);
|
|
|
|
return m.str(1) + "(" + m.str(2) + ")";
|
2019-07-17 22:54:02 +08:00
|
|
|
}
|
|
|
|
|
2020-01-29 03:23:46 +08:00
|
|
|
return std::string(logName);
|
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) {
|
2019-08-07 16:08:17 +08:00
|
|
|
if (!verbose)
|
|
|
|
return;
|
|
|
|
std::lock_guard<std::mutex> lock(mu);
|
Make it possible to redirect not only errs() but also outs()
This change is for those who use lld as a library. Context:
https://reviews.llvm.org/D70287
This patch adds a new parmeter to lld::*::link() so that we can pass
an raw_ostream object representing stdout. Previously, lld::*::link()
took only an stderr object.
Justification for making stdoutOS and stderrOS mandatory: I wanted to
make link() functions to take stdout and stderr in that order.
However, if we change the function signature from
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stderrOS = llvm::errs());
to
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stdoutOS = llvm::outs(),
raw_ostream &stderrOS = llvm::errs());
, then the meaning of existing code that passes stderrOS silently
changes (stderrOS would be interpreted as stdoutOS). So, I chose to
make existing code not to compile, so that developers can fix their
code.
Differential Revision: https://reviews.llvm.org/D70292
2019-11-15 13:06:57 +08:00
|
|
|
lld::errs() << 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);
|
Make it possible to redirect not only errs() but also outs()
This change is for those who use lld as a library. Context:
https://reviews.llvm.org/D70287
This patch adds a new parmeter to lld::*::link() so that we can pass
an raw_ostream object representing stdout. Previously, lld::*::link()
took only an stderr object.
Justification for making stdoutOS and stderrOS mandatory: I wanted to
make link() functions to take stdout and stderr in that order.
However, if we change the function signature from
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stderrOS = llvm::errs());
to
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stdoutOS = llvm::outs(),
raw_ostream &stderrOS = llvm::errs());
, then the meaning of existing code that passes stderrOS silently
changes (stderrOS would be interpreted as stdoutOS). So, I chose to
make existing code not to compile, so that developers can fix their
code.
Differential Revision: https://reviews.llvm.org/D70292
2019-11-15 13:06:57 +08:00
|
|
|
lld::outs() << msg << "\n";
|
|
|
|
lld::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);
|
Make it possible to redirect not only errs() but also outs()
This change is for those who use lld as a library. Context:
https://reviews.llvm.org/D70287
This patch adds a new parmeter to lld::*::link() so that we can pass
an raw_ostream object representing stdout. Previously, lld::*::link()
took only an stderr object.
Justification for making stdoutOS and stderrOS mandatory: I wanted to
make link() functions to take stdout and stderr in that order.
However, if we change the function signature from
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stderrOS = llvm::errs());
to
bool link(ArrayRef<const char *> args, bool canExitEarly,
raw_ostream &stdoutOS = llvm::outs(),
raw_ostream &stderrOS = llvm::errs());
, then the meaning of existing code that passes stderrOS silently
changes (stderrOS would be interpreted as stdoutOS). So, I chose to
make existing code not to compile, so that developers can fix their
code.
Differential Revision: https://reviews.llvm.org/D70292
2019-11-15 13:06:57 +08:00
|
|
|
lld::errs() << sep << getLocation(msg) << ": " << Colors::MAGENTA
|
|
|
|
<< "warning: " << Colors::RESET << msg << "\n";
|
2019-08-07 18:11:24 +08:00
|
|
|
sep = getSeparator(msg);
|
2019-08-01 17:58:03 +08:00
|
|
|
}
|
|
|
|
|
2019-08-07 16:08:17 +08:00
|
|
|
void ErrorHandler::error(const Twine &msg) {
|
|
|
|
// If Visual Studio-style error message mode is enabled,
|
|
|
|
// this particular error is printed out as two errors.
|
2019-08-01 17:58:03 +08:00
|
|
|
if (vsDiagnostics) {
|
2019-08-07 16:08:17 +08:00
|
|
|
static std::regex re(R"(^(duplicate symbol: .*))"
|
2019-08-07 19:32:43 +08:00
|
|
|
R"((\n>>> defined at \S+:\d+.*\n>>>.*))"
|
|
|
|
R"((\n>>> defined at \S+:\d+.*\n>>>.*))");
|
2019-08-07 16:08:17 +08:00
|
|
|
std::string str = msg.str();
|
|
|
|
std::smatch m;
|
|
|
|
|
|
|
|
if (std::regex_match(str, m, re)) {
|
|
|
|
error(m.str(1) + m.str(2));
|
|
|
|
error(m.str(1) + m.str(3));
|
2019-08-01 17:58:03 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-23 01:08:09 +08:00
|
|
|
bool exit = false;
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(mu);
|
|
|
|
|
|
|
|
if (errorLimit == 0 || errorCount < errorLimit) {
|
|
|
|
lld::errs() << sep << getLocation(msg) << ": " << Colors::RED
|
|
|
|
<< "error: " << Colors::RESET << msg << "\n";
|
|
|
|
} else if (errorCount == errorLimit) {
|
|
|
|
lld::errs() << sep << getLocation(msg) << ": " << Colors::RED
|
|
|
|
<< "error: " << Colors::RESET << errorLimitExceededMsg
|
|
|
|
<< "\n";
|
|
|
|
exit = exitEarly;
|
|
|
|
}
|
2016-11-24 02:34:28 +08:00
|
|
|
|
2020-01-23 01:08:09 +08:00
|
|
|
sep = getSeparator(msg);
|
|
|
|
++errorCount;
|
2016-11-24 02:15:37 +08:00
|
|
|
}
|
|
|
|
|
2020-01-23 01:08:09 +08:00
|
|
|
if (exit)
|
|
|
|
exitLld(1);
|
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
|
|
|
}
|