| //===-- ubsan_handlers.h ----------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Entry points to the runtime library for Clang's undefined behavior sanitizer. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef UBSAN_HANDLERS_H |
| #define UBSAN_HANDLERS_H |
| |
| #include "ubsan_value.h" |
| |
| namespace __ubsan { |
| |
| struct TypeMismatchData { |
| SourceLocation Loc; |
| const TypeDescriptor &Type; |
| unsigned char LogAlignment; |
| unsigned char TypeCheckKind; |
| }; |
| |
| #define UNRECOVERABLE(checkname, ...) \ |
| extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \ |
| void __ubsan_handle_ ## checkname( __VA_ARGS__ ); |
| |
| #define RECOVERABLE(checkname, ...) \ |
| extern "C" SANITIZER_INTERFACE_ATTRIBUTE \ |
| void __ubsan_handle_ ## checkname( __VA_ARGS__ ); \ |
| extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \ |
| void __ubsan_handle_ ## checkname ## _abort( __VA_ARGS__ ); |
| |
| /// \brief Handle a runtime type check failure, caused by either a misaligned |
| /// pointer, a null pointer, or a pointer to insufficient storage for the |
| /// type. |
| RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer) |
| |
| struct AlignmentAssumptionData { |
| SourceLocation Loc; |
| SourceLocation AssumptionLoc; |
| const TypeDescriptor &Type; |
| }; |
| |
| /// \brief Handle a runtime alignment assumption check failure, |
| /// caused by a misaligned pointer. |
| RECOVERABLE(alignment_assumption, AlignmentAssumptionData *Data, |
| ValueHandle Pointer, ValueHandle Alignment, ValueHandle Offset) |
| |
| struct OverflowData { |
| SourceLocation Loc; |
| const TypeDescriptor &Type; |
| }; |
| |
| /// \brief Handle an integer addition overflow. |
| RECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) |
| |
| /// \brief Handle an integer subtraction overflow. |
| RECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) |
| |
| /// \brief Handle an integer multiplication overflow. |
| RECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) |
| |
| /// \brief Handle a signed integer overflow for a unary negate operator. |
| RECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal) |
| |
| /// \brief Handle an INT_MIN/-1 overflow or division by zero. |
| RECOVERABLE(divrem_overflow, OverflowData *Data, |
| ValueHandle LHS, ValueHandle RHS) |
| |
| struct ShiftOutOfBoundsData { |
| SourceLocation Loc; |
| const TypeDescriptor &LHSType; |
| const TypeDescriptor &RHSType; |
| }; |
| |
| /// \brief Handle a shift where the RHS is out of bounds or a left shift where |
| /// the LHS is negative or overflows. |
| RECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data, |
| ValueHandle LHS, ValueHandle RHS) |
| |
| struct OutOfBoundsData { |
| SourceLocation Loc; |
| const TypeDescriptor &ArrayType; |
| const TypeDescriptor &IndexType; |
| }; |
| |
| /// \brief Handle an array index out of bounds error. |
| RECOVERABLE(out_of_bounds, OutOfBoundsData *Data, ValueHandle Index) |
| |
| struct UnreachableData { |
| SourceLocation Loc; |
| }; |
| |
| /// \brief Handle a __builtin_unreachable which is reached. |
| UNRECOVERABLE(builtin_unreachable, UnreachableData *Data) |
| /// \brief Handle reaching the end of a value-returning function. |
| UNRECOVERABLE(missing_return, UnreachableData *Data) |
| |
| struct VLABoundData { |
| SourceLocation Loc; |
| const TypeDescriptor &Type; |
| }; |
| |
| /// \brief Handle a VLA with a non-positive bound. |
| RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound) |
| |
| // Keeping this around for binary compatibility with (sanitized) programs |
| // compiled with older compilers. |
| struct FloatCastOverflowData { |
| const TypeDescriptor &FromType; |
| const TypeDescriptor &ToType; |
| }; |
| |
| struct FloatCastOverflowDataV2 { |
| SourceLocation Loc; |
| const TypeDescriptor &FromType; |
| const TypeDescriptor &ToType; |
| }; |
| |
| /// Handle overflow in a conversion to or from a floating-point type. |
| /// void *Data is one of FloatCastOverflowData* or FloatCastOverflowDataV2* |
| RECOVERABLE(float_cast_overflow, void *Data, ValueHandle From) |
| |
| struct InvalidValueData { |
| SourceLocation Loc; |
| const TypeDescriptor &Type; |
| }; |
| |
| /// \brief Handle a load of an invalid value for the type. |
| RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val) |
| |
| /// Known implicit conversion check kinds. |
| /// Keep in sync with the enum of the same name in CGExprScalar.cpp |
| enum ImplicitConversionCheckKind : unsigned char { |
| ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7. |
| ICCK_UnsignedIntegerTruncation = 1, |
| ICCK_SignedIntegerTruncation = 2, |
| ICCK_IntegerSignChange = 3, |
| ICCK_SignedIntegerTruncationOrSignChange = 4, |
| }; |
| |
| struct ImplicitConversionData { |
| SourceLocation Loc; |
| const TypeDescriptor &FromType; |
| const TypeDescriptor &ToType; |
| /* ImplicitConversionCheckKind */ unsigned char Kind; |
| }; |
| |
| /// \brief Implict conversion that changed the value. |
| RECOVERABLE(implicit_conversion, ImplicitConversionData *Data, ValueHandle Src, |
| ValueHandle Dst) |
| |
| /// Known builtin check kinds. |
| /// Keep in sync with the enum of the same name in CodeGenFunction.h |
| enum BuiltinCheckKind : unsigned char { |
| BCK_CTZPassedZero, |
| BCK_CLZPassedZero, |
| }; |
| |
| struct InvalidBuiltinData { |
| SourceLocation Loc; |
| unsigned char Kind; |
| }; |
| |
| /// Handle a builtin called in an invalid way. |
| RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data) |
| |
| struct NonNullReturnData { |
| SourceLocation AttrLoc; |
| }; |
| |
| /// \brief Handle returning null from function with the returns_nonnull |
| /// attribute, or a return type annotated with _Nonnull. |
| RECOVERABLE(nonnull_return_v1, NonNullReturnData *Data, SourceLocation *Loc) |
| RECOVERABLE(nullability_return_v1, NonNullReturnData *Data, SourceLocation *Loc) |
| |
| struct NonNullArgData { |
| SourceLocation Loc; |
| SourceLocation AttrLoc; |
| int ArgIndex; |
| }; |
| |
| /// \brief Handle passing null pointer to a function parameter with the nonnull |
| /// attribute, or a _Nonnull type annotation. |
| RECOVERABLE(nonnull_arg, NonNullArgData *Data) |
| RECOVERABLE(nullability_arg, NonNullArgData *Data) |
| |
| struct PointerOverflowData { |
| SourceLocation Loc; |
| }; |
| |
| RECOVERABLE(pointer_overflow, PointerOverflowData *Data, ValueHandle Base, |
| ValueHandle Result) |
| |
| /// \brief Known CFI check kinds. |
| /// Keep in sync with the enum of the same name in CodeGenFunction.h |
| enum CFITypeCheckKind : unsigned char { |
| CFITCK_VCall, |
| CFITCK_NVCall, |
| CFITCK_DerivedCast, |
| CFITCK_UnrelatedCast, |
| CFITCK_ICall, |
| CFITCK_NVMFCall, |
| CFITCK_VMFCall, |
| }; |
| |
| struct CFIBadIcallData { |
| SourceLocation Loc; |
| const TypeDescriptor &Type; |
| }; |
| |
| struct CFICheckFailData { |
| CFITypeCheckKind CheckKind; |
| SourceLocation Loc; |
| const TypeDescriptor &Type; |
| }; |
| |
| /// \brief Handle control flow integrity failure for indirect function calls. |
| RECOVERABLE(cfi_bad_icall, CFIBadIcallData *Data, ValueHandle Function) |
| |
| /// \brief Handle control flow integrity failures. |
| RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, |
| uptr VtableIsValid) |
| |
| struct ReportOptions; |
| |
| extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_handle_cfi_bad_type( |
| CFICheckFailData *Data, ValueHandle Vtable, bool ValidVtable, |
| ReportOptions Opts); |
| |
| } |
| |
| #endif // UBSAN_HANDLERS_H |