|
@@ -608,7 +608,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
|
|
|
llvm::ConstantInt::get(SizeTy, AlignVal),
|
|
|
llvm::ConstantInt::get(Int8Ty, TCK)
|
|
|
};
|
|
|
- EmitCheck(Checks, "type_mismatch", StaticData, Ptr);
|
|
|
+ EmitCheck(Checks, SanitizerHandler::TypeMismatch, StaticData, Ptr);
|
|
|
}
|
|
|
|
|
|
// If possible, check that the vptr indicates that there is a subobject of
|
|
@@ -676,7 +676,8 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
|
|
|
};
|
|
|
llvm::Value *DynamicData[] = { Ptr, Hash };
|
|
|
EmitCheck(std::make_pair(EqualHash, SanitizerKind::Vptr),
|
|
|
- "dynamic_type_cache_miss", StaticData, DynamicData);
|
|
|
+ SanitizerHandler::DynamicTypeCacheMiss, StaticData,
|
|
|
+ DynamicData);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -766,8 +767,8 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
|
|
|
};
|
|
|
llvm::Value *Check = Accessed ? Builder.CreateICmpULT(IndexVal, BoundVal)
|
|
|
: Builder.CreateICmpULE(IndexVal, BoundVal);
|
|
|
- EmitCheck(std::make_pair(Check, SanitizerKind::ArrayBounds), "out_of_bounds",
|
|
|
- StaticData, Index);
|
|
|
+ EmitCheck(std::make_pair(Check, SanitizerKind::ArrayBounds),
|
|
|
+ SanitizerHandler::OutOfBounds, StaticData, Index);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1339,8 +1340,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
|
|
|
EmitCheckTypeDescriptor(Ty)
|
|
|
};
|
|
|
SanitizerMask Kind = NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool;
|
|
|
- EmitCheck(std::make_pair(Check, Kind), "load_invalid_value", StaticArgs,
|
|
|
- EmitCheckValue(Load));
|
|
|
+ EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue,
|
|
|
+ StaticArgs, EmitCheckValue(Load));
|
|
|
}
|
|
|
} else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
|
|
|
if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
|
|
@@ -2500,17 +2501,35 @@ static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+namespace {
|
|
|
+struct SanitizerHandlerInfo {
|
|
|
+ char const *const Name;
|
|
|
+ unsigned Version;
|
|
|
+};
|
|
|
+};
|
|
|
+
|
|
|
+const SanitizerHandlerInfo SanitizerHandlers[] = {
|
|
|
+#define SANITIZER_CHECK(Enum, Name, Version) {#Name, Version},
|
|
|
+ LIST_SANITIZER_CHECKS
|
|
|
+#undef SANITIZER_CHECK
|
|
|
+};
|
|
|
+
|
|
|
static void emitCheckHandlerCall(CodeGenFunction &CGF,
|
|
|
llvm::FunctionType *FnType,
|
|
|
ArrayRef<llvm::Value *> FnArgs,
|
|
|
- StringRef CheckName,
|
|
|
+ SanitizerHandler CheckHandler,
|
|
|
CheckRecoverableKind RecoverKind, bool IsFatal,
|
|
|
llvm::BasicBlock *ContBB) {
|
|
|
assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
|
|
|
bool NeedsAbortSuffix =
|
|
|
IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
|
|
|
- std::string FnName = ("__ubsan_handle_" + CheckName +
|
|
|
- (NeedsAbortSuffix ? "_abort" : "")).str();
|
|
|
+ const SanitizerHandlerInfo &CheckInfo = SanitizerHandlers[CheckHandler];
|
|
|
+ const StringRef CheckName = CheckInfo.Name;
|
|
|
+ std::string FnName =
|
|
|
+ ("__ubsan_handle_" + CheckName +
|
|
|
+ (CheckInfo.Version ? "_v" + std::to_string(CheckInfo.Version) : "") +
|
|
|
+ (NeedsAbortSuffix ? "_abort" : ""))
|
|
|
+ .str();
|
|
|
bool MayReturn =
|
|
|
!IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;
|
|
|
|
|
@@ -2536,10 +2555,13 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
|
|
|
|
|
|
void CodeGenFunction::EmitCheck(
|
|
|
ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
|
|
|
- StringRef CheckName, ArrayRef<llvm::Constant *> StaticArgs,
|
|
|
+ SanitizerHandler CheckHandler, ArrayRef<llvm::Constant *> StaticArgs,
|
|
|
ArrayRef<llvm::Value *> DynamicArgs) {
|
|
|
assert(IsSanitizerScope);
|
|
|
assert(Checked.size() > 0);
|
|
|
+ assert(CheckHandler >= 0 &&
|
|
|
+ CheckHandler < sizeof(SanitizerHandlers) / sizeof(*SanitizerHandlers));
|
|
|
+ const StringRef CheckName = SanitizerHandlers[CheckHandler].Name;
|
|
|
|
|
|
llvm::Value *FatalCond = nullptr;
|
|
|
llvm::Value *RecoverableCond = nullptr;
|
|
@@ -2619,7 +2641,7 @@ void CodeGenFunction::EmitCheck(
|
|
|
if (!FatalCond || !RecoverableCond) {
|
|
|
// Simple case: we need to generate a single handler call, either
|
|
|
// fatal, or non-fatal.
|
|
|
- emitCheckHandlerCall(*this, FnType, Args, CheckName, RecoverKind,
|
|
|
+ emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind,
|
|
|
(FatalCond != nullptr), Cont);
|
|
|
} else {
|
|
|
// Emit two handler calls: first one for set of unrecoverable checks,
|
|
@@ -2629,10 +2651,10 @@ void CodeGenFunction::EmitCheck(
|
|
|
llvm::BasicBlock *FatalHandlerBB = createBasicBlock("fatal." + CheckName);
|
|
|
Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
|
|
|
EmitBlock(FatalHandlerBB);
|
|
|
- emitCheckHandlerCall(*this, FnType, Args, CheckName, RecoverKind, true,
|
|
|
+ emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, true,
|
|
|
NonFatalHandlerBB);
|
|
|
EmitBlock(NonFatalHandlerBB);
|
|
|
- emitCheckHandlerCall(*this, FnType, Args, CheckName, RecoverKind, false,
|
|
|
+ emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, false,
|
|
|
Cont);
|
|
|
}
|
|
|
|
|
@@ -2757,7 +2779,7 @@ void CodeGenFunction::EmitCfiCheckFail() {
|
|
|
llvm::Value *Cond =
|
|
|
Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind));
|
|
|
if (CGM.getLangOpts().Sanitize.has(Mask))
|
|
|
- EmitCheck(std::make_pair(Cond, Mask), "cfi_check_fail", {},
|
|
|
+ EmitCheck(std::make_pair(Cond, Mask), SanitizerHandler::CFICheckFail, {},
|
|
|
{Data, Addr, ValidVtable});
|
|
|
else
|
|
|
EmitTrapCheck(Cond);
|
|
@@ -4127,7 +4149,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
|
|
|
EmitCheckTypeDescriptor(CalleeType)
|
|
|
};
|
|
|
EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
|
|
|
- "function_type_mismatch", StaticData, CalleePtr);
|
|
|
+ SanitizerHandler::FunctionTypeMismatch, StaticData, CalleePtr);
|
|
|
|
|
|
Builder.CreateBr(Cont);
|
|
|
EmitBlock(Cont);
|
|
@@ -4160,7 +4182,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
|
|
|
CastedCallee, StaticData);
|
|
|
} else {
|
|
|
EmitCheck(std::make_pair(TypeTest, SanitizerKind::CFIICall),
|
|
|
- "cfi_check_fail", StaticData,
|
|
|
+ SanitizerHandler::CFICheckFail, StaticData,
|
|
|
{CastedCallee, llvm::UndefValue::get(IntPtrTy)});
|
|
|
}
|
|
|
}
|