ubsan.c revision 1.11 1 1.11 andvar /* $NetBSD: ubsan.c,v 1.11 2021/09/19 10:34:06 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.11 andvar __KERNEL_RCSID(0, "$NetBSD: ubsan.c,v 1.11 2021/09/19 10:34:06 andvar Exp $");
42 1.1 kamil #else
43 1.11 andvar __RCSID("$NetBSD: ubsan.c,v 1.11 2021/09/19 10:34:06 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.1 kamil * with atomic operations with the property of miltiple 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