1*7c3d14c8STreehugger Robot //===-- ubsan_handlers.h ----------------------------------------*- C++ -*-===// 2*7c3d14c8STreehugger Robot // 3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure 4*7c3d14c8STreehugger Robot // 5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source 6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details. 7*7c3d14c8STreehugger Robot // 8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===// 9*7c3d14c8STreehugger Robot // 10*7c3d14c8STreehugger Robot // Entry points to the runtime library for Clang's undefined behavior sanitizer. 11*7c3d14c8STreehugger Robot // 12*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===// 13*7c3d14c8STreehugger Robot #ifndef UBSAN_HANDLERS_H 14*7c3d14c8STreehugger Robot #define UBSAN_HANDLERS_H 15*7c3d14c8STreehugger Robot 16*7c3d14c8STreehugger Robot #include "ubsan_value.h" 17*7c3d14c8STreehugger Robot 18*7c3d14c8STreehugger Robot namespace __ubsan { 19*7c3d14c8STreehugger Robot 20*7c3d14c8STreehugger Robot struct TypeMismatchData { 21*7c3d14c8STreehugger Robot SourceLocation Loc; 22*7c3d14c8STreehugger Robot const TypeDescriptor &Type; 23*7c3d14c8STreehugger Robot uptr Alignment; 24*7c3d14c8STreehugger Robot unsigned char TypeCheckKind; 25*7c3d14c8STreehugger Robot }; 26*7c3d14c8STreehugger Robot 27*7c3d14c8STreehugger Robot #define UNRECOVERABLE(checkname, ...) \ 28*7c3d14c8STreehugger Robot extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \ 29*7c3d14c8STreehugger Robot void __ubsan_handle_ ## checkname( __VA_ARGS__ ); 30*7c3d14c8STreehugger Robot 31*7c3d14c8STreehugger Robot #define RECOVERABLE(checkname, ...) \ 32*7c3d14c8STreehugger Robot extern "C" SANITIZER_INTERFACE_ATTRIBUTE \ 33*7c3d14c8STreehugger Robot void __ubsan_handle_ ## checkname( __VA_ARGS__ ); \ 34*7c3d14c8STreehugger Robot extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \ 35*7c3d14c8STreehugger Robot void __ubsan_handle_ ## checkname ## _abort( __VA_ARGS__ ); 36*7c3d14c8STreehugger Robot 37*7c3d14c8STreehugger Robot /// \brief Handle a runtime type check failure, caused by either a misaligned 38*7c3d14c8STreehugger Robot /// pointer, a null pointer, or a pointer to insufficient storage for the 39*7c3d14c8STreehugger Robot /// type. 40*7c3d14c8STreehugger Robot RECOVERABLE(type_mismatch, TypeMismatchData *Data, ValueHandle Pointer) 41*7c3d14c8STreehugger Robot 42*7c3d14c8STreehugger Robot struct OverflowData { 43*7c3d14c8STreehugger Robot SourceLocation Loc; 44*7c3d14c8STreehugger Robot const TypeDescriptor &Type; 45*7c3d14c8STreehugger Robot }; 46*7c3d14c8STreehugger Robot 47*7c3d14c8STreehugger Robot /// \brief Handle an integer addition overflow. 48*7c3d14c8STreehugger Robot RECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 49*7c3d14c8STreehugger Robot 50*7c3d14c8STreehugger Robot /// \brief Handle an integer subtraction overflow. 51*7c3d14c8STreehugger Robot RECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 52*7c3d14c8STreehugger Robot 53*7c3d14c8STreehugger Robot /// \brief Handle an integer multiplication overflow. 54*7c3d14c8STreehugger Robot RECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 55*7c3d14c8STreehugger Robot 56*7c3d14c8STreehugger Robot /// \brief Handle a signed integer overflow for a unary negate operator. 57*7c3d14c8STreehugger Robot RECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal) 58*7c3d14c8STreehugger Robot 59*7c3d14c8STreehugger Robot /// \brief Handle an INT_MIN/-1 overflow or division by zero. 60*7c3d14c8STreehugger Robot RECOVERABLE(divrem_overflow, OverflowData *Data, 61*7c3d14c8STreehugger Robot ValueHandle LHS, ValueHandle RHS) 62*7c3d14c8STreehugger Robot 63*7c3d14c8STreehugger Robot struct ShiftOutOfBoundsData { 64*7c3d14c8STreehugger Robot SourceLocation Loc; 65*7c3d14c8STreehugger Robot const TypeDescriptor &LHSType; 66*7c3d14c8STreehugger Robot const TypeDescriptor &RHSType; 67*7c3d14c8STreehugger Robot }; 68*7c3d14c8STreehugger Robot 69*7c3d14c8STreehugger Robot /// \brief Handle a shift where the RHS is out of bounds or a left shift where 70*7c3d14c8STreehugger Robot /// the LHS is negative or overflows. 71*7c3d14c8STreehugger Robot RECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data, 72*7c3d14c8STreehugger Robot ValueHandle LHS, ValueHandle RHS) 73*7c3d14c8STreehugger Robot 74*7c3d14c8STreehugger Robot struct OutOfBoundsData { 75*7c3d14c8STreehugger Robot SourceLocation Loc; 76*7c3d14c8STreehugger Robot const TypeDescriptor &ArrayType; 77*7c3d14c8STreehugger Robot const TypeDescriptor &IndexType; 78*7c3d14c8STreehugger Robot }; 79*7c3d14c8STreehugger Robot 80*7c3d14c8STreehugger Robot /// \brief Handle an array index out of bounds error. 81*7c3d14c8STreehugger Robot RECOVERABLE(out_of_bounds, OutOfBoundsData *Data, ValueHandle Index) 82*7c3d14c8STreehugger Robot 83*7c3d14c8STreehugger Robot struct UnreachableData { 84*7c3d14c8STreehugger Robot SourceLocation Loc; 85*7c3d14c8STreehugger Robot }; 86*7c3d14c8STreehugger Robot 87*7c3d14c8STreehugger Robot /// \brief Handle a __builtin_unreachable which is reached. 88*7c3d14c8STreehugger Robot UNRECOVERABLE(builtin_unreachable, UnreachableData *Data) 89*7c3d14c8STreehugger Robot /// \brief Handle reaching the end of a value-returning function. 90*7c3d14c8STreehugger Robot UNRECOVERABLE(missing_return, UnreachableData *Data) 91*7c3d14c8STreehugger Robot 92*7c3d14c8STreehugger Robot struct VLABoundData { 93*7c3d14c8STreehugger Robot SourceLocation Loc; 94*7c3d14c8STreehugger Robot const TypeDescriptor &Type; 95*7c3d14c8STreehugger Robot }; 96*7c3d14c8STreehugger Robot 97*7c3d14c8STreehugger Robot /// \brief Handle a VLA with a non-positive bound. 98*7c3d14c8STreehugger Robot RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound) 99*7c3d14c8STreehugger Robot 100*7c3d14c8STreehugger Robot // Keeping this around for binary compatibility with (sanitized) programs 101*7c3d14c8STreehugger Robot // compiled with older compilers. 102*7c3d14c8STreehugger Robot struct FloatCastOverflowData { 103*7c3d14c8STreehugger Robot const TypeDescriptor &FromType; 104*7c3d14c8STreehugger Robot const TypeDescriptor &ToType; 105*7c3d14c8STreehugger Robot }; 106*7c3d14c8STreehugger Robot 107*7c3d14c8STreehugger Robot struct FloatCastOverflowDataV2 { 108*7c3d14c8STreehugger Robot SourceLocation Loc; 109*7c3d14c8STreehugger Robot const TypeDescriptor &FromType; 110*7c3d14c8STreehugger Robot const TypeDescriptor &ToType; 111*7c3d14c8STreehugger Robot }; 112*7c3d14c8STreehugger Robot 113*7c3d14c8STreehugger Robot /// Handle overflow in a conversion to or from a floating-point type. 114*7c3d14c8STreehugger Robot /// void *Data is one of FloatCastOverflowData* or FloatCastOverflowDataV2* 115*7c3d14c8STreehugger Robot RECOVERABLE(float_cast_overflow, void *Data, ValueHandle From) 116*7c3d14c8STreehugger Robot 117*7c3d14c8STreehugger Robot struct InvalidValueData { 118*7c3d14c8STreehugger Robot SourceLocation Loc; 119*7c3d14c8STreehugger Robot const TypeDescriptor &Type; 120*7c3d14c8STreehugger Robot }; 121*7c3d14c8STreehugger Robot 122*7c3d14c8STreehugger Robot /// \brief Handle a load of an invalid value for the type. 123*7c3d14c8STreehugger Robot RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val) 124*7c3d14c8STreehugger Robot 125*7c3d14c8STreehugger Robot struct FunctionTypeMismatchData { 126*7c3d14c8STreehugger Robot SourceLocation Loc; 127*7c3d14c8STreehugger Robot const TypeDescriptor &Type; 128*7c3d14c8STreehugger Robot }; 129*7c3d14c8STreehugger Robot 130*7c3d14c8STreehugger Robot RECOVERABLE(function_type_mismatch, 131*7c3d14c8STreehugger Robot FunctionTypeMismatchData *Data, 132*7c3d14c8STreehugger Robot ValueHandle Val) 133*7c3d14c8STreehugger Robot 134*7c3d14c8STreehugger Robot struct NonNullReturnData { 135*7c3d14c8STreehugger Robot SourceLocation Loc; 136*7c3d14c8STreehugger Robot SourceLocation AttrLoc; 137*7c3d14c8STreehugger Robot }; 138*7c3d14c8STreehugger Robot 139*7c3d14c8STreehugger Robot /// \brief Handle returning null from function with returns_nonnull attribute. 140*7c3d14c8STreehugger Robot RECOVERABLE(nonnull_return, NonNullReturnData *Data) 141*7c3d14c8STreehugger Robot 142*7c3d14c8STreehugger Robot struct NonNullArgData { 143*7c3d14c8STreehugger Robot SourceLocation Loc; 144*7c3d14c8STreehugger Robot SourceLocation AttrLoc; 145*7c3d14c8STreehugger Robot int ArgIndex; 146*7c3d14c8STreehugger Robot }; 147*7c3d14c8STreehugger Robot 148*7c3d14c8STreehugger Robot /// \brief Handle passing null pointer to function with nonnull attribute. 149*7c3d14c8STreehugger Robot RECOVERABLE(nonnull_arg, NonNullArgData *Data) 150*7c3d14c8STreehugger Robot 151*7c3d14c8STreehugger Robot /// \brief Known CFI check kinds. 152*7c3d14c8STreehugger Robot /// Keep in sync with the enum of the same name in CodeGenFunction.h 153*7c3d14c8STreehugger Robot enum CFITypeCheckKind : unsigned char { 154*7c3d14c8STreehugger Robot CFITCK_VCall, 155*7c3d14c8STreehugger Robot CFITCK_NVCall, 156*7c3d14c8STreehugger Robot CFITCK_DerivedCast, 157*7c3d14c8STreehugger Robot CFITCK_UnrelatedCast, 158*7c3d14c8STreehugger Robot CFITCK_ICall, 159*7c3d14c8STreehugger Robot }; 160*7c3d14c8STreehugger Robot 161*7c3d14c8STreehugger Robot struct CFICheckFailData { 162*7c3d14c8STreehugger Robot CFITypeCheckKind CheckKind; 163*7c3d14c8STreehugger Robot SourceLocation Loc; 164*7c3d14c8STreehugger Robot const TypeDescriptor &Type; 165*7c3d14c8STreehugger Robot }; 166*7c3d14c8STreehugger Robot 167*7c3d14c8STreehugger Robot /// \brief Handle control flow integrity failures. 168*7c3d14c8STreehugger Robot RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, 169*7c3d14c8STreehugger Robot uptr VtableIsValid) 170*7c3d14c8STreehugger Robot } 171*7c3d14c8STreehugger Robot 172*7c3d14c8STreehugger Robot #endif // UBSAN_HANDLERS_H 173