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