aboutsummaryrefslogtreecommitdiff
path: root/bolt
diff options
context:
space:
mode:
authorAmir Ayupov <aaupov@fb.com>2024-02-12 14:39:59 -0800
committerGitHub <noreply@github.com>2024-02-12 14:39:59 -0800
commitfa7dd4919aa705f18f268fab5b2887d45f89d8dd (patch)
treebba047f6260626f329cc9e094607e8cef66e829c /bolt
parenta5f3d1a803020167bd9d494a8a3921e7dcc1550a (diff)
downloadllvm-fa7dd4919aa705f18f268fab5b2887d45f89d8dd.zip
llvm-fa7dd4919aa705f18f268fab5b2887d45f89d8dd.tar.gz
llvm-fa7dd4919aa705f18f268fab5b2887d45f89d8dd.tar.bz2
[BOLT][NFC] Add BOLTError and return it from passes (1/2) (#81522)
As part of the effort to refactor old error handling code that would directly call exit(1), in this patch we add a new class BOLTError and auxiliary functions `createFatalBOLTError()` and `createNonFatalBOLTError()` that allow BOLT code to bubble up the problem to the caller by using the Error class as a return type (or Expected). Also changes passes to use these. Co-authored-by: Rafael Auler <rafaelauler@fb.com> Test Plan: NFC
Diffstat (limited to 'bolt')
-rw-r--r--bolt/include/bolt/Core/BinaryContext.h23
-rw-r--r--bolt/lib/Core/BinaryContext.cpp31
-rw-r--r--bolt/lib/Passes/ADRRelaxationPass.cpp2
-rw-r--r--bolt/lib/Passes/BinaryPasses.cpp6
-rw-r--r--bolt/lib/Passes/Instrumentation.cpp14
-rw-r--r--bolt/lib/Passes/PatchEntries.cpp2
-rw-r--r--bolt/lib/Passes/ReorderFunctions.cpp4
-rw-r--r--bolt/lib/Passes/VeneerElimination.cpp4
8 files changed, 71 insertions, 15 deletions
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index f1db1fb..5dc5fdb 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -145,6 +145,29 @@ public:
}
};
+/// BOLT-exclusive errors generated in core BOLT libraries, optionally holding a
+/// string message and whether it is fatal or not. In case it is fatal and if
+/// BOLT is running as a standalone process, the process might be killed as soon
+/// as the error is checked.
+class BOLTError : public ErrorInfo<BOLTError> {
+public:
+ static char ID;
+
+ BOLTError(bool IsFatal, const Twine &S = Twine());
+ void log(raw_ostream &OS) const override;
+ bool isFatal() const { return IsFatal; }
+
+ const std::string &getMessage() const { return Msg; }
+ std::error_code convertToErrorCode() const override;
+
+private:
+ bool IsFatal;
+ std::string Msg;
+};
+
+Error createNonFatalBOLTError(const Twine &S);
+Error createFatalBOLTError(const Twine &S);
+
class BinaryContext {
BinaryContext() = delete;
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index df835d2..1c33544 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -83,6 +83,37 @@ cl::opt<std::string> CompDirOverride(
namespace llvm {
namespace bolt {
+char BOLTError::ID = 0;
+
+BOLTError::BOLTError(bool IsFatal, const Twine &S)
+ : IsFatal(IsFatal), Msg(S.str()) {}
+
+void BOLTError::log(raw_ostream &OS) const {
+ if (IsFatal)
+ OS << "FATAL ";
+ StringRef ErrMsg = StringRef(Msg);
+ // Prepend our error prefix if it is missing
+ if (ErrMsg.empty()) {
+ OS << "BOLT-ERROR\n";
+ } else {
+ if (!ErrMsg.starts_with("BOLT-ERROR"))
+ OS << "BOLT-ERROR: ";
+ OS << ErrMsg << "\n";
+ }
+}
+
+std::error_code BOLTError::convertToErrorCode() const {
+ return inconvertibleErrorCode();
+}
+
+Error createNonFatalBOLTError(const Twine &S) {
+ return make_error<BOLTError>(/*IsFatal*/ false, S);
+}
+
+Error createFatalBOLTError(const Twine &S) {
+ return make_error<BOLTError>(/*IsFatal*/ true, S);
+}
+
BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
std::unique_ptr<DWARFContext> DwCtx,
std::unique_ptr<Triple> TheTriple,
diff --git a/bolt/lib/Passes/ADRRelaxationPass.cpp b/bolt/lib/Passes/ADRRelaxationPass.cpp
index 681b5ab..aa715a3 100644
--- a/bolt/lib/Passes/ADRRelaxationPass.cpp
+++ b/bolt/lib/Passes/ADRRelaxationPass.cpp
@@ -110,7 +110,7 @@ Error ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
"ADRRelaxationPass");
if (PassFailed)
- exit(1);
+ return createFatalBOLTError("");
return Error::success();
}
diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp
index e90f01a..281488b 100644
--- a/bolt/lib/Passes/BinaryPasses.cpp
+++ b/bolt/lib/Passes/BinaryPasses.cpp
@@ -528,12 +528,14 @@ Error FixupBranches::runOnFunctions(BinaryContext &BC) {
}
Error FinalizeFunctions::runOnFunctions(BinaryContext &BC) {
+ std::atomic<bool> HasFatal{false};
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
if (!BF.finalizeCFIState()) {
if (BC.HasRelocations) {
errs() << "BOLT-ERROR: unable to fix CFI state for function " << BF
<< ". Exiting.\n";
- exit(1);
+ HasFatal = true;
+ return;
}
BF.setSimple(false);
return;
@@ -552,6 +554,8 @@ Error FinalizeFunctions::runOnFunctions(BinaryContext &BC) {
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_CONSTANT, WorkFun,
SkipPredicate, "FinalizeFunctions");
+ if (HasFatal)
+ return createFatalBOLTError("finalize CFI state failure");
return Error::success();
}
diff --git a/bolt/lib/Passes/Instrumentation.cpp b/bolt/lib/Passes/Instrumentation.cpp
index b6dc770..26b4a67 100644
--- a/bolt/lib/Passes/Instrumentation.cpp
+++ b/bolt/lib/Passes/Instrumentation.cpp
@@ -567,10 +567,9 @@ Error Instrumentation::runOnFunctions(BinaryContext &BC) {
ErrorOr<BinarySection &> SetupSection =
BC.getUniqueSectionByName("I__setup");
- if (!SetupSection) {
- llvm::errs() << "Cannot find I__setup section\n";
- exit(1);
- }
+ if (!SetupSection)
+ return createFatalBOLTError("Cannot find I__setup section\n");
+
MCSymbol *Target = BC.registerNameAtAddress(
"__bolt_instr_setup", SetupSection->getAddress(), 0, 0);
MCInst NewInst;
@@ -586,10 +585,9 @@ Error Instrumentation::runOnFunctions(BinaryContext &BC) {
BinaryBasicBlock &BB = Ctor->front();
ErrorOr<BinarySection &> FiniSection =
BC.getUniqueSectionByName("I__fini");
- if (!FiniSection) {
- llvm::errs() << "Cannot find I__fini section\n";
- exit(1);
- }
+ if (!FiniSection)
+ return createFatalBOLTError("Cannot find I__fini section");
+
MCSymbol *Target = BC.registerNameAtAddress(
"__bolt_instr_fini", FiniSection->getAddress(), 0, 0);
auto IsLEA = [&BC](const MCInst &Inst) { return BC.MIB->isLEA64r(Inst); };
diff --git a/bolt/lib/Passes/PatchEntries.cpp b/bolt/lib/Passes/PatchEntries.cpp
index ddef854..0b0e15f 100644
--- a/bolt/lib/Passes/PatchEntries.cpp
+++ b/bolt/lib/Passes/PatchEntries.cpp
@@ -103,7 +103,7 @@ Error PatchEntries::runOnFunctions(BinaryContext &BC) {
if (opts::ForcePatch) {
errs() << "BOLT-ERROR: unable to patch entries in " << Function
<< "\n";
- exit(1);
+ return createFatalBOLTError("");
}
continue;
diff --git a/bolt/lib/Passes/ReorderFunctions.cpp b/bolt/lib/Passes/ReorderFunctions.cpp
index 86fc03d..9cecd08 100644
--- a/bolt/lib/Passes/ReorderFunctions.cpp
+++ b/bolt/lib/Passes/ReorderFunctions.cpp
@@ -444,7 +444,7 @@ Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
if (!FuncsFile) {
errs() << "BOLT-ERROR: ordered functions file "
<< opts::GenerateFunctionOrderFile << " cannot be opened\n";
- exit(1);
+ return createFatalBOLTError("");
}
}
@@ -455,7 +455,7 @@ Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
if (!LinkSectionsFile) {
errs() << "BOLT-ERROR: link sections file " << opts::LinkSectionsFile
<< " cannot be opened\n";
- exit(1);
+ return createFatalBOLTError("");
}
}
diff --git a/bolt/lib/Passes/VeneerElimination.cpp b/bolt/lib/Passes/VeneerElimination.cpp
index 06cfecc..d844a06 100644
--- a/bolt/lib/Passes/VeneerElimination.cpp
+++ b/bolt/lib/Passes/VeneerElimination.cpp
@@ -79,8 +79,8 @@ Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
VeneerCallers++;
if (!BC.MIB->replaceBranchTarget(
Instr, VeneerDestinations[TargetSymbol], BC.Ctx.get())) {
- errs() << "BOLT-ERROR: updating veneer call destination failed\n";
- exit(1);
+ return createFatalBOLTError(
+ "BOLT-ERROR: updating veneer call destination failed\n");
}
}
}