1238106Sdes//===-- ubsan_handlers.h ----------------------------------------*- C++ -*-===// 2238106Sdes// 3238106Sdes// The LLVM Compiler Infrastructure 4238106Sdes// 5238106Sdes// This file is distributed under the University of Illinois Open Source 6238106Sdes// License. See LICENSE.TXT for details. 7238106Sdes// 8238106Sdes//===----------------------------------------------------------------------===// 9238106Sdes// 10238106Sdes// Entry points to the runtime library for Clang's undefined behavior sanitizer. 11238106Sdes// 12238106Sdes//===----------------------------------------------------------------------===// 13238106Sdes#ifndef UBSAN_HANDLERS_H 14238106Sdes#define UBSAN_HANDLERS_H 15238106Sdes 16238106Sdes#include "ubsan_value.h" 17238106Sdes 18238106Sdesnamespace __ubsan { 19238106Sdes 20238106Sdesstruct TypeMismatchData { 21238106Sdes SourceLocation Loc; 22238106Sdes const TypeDescriptor &Type; 23238106Sdes unsigned char LogAlignment; 24269257Sdes unsigned char TypeCheckKind; 25269257Sdes}; 26269257Sdes 27269257Sdes#define UNRECOVERABLE(checkname, ...) \ 28269257Sdes extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \ 29269257Sdes void __ubsan_handle_ ## checkname( __VA_ARGS__ ); 30269257Sdes 31269257Sdes#define RECOVERABLE(checkname, ...) \ 32269257Sdes extern "C" SANITIZER_INTERFACE_ATTRIBUTE \ 33269257Sdes void __ubsan_handle_ ## checkname( __VA_ARGS__ ); \ 34238106Sdes extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \ 35238106Sdes void __ubsan_handle_ ## checkname ## _abort( __VA_ARGS__ ); 36238106Sdes 37238106Sdes/// \brief Handle a runtime type check failure, caused by either a misaligned 38238106Sdes/// pointer, a null pointer, or a pointer to insufficient storage for the 39238106Sdes/// type. 40238106SdesRECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer) 41238106Sdes 42238106Sdesstruct OverflowData { 43238106Sdes SourceLocation Loc; 44238106Sdes const TypeDescriptor &Type; 45238106Sdes}; 46238106Sdes 47238106Sdes/// \brief Handle an integer addition overflow. 48238106SdesRECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 49238106Sdes 50238106Sdes/// \brief Handle an integer subtraction overflow. 51238106SdesRECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 52238106Sdes 53238106Sdes/// \brief Handle an integer multiplication overflow. 54238106SdesRECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 55238106Sdes 56238106Sdes/// \brief Handle a signed integer overflow for a unary negate operator. 57238106SdesRECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal) 58238106Sdes 59238106Sdes/// \brief Handle an INT_MIN/-1 overflow or division by zero. 60238106SdesRECOVERABLE(divrem_overflow, OverflowData *Data, 61238106Sdes ValueHandle LHS, ValueHandle RHS) 62238106Sdes 63269257Sdesstruct ShiftOutOfBoundsData { 64269257Sdes SourceLocation Loc; 65249141Sdes const TypeDescriptor &LHSType; 66249141Sdes const TypeDescriptor &RHSType; 67249141Sdes}; 68249141Sdes 69238106Sdes/// \brief Handle a shift where the RHS is out of bounds or a left shift where 70238106Sdes/// the LHS is negative or overflows. 71238106SdesRECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data, 72238106Sdes ValueHandle LHS, ValueHandle RHS) 73238106Sdes 74238106Sdesstruct OutOfBoundsData { 75238106Sdes SourceLocation Loc; 76238106Sdes const TypeDescriptor &ArrayType; 77238106Sdes const TypeDescriptor &IndexType; 78238106Sdes}; 79238106Sdes 80238106Sdes/// \brief Handle an array index out of bounds error. 81238106SdesRECOVERABLE(out_of_bounds, OutOfBoundsData *Data, ValueHandle Index) 82238106Sdes 83238106Sdesstruct UnreachableData { 84238106Sdes SourceLocation Loc; 85238106Sdes}; 86238106Sdes 87238106Sdes/// \brief Handle a __builtin_unreachable which is reached. 88285206SdesUNRECOVERABLE(builtin_unreachable, UnreachableData *Data) 89285206Sdes/// \brief Handle reaching the end of a value-returning function. 90238106SdesUNRECOVERABLE(missing_return, UnreachableData *Data) 91238106Sdes 92238106Sdesstruct VLABoundData { 93238106Sdes SourceLocation Loc; 94238106Sdes const TypeDescriptor &Type; 95238106Sdes}; 96238106Sdes 97238106Sdes/// \brief Handle a VLA with a non-positive bound. 98238106SdesRECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound) 99238106Sdes 100238106Sdes// Keeping this around for binary compatibility with (sanitized) programs 101238106Sdes// compiled with older compilers. 102238106Sdesstruct FloatCastOverflowData { 103238106Sdes const TypeDescriptor &FromType; 104238106Sdes const TypeDescriptor &ToType; 105238106Sdes}; 106238106Sdes 107238106Sdesstruct FloatCastOverflowDataV2 { 108238106Sdes SourceLocation Loc; 109238106Sdes const TypeDescriptor &FromType; 110238106Sdes const TypeDescriptor &ToType; 111238106Sdes}; 112238106Sdes 113238106Sdes/// Handle overflow in a conversion to or from a floating-point type. 114238106Sdes/// void *Data is one of FloatCastOverflowData* or FloatCastOverflowDataV2* 115238106SdesRECOVERABLE(float_cast_overflow, void *Data, ValueHandle From) 116238106Sdes 117238106Sdesstruct InvalidValueData { 118238106Sdes SourceLocation Loc; 119238106Sdes const TypeDescriptor &Type; 120238106Sdes}; 121238106Sdes 122238106Sdes/// \brief Handle a load of an invalid value for the type. 123238106SdesRECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val) 124238106Sdes 125238106Sdes/// Known implicit conversion check kinds. 126238106Sdes/// Keep in sync with the enum of the same name in CGExprScalar.cpp 127238106Sdesenum ImplicitConversionCheckKind : unsigned char { 128238106Sdes ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7. 129238106Sdes ICCK_UnsignedIntegerTruncation = 1, 130238106Sdes ICCK_SignedIntegerTruncation = 2, 131238106Sdes ICCK_IntegerSignChange = 3, 132238106Sdes ICCK_SignedIntegerTruncationOrSignChange = 4, 133238106Sdes}; 134238106Sdes 135238106Sdesstruct ImplicitConversionData { 136238106Sdes SourceLocation Loc; 137238106Sdes const TypeDescriptor &FromType; 138238106Sdes const TypeDescriptor &ToType; 139238106Sdes /* ImplicitConversionCheckKind */ unsigned char Kind; 140238106Sdes}; 141238106Sdes 142238106Sdes/// \brief Implict conversion that changed the value. 143238106SdesRECOVERABLE(implicit_conversion, ImplicitConversionData *Data, ValueHandle Src, 144238106Sdes ValueHandle Dst) 145238106Sdes 146238106Sdes/// Known builtin check kinds. 147238106Sdes/// Keep in sync with the enum of the same name in CodeGenFunction.h 148238106Sdesenum BuiltinCheckKind : unsigned char { 149238106Sdes BCK_CTZPassedZero, 150238106Sdes BCK_CLZPassedZero, 151238106Sdes}; 152238106Sdes 153238106Sdesstruct InvalidBuiltinData { 154238106Sdes SourceLocation Loc; 155238106Sdes unsigned char Kind; 156238106Sdes}; 157238106Sdes 158238106Sdes/// Handle a builtin called in an invalid way. 159238106SdesRECOVERABLE(invalid_builtin, InvalidBuiltinData *Data) 160238106Sdes 161238106Sdesstruct FunctionTypeMismatchData { 162238106Sdes SourceLocation Loc; 163238106Sdes const TypeDescriptor &Type; 164238106Sdes}; 165238106Sdes 166238106SdesRECOVERABLE(function_type_mismatch, 167238106Sdes FunctionTypeMismatchData *Data, 168238106Sdes ValueHandle Val) 169238106Sdes 170238106Sdesstruct NonNullReturnData { 171238106Sdes SourceLocation AttrLoc; 172238106Sdes}; 173238106Sdes 174238106Sdes/// \brief Handle returning null from function with the returns_nonnull 175238106Sdes/// attribute, or a return type annotated with _Nonnull. 176238106SdesRECOVERABLE(nonnull_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 177238106SdesRECOVERABLE(nullability_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 178269257Sdes 179238106Sdesstruct NonNullArgData { 180238106Sdes SourceLocation Loc; 181238106Sdes SourceLocation AttrLoc; 182238106Sdes int ArgIndex; 183238106Sdes}; 184238106Sdes 185238106Sdes/// \brief Handle passing null pointer to a function parameter with the nonnull 186238106Sdes/// attribute, or a _Nonnull type annotation. 187238106SdesRECOVERABLE(nonnull_arg, NonNullArgData *Data) 188238106SdesRECOVERABLE(nullability_arg, NonNullArgData *Data) 189238106Sdes 190238106Sdesstruct PointerOverflowData { 191238106Sdes SourceLocation Loc; 192238106Sdes}; 193238106Sdes 194238106SdesRECOVERABLE(pointer_overflow, PointerOverflowData *Data, ValueHandle Base, 195238106Sdes ValueHandle Result) 196238106Sdes 197269257Sdes/// \brief Known CFI check kinds. 198238106Sdes/// Keep in sync with the enum of the same name in CodeGenFunction.h 199238106Sdesenum CFITypeCheckKind : unsigned char { 200238106Sdes CFITCK_VCall, 201238106Sdes CFITCK_NVCall, 202238106Sdes CFITCK_DerivedCast, 203238106Sdes CFITCK_UnrelatedCast, 204238106Sdes CFITCK_ICall, 205238106Sdes CFITCK_NVMFCall, 206238106Sdes CFITCK_VMFCall, 207238106Sdes}; 208238106Sdes 209238106Sdesstruct CFICheckFailData { 210238106Sdes CFITypeCheckKind CheckKind; 211238106Sdes SourceLocation Loc; 212238106Sdes const TypeDescriptor &Type; 213238106Sdes}; 214238106Sdes 215238106Sdes/// \brief Handle control flow integrity failures. 216238106SdesRECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, 217238106Sdes uptr VtableIsValid) 218238106Sdes 219238106Sdesstruct ReportOptions; 220238106Sdes 221269257Sdesextern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_handle_cfi_bad_type( 222269257Sdes CFICheckFailData *Data, ValueHandle Vtable, bool ValidVtable, 223238106Sdes ReportOptions Opts); 224238106Sdes 225238106Sdes} 226238106Sdes 227238106Sdes#endif // UBSAN_HANDLERS_H 228238106Sdes