[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
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -110,7 +110,7 @@ Error ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
|
||||
"ADRRelaxationPass");
|
||||
|
||||
if (PassFailed)
|
||||
exit(1);
|
||||
return createFatalBOLTError("");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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); };
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user