Home | History | Annotate | Line # | Download | only in misc
ubsan.c revision 1.7
      1  1.7    mrg /*	$NetBSD: ubsan.c,v 1.7 2019/10/04 12:12:47 mrg Exp $	*/
      2  1.1  kamil 
      3  1.1  kamil /*-
      4  1.1  kamil  * Copyright (c) 2018 The NetBSD Foundation, Inc.
      5  1.1  kamil  * All rights reserved.
      6  1.1  kamil  *
      7  1.1  kamil  * Redistribution and use in source and binary forms, with or without
      8  1.1  kamil  * modification, are permitted provided that the following conditions
      9  1.1  kamil  * are met:
     10  1.1  kamil  * 1. Redistributions of source code must retain the above copyright
     11  1.1  kamil  *    notice, this list of conditions and the following disclaimer.
     12  1.1  kamil  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  kamil  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  kamil  *    documentation and/or other materials provided with the distribution.
     15  1.1  kamil  *
     16  1.1  kamil  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  1.1  kamil  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  1.1  kamil  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  1.1  kamil  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  1.1  kamil  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  1.1  kamil  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  1.1  kamil  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  1.1  kamil  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  1.1  kamil  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  1.1  kamil  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  1.1  kamil  * POSSIBILITY OF SUCH DAMAGE.
     27  1.1  kamil  */
     28  1.1  kamil 
     29  1.1  kamil 
     30  1.1  kamil /*
     31  1.1  kamil  * The micro UBSan implementation for the userland (uUBSan) and kernel (kUBSan).
     32  1.1  kamil  * The uBSSan versions is suitable for inclusion into libc or used standalone
     33  1.1  kamil  * with ATF tests.
     34  1.1  kamil  *
     35  1.2  kamil  * This file due to long symbol names generated by a compiler during the
     36  1.2  kamil  * instrumentation process does not follow the KNF style with 80-column limit.
     37  1.1  kamil  */
     38  1.1  kamil 
     39  1.1  kamil #include <sys/cdefs.h>
     40  1.1  kamil #if defined(_KERNEL)
     41  1.7    mrg __KERNEL_RCSID(0, "$NetBSD: ubsan.c,v 1.7 2019/10/04 12:12:47 mrg Exp $");
     42  1.1  kamil #else
     43  1.7    mrg __RCSID("$NetBSD: ubsan.c,v 1.7 2019/10/04 12:12:47 mrg Exp $");
     44  1.1  kamil #endif
     45  1.1  kamil 
     46  1.1  kamil #if defined(_KERNEL)
     47  1.1  kamil #include <sys/param.h>
     48  1.1  kamil #include <sys/types.h>
     49  1.1  kamil #include <sys/stdarg.h>
     50  1.1  kamil #define ASSERT(x) KASSERT(x)
     51  1.1  kamil #else
     52  1.1  kamil #if defined(_LIBC)
     53  1.1  kamil #include "namespace.h"
     54  1.1  kamil #endif
     55  1.1  kamil #include <sys/param.h>
     56  1.1  kamil #include <assert.h>
     57  1.1  kamil #include <inttypes.h>
     58  1.1  kamil #include <math.h>
     59  1.1  kamil #include <signal.h>
     60  1.1  kamil #include <stdarg.h>
     61  1.1  kamil #include <stdbool.h>
     62  1.1  kamil #include <stdint.h>
     63  1.1  kamil #include <stdio.h>
     64  1.1  kamil #include <stdlib.h>
     65  1.1  kamil #include <string.h>
     66  1.1  kamil #include <syslog.h>
     67  1.1  kamil #include <unistd.h>
     68  1.1  kamil #if defined(_LIBC)
     69  1.1  kamil #include "extern.h"
     70  1.1  kamil #define ubsan_vsyslog vsyslog_ss
     71  1.1  kamil #define ASSERT(x) _DIAGASSERT(x)
     72  1.1  kamil #else
     73  1.1  kamil #define ubsan_vsyslog vsyslog_r
     74  1.1  kamil #define ASSERT(x) assert(x)
     75  1.1  kamil #endif
     76  1.1  kamil /* These macros are available in _KERNEL only */
     77  1.1  kamil #define SET(t, f)	((t) |= (f))
     78  1.1  kamil #define ISSET(t, f)	((t) & (f))
     79  1.1  kamil #define CLR(t, f)	((t) &= ~(f))
     80  1.1  kamil #endif
     81  1.1  kamil 
     82  1.6  kamil #ifdef UBSAN_ALWAYS_FATAL
     83  1.6  kamil static const bool alwaysFatal = true;
     84  1.6  kamil #else
     85  1.6  kamil static const bool alwaysFatal = false;
     86  1.6  kamil #endif
     87  1.6  kamil 
     88  1.1  kamil #define REINTERPRET_CAST(__dt, __st)	((__dt)(__st))
     89  1.1  kamil #define STATIC_CAST(__dt, __st)		((__dt)(__st))
     90  1.1  kamil 
     91  1.1  kamil #define ACK_REPORTED	__BIT(31)
     92  1.1  kamil 
     93  1.1  kamil #define MUL_STRING	"*"
     94  1.1  kamil #define PLUS_STRING	"+"
     95  1.1  kamil #define MINUS_STRING	"-"
     96  1.1  kamil #define DIVREM_STRING	"divrem"
     97  1.1  kamil 
     98  1.1  kamil #define CFI_VCALL		0
     99  1.1  kamil #define CFI_NVCALL		1
    100  1.1  kamil #define CFI_DERIVEDCAST		2
    101  1.1  kamil #define CFI_UNRELATEDCAST	3
    102  1.1  kamil #define CFI_ICALL		4
    103  1.1  kamil #define CFI_NVMFCALL		5
    104  1.1  kamil #define CFI_VMFCALL		6
    105  1.1  kamil 
    106  1.1  kamil #define NUMBER_MAXLEN	128
    107  1.1  kamil #define LOCATION_MAXLEN	(PATH_MAX + 32 /* ':LINE:COLUMN' */)
    108  1.1  kamil 
    109  1.1  kamil #define WIDTH_8		8
    110  1.1  kamil #define WIDTH_16	16
    111  1.1  kamil #define WIDTH_32	32
    112  1.1  kamil #define WIDTH_64	64
    113  1.1  kamil #define WIDTH_80	80
    114  1.1  kamil #define WIDTH_96	96
    115  1.1  kamil #define WIDTH_128	128
    116  1.1  kamil 
    117  1.1  kamil #define NUMBER_SIGNED_BIT	1U
    118  1.1  kamil 
    119  1.5  kamil #ifdef __SIZEOF_INT128__
    120  1.1  kamil typedef __int128 longest;
    121  1.1  kamil typedef unsigned __int128 ulongest;
    122  1.1  kamil #else
    123  1.1  kamil typedef int64_t longest;
    124  1.1  kamil typedef uint64_t ulongest;
    125  1.1  kamil #endif
    126  1.1  kamil 
    127  1.1  kamil #ifndef _KERNEL
    128  1.1  kamil static int ubsan_flags = -1;
    129  1.1  kamil #define UBSAN_ABORT	__BIT(0)
    130  1.1  kamil #define UBSAN_STDOUT	__BIT(1)
    131  1.1  kamil #define UBSAN_STDERR	__BIT(2)
    132  1.1  kamil #define UBSAN_SYSLOG	__BIT(3)
    133  1.1  kamil #endif
    134  1.1  kamil 
    135  1.1  kamil /* Undefined Behavior specific defines and structures */
    136  1.1  kamil 
    137  1.1  kamil #define KIND_INTEGER	0
    138  1.1  kamil #define KIND_FLOAT	1
    139  1.1  kamil #define KIND_UNKNOWN	UINT16_MAX
    140  1.1  kamil 
    141  1.1  kamil struct CSourceLocation {
    142  1.1  kamil 	char *mFilename;
    143  1.1  kamil 	uint32_t mLine;
    144  1.1  kamil 	uint32_t mColumn;
    145  1.1  kamil };
    146  1.1  kamil 
    147  1.1  kamil struct CTypeDescriptor {
    148  1.1  kamil 	uint16_t mTypeKind;
    149  1.1  kamil 	uint16_t mTypeInfo;
    150  1.1  kamil 	uint8_t mTypeName[1];
    151  1.1  kamil };
    152  1.1  kamil 
    153  1.1  kamil struct COverflowData {
    154  1.1  kamil 	struct CSourceLocation mLocation;
    155  1.1  kamil 	struct CTypeDescriptor *mType;
    156  1.1  kamil };
    157  1.1  kamil 
    158  1.1  kamil struct CUnreachableData {
    159  1.1  kamil 	struct CSourceLocation mLocation;
    160  1.1  kamil };
    161  1.1  kamil 
    162  1.1  kamil struct CCFICheckFailData {
    163  1.1  kamil 	uint8_t mCheckKind;
    164  1.1  kamil 	struct CSourceLocation mLocation;
    165  1.1  kamil 	struct CTypeDescriptor *mType;
    166  1.1  kamil };
    167  1.1  kamil 
    168  1.1  kamil struct CDynamicTypeCacheMissData {
    169  1.1  kamil 	struct CSourceLocation mLocation;
    170  1.1  kamil 	struct CTypeDescriptor *mType;
    171  1.1  kamil 	void *mTypeInfo;
    172  1.1  kamil 	uint8_t mTypeCheckKind;
    173  1.1  kamil };
    174  1.1  kamil 
    175  1.1  kamil struct CFunctionTypeMismatchData {
    176  1.1  kamil 	struct CSourceLocation mLocation;
    177  1.1  kamil 	struct CTypeDescriptor *mType;
    178  1.1  kamil };
    179  1.1  kamil 
    180  1.1  kamil struct CInvalidBuiltinData {
    181  1.1  kamil 	struct CSourceLocation mLocation;
    182  1.1  kamil 	uint8_t mKind;
    183  1.1  kamil };
    184  1.1  kamil 
    185  1.1  kamil struct CInvalidValueData {
    186  1.1  kamil 	struct CSourceLocation mLocation;
    187  1.1  kamil 	struct CTypeDescriptor *mType;
    188  1.1  kamil };
    189  1.1  kamil 
    190  1.1  kamil struct CNonNullArgData {
    191  1.1  kamil 	struct CSourceLocation mLocation;
    192  1.1  kamil 	struct CSourceLocation mAttributeLocation;
    193  1.1  kamil 	int mArgIndex;
    194  1.1  kamil };
    195  1.1  kamil 
    196  1.1  kamil struct CNonNullReturnData {
    197  1.1  kamil 	struct CSourceLocation mAttributeLocation;
    198  1.1  kamil };
    199  1.1  kamil 
    200  1.1  kamil struct COutOfBoundsData {
    201  1.1  kamil 	struct CSourceLocation mLocation;
    202  1.1  kamil 	struct CTypeDescriptor *mArrayType;
    203  1.1  kamil 	struct CTypeDescriptor *mIndexType;
    204  1.1  kamil };
    205  1.1  kamil 
    206  1.1  kamil struct CPointerOverflowData {
    207  1.1  kamil 	struct CSourceLocation mLocation;
    208  1.1  kamil };
    209  1.1  kamil 
    210  1.1  kamil struct CShiftOutOfBoundsData {
    211  1.1  kamil 	struct CSourceLocation mLocation;
    212  1.1  kamil 	struct CTypeDescriptor *mLHSType;
    213  1.1  kamil 	struct CTypeDescriptor *mRHSType;
    214  1.1  kamil };
    215  1.1  kamil 
    216  1.1  kamil struct CTypeMismatchData {
    217  1.1  kamil 	struct CSourceLocation mLocation;
    218  1.1  kamil 	struct CTypeDescriptor *mType;
    219  1.1  kamil 	unsigned long mLogAlignment;
    220  1.1  kamil 	uint8_t mTypeCheckKind;
    221  1.1  kamil };
    222  1.1  kamil 
    223  1.1  kamil struct CTypeMismatchData_v1 {
    224  1.1  kamil 	struct CSourceLocation mLocation;
    225  1.1  kamil 	struct CTypeDescriptor *mType;
    226  1.1  kamil 	uint8_t mLogAlignment;
    227  1.1  kamil 	uint8_t mTypeCheckKind;
    228  1.1  kamil };
    229  1.1  kamil 
    230  1.1  kamil struct CVLABoundData {
    231  1.1  kamil 	struct CSourceLocation mLocation;
    232  1.1  kamil 	struct CTypeDescriptor *mType;
    233  1.1  kamil };
    234  1.1  kamil 
    235  1.1  kamil struct CFloatCastOverflowData {
    236  1.1  kamil 	struct CSourceLocation mLocation;	/* This field exists in this struct since 2015 August 11th */
    237  1.1  kamil 	struct CTypeDescriptor *mFromType;
    238  1.1  kamil 	struct CTypeDescriptor *mToType;
    239  1.1  kamil };
    240  1.1  kamil 
    241  1.1  kamil /* Local utility functions */
    242  1.1  kamil static void Report(bool isFatal, const char *pFormat, ...) __printflike(2, 3);
    243  1.1  kamil static bool isAlreadyReported(struct CSourceLocation *pLocation);
    244  1.1  kamil static size_t zDeserializeTypeWidth(struct CTypeDescriptor *pType);
    245  1.1  kamil static void DeserializeLocation(char *pBuffer, size_t zBUfferLength, struct CSourceLocation *pLocation);
    246  1.1  kamil #ifdef __SIZEOF_INT128__
    247  1.1  kamil static void DeserializeUINT128(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, __uint128_t U128);
    248  1.1  kamil #endif
    249  1.1  kamil static void DeserializeNumberSigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, longest L);
    250  1.1  kamil static void DeserializeNumberUnsigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, ulongest L);
    251  1.1  kamil #ifndef _KERNEL
    252  1.1  kamil static void DeserializeFloatOverPointer(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long *pNumber);
    253  1.1  kamil static void DeserializeFloatInlined(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber);
    254  1.1  kamil #endif
    255  1.1  kamil static longest llliGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber);
    256  1.1  kamil static ulongest llluGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber);
    257  1.1  kamil #ifndef _KERNEL
    258  1.1  kamil static void DeserializeNumberFloat(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber);
    259  1.1  kamil #endif
    260  1.1  kamil static void DeserializeNumber(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber);
    261  1.1  kamil static const char *DeserializeTypeCheckKind(uint8_t hhuTypeCheckKind);
    262  1.1  kamil static const char *DeserializeBuiltinCheckKind(uint8_t hhuBuiltinCheckKind);
    263  1.1  kamil static const char *DeserializeCFICheckKind(uint8_t hhuCFICheckKind);
    264  1.1  kamil static bool isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber);
    265  1.1  kamil static bool isShiftExponentTooLarge(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber, size_t zWidth);
    266  1.1  kamil 
    267  1.1  kamil /* Unused in this implementation, emitted by the C++ check dynamic type cast. */
    268  1.1  kamil intptr_t __ubsan_vptr_type_cache[128];
    269  1.1  kamil 
    270  1.1  kamil /* Public symbols used in the instrumentation of the code generation part */
    271  1.1  kamil void __ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
    272  1.1  kamil void __ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
    273  1.1  kamil void __ubsan_handle_builtin_unreachable(struct CUnreachableData *pData);
    274  1.1  kamil void __ubsan_handle_cfi_bad_type(struct CCFICheckFailData *pData, unsigned long ulVtable, bool bValidVtable, bool FromUnrecoverableHandler, unsigned long ProgramCounter, unsigned long FramePointer);
    275  1.1  kamil void __ubsan_handle_cfi_check_fail(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable);
    276  1.1  kamil void __ubsan_handle_cfi_check_fail_abort(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable);
    277  1.1  kamil void __ubsan_handle_divrem_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
    278  1.1  kamil void __ubsan_handle_divrem_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
    279  1.1  kamil void __ubsan_handle_dynamic_type_cache_miss(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash);
    280  1.1  kamil void __ubsan_handle_dynamic_type_cache_miss_abort(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash);
    281  1.1  kamil void __ubsan_handle_float_cast_overflow(struct CFloatCastOverflowData *pData, unsigned long ulFrom);
    282  1.1  kamil void __ubsan_handle_float_cast_overflow_abort(struct CFloatCastOverflowData *pData, unsigned long ulFrom);
    283  1.1  kamil void __ubsan_handle_function_type_mismatch(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction);
    284  1.1  kamil void __ubsan_handle_function_type_mismatch_abort(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction);
    285  1.1  kamil void __ubsan_handle_invalid_builtin(struct CInvalidBuiltinData *pData);
    286  1.1  kamil void __ubsan_handle_invalid_builtin_abort(struct CInvalidBuiltinData *pData);
    287  1.1  kamil void __ubsan_handle_load_invalid_value(struct CInvalidValueData *pData, unsigned long ulVal);
    288  1.1  kamil void __ubsan_handle_load_invalid_value_abort(struct CInvalidValueData *pData, unsigned long ulVal);
    289  1.1  kamil void __ubsan_handle_missing_return(struct CUnreachableData *pData);
    290  1.1  kamil void __ubsan_handle_mul_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
    291  1.1  kamil void __ubsan_handle_mul_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
    292  1.1  kamil void __ubsan_handle_negate_overflow(struct COverflowData *pData, unsigned long ulOldVal);
    293  1.1  kamil void __ubsan_handle_negate_overflow_abort(struct COverflowData *pData, unsigned long ulOldVal);
    294  1.1  kamil void __ubsan_handle_nonnull_arg(struct CNonNullArgData *pData);
    295  1.1  kamil void __ubsan_handle_nonnull_arg_abort(struct CNonNullArgData *pData);
    296  1.1  kamil void __ubsan_handle_nonnull_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
    297  1.1  kamil void __ubsan_handle_nonnull_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
    298  1.1  kamil void __ubsan_handle_nullability_arg(struct CNonNullArgData *pData);
    299  1.1  kamil void __ubsan_handle_nullability_arg_abort(struct CNonNullArgData *pData);
    300  1.1  kamil void __ubsan_handle_nullability_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
    301  1.1  kamil void __ubsan_handle_nullability_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
    302  1.1  kamil void __ubsan_handle_out_of_bounds(struct COutOfBoundsData *pData, unsigned long ulIndex);
    303  1.1  kamil void __ubsan_handle_out_of_bounds_abort(struct COutOfBoundsData *pData, unsigned long ulIndex);
    304  1.1  kamil void __ubsan_handle_pointer_overflow(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult);
    305  1.1  kamil void __ubsan_handle_pointer_overflow_abort(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult);
    306  1.1  kamil void __ubsan_handle_shift_out_of_bounds(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS);
    307  1.1  kamil void __ubsan_handle_shift_out_of_bounds_abort(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS);
    308  1.1  kamil void __ubsan_handle_sub_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
    309  1.1  kamil void __ubsan_handle_sub_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
    310  1.1  kamil void __ubsan_handle_type_mismatch(struct CTypeMismatchData *pData, unsigned long ulPointer);
    311  1.1  kamil void __ubsan_handle_type_mismatch_abort(struct CTypeMismatchData *pData, unsigned long ulPointer);
    312  1.1  kamil void __ubsan_handle_type_mismatch_v1(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer);
    313  1.1  kamil void __ubsan_handle_type_mismatch_v1_abort(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer);
    314  1.1  kamil void __ubsan_handle_vla_bound_not_positive(struct CVLABoundData *pData, unsigned long ulBound);
    315  1.1  kamil void __ubsan_handle_vla_bound_not_positive_abort(struct CVLABoundData *pData, unsigned long ulBound);
    316  1.1  kamil void __ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr);
    317  1.1  kamil 
    318  1.1  kamil static void HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation);
    319  1.1  kamil static void HandleNegateOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulOldValue);
    320  1.1  kamil static void HandleBuiltinUnreachable(bool isFatal, struct CUnreachableData *pData);
    321  1.1  kamil static void HandleTypeMismatch(bool isFatal, struct CSourceLocation *mLocation, struct CTypeDescriptor *mType, unsigned long mLogAlignment, uint8_t mTypeCheckKind, unsigned long ulPointer);
    322  1.1  kamil static void HandleVlaBoundNotPositive(bool isFatal, struct CVLABoundData *pData, unsigned long ulBound);
    323  1.1  kamil static void HandleOutOfBounds(bool isFatal, struct COutOfBoundsData *pData, unsigned long ulIndex);
    324  1.1  kamil static void HandleShiftOutOfBounds(bool isFatal, struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS);
    325  1.1  kamil static void HandleLoadInvalidValue(bool isFatal, struct CInvalidValueData *pData, unsigned long ulValue);
    326  1.1  kamil static void HandleInvalidBuiltin(bool isFatal, struct CInvalidBuiltinData *pData);
    327  1.1  kamil static void HandleFunctionTypeMismatch(bool isFatal, struct CFunctionTypeMismatchData *pData, unsigned long ulFunction);
    328  1.1  kamil static void HandleCFIBadType(bool isFatal, struct CCFICheckFailData *pData, unsigned long ulVtable, bool *bValidVtable, bool *FromUnrecoverableHandler, unsigned long *ProgramCounter, unsigned long *FramePointer);
    329  1.1  kamil static void HandleDynamicTypeCacheMiss(bool isFatal, struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash);
    330  1.1  kamil static void HandleFloatCastOverflow(bool isFatal, struct CFloatCastOverflowData *pData, unsigned long ulFrom);
    331  1.1  kamil static void HandleMissingReturn(bool isFatal, struct CUnreachableData *pData);
    332  1.1  kamil static void HandleNonnullArg(bool isFatal, struct CNonNullArgData *pData);
    333  1.1  kamil static void HandleNonnullReturn(bool isFatal, struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
    334  1.1  kamil static void HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult);
    335  1.1  kamil 
    336  1.1  kamil static void
    337  1.1  kamil HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation)
    338  1.1  kamil {
    339  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    340  1.1  kamil 	char szLHS[NUMBER_MAXLEN];
    341  1.1  kamil 	char szRHS[NUMBER_MAXLEN];
    342  1.1  kamil 
    343  1.1  kamil 	ASSERT(pData);
    344  1.1  kamil 
    345  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    346  1.1  kamil 		return;
    347  1.1  kamil 
    348  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    349  1.1  kamil 	DeserializeNumber(szLocation, szLHS, NUMBER_MAXLEN, pData->mType, ulLHS);
    350  1.1  kamil 	DeserializeNumber(szLocation, szRHS, NUMBER_MAXLEN, pData->mType, ulRHS);
    351  1.1  kamil 
    352  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, %s integer overflow: %s %s %s cannot be represented in type %s\n",
    353  1.1  kamil 	       szLocation, ISSET(pData->mType->mTypeInfo, NUMBER_SIGNED_BIT) ? "signed" : "unsigned", szLHS, szOperation, szRHS, pData->mType->mTypeName);
    354  1.1  kamil }
    355  1.1  kamil 
    356  1.1  kamil static void
    357  1.1  kamil HandleNegateOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulOldValue)
    358  1.1  kamil {
    359  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    360  1.1  kamil 	char szOldValue[NUMBER_MAXLEN];
    361  1.1  kamil 
    362  1.1  kamil 	ASSERT(pData);
    363  1.1  kamil 
    364  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    365  1.1  kamil 		return;
    366  1.1  kamil 
    367  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    368  1.1  kamil 	DeserializeNumber(szLocation, szOldValue, NUMBER_MAXLEN, pData->mType, ulOldValue);
    369  1.1  kamil 
    370  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, negation of %s cannot be represented in type %s\n",
    371  1.1  kamil 	       szLocation, szOldValue, pData->mType->mTypeName);
    372  1.1  kamil }
    373  1.1  kamil 
    374  1.1  kamil static void
    375  1.1  kamil HandleBuiltinUnreachable(bool isFatal, struct CUnreachableData *pData)
    376  1.1  kamil {
    377  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    378  1.1  kamil 
    379  1.1  kamil 	ASSERT(pData);
    380  1.1  kamil 
    381  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    382  1.1  kamil 		return;
    383  1.1  kamil 
    384  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    385  1.1  kamil 
    386  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, calling __builtin_unreachable()\n",
    387  1.1  kamil 	       szLocation);
    388  1.1  kamil }
    389  1.1  kamil 
    390  1.1  kamil static void
    391  1.1  kamil HandleTypeMismatch(bool isFatal, struct CSourceLocation *mLocation, struct CTypeDescriptor *mType, unsigned long mLogAlignment, uint8_t mTypeCheckKind, unsigned long ulPointer)
    392  1.1  kamil {
    393  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    394  1.1  kamil 
    395  1.1  kamil 	ASSERT(mLocation);
    396  1.1  kamil 	ASSERT(mType);
    397  1.1  kamil 
    398  1.1  kamil 	if (isAlreadyReported(mLocation))
    399  1.1  kamil 		return;
    400  1.1  kamil 
    401  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, mLocation);
    402  1.1  kamil 
    403  1.1  kamil 	if (ulPointer == 0) {
    404  1.1  kamil 		Report(isFatal, "UBSan: Undefined Behavior in %s, %s null pointer of type %s\n",
    405  1.1  kamil 		       szLocation, DeserializeTypeCheckKind(mTypeCheckKind), mType->mTypeName);
    406  1.1  kamil 	} else if ((mLogAlignment - 1) & ulPointer) {
    407  1.1  kamil 		Report(isFatal, "UBSan: Undefined Behavior in %s, %s misaligned address %p for type %s which requires %ld byte alignment\n",
    408  1.1  kamil 		       szLocation, DeserializeTypeCheckKind(mTypeCheckKind), REINTERPRET_CAST(void *, ulPointer), mType->mTypeName, mLogAlignment);
    409  1.1  kamil 	} else {
    410  1.1  kamil 		Report(isFatal, "UBSan: Undefined Behavior in %s, %s address %p with insufficient space for an object of type %s\n",
    411  1.1  kamil 		       szLocation, DeserializeTypeCheckKind(mTypeCheckKind), REINTERPRET_CAST(void *, ulPointer), mType->mTypeName);
    412  1.1  kamil 	}
    413  1.1  kamil }
    414  1.1  kamil 
    415  1.1  kamil static void
    416  1.1  kamil HandleVlaBoundNotPositive(bool isFatal, struct CVLABoundData *pData, unsigned long ulBound)
    417  1.1  kamil {
    418  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    419  1.1  kamil 	char szBound[NUMBER_MAXLEN];
    420  1.1  kamil 
    421  1.1  kamil 	ASSERT(pData);
    422  1.1  kamil 
    423  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    424  1.1  kamil 		return;
    425  1.1  kamil 
    426  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    427  1.1  kamil 	DeserializeNumber(szLocation, szBound, NUMBER_MAXLEN, pData->mType, ulBound);
    428  1.1  kamil 
    429  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, variable length array bound value %s <= 0\n",
    430  1.1  kamil 	       szLocation, szBound);
    431  1.1  kamil }
    432  1.1  kamil 
    433  1.1  kamil static void
    434  1.1  kamil HandleOutOfBounds(bool isFatal, struct COutOfBoundsData *pData, unsigned long ulIndex)
    435  1.1  kamil {
    436  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    437  1.1  kamil 	char szIndex[NUMBER_MAXLEN];
    438  1.1  kamil 
    439  1.1  kamil 	ASSERT(pData);
    440  1.1  kamil 
    441  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    442  1.1  kamil 		return;
    443  1.1  kamil 
    444  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    445  1.1  kamil 	DeserializeNumber(szLocation, szIndex, NUMBER_MAXLEN, pData->mIndexType, ulIndex);
    446  1.1  kamil 
    447  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, index %s is out of range for type %s\n",
    448  1.1  kamil 	       szLocation, szIndex, pData->mArrayType->mTypeName);
    449  1.1  kamil }
    450  1.1  kamil 
    451  1.1  kamil static void
    452  1.1  kamil HandleShiftOutOfBounds(bool isFatal, struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
    453  1.1  kamil {
    454  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    455  1.1  kamil 	char szLHS[NUMBER_MAXLEN];
    456  1.1  kamil 	char szRHS[NUMBER_MAXLEN];
    457  1.1  kamil 
    458  1.1  kamil 	ASSERT(pData);
    459  1.1  kamil 
    460  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    461  1.1  kamil 		return;
    462  1.1  kamil 
    463  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    464  1.1  kamil 	DeserializeNumber(szLocation, szLHS, NUMBER_MAXLEN, pData->mLHSType, ulLHS);
    465  1.1  kamil 	DeserializeNumber(szLocation, szRHS, NUMBER_MAXLEN, pData->mRHSType, ulRHS);
    466  1.1  kamil 
    467  1.1  kamil 	if (isNegativeNumber(szLocation, pData->mRHSType, ulRHS))
    468  1.1  kamil 		Report(isFatal, "UBSan: Undefined Behavior in %s, shift exponent %s is negative\n",
    469  1.1  kamil 		       szLocation, szRHS);
    470  1.1  kamil 	else if (isShiftExponentTooLarge(szLocation, pData->mRHSType, ulRHS, zDeserializeTypeWidth(pData->mLHSType)))
    471  1.1  kamil 		Report(isFatal, "UBSan: Undefined Behavior in %s, shift exponent %s is too large for %zu-bit type %s\n",
    472  1.1  kamil 		       szLocation, szRHS, zDeserializeTypeWidth(pData->mLHSType), pData->mLHSType->mTypeName);
    473  1.1  kamil 	else if (isNegativeNumber(szLocation, pData->mLHSType, ulLHS))
    474  1.1  kamil 		Report(isFatal, "UBSan: Undefined Behavior in %s, left shift of negative value %s\n",
    475  1.1  kamil 		       szLocation, szLHS);
    476  1.1  kamil 	else
    477  1.1  kamil 		Report(isFatal, "UBSan: Undefined Behavior in %s, left shift of %s by %s places cannot be represented in type %s\n",
    478  1.1  kamil 		       szLocation, szLHS, szRHS, pData->mLHSType->mTypeName);
    479  1.1  kamil }
    480  1.1  kamil 
    481  1.1  kamil static void
    482  1.1  kamil HandleLoadInvalidValue(bool isFatal, struct CInvalidValueData *pData, unsigned long ulValue)
    483  1.1  kamil {
    484  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    485  1.1  kamil 	char szValue[NUMBER_MAXLEN];
    486  1.1  kamil 
    487  1.1  kamil 	ASSERT(pData);
    488  1.1  kamil 
    489  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    490  1.1  kamil 		return;
    491  1.1  kamil 
    492  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    493  1.1  kamil 	DeserializeNumber(szLocation, szValue, NUMBER_MAXLEN, pData->mType, ulValue);
    494  1.1  kamil 
    495  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, load of value %s is not a valid value for type %s\n",
    496  1.1  kamil 	       szLocation, szValue, pData->mType->mTypeName);
    497  1.1  kamil }
    498  1.1  kamil 
    499  1.1  kamil static void
    500  1.1  kamil HandleInvalidBuiltin(bool isFatal, struct CInvalidBuiltinData *pData)
    501  1.1  kamil {
    502  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    503  1.1  kamil 
    504  1.1  kamil 	ASSERT(pData);
    505  1.1  kamil 
    506  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    507  1.1  kamil 		return;
    508  1.1  kamil 
    509  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    510  1.1  kamil 
    511  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, passing zero to %s, which is not a valid argument\n",
    512  1.1  kamil 	       szLocation, DeserializeBuiltinCheckKind(pData->mKind));
    513  1.1  kamil }
    514  1.1  kamil 
    515  1.1  kamil static void
    516  1.1  kamil HandleFunctionTypeMismatch(bool isFatal, struct CFunctionTypeMismatchData *pData, unsigned long ulFunction)
    517  1.1  kamil {
    518  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    519  1.1  kamil 
    520  1.1  kamil 	/*
    521  1.1  kamil 	 * There is no a portable C solution to translate an address of a
    522  1.1  kamil 	 * function to its name. On the cost of getting this routine simple
    523  1.1  kamil 	 * and portable without ifdefs between the userland and the kernel
    524  1.1  kamil 	 * just print the address of the function as-is.
    525  1.1  kamil 	 *
    526  1.1  kamil 	 * For better diagnostic messages in the userland, users shall use
    527  1.1  kamil 	 * the full upstream version shipped along with the compiler toolchain.
    528  1.1  kamil 	 */
    529  1.1  kamil 
    530  1.1  kamil 	ASSERT(pData);
    531  1.1  kamil 
    532  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    533  1.1  kamil 		return;
    534  1.1  kamil 
    535  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    536  1.1  kamil 
    537  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, call to function %#lx through pointer to incorrect function type %s\n",
    538  1.1  kamil 	      szLocation, ulFunction, pData->mType->mTypeName);
    539  1.1  kamil }
    540  1.1  kamil 
    541  1.1  kamil static void
    542  1.1  kamil HandleCFIBadType(bool isFatal, struct CCFICheckFailData *pData, unsigned long ulVtable, bool *bValidVtable, bool *FromUnrecoverableHandler, unsigned long *ProgramCounter, unsigned long *FramePointer)
    543  1.1  kamil {
    544  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    545  1.1  kamil 
    546  1.1  kamil 	/*
    547  1.1  kamil 	 * This is a minimal implementation without diving into C++
    548  1.1  kamil 	 * specifics and (Itanium) ABI deserialization.
    549  1.1  kamil 	 */
    550  1.1  kamil 
    551  1.1  kamil 	ASSERT(pData);
    552  1.1  kamil 
    553  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    554  1.1  kamil 		return;
    555  1.1  kamil 
    556  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    557  1.1  kamil 
    558  1.1  kamil 	if (pData->mCheckKind == CFI_ICALL || pData->mCheckKind == CFI_VMFCALL) {
    559  1.1  kamil 		Report(isFatal, "UBSan: Undefined Behavior in %s, control flow integrity check for type %s failed during %s (vtable address %#lx)\n",
    560  1.1  kamil 		      szLocation, pData->mType->mTypeName, DeserializeCFICheckKind(pData->mCheckKind), ulVtable);
    561  1.1  kamil 	} else {
    562  1.1  kamil 		Report(isFatal || FromUnrecoverableHandler, "UBSan: Undefined Behavior in %s, control flow integrity check for type %s failed during %s (vtable address %#lx; %s vtable; from %s handler; Program Counter %#lx; Frame Pointer %#lx)\n",
    563  1.1  kamil 		      szLocation, pData->mType->mTypeName, DeserializeCFICheckKind(pData->mCheckKind), ulVtable, *bValidVtable ? "valid" : "invalid", *FromUnrecoverableHandler ? "unrecoverable" : "recoverable", *ProgramCounter, *FramePointer);
    564  1.1  kamil 	}
    565  1.1  kamil }
    566  1.1  kamil 
    567  1.1  kamil static void
    568  1.1  kamil HandleDynamicTypeCacheMiss(bool isFatal, struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
    569  1.1  kamil {
    570  1.1  kamil #if 0
    571  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    572  1.1  kamil 
    573  1.1  kamil 	/*
    574  1.1  kamil 	 * Unimplemented.
    575  1.1  kamil 	 *
    576  1.1  kamil 	 * This UBSan handler is special as the check has to be impelemented
    577  1.1  kamil 	 * in an implementation. In order to handle it there is need to
    578  1.1  kamil 	 * introspect into C++ ABI internals (RTTI) and use low-level
    579  1.1  kamil 	 * C++ runtime interfaces.
    580  1.1  kamil 	 */
    581  1.1  kamil 
    582  1.1  kamil 	ASSERT(pData);
    583  1.1  kamil 
    584  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    585  1.1  kamil 		return;
    586  1.1  kamil 
    587  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    588  1.1  kamil 
    589  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, %s address %#lx which might not point to an object of type %s\n"
    590  1.1  kamil 	      szLocation, DeserializeTypeCheckKind(pData->mTypeCheckKind), ulPointer, pData->mType);
    591  1.1  kamil #endif
    592  1.1  kamil }
    593  1.1  kamil 
    594  1.1  kamil static void
    595  1.1  kamil HandleFloatCastOverflow(bool isFatal, struct CFloatCastOverflowData *pData, unsigned long ulFrom)
    596  1.1  kamil {
    597  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    598  1.1  kamil 	char szFrom[NUMBER_MAXLEN];
    599  1.1  kamil 
    600  1.1  kamil 	ASSERT(pData);
    601  1.1  kamil 
    602  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    603  1.1  kamil 		return;
    604  1.1  kamil 
    605  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    606  1.1  kamil 	DeserializeNumber(szLocation, szFrom, NUMBER_MAXLEN, pData->mFromType, ulFrom);
    607  1.1  kamil 
    608  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, %s (of type %s) is outside the range of representable values of type %s\n",
    609  1.1  kamil 	       szLocation, szFrom, pData->mFromType->mTypeName, pData->mToType->mTypeName);
    610  1.1  kamil }
    611  1.1  kamil 
    612  1.1  kamil static void
    613  1.1  kamil HandleMissingReturn(bool isFatal, struct CUnreachableData *pData)
    614  1.1  kamil {
    615  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    616  1.1  kamil 
    617  1.1  kamil 	ASSERT(pData);
    618  1.1  kamil 
    619  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    620  1.1  kamil 		return;
    621  1.1  kamil 
    622  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    623  1.1  kamil 
    624  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, execution reached the end of a value-returning function without returning a value\n",
    625  1.1  kamil 	       szLocation);
    626  1.1  kamil }
    627  1.1  kamil 
    628  1.1  kamil static void
    629  1.1  kamil HandleNonnullArg(bool isFatal, struct CNonNullArgData *pData)
    630  1.1  kamil {
    631  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    632  1.1  kamil 	char szAttributeLocation[LOCATION_MAXLEN];
    633  1.1  kamil 
    634  1.1  kamil 	ASSERT(pData);
    635  1.1  kamil 
    636  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    637  1.1  kamil 		return;
    638  1.1  kamil 
    639  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    640  1.1  kamil 	if (pData->mAttributeLocation.mFilename)
    641  1.1  kamil 		DeserializeLocation(szAttributeLocation, LOCATION_MAXLEN, &pData->mAttributeLocation);
    642  1.1  kamil 	else
    643  1.1  kamil 		szAttributeLocation[0] = '\0';
    644  1.1  kamil 
    645  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, null pointer passed as argument %d, which is declared to never be null%s%s\n",
    646  1.1  kamil 	       szLocation, pData->mArgIndex, pData->mAttributeLocation.mFilename ? ", nonnull/_Nonnull specified in " : "", szAttributeLocation);
    647  1.1  kamil }
    648  1.1  kamil 
    649  1.1  kamil static void
    650  1.1  kamil HandleNonnullReturn(bool isFatal, struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
    651  1.1  kamil {
    652  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    653  1.1  kamil 	char szAttributeLocation[LOCATION_MAXLEN];
    654  1.1  kamil 
    655  1.1  kamil 	ASSERT(pData);
    656  1.1  kamil 	ASSERT(pLocationPointer);
    657  1.1  kamil 
    658  1.1  kamil 	if (isAlreadyReported(pLocationPointer))
    659  1.1  kamil 		return;
    660  1.1  kamil 
    661  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, pLocationPointer);
    662  1.1  kamil 	if (pData->mAttributeLocation.mFilename)
    663  1.1  kamil 		DeserializeLocation(szAttributeLocation, LOCATION_MAXLEN, &pData->mAttributeLocation);
    664  1.1  kamil 	else
    665  1.1  kamil 		szAttributeLocation[0] = '\0';
    666  1.1  kamil 
    667  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, null pointer returned from function declared to never return null%s%s\n",
    668  1.1  kamil 	       szLocation, pData->mAttributeLocation.mFilename ? ", nonnull/_Nonnull specified in " : "", szAttributeLocation);
    669  1.1  kamil }
    670  1.1  kamil 
    671  1.1  kamil static void
    672  1.1  kamil HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
    673  1.1  kamil {
    674  1.1  kamil 	char szLocation[LOCATION_MAXLEN];
    675  1.1  kamil 
    676  1.1  kamil 	ASSERT(pData);
    677  1.1  kamil 
    678  1.1  kamil 	if (isAlreadyReported(&pData->mLocation))
    679  1.1  kamil 		return;
    680  1.1  kamil 
    681  1.1  kamil 	DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
    682  1.1  kamil 
    683  1.1  kamil 	Report(isFatal, "UBSan: Undefined Behavior in %s, pointer expression with base %#lx overflowed to %#lx\n",
    684  1.1  kamil 	       szLocation, ulBase, ulResult);
    685  1.1  kamil }
    686  1.1  kamil 
    687  1.1  kamil /* Definions of public symbols emitted by the instrumentation code */
    688  1.1  kamil void
    689  1.1  kamil __ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
    690  1.1  kamil {
    691  1.1  kamil 
    692  1.1  kamil 	ASSERT(pData);
    693  1.1  kamil 
    694  1.1  kamil 	HandleOverflow(false, pData, ulLHS, ulRHS, PLUS_STRING);
    695  1.1  kamil }
    696  1.1  kamil 
    697  1.1  kamil void
    698  1.1  kamil __ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
    699  1.1  kamil {
    700  1.1  kamil 
    701  1.1  kamil 	ASSERT(pData);
    702  1.1  kamil 
    703  1.1  kamil 	HandleOverflow(true, pData, ulLHS, ulRHS, PLUS_STRING);
    704  1.1  kamil }
    705  1.1  kamil 
    706  1.1  kamil void
    707  1.1  kamil __ubsan_handle_builtin_unreachable(struct CUnreachableData *pData)
    708  1.1  kamil {
    709  1.1  kamil 
    710  1.1  kamil 	ASSERT(pData);
    711  1.1  kamil 
    712  1.1  kamil 	HandleBuiltinUnreachable(true, pData);
    713  1.1  kamil }
    714  1.1  kamil 
    715  1.1  kamil void
    716  1.1  kamil __ubsan_handle_cfi_bad_type(struct CCFICheckFailData *pData, unsigned long ulVtable, bool bValidVtable, bool FromUnrecoverableHandler, unsigned long ProgramCounter, unsigned long FramePointer)
    717  1.1  kamil {
    718  1.1  kamil 
    719  1.1  kamil 	ASSERT(pData);
    720  1.1  kamil 
    721  1.1  kamil 	HandleCFIBadType(false, pData, ulVtable, &bValidVtable, &FromUnrecoverableHandler, &ProgramCounter, &FramePointer);
    722  1.1  kamil }
    723  1.1  kamil 
    724  1.1  kamil void
    725  1.1  kamil __ubsan_handle_cfi_check_fail(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable)
    726  1.1  kamil {
    727  1.1  kamil 
    728  1.1  kamil 	ASSERT(pData);
    729  1.1  kamil 
    730  1.1  kamil 	HandleCFIBadType(false, pData, ulValue, 0, 0, 0, 0);
    731  1.1  kamil }
    732  1.1  kamil 
    733  1.1  kamil void
    734  1.1  kamil __ubsan_handle_cfi_check_fail_abort(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable)
    735  1.1  kamil {
    736  1.1  kamil 
    737  1.1  kamil 	ASSERT(pData);
    738  1.1  kamil 
    739  1.1  kamil 	HandleCFIBadType(true, pData, ulValue, 0, 0, 0, 0);
    740  1.1  kamil }
    741  1.1  kamil 
    742  1.1  kamil void
    743  1.1  kamil __ubsan_handle_divrem_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
    744  1.1  kamil {
    745  1.1  kamil 
    746  1.1  kamil 	ASSERT(pData);
    747  1.1  kamil 
    748  1.1  kamil 	HandleOverflow(false, pData, ulLHS, ulRHS, DIVREM_STRING);
    749  1.1  kamil }
    750  1.1  kamil 
    751  1.1  kamil void
    752  1.1  kamil __ubsan_handle_divrem_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
    753  1.1  kamil {
    754  1.1  kamil 
    755  1.1  kamil 	ASSERT(pData);
    756  1.1  kamil 
    757  1.1  kamil 	HandleOverflow(true, pData, ulLHS, ulRHS, DIVREM_STRING);
    758  1.1  kamil }
    759  1.1  kamil 
    760  1.1  kamil void
    761  1.1  kamil __ubsan_handle_dynamic_type_cache_miss(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
    762  1.1  kamil {
    763  1.1  kamil 
    764  1.1  kamil 	ASSERT(pData);
    765  1.1  kamil 
    766  1.1  kamil 	HandleDynamicTypeCacheMiss(false, pData, ulPointer, ulHash);
    767  1.1  kamil }
    768  1.1  kamil 
    769  1.1  kamil void
    770  1.1  kamil __ubsan_handle_dynamic_type_cache_miss_abort(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
    771  1.1  kamil {
    772  1.1  kamil 
    773  1.1  kamil 	ASSERT(pData);
    774  1.1  kamil 
    775  1.1  kamil 	HandleDynamicTypeCacheMiss(false, pData, ulPointer, ulHash);
    776  1.1  kamil }
    777  1.1  kamil 
    778  1.1  kamil void
    779  1.1  kamil __ubsan_handle_float_cast_overflow(struct CFloatCastOverflowData *pData, unsigned long ulFrom)
    780  1.1  kamil {
    781  1.1  kamil 
    782  1.1  kamil 	ASSERT(pData);
    783  1.1  kamil 
    784  1.1  kamil 	HandleFloatCastOverflow(false, pData, ulFrom);
    785  1.1  kamil }
    786  1.1  kamil 
    787  1.1  kamil void
    788  1.1  kamil __ubsan_handle_float_cast_overflow_abort(struct CFloatCastOverflowData *pData, unsigned long ulFrom)
    789  1.1  kamil {
    790  1.1  kamil 
    791  1.1  kamil 	ASSERT(pData);
    792  1.1  kamil 
    793  1.1  kamil 	HandleFloatCastOverflow(true, pData, ulFrom);
    794  1.1  kamil }
    795  1.1  kamil 
    796  1.1  kamil void
    797  1.1  kamil __ubsan_handle_function_type_mismatch(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction)
    798  1.1  kamil {
    799  1.1  kamil 
    800  1.1  kamil 	ASSERT(pData);
    801  1.1  kamil 
    802  1.1  kamil 	HandleFunctionTypeMismatch(false, pData, ulFunction);
    803  1.1  kamil }
    804  1.1  kamil 
    805  1.1  kamil void
    806  1.1  kamil __ubsan_handle_function_type_mismatch_abort(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction)
    807  1.1  kamil {
    808  1.1  kamil 
    809  1.1  kamil 	ASSERT(pData);
    810  1.1  kamil 
    811  1.1  kamil 	HandleFunctionTypeMismatch(false, pData, ulFunction);
    812  1.1  kamil }
    813  1.1  kamil 
    814  1.1  kamil void
    815  1.1  kamil __ubsan_handle_invalid_builtin(struct CInvalidBuiltinData *pData)
    816  1.1  kamil {
    817  1.1  kamil 
    818  1.1  kamil 	ASSERT(pData);
    819  1.1  kamil 
    820  1.1  kamil 	HandleInvalidBuiltin(true, pData);
    821  1.1  kamil }
    822  1.1  kamil 
    823  1.1  kamil void
    824  1.1  kamil __ubsan_handle_invalid_builtin_abort(struct CInvalidBuiltinData *pData)
    825  1.1  kamil {
    826  1.1  kamil 
    827  1.1  kamil 	ASSERT(pData);
    828  1.1  kamil 
    829  1.1  kamil 	HandleInvalidBuiltin(true, pData);
    830  1.1  kamil }
    831  1.1  kamil 
    832  1.1  kamil void
    833  1.1  kamil __ubsan_handle_load_invalid_value(struct CInvalidValueData *pData, unsigned long ulValue)
    834  1.1  kamil {
    835  1.1  kamil 
    836  1.1  kamil 	ASSERT(pData);
    837  1.1  kamil 
    838  1.1  kamil 	HandleLoadInvalidValue(false, pData, ulValue);
    839  1.1  kamil }
    840  1.1  kamil 
    841  1.1  kamil void
    842  1.1  kamil __ubsan_handle_load_invalid_value_abort(struct CInvalidValueData *pData, unsigned long ulValue)
    843  1.1  kamil {
    844  1.1  kamil 
    845  1.1  kamil 	ASSERT(pData);
    846  1.1  kamil 
    847  1.1  kamil 	HandleLoadInvalidValue(true, pData, ulValue);
    848  1.1  kamil }
    849  1.1  kamil 
    850  1.1  kamil void
    851  1.1  kamil __ubsan_handle_missing_return(struct CUnreachableData *pData)
    852  1.1  kamil {
    853  1.1  kamil 
    854  1.1  kamil 	ASSERT(pData);
    855  1.1  kamil 
    856  1.1  kamil 	HandleMissingReturn(true, pData);
    857  1.1  kamil }
    858  1.1  kamil 
    859  1.1  kamil void
    860  1.1  kamil __ubsan_handle_mul_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
    861  1.1  kamil {
    862  1.1  kamil 
    863  1.1  kamil 	ASSERT(pData);
    864  1.1  kamil 
    865  1.1  kamil 	HandleOverflow(false, pData, ulLHS, ulRHS, MUL_STRING);
    866  1.1  kamil }
    867  1.1  kamil 
    868  1.1  kamil void
    869  1.1  kamil __ubsan_handle_mul_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
    870  1.1  kamil {
    871  1.1  kamil 
    872  1.1  kamil 	ASSERT(pData);
    873  1.1  kamil 
    874  1.1  kamil 	HandleOverflow(true, pData, ulLHS, ulRHS, MUL_STRING);
    875  1.1  kamil }
    876  1.1  kamil 
    877  1.1  kamil void
    878  1.1  kamil __ubsan_handle_negate_overflow(struct COverflowData *pData, unsigned long ulOldValue)
    879  1.1  kamil {
    880  1.1  kamil 
    881  1.1  kamil 	ASSERT(pData);
    882  1.1  kamil 
    883  1.1  kamil 	HandleNegateOverflow(false, pData, ulOldValue);
    884  1.1  kamil }
    885  1.1  kamil 
    886  1.1  kamil void
    887  1.1  kamil __ubsan_handle_negate_overflow_abort(struct COverflowData *pData, unsigned long ulOldValue)
    888  1.1  kamil {
    889  1.1  kamil 
    890  1.1  kamil 	ASSERT(pData);
    891  1.1  kamil 
    892  1.1  kamil 	HandleNegateOverflow(true, pData, ulOldValue);
    893  1.1  kamil }
    894  1.1  kamil 
    895  1.1  kamil void
    896  1.1  kamil __ubsan_handle_nonnull_arg(struct CNonNullArgData *pData)
    897  1.1  kamil {
    898  1.1  kamil 
    899  1.1  kamil 	ASSERT(pData);
    900  1.1  kamil 
    901  1.1  kamil 	HandleNonnullArg(false, pData);
    902  1.1  kamil }
    903  1.1  kamil 
    904  1.1  kamil void
    905  1.1  kamil __ubsan_handle_nonnull_arg_abort(struct CNonNullArgData *pData)
    906  1.1  kamil {
    907  1.1  kamil 
    908  1.1  kamil 	ASSERT(pData);
    909  1.1  kamil 
    910  1.1  kamil 	HandleNonnullArg(true, pData);
    911  1.1  kamil }
    912  1.1  kamil 
    913  1.1  kamil void
    914  1.1  kamil __ubsan_handle_nonnull_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
    915  1.1  kamil {
    916  1.1  kamil 
    917  1.1  kamil 	ASSERT(pData);
    918  1.1  kamil 	ASSERT(pLocationPointer);
    919  1.1  kamil 
    920  1.1  kamil 	HandleNonnullReturn(false, pData, pLocationPointer);
    921  1.1  kamil }
    922  1.1  kamil 
    923  1.1  kamil void
    924  1.1  kamil __ubsan_handle_nonnull_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
    925  1.1  kamil {
    926  1.1  kamil 
    927  1.1  kamil 	ASSERT(pData);
    928  1.1  kamil 	ASSERT(pLocationPointer);
    929  1.1  kamil 
    930  1.1  kamil 	HandleNonnullReturn(true, pData, pLocationPointer);
    931  1.1  kamil }
    932  1.1  kamil 
    933  1.1  kamil void
    934  1.1  kamil __ubsan_handle_nullability_arg(struct CNonNullArgData *pData)
    935  1.1  kamil {
    936  1.1  kamil 
    937  1.1  kamil 	ASSERT(pData);
    938  1.1  kamil 
    939  1.1  kamil 	HandleNonnullArg(false, pData);
    940  1.1  kamil }
    941  1.1  kamil 
    942  1.1  kamil void
    943  1.1  kamil __ubsan_handle_nullability_arg_abort(struct CNonNullArgData *pData)
    944  1.1  kamil {
    945  1.1  kamil 
    946  1.1  kamil 	ASSERT(pData);
    947  1.1  kamil 
    948  1.1  kamil 	HandleNonnullArg(true, pData);
    949  1.1  kamil }
    950  1.1  kamil 
    951  1.1  kamil void
    952  1.1  kamil __ubsan_handle_nullability_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
    953  1.1  kamil {
    954  1.1  kamil 
    955  1.1  kamil 	ASSERT(pData);
    956  1.1  kamil 	ASSERT(pLocationPointer);
    957  1.1  kamil 
    958  1.1  kamil 	HandleNonnullReturn(false, pData, pLocationPointer);
    959  1.1  kamil }
    960  1.1  kamil 
    961  1.1  kamil void
    962  1.1  kamil __ubsan_handle_nullability_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
    963  1.1  kamil {
    964  1.1  kamil 
    965  1.1  kamil 	ASSERT(pData);
    966  1.1  kamil 	ASSERT(pLocationPointer);
    967  1.1  kamil 
    968  1.1  kamil 	HandleNonnullReturn(true, pData, pLocationPointer);
    969  1.1  kamil }
    970  1.1  kamil 
    971  1.1  kamil void
    972  1.1  kamil __ubsan_handle_out_of_bounds(struct COutOfBoundsData *pData, unsigned long ulIndex)
    973  1.1  kamil {
    974  1.1  kamil 
    975  1.1  kamil 	ASSERT(pData);
    976  1.1  kamil 
    977  1.1  kamil 	HandleOutOfBounds(false, pData, ulIndex);
    978  1.1  kamil }
    979  1.1  kamil 
    980  1.1  kamil void
    981  1.1  kamil __ubsan_handle_out_of_bounds_abort(struct COutOfBoundsData *pData, unsigned long ulIndex)
    982  1.1  kamil {
    983  1.1  kamil 
    984  1.1  kamil 	ASSERT(pData);
    985  1.1  kamil 
    986  1.1  kamil 	HandleOutOfBounds(true, pData, ulIndex);
    987  1.1  kamil }
    988  1.1  kamil 
    989  1.1  kamil void
    990  1.1  kamil __ubsan_handle_pointer_overflow(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
    991  1.1  kamil {
    992  1.1  kamil 
    993  1.1  kamil 	ASSERT(pData);
    994  1.1  kamil 
    995  1.1  kamil 	HandlePointerOverflow(false, pData, ulBase, ulResult);
    996  1.1  kamil }
    997  1.1  kamil 
    998  1.1  kamil void
    999  1.1  kamil __ubsan_handle_pointer_overflow_abort(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
   1000  1.1  kamil {
   1001  1.1  kamil 
   1002  1.1  kamil 	ASSERT(pData);
   1003  1.1  kamil 
   1004  1.1  kamil 	HandlePointerOverflow(true, pData, ulBase, ulResult);
   1005  1.1  kamil }
   1006  1.1  kamil 
   1007  1.1  kamil void
   1008  1.1  kamil __ubsan_handle_shift_out_of_bounds(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
   1009  1.1  kamil {
   1010  1.1  kamil 
   1011  1.1  kamil 	ASSERT(pData);
   1012  1.1  kamil 
   1013  1.1  kamil 	HandleShiftOutOfBounds(false, pData, ulLHS, ulRHS);
   1014  1.1  kamil }
   1015  1.1  kamil 
   1016  1.1  kamil void
   1017  1.1  kamil __ubsan_handle_shift_out_of_bounds_abort(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
   1018  1.1  kamil {
   1019  1.1  kamil 
   1020  1.1  kamil 	ASSERT(pData);
   1021  1.1  kamil 
   1022  1.1  kamil 	HandleShiftOutOfBounds(true, pData, ulLHS, ulRHS);
   1023  1.1  kamil }
   1024  1.1  kamil 
   1025  1.1  kamil void
   1026  1.1  kamil __ubsan_handle_sub_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
   1027  1.1  kamil {
   1028  1.1  kamil 
   1029  1.1  kamil 	ASSERT(pData);
   1030  1.1  kamil 
   1031  1.1  kamil 	HandleOverflow(false, pData, ulLHS, ulRHS, MINUS_STRING);
   1032  1.1  kamil }
   1033  1.1  kamil 
   1034  1.1  kamil void
   1035  1.1  kamil __ubsan_handle_sub_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
   1036  1.1  kamil {
   1037  1.1  kamil 
   1038  1.1  kamil 	ASSERT(pData);
   1039  1.1  kamil 
   1040  1.1  kamil 	HandleOverflow(true, pData, ulLHS, ulRHS, MINUS_STRING);
   1041  1.1  kamil }
   1042  1.1  kamil 
   1043  1.1  kamil void
   1044  1.1  kamil __ubsan_handle_type_mismatch(struct CTypeMismatchData *pData, unsigned long ulPointer)
   1045  1.1  kamil {
   1046  1.1  kamil 
   1047  1.1  kamil 	ASSERT(pData);
   1048  1.1  kamil 
   1049  1.1  kamil 	HandleTypeMismatch(false, &pData->mLocation, pData->mType, pData->mLogAlignment, pData->mTypeCheckKind, ulPointer);
   1050  1.1  kamil }
   1051  1.1  kamil 
   1052  1.1  kamil void
   1053  1.1  kamil __ubsan_handle_type_mismatch_abort(struct CTypeMismatchData *pData, unsigned long ulPointer)
   1054  1.1  kamil {
   1055  1.1  kamil 
   1056  1.1  kamil 	ASSERT(pData);
   1057  1.1  kamil 
   1058  1.1  kamil 	HandleTypeMismatch(true, &pData->mLocation, pData->mType, pData->mLogAlignment, pData->mTypeCheckKind, ulPointer);
   1059  1.1  kamil }
   1060  1.1  kamil 
   1061  1.1  kamil void
   1062  1.1  kamil __ubsan_handle_type_mismatch_v1(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer)
   1063  1.1  kamil {
   1064  1.1  kamil 
   1065  1.1  kamil 	ASSERT(pData);
   1066  1.1  kamil 
   1067  1.1  kamil 	HandleTypeMismatch(false, &pData->mLocation, pData->mType, __BIT(pData->mLogAlignment), pData->mTypeCheckKind, ulPointer);
   1068  1.1  kamil }
   1069  1.1  kamil 
   1070  1.1  kamil void
   1071  1.1  kamil __ubsan_handle_type_mismatch_v1_abort(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer)
   1072  1.1  kamil {
   1073  1.1  kamil 
   1074  1.1  kamil 	ASSERT(pData);
   1075  1.1  kamil 
   1076  1.1  kamil 	HandleTypeMismatch(true, &pData->mLocation, pData->mType, __BIT(pData->mLogAlignment), pData->mTypeCheckKind, ulPointer);
   1077  1.1  kamil }
   1078  1.1  kamil 
   1079  1.1  kamil void
   1080  1.1  kamil __ubsan_handle_vla_bound_not_positive(struct CVLABoundData *pData, unsigned long ulBound)
   1081  1.1  kamil {
   1082  1.1  kamil 
   1083  1.1  kamil 	ASSERT(pData);
   1084  1.1  kamil 
   1085  1.1  kamil 	HandleVlaBoundNotPositive(false, pData, ulBound);
   1086  1.1  kamil }
   1087  1.1  kamil 
   1088  1.1  kamil void
   1089  1.1  kamil __ubsan_handle_vla_bound_not_positive_abort(struct CVLABoundData *pData, unsigned long ulBound)
   1090  1.1  kamil {
   1091  1.1  kamil 
   1092  1.1  kamil 	ASSERT(pData);
   1093  1.1  kamil 
   1094  1.1  kamil 	HandleVlaBoundNotPositive(true, pData, ulBound);
   1095  1.1  kamil }
   1096  1.1  kamil 
   1097  1.1  kamil void
   1098  1.1  kamil __ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr)
   1099  1.1  kamil {
   1100  1.1  kamil 	/*
   1101  1.1  kamil 	 * Unimplemented.
   1102  1.1  kamil 	 *
   1103  1.1  kamil 	 * The __ubsan_on_report() feature is non trivial to implement in a
   1104  1.1  kamil 	 * shared code between the kernel and userland. It's also opening
   1105  1.1  kamil 	 * new sets of potential problems as we are not expected to slow down
   1106  1.1  kamil 	 * execution of certain kernel subsystems (synchronization issues,
   1107  1.1  kamil 	 * interrupt handling etc).
   1108  1.1  kamil 	 *
   1109  1.1  kamil 	 * A proper solution would need probably a lock-free bounded queue built
   1110  1.1  kamil 	 * with atomic operations with the property of miltiple consumers and
   1111  1.1  kamil 	 * multiple producers. Maintaining and validating such code is not
   1112  1.1  kamil 	 * worth the effort.
   1113  1.1  kamil 	 *
   1114  1.1  kamil 	 * A legitimate user - besides testing framework - is a debugger plugin
   1115  1.1  kamil 	 * intercepting reports from the UBSan instrumentation. For such
   1116  1.1  kamil 	 * scenarios it is better to run the Clang/GCC version.
   1117  1.1  kamil 	 */
   1118  1.1  kamil }
   1119  1.1  kamil 
   1120  1.1  kamil /* Local utility functions */
   1121  1.1  kamil 
   1122  1.1  kamil static void
   1123  1.1  kamil Report(bool isFatal, const char *pFormat, ...)
   1124  1.1  kamil {
   1125  1.1  kamil 	va_list ap;
   1126  1.1  kamil 
   1127  1.1  kamil 	ASSERT(pFormat);
   1128  1.1  kamil 
   1129  1.1  kamil 	va_start(ap, pFormat);
   1130  1.1  kamil #if defined(_KERNEL)
   1131  1.6  kamil 	if (isFatal || alwaysFatal)
   1132  1.1  kamil 		vpanic(pFormat, ap);
   1133  1.1  kamil 	else
   1134  1.1  kamil 		vprintf(pFormat, ap);
   1135  1.1  kamil #else
   1136  1.1  kamil 	if (ubsan_flags == -1) {
   1137  1.1  kamil 		char buf[1024];
   1138  1.1  kamil 		char *p;
   1139  1.1  kamil 
   1140  1.1  kamil 		ubsan_flags = UBSAN_STDERR;
   1141  1.1  kamil 
   1142  1.1  kamil 		if (getenv_r("LIBC_UBSAN", buf, sizeof(buf)) != -1) {
   1143  1.1  kamil 			for (p = buf; *p; p++) {
   1144  1.1  kamil 				switch (*p) {
   1145  1.1  kamil 				case 'a':
   1146  1.1  kamil 					SET(ubsan_flags, UBSAN_ABORT);
   1147  1.1  kamil 					break;
   1148  1.1  kamil 				case 'A':
   1149  1.1  kamil 					CLR(ubsan_flags, UBSAN_ABORT);
   1150  1.1  kamil 					break;
   1151  1.1  kamil 				case 'e':
   1152  1.1  kamil 					SET(ubsan_flags, UBSAN_STDERR);
   1153  1.1  kamil 					break;
   1154  1.1  kamil 				case 'E':
   1155  1.1  kamil 					CLR(ubsan_flags, UBSAN_STDERR);
   1156  1.1  kamil 					break;
   1157  1.1  kamil 				case 'l':
   1158  1.1  kamil 					SET(ubsan_flags, UBSAN_SYSLOG);
   1159  1.1  kamil 					break;
   1160  1.1  kamil 				case 'L':
   1161  1.1  kamil 					CLR(ubsan_flags, UBSAN_SYSLOG);
   1162  1.1  kamil 					break;
   1163  1.1  kamil 				case 'o':
   1164  1.1  kamil 					SET(ubsan_flags, UBSAN_STDOUT);
   1165  1.1  kamil 					break;
   1166  1.1  kamil 				case 'O':
   1167  1.1  kamil 					CLR(ubsan_flags, UBSAN_STDOUT);
   1168  1.1  kamil 					break;
   1169  1.1  kamil 				default:
   1170  1.1  kamil 					break;
   1171  1.1  kamil 				}
   1172  1.1  kamil 			}
   1173  1.1  kamil 		}
   1174  1.1  kamil 	}
   1175  1.1  kamil 
   1176  1.1  kamil 	// The *v*print* functions can flush the va_list argument.
   1177  1.1  kamil 	// Create a local copy for each call to prevent invalid read.
   1178  1.1  kamil 	if (ISSET(ubsan_flags, UBSAN_STDOUT)) {
   1179  1.1  kamil 		va_list tmp;
   1180  1.1  kamil 		va_copy(tmp, ap);
   1181  1.1  kamil 		vprintf(pFormat, tmp);
   1182  1.1  kamil 		va_end(tmp);
   1183  1.1  kamil 		fflush(stdout);
   1184  1.1  kamil 	}
   1185  1.1  kamil 	if (ISSET(ubsan_flags, UBSAN_STDERR)) {
   1186  1.1  kamil 		va_list tmp;
   1187  1.1  kamil 		va_copy(tmp, ap);
   1188  1.1  kamil 		vfprintf(stderr, pFormat, tmp);
   1189  1.1  kamil 		va_end(tmp);
   1190  1.1  kamil 		fflush(stderr);
   1191  1.1  kamil 	}
   1192  1.1  kamil 	if (ISSET(ubsan_flags, UBSAN_SYSLOG)) {
   1193  1.1  kamil 		va_list tmp;
   1194  1.1  kamil 		va_copy(tmp, ap);
   1195  1.1  kamil 		struct syslog_data SyslogData = SYSLOG_DATA_INIT;
   1196  1.1  kamil 		ubsan_vsyslog(LOG_DEBUG | LOG_USER, &SyslogData, pFormat, tmp);
   1197  1.1  kamil 		va_end(tmp);
   1198  1.1  kamil 	}
   1199  1.6  kamil 	if (isFatal || alwaysFatal || ISSET(ubsan_flags, UBSAN_ABORT)) {
   1200  1.1  kamil 		abort();
   1201  1.5  kamil 		__unreachable();
   1202  1.1  kamil 		/* NOTREACHED */
   1203  1.1  kamil 	}
   1204  1.1  kamil #endif
   1205  1.1  kamil 	va_end(ap);
   1206  1.1  kamil }
   1207  1.1  kamil 
   1208  1.1  kamil static bool
   1209  1.1  kamil isAlreadyReported(struct CSourceLocation *pLocation)
   1210  1.1  kamil {
   1211  1.1  kamil 	/*
   1212  1.1  kamil 	 * This code is shared between libc, kernel and standalone usage.
   1213  1.1  kamil 	 * It shall work in early bootstrap phase of both of them.
   1214  1.1  kamil 	 */
   1215  1.1  kamil 
   1216  1.1  kamil 	uint32_t siOldValue;
   1217  1.1  kamil 	volatile uint32_t *pLine;
   1218  1.1  kamil 
   1219  1.1  kamil 	ASSERT(pLocation);
   1220  1.1  kamil 
   1221  1.1  kamil 	pLine = &pLocation->mLine;
   1222  1.1  kamil 
   1223  1.1  kamil 	do {
   1224  1.1  kamil 		siOldValue = *pLine;
   1225  1.1  kamil 	} while (__sync_val_compare_and_swap(pLine, siOldValue, siOldValue | ACK_REPORTED) != siOldValue);
   1226  1.1  kamil 
   1227  1.1  kamil 	return ISSET(siOldValue, ACK_REPORTED);
   1228  1.1  kamil }
   1229  1.1  kamil 
   1230  1.1  kamil static size_t
   1231  1.1  kamil zDeserializeTypeWidth(struct CTypeDescriptor *pType)
   1232  1.1  kamil {
   1233  1.1  kamil 	size_t zWidth = 0;
   1234  1.1  kamil 
   1235  1.1  kamil 	ASSERT(pType);
   1236  1.1  kamil 
   1237  1.1  kamil 	switch (pType->mTypeKind) {
   1238  1.1  kamil 	case KIND_INTEGER:
   1239  1.1  kamil 		zWidth = __BIT(__SHIFTOUT(pType->mTypeInfo, ~NUMBER_SIGNED_BIT));
   1240  1.1  kamil 		break;
   1241  1.1  kamil 	case KIND_FLOAT:
   1242  1.1  kamil 		zWidth = pType->mTypeInfo;
   1243  1.1  kamil 		break;
   1244  1.1  kamil 	default:
   1245  1.1  kamil 		Report(true, "UBSan: Unknown variable type %#04" PRIx16 "\n", pType->mTypeKind);
   1246  1.4    mrg 		__unreachable();
   1247  1.1  kamil 		/* NOTREACHED */
   1248  1.1  kamil 	}
   1249  1.1  kamil 
   1250  1.1  kamil 	/* Invalid width will be transformed to 0 */
   1251  1.1  kamil 	ASSERT(zWidth > 0);
   1252  1.1  kamil 
   1253  1.1  kamil 	return zWidth;
   1254  1.1  kamil }
   1255  1.1  kamil 
   1256  1.1  kamil static void
   1257  1.1  kamil DeserializeLocation(char *pBuffer, size_t zBUfferLength, struct CSourceLocation *pLocation)
   1258  1.1  kamil {
   1259  1.1  kamil 
   1260  1.1  kamil 	ASSERT(pLocation);
   1261  1.1  kamil 	ASSERT(pLocation->mFilename);
   1262  1.1  kamil 
   1263  1.1  kamil 	snprintf(pBuffer, zBUfferLength, "%s:%" PRIu32 ":%" PRIu32, pLocation->mFilename, pLocation->mLine & (uint32_t)~ACK_REPORTED, pLocation->mColumn);
   1264  1.1  kamil }
   1265  1.1  kamil 
   1266  1.1  kamil #ifdef __SIZEOF_INT128__
   1267  1.1  kamil static void
   1268  1.1  kamil DeserializeUINT128(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, __uint128_t U128)
   1269  1.1  kamil {
   1270  1.1  kamil 	char szBuf[3]; /* 'XX\0' */
   1271  1.1  kamil 	char rgNumber[sizeof(ulongest)];
   1272  1.1  kamil 	ssize_t zI;
   1273  1.1  kamil 
   1274  1.1  kamil 	memcpy(rgNumber, &U128, sizeof(U128));
   1275  1.1  kamil 
   1276  1.1  kamil 	strlcpy(pBuffer, "Undecoded-128-bit-Integer-Type (0x", zBUfferLength);
   1277  1.1  kamil #if BYTE_ORDER == LITTLE_ENDIAN
   1278  1.1  kamil 	for (zI = sizeof(ulongest) - 1; zI >= 0; zI--) {
   1279  1.1  kamil #else
   1280  1.3  kamil 	for (zI = 0; zI < (ssize_t)sizeof(ulongest); zI++) {
   1281  1.1  kamil #endif
   1282  1.1  kamil 		snprintf(szBuf, sizeof(szBuf), "%02" PRIx8, rgNumber[zI]);
   1283  1.1  kamil 		strlcat(pBuffer, szBuf, zBUfferLength);
   1284  1.1  kamil 	}
   1285  1.1  kamil 	strlcat(pBuffer, ")", zBUfferLength);
   1286  1.1  kamil }
   1287  1.1  kamil #endif
   1288  1.1  kamil 
   1289  1.1  kamil static void
   1290  1.1  kamil DeserializeNumberSigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, longest L)
   1291  1.1  kamil {
   1292  1.1  kamil 
   1293  1.1  kamil 	ASSERT(pBuffer);
   1294  1.1  kamil 	ASSERT(zBUfferLength > 0);
   1295  1.1  kamil 	ASSERT(pType);
   1296  1.1  kamil 	ASSERT(ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT));
   1297  1.1  kamil 
   1298  1.1  kamil 	switch (zDeserializeTypeWidth(pType)) {
   1299  1.1  kamil 	default:
   1300  1.1  kamil 		ASSERT(0 && "Invalid codepath");
   1301  1.5  kamil 		__unreachable();
   1302  1.1  kamil 		/* NOTREACHED */
   1303  1.1  kamil #ifdef __SIZEOF_INT128__
   1304  1.1  kamil 	case WIDTH_128:
   1305  1.1  kamil 		DeserializeUINT128(pBuffer, zBUfferLength, pType, STATIC_CAST(__uint128_t, L));
   1306  1.1  kamil 		break;
   1307  1.1  kamil #endif
   1308  1.1  kamil 	case WIDTH_64:
   1309  1.5  kamil 		/* FALLTHROUGH */
   1310  1.1  kamil 	case WIDTH_32:
   1311  1.5  kamil 		/* FALLTHROUGH */
   1312  1.1  kamil 	case WIDTH_16:
   1313  1.5  kamil 		/* FALLTHROUGH */
   1314  1.1  kamil 	case WIDTH_8:
   1315  1.1  kamil 		snprintf(pBuffer, zBUfferLength, "%" PRId64, STATIC_CAST(int64_t, L));
   1316  1.1  kamil 		break;
   1317  1.1  kamil 	}
   1318  1.1  kamil }
   1319  1.1  kamil 
   1320  1.1  kamil static void
   1321  1.1  kamil DeserializeNumberUnsigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, ulongest L)
   1322  1.1  kamil {
   1323  1.1  kamil 
   1324  1.1  kamil 	ASSERT(pBuffer);
   1325  1.1  kamil 	ASSERT(zBUfferLength > 0);
   1326  1.1  kamil 	ASSERT(pType);
   1327  1.1  kamil 	ASSERT(!ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT));
   1328  1.1  kamil 
   1329  1.1  kamil 	switch (zDeserializeTypeWidth(pType)) {
   1330  1.1  kamil 	default:
   1331  1.1  kamil 		ASSERT(0 && "Invalid codepath");
   1332  1.5  kamil 		__unreachable();
   1333  1.1  kamil 		/* NOTREACHED */
   1334  1.1  kamil #ifdef __SIZEOF_INT128__
   1335  1.1  kamil 	case WIDTH_128:
   1336  1.1  kamil 		DeserializeUINT128(pBuffer, zBUfferLength, pType, STATIC_CAST(__uint128_t, L));
   1337  1.1  kamil 		break;
   1338  1.1  kamil #endif
   1339  1.1  kamil 	case WIDTH_64:
   1340  1.5  kamil 		/* FALLTHROUGH */
   1341  1.1  kamil 	case WIDTH_32:
   1342  1.5  kamil 		/* FALLTHROUGH */
   1343  1.1  kamil 	case WIDTH_16:
   1344  1.5  kamil 		/* FALLTHROUGH */
   1345  1.1  kamil 	case WIDTH_8:
   1346  1.1  kamil 		snprintf(pBuffer, zBUfferLength, "%" PRIu64, STATIC_CAST(uint64_t, L));
   1347  1.1  kamil 		break;
   1348  1.1  kamil 	}
   1349  1.1  kamil }
   1350  1.1  kamil 
   1351  1.1  kamil #ifndef _KERNEL
   1352  1.1  kamil static void
   1353  1.1  kamil DeserializeFloatOverPointer(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long *pNumber)
   1354  1.1  kamil {
   1355  1.1  kamil 	double D;
   1356  1.1  kamil #ifdef __HAVE_LONG_DOUBLE
   1357  1.1  kamil 	long double LD;
   1358  1.1  kamil #endif
   1359  1.1  kamil 
   1360  1.1  kamil 	ASSERT(pBuffer);
   1361  1.1  kamil 	ASSERT(zBUfferLength > 0);
   1362  1.1  kamil 	ASSERT(pType);
   1363  1.1  kamil 	ASSERT(pNumber);
   1364  1.1  kamil 	/*
   1365  1.1  kamil 	 * This function handles 64-bit number over a pointer on 32-bit CPUs.
   1366  1.1  kamil 	 */
   1367  1.1  kamil 	ASSERT((sizeof(*pNumber) * CHAR_BIT < WIDTH_64) || (zDeserializeTypeWidth(pType) >= WIDTH_64));
   1368  1.1  kamil 	ASSERT(sizeof(D) == sizeof(uint64_t));
   1369  1.1  kamil #ifdef __HAVE_LONG_DOUBLE
   1370  1.1  kamil 	ASSERT(sizeof(LD) > sizeof(uint64_t));
   1371  1.1  kamil #endif
   1372  1.1  kamil 
   1373  1.1  kamil 	switch (zDeserializeTypeWidth(pType)) {
   1374  1.1  kamil #ifdef __HAVE_LONG_DOUBLE
   1375  1.1  kamil 	case WIDTH_128:
   1376  1.5  kamil 		/* FALLTHROUGH */
   1377  1.1  kamil 	case WIDTH_96:
   1378  1.5  kamil 		/* FALLTHROUGH */
   1379  1.1  kamil 	case WIDTH_80:
   1380  1.1  kamil 		memcpy(&LD, pNumber, sizeof(long double));
   1381  1.1  kamil 		snprintf(pBuffer, zBUfferLength, "%Lg", LD);
   1382  1.1  kamil 		break;
   1383  1.1  kamil #endif
   1384  1.1  kamil 	case WIDTH_64:
   1385  1.1  kamil 		memcpy(&D, pNumber, sizeof(double));
   1386  1.1  kamil 		snprintf(pBuffer, zBUfferLength, "%g", D);
   1387  1.1  kamil 		break;
   1388  1.1  kamil 	}
   1389  1.1  kamil }
   1390  1.1  kamil 
   1391  1.1  kamil static void
   1392  1.1  kamil DeserializeFloatInlined(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber)
   1393  1.1  kamil {
   1394  1.1  kamil 	float F;
   1395  1.1  kamil 	double D;
   1396  1.1  kamil 	uint32_t U32;
   1397  1.1  kamil 
   1398  1.1  kamil 	ASSERT(pBuffer);
   1399  1.1  kamil 	ASSERT(zBUfferLength > 0);
   1400  1.1  kamil 	ASSERT(pType);
   1401  1.1  kamil 	ASSERT(sizeof(F) == sizeof(uint32_t));
   1402  1.1  kamil 	ASSERT(sizeof(D) == sizeof(uint64_t));
   1403  1.1  kamil 
   1404  1.1  kamil 	switch (zDeserializeTypeWidth(pType)) {
   1405  1.1  kamil 	case WIDTH_64:
   1406  1.7    mrg 		ASSERT(sizeof(D) == sizeof(ulNumber));
   1407  1.7    mrg 		memcpy(&D, &ulNumber, sizeof(ulNumber));
   1408  1.1  kamil 		snprintf(pBuffer, zBUfferLength, "%g", D);
   1409  1.1  kamil 		break;
   1410  1.1  kamil 	case WIDTH_32:
   1411  1.1  kamil 		/*
   1412  1.1  kamil 		 * On supported platforms sizeof(float)==sizeof(uint32_t)
   1413  1.1  kamil 		 * unsigned long is either 32 or 64-bit, cast it to 32-bit
   1414  1.1  kamil 		 * value in order to call memcpy(3) in an Endian-aware way.
   1415  1.1  kamil 		 */
   1416  1.1  kamil 		U32 = STATIC_CAST(uint32_t, ulNumber);
   1417  1.1  kamil 		memcpy(&F, &U32, sizeof(float));
   1418  1.1  kamil 		snprintf(pBuffer, zBUfferLength, "%g", F);
   1419  1.1  kamil 		break;
   1420  1.1  kamil 	case WIDTH_16:
   1421  1.1  kamil 		snprintf(pBuffer, zBUfferLength, "Undecoded-16-bit-Floating-Type (%#04" PRIx16 ")", STATIC_CAST(uint16_t, ulNumber));
   1422  1.1  kamil 		break;
   1423  1.1  kamil 	}
   1424  1.1  kamil }
   1425  1.1  kamil #endif
   1426  1.1  kamil 
   1427  1.1  kamil static longest
   1428  1.1  kamil llliGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
   1429  1.1  kamil {
   1430  1.1  kamil 	size_t zNumberWidth;
   1431  1.1  kamil 	longest L = 0;
   1432  1.1  kamil 
   1433  1.1  kamil 	ASSERT(szLocation);
   1434  1.1  kamil 	ASSERT(pType);
   1435  1.1  kamil 
   1436  1.1  kamil 	zNumberWidth = zDeserializeTypeWidth(pType);
   1437  1.1  kamil 	switch (zNumberWidth) {
   1438  1.1  kamil 	default:
   1439  1.1  kamil 		Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation);
   1440  1.4    mrg 		__unreachable();
   1441  1.1  kamil 		/* NOTREACHED */
   1442  1.1  kamil 	case WIDTH_128:
   1443  1.1  kamil #ifdef __SIZEOF_INT128__
   1444  1.1  kamil 		memcpy(&L, REINTERPRET_CAST(longest *, ulNumber), sizeof(longest));
   1445  1.4    mrg 		break;
   1446  1.1  kamil #else
   1447  1.1  kamil 		Report(true, "UBSan: Unexpected 128-Bit Type in %s\n", szLocation);
   1448  1.4    mrg 		__unreachable();
   1449  1.1  kamil 		/* NOTREACHED */
   1450  1.1  kamil #endif
   1451  1.1  kamil 	case WIDTH_64:
   1452  1.1  kamil 		if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) {
   1453  1.1  kamil 			L = *REINTERPRET_CAST(int64_t *, ulNumber);
   1454  1.1  kamil 		} else {
   1455  1.1  kamil 			L = STATIC_CAST(int64_t, STATIC_CAST(uint64_t, ulNumber));
   1456  1.1  kamil 		}
   1457  1.1  kamil 		break;
   1458  1.1  kamil 	case WIDTH_32:
   1459  1.1  kamil 		L = STATIC_CAST(int32_t, STATIC_CAST(uint32_t, ulNumber));
   1460  1.1  kamil 		break;
   1461  1.1  kamil 	case WIDTH_16:
   1462  1.1  kamil 		L = STATIC_CAST(int16_t, STATIC_CAST(uint16_t, ulNumber));
   1463  1.1  kamil 		break;
   1464  1.1  kamil 	case WIDTH_8:
   1465  1.1  kamil 		L = STATIC_CAST(int8_t, STATIC_CAST(uint8_t, ulNumber));
   1466  1.1  kamil 		break;
   1467  1.1  kamil 	}
   1468  1.1  kamil 
   1469  1.1  kamil 	return L;
   1470  1.1  kamil }
   1471  1.1  kamil 
   1472  1.1  kamil static ulongest
   1473  1.1  kamil llluGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
   1474  1.1  kamil {
   1475  1.1  kamil 	size_t zNumberWidth;
   1476  1.1  kamil 	ulongest UL = 0;
   1477  1.1  kamil 
   1478  1.1  kamil 	ASSERT(pType);
   1479  1.1  kamil 
   1480  1.1  kamil 	zNumberWidth = zDeserializeTypeWidth(pType);
   1481  1.1  kamil 	switch (zNumberWidth) {
   1482  1.1  kamil 	default:
   1483  1.1  kamil 		Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation);
   1484  1.4    mrg 		__unreachable();
   1485  1.1  kamil 		/* NOTREACHED */
   1486  1.1  kamil 	case WIDTH_128:
   1487  1.1  kamil #ifdef __SIZEOF_INT128__
   1488  1.1  kamil 		memcpy(&UL, REINTERPRET_CAST(ulongest *, ulNumber), sizeof(ulongest));
   1489  1.1  kamil 		break;
   1490  1.1  kamil #else
   1491  1.1  kamil 		Report(true, "UBSan: Unexpected 128-Bit Type in %s\n", szLocation);
   1492  1.4    mrg 		__unreachable();
   1493  1.1  kamil 		/* NOTREACHED */
   1494  1.1  kamil #endif
   1495  1.1  kamil 	case WIDTH_64:
   1496  1.1  kamil 		if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) {
   1497  1.1  kamil 			UL = *REINTERPRET_CAST(uint64_t *, ulNumber);
   1498  1.1  kamil 			break;
   1499  1.1  kamil 		}
   1500  1.1  kamil 		/* FALLTHROUGH */
   1501  1.1  kamil 	case WIDTH_32:
   1502  1.1  kamil 		/* FALLTHROUGH */
   1503  1.1  kamil 	case WIDTH_16:
   1504  1.1  kamil 		/* FALLTHROUGH */
   1505  1.1  kamil 	case WIDTH_8:
   1506  1.1  kamil 		UL = ulNumber;
   1507  1.1  kamil 		break;
   1508  1.1  kamil 	}
   1509  1.1  kamil 
   1510  1.1  kamil 	return UL;
   1511  1.1  kamil }
   1512  1.1  kamil 
   1513  1.1  kamil #ifndef _KERNEL
   1514  1.1  kamil static void
   1515  1.1  kamil DeserializeNumberFloat(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber)
   1516  1.1  kamil {
   1517  1.1  kamil 	size_t zNumberWidth;
   1518  1.1  kamil 
   1519  1.1  kamil 	ASSERT(szLocation);
   1520  1.1  kamil 	ASSERT(pBuffer);
   1521  1.1  kamil 	ASSERT(zBUfferLength > 0);
   1522  1.1  kamil 	ASSERT(pType);
   1523  1.1  kamil 	ASSERT(pType->mTypeKind == KIND_FLOAT);
   1524  1.1  kamil 
   1525  1.1  kamil 	zNumberWidth = zDeserializeTypeWidth(pType);
   1526  1.1  kamil 	switch (zNumberWidth) {
   1527  1.1  kamil 	default:
   1528  1.1  kamil 		Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation);
   1529  1.4    mrg 		__unreachable();
   1530  1.1  kamil 		/* NOTREACHED */
   1531  1.1  kamil #ifdef __HAVE_LONG_DOUBLE
   1532  1.1  kamil 	case WIDTH_128:
   1533  1.5  kamil 		/* FALLTHROUGH */
   1534  1.1  kamil 	case WIDTH_96:
   1535  1.5  kamil 		/* FALLTHROUGH */
   1536  1.1  kamil 	case WIDTH_80:
   1537  1.1  kamil 		DeserializeFloatOverPointer(pBuffer, zBUfferLength, pType, REINTERPRET_CAST(unsigned long *, ulNumber));
   1538  1.1  kamil 		break;
   1539  1.1  kamil #endif
   1540  1.1  kamil 	case WIDTH_64:
   1541  1.1  kamil 		if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) {
   1542  1.1  kamil 			DeserializeFloatOverPointer(pBuffer, zBUfferLength, pType, REINTERPRET_CAST(unsigned long *, ulNumber));
   1543  1.1  kamil 			break;
   1544  1.1  kamil 		}
   1545  1.4    mrg 		/* FALLTHROUGH */
   1546  1.1  kamil 	case WIDTH_32:
   1547  1.5  kamil 		/* FALLTHROUGH */
   1548  1.1  kamil 	case WIDTH_16:
   1549  1.1  kamil 		DeserializeFloatInlined(pBuffer, zBUfferLength, pType, ulNumber);
   1550  1.1  kamil 		break;
   1551  1.1  kamil 	}
   1552  1.1  kamil }
   1553  1.1  kamil #endif
   1554  1.1  kamil 
   1555  1.1  kamil static void
   1556  1.1  kamil DeserializeNumber(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber)
   1557  1.1  kamil {
   1558  1.1  kamil 
   1559  1.1  kamil 	ASSERT(szLocation);
   1560  1.1  kamil 	ASSERT(pBuffer);
   1561  1.1  kamil 	ASSERT(zBUfferLength > 0);
   1562  1.1  kamil 	ASSERT(pType);
   1563  1.1  kamil 
   1564  1.1  kamil 	switch(pType->mTypeKind) {
   1565  1.1  kamil 	case KIND_INTEGER:
   1566  1.1  kamil 		if (ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT)) {
   1567  1.1  kamil 			longest L = llliGetNumber(szLocation, pType, ulNumber);
   1568  1.1  kamil 			DeserializeNumberSigned(pBuffer, zBUfferLength, pType, L);
   1569  1.1  kamil 		} else {
   1570  1.1  kamil 			ulongest UL = llluGetNumber(szLocation, pType, ulNumber);
   1571  1.1  kamil 			DeserializeNumberUnsigned(pBuffer, zBUfferLength, pType, UL);
   1572  1.1  kamil 		}
   1573  1.1  kamil 		break;
   1574  1.1  kamil 	case KIND_FLOAT:
   1575  1.1  kamil #ifdef _KERNEL
   1576  1.1  kamil 		Report(true, "UBSan: Unexpected Float Type in %s\n", szLocation);
   1577  1.4    mrg 		__unreachable();
   1578  1.1  kamil 		/* NOTREACHED */
   1579  1.1  kamil #else
   1580  1.1  kamil 		DeserializeNumberFloat(szLocation, pBuffer, zBUfferLength, pType, ulNumber);
   1581  1.4    mrg 		break;
   1582  1.1  kamil #endif
   1583  1.1  kamil 	case KIND_UNKNOWN:
   1584  1.1  kamil 		Report(true, "UBSan: Unknown Type in %s\n", szLocation);
   1585  1.4    mrg 		__unreachable();
   1586  1.1  kamil 		/* NOTREACHED */
   1587  1.1  kamil 	}
   1588  1.1  kamil }
   1589  1.1  kamil 
   1590  1.1  kamil static const char *
   1591  1.1  kamil DeserializeTypeCheckKind(uint8_t hhuTypeCheckKind)
   1592  1.1  kamil {
   1593  1.1  kamil 	const char *rgczTypeCheckKinds[] = {
   1594  1.1  kamil 		"load of",
   1595  1.1  kamil 		"store to",
   1596  1.1  kamil 		"reference binding to",
   1597  1.1  kamil 		"member access within",
   1598  1.1  kamil 		"member call on",
   1599  1.1  kamil 		"constructor call on",
   1600  1.1  kamil 		"downcast of",
   1601  1.1  kamil 		"downcast of",
   1602  1.1  kamil 		"upcast of",
   1603  1.1  kamil 		"cast to virtual base of",
   1604  1.1  kamil 		"_Nonnull binding to",
   1605  1.1  kamil 		"dynamic operation on"
   1606  1.1  kamil 	};
   1607  1.1  kamil 
   1608  1.1  kamil 	ASSERT(__arraycount(rgczTypeCheckKinds) > hhuTypeCheckKind);
   1609  1.1  kamil 
   1610  1.1  kamil 	return rgczTypeCheckKinds[hhuTypeCheckKind];
   1611  1.1  kamil }
   1612  1.1  kamil 
   1613  1.1  kamil static const char *
   1614  1.1  kamil DeserializeBuiltinCheckKind(uint8_t hhuBuiltinCheckKind)
   1615  1.1  kamil {
   1616  1.1  kamil 	const char *rgczBuiltinCheckKinds[] = {
   1617  1.1  kamil 		"ctz()",
   1618  1.1  kamil 		"clz()"
   1619  1.1  kamil 	};
   1620  1.1  kamil 
   1621  1.1  kamil 	ASSERT(__arraycount(rgczBuiltinCheckKinds) > hhuBuiltinCheckKind);
   1622  1.1  kamil 
   1623  1.1  kamil 	return rgczBuiltinCheckKinds[hhuBuiltinCheckKind];
   1624  1.1  kamil }
   1625  1.1  kamil 
   1626  1.1  kamil static const char *
   1627  1.1  kamil DeserializeCFICheckKind(uint8_t hhuCFICheckKind)
   1628  1.1  kamil {
   1629  1.1  kamil 	const char *rgczCFICheckKinds[] = {
   1630  1.1  kamil 		"virtual call",					// CFI_VCALL
   1631  1.1  kamil 		"non-virtual call",				// CFI_NVCALL
   1632  1.1  kamil 		"base-to-derived cast",				// CFI_DERIVEDCAST
   1633  1.1  kamil 		"cast to unrelated type",			// CFI_UNRELATEDCAST
   1634  1.1  kamil 		"indirect function call",			// CFI_ICALL
   1635  1.1  kamil 		"non-virtual pointer to member function call",	// CFI_NVMFCALL
   1636  1.1  kamil 		"virtual pointer to member function call",	// CFI_VMFCALL
   1637  1.1  kamil 	};
   1638  1.1  kamil 
   1639  1.1  kamil 	ASSERT(__arraycount(rgczCFICheckKinds) > hhuCFICheckKind);
   1640  1.1  kamil 
   1641  1.1  kamil 	return rgczCFICheckKinds[hhuCFICheckKind];
   1642  1.1  kamil }
   1643  1.1  kamil 
   1644  1.1  kamil static bool
   1645  1.1  kamil isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
   1646  1.1  kamil {
   1647  1.1  kamil 
   1648  1.1  kamil 	ASSERT(szLocation);
   1649  1.1  kamil 	ASSERT(pType);
   1650  1.1  kamil 	ASSERT(pType->mTypeKind == KIND_INTEGER);
   1651  1.1  kamil 
   1652  1.1  kamil 	if (!ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT))
   1653  1.1  kamil 		return false;
   1654  1.1  kamil 
   1655  1.1  kamil 	return llliGetNumber(szLocation, pType, ulNumber) < 0;
   1656  1.1  kamil }
   1657  1.1  kamil 
   1658  1.1  kamil static bool
   1659  1.1  kamil isShiftExponentTooLarge(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber, size_t zWidth)
   1660  1.1  kamil {
   1661  1.1  kamil 
   1662  1.1  kamil 	ASSERT(szLocation);
   1663  1.1  kamil 	ASSERT(pType);
   1664  1.1  kamil 	ASSERT(pType->mTypeKind == KIND_INTEGER);
   1665  1.1  kamil 
   1666  1.1  kamil 	return llluGetNumber(szLocation, pType, ulNumber) >= zWidth;
   1667  1.1  kamil }
   1668