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