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