diff options
author | Amir Ayupov <aaupov@fb.com> | 2024-02-12 14:39:59 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-12 14:39:59 -0800 |
commit | fa7dd4919aa705f18f268fab5b2887d45f89d8dd (patch) | |
tree | bba047f6260626f329cc9e094607e8cef66e829c /bolt | |
parent | a5f3d1a803020167bd9d494a8a3921e7dcc1550a (diff) | |
download | llvm-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.h | 23 | ||||
-rw-r--r-- | bolt/lib/Core/BinaryContext.cpp | 31 | ||||
-rw-r--r-- | bolt/lib/Passes/ADRRelaxationPass.cpp | 2 | ||||
-rw-r--r-- | bolt/lib/Passes/BinaryPasses.cpp | 6 | ||||
-rw-r--r-- | bolt/lib/Passes/Instrumentation.cpp | 14 | ||||
-rw-r--r-- | bolt/lib/Passes/PatchEntries.cpp | 2 | ||||
-rw-r--r-- | bolt/lib/Passes/ReorderFunctions.cpp | 4 | ||||
-rw-r--r-- | bolt/lib/Passes/VeneerElimination.cpp | 4 |
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"); } } } |