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