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