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