2015-08-06 23:08:23 +08:00
|
|
|
//===- Error.cpp ----------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "Error.h"
|
2016-02-26 02:56:01 +08:00
|
|
|
#include "Config.h"
|
2015-08-06 23:08:23 +08:00
|
|
|
|
|
|
|
#include "llvm/ADT/Twine.h"
|
2016-07-14 10:35:18 +08:00
|
|
|
#include "llvm/Support/Error.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-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;
|
|
|
|
|
2015-08-06 23:08:23 +08:00
|
|
|
namespace lld {
|
|
|
|
|
2016-07-19 02:24:41 +08:00
|
|
|
bool elf::HasError;
|
2016-11-24 02:15:37 +08:00
|
|
|
uint64_t elf::ErrorCount;
|
2016-07-19 02:24:41 +08:00
|
|
|
raw_ostream *elf::ErrorOS;
|
2016-10-20 04:05:43 +08:00
|
|
|
StringRef elf::Argv0;
|
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-07-19 02:24:41 +08:00
|
|
|
void elf::log(const Twine &Msg) {
|
2016-02-26 02:56:01 +08:00
|
|
|
if (Config->Verbose)
|
2016-10-20 04:05:43 +08:00
|
|
|
outs() << Argv0 << ": " << Msg << "\n";
|
2016-02-26 02:56:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-30 05:00:23 +08:00
|
|
|
void elf::warn(const Twine &Msg) {
|
2016-07-04 21:43:12 +08:00
|
|
|
if (Config->FatalWarnings)
|
|
|
|
error(Msg);
|
|
|
|
else
|
2016-10-20 04:05:43 +08:00
|
|
|
*ErrorOS << Argv0 << ": warning: " << Msg << "\n";
|
2016-07-04 21:43:12 +08:00
|
|
|
}
|
2015-09-25 02:55:33 +08:00
|
|
|
|
2016-07-19 02:24:41 +08:00
|
|
|
void elf::error(const Twine &Msg) {
|
2016-11-24 02:15:37 +08:00
|
|
|
if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
|
|
|
|
*ErrorOS << Argv0 << ": error: " << Msg << "\n";
|
|
|
|
} else if (ErrorCount == Config->ErrorLimit) {
|
|
|
|
*ErrorOS << Argv0 << ": error: too many errors emitted, stopping now\n";
|
|
|
|
if (Config->ExitEarly)
|
|
|
|
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
|
|
|
HasError = true;
|
2016-11-24 02:15:37 +08:00
|
|
|
++ErrorCount;
|
2015-08-06 23:08:23 +08:00
|
|
|
}
|
|
|
|
|
2016-07-19 02:24:41 +08:00
|
|
|
void elf::error(std::error_code EC, const Twine &Prefix) {
|
2016-07-15 09:38:54 +08:00
|
|
|
error(Prefix + ": " + EC.message());
|
2015-08-06 23:08:23 +08:00
|
|
|
}
|
|
|
|
|
2016-10-27 21:32:32 +08:00
|
|
|
void elf::exitLld(int Val) {
|
2016-11-11 03:39:05 +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();
|
|
|
|
|
2016-11-11 10:16:15 +08:00
|
|
|
outs().flush();
|
|
|
|
errs().flush();
|
2016-10-27 21:32:32 +08:00
|
|
|
_exit(Val);
|
|
|
|
}
|
|
|
|
|
2016-07-19 02:24:41 +08:00
|
|
|
void elf::fatal(const Twine &Msg) {
|
2016-10-20 04:05:43 +08:00
|
|
|
*ErrorOS << Argv0 << ": error: " << Msg << "\n";
|
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
|
|
|
}
|
|
|
|
|
2016-10-07 16:51:57 +08:00
|
|
|
void elf::fatal(std::error_code EC, const Twine &Prefix) {
|
|
|
|
fatal(Prefix + ": " + EC.message());
|
|
|
|
}
|
|
|
|
|
2015-08-06 23:08:23 +08:00
|
|
|
} // namespace lld
|