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