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