Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
c6d30853 AR |
2 | #ifndef _LIB_UBSAN_H |
3 | #define _LIB_UBSAN_H | |
4 | ||
25b84002 KC |
5 | /* |
6 | * ABI defined by Clang's UBSAN enum SanitizerHandler: | |
7 | * https://github.com/llvm/llvm-project/blob/release/16.x/clang/lib/CodeGen/CodeGenFunction.h#L113 | |
8 | */ | |
9 | enum ubsan_checks { | |
10 | ubsan_add_overflow, | |
11 | ubsan_builtin_unreachable, | |
12 | ubsan_cfi_check_fail, | |
13 | ubsan_divrem_overflow, | |
14 | ubsan_dynamic_type_cache_miss, | |
15 | ubsan_float_cast_overflow, | |
16 | ubsan_function_type_mismatch, | |
17 | ubsan_implicit_conversion, | |
18 | ubsan_invalid_builtin, | |
19 | ubsan_invalid_objc_cast, | |
20 | ubsan_load_invalid_value, | |
21 | ubsan_missing_return, | |
22 | ubsan_mul_overflow, | |
23 | ubsan_negate_overflow, | |
24 | ubsan_nullability_arg, | |
25 | ubsan_nullability_return, | |
26 | ubsan_nonnull_arg, | |
27 | ubsan_nonnull_return, | |
28 | ubsan_out_of_bounds, | |
29 | ubsan_pointer_overflow, | |
30 | ubsan_shift_out_of_bounds, | |
31 | ubsan_sub_overflow, | |
32 | ubsan_type_mismatch, | |
33 | ubsan_alignment_assumption, | |
34 | ubsan_vla_bound_not_positive, | |
35 | }; | |
36 | ||
c6d30853 AR |
37 | enum { |
38 | type_kind_int = 0, | |
39 | type_kind_float = 1, | |
40 | type_unknown = 0xffff | |
41 | }; | |
42 | ||
43 | struct type_descriptor { | |
44 | u16 type_kind; | |
45 | u16 type_info; | |
c2098267 | 46 | char type_name[]; |
c6d30853 AR |
47 | }; |
48 | ||
49 | struct source_location { | |
50 | const char *file_name; | |
51 | union { | |
52 | unsigned long reported; | |
53 | struct { | |
54 | u32 line; | |
55 | u32 column; | |
56 | }; | |
57 | }; | |
58 | }; | |
59 | ||
60 | struct overflow_data { | |
61 | struct source_location location; | |
62 | struct type_descriptor *type; | |
63 | }; | |
64 | ||
ed2b548f KC |
65 | struct implicit_conversion_data { |
66 | struct source_location location; | |
67 | struct type_descriptor *from_type; | |
68 | struct type_descriptor *to_type; | |
69 | unsigned char type_check_kind; | |
70 | }; | |
71 | ||
c6d30853 AR |
72 | struct type_mismatch_data { |
73 | struct source_location location; | |
74 | struct type_descriptor *type; | |
42440c1f AR |
75 | unsigned long alignment; |
76 | unsigned char type_check_kind; | |
77 | }; | |
78 | ||
79 | struct type_mismatch_data_v1 { | |
80 | struct source_location location; | |
81 | struct type_descriptor *type; | |
82 | unsigned char log_alignment; | |
83 | unsigned char type_check_kind; | |
84 | }; | |
85 | ||
86 | struct type_mismatch_data_common { | |
87 | struct source_location *location; | |
88 | struct type_descriptor *type; | |
c6d30853 AR |
89 | unsigned long alignment; |
90 | unsigned char type_check_kind; | |
91 | }; | |
92 | ||
93 | struct nonnull_arg_data { | |
94 | struct source_location location; | |
95 | struct source_location attr_location; | |
96 | int arg_index; | |
97 | }; | |
98 | ||
c6d30853 AR |
99 | struct out_of_bounds_data { |
100 | struct source_location location; | |
101 | struct type_descriptor *array_type; | |
102 | struct type_descriptor *index_type; | |
103 | }; | |
104 | ||
105 | struct shift_out_of_bounds_data { | |
106 | struct source_location location; | |
107 | struct type_descriptor *lhs_type; | |
108 | struct type_descriptor *rhs_type; | |
109 | }; | |
110 | ||
111 | struct unreachable_data { | |
112 | struct source_location location; | |
113 | }; | |
114 | ||
115 | struct invalid_value_data { | |
116 | struct source_location location; | |
117 | struct type_descriptor *type; | |
118 | }; | |
119 | ||
28abcc96 NC |
120 | struct alignment_assumption_data { |
121 | struct source_location location; | |
122 | struct source_location assumption_location; | |
123 | struct type_descriptor *type; | |
124 | }; | |
125 | ||
c12d3362 | 126 | #if defined(CONFIG_ARCH_SUPPORTS_INT128) |
c6d30853 AR |
127 | typedef __int128 s_max; |
128 | typedef unsigned __int128 u_max; | |
129 | #else | |
130 | typedef s64 s_max; | |
131 | typedef u64 u_max; | |
132 | #endif | |
133 | ||
2e431b23 KC |
134 | /* |
135 | * When generating Runtime Calls, Clang doesn't respect the -mregparm=3 | |
136 | * option used on i386: https://github.com/llvm/llvm-project/issues/89670 | |
137 | * Fix this for earlier Clang versions by forcing the calling convention | |
138 | * to use non-register arguments. | |
139 | */ | |
140 | #if defined(CONFIG_X86_32) && \ | |
141 | defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 190000 | |
142 | # define ubsan_linkage asmlinkage | |
143 | #else | |
144 | # define ubsan_linkage | |
145 | #endif | |
146 | ||
147 | void ubsan_linkage __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs); | |
148 | void ubsan_linkage __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs); | |
149 | void ubsan_linkage __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs); | |
150 | void ubsan_linkage __ubsan_handle_negate_overflow(void *_data, void *old_val); | |
151 | void ubsan_linkage __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs); | |
ed2b548f | 152 | void ubsan_linkage __ubsan_handle_implicit_conversion(void *_data, void *lhs, void *rhs); |
2e431b23 KC |
153 | void ubsan_linkage __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr); |
154 | void ubsan_linkage __ubsan_handle_type_mismatch_v1(void *_data, void *ptr); | |
155 | void ubsan_linkage __ubsan_handle_out_of_bounds(void *_data, void *index); | |
156 | void ubsan_linkage __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs); | |
157 | void ubsan_linkage __ubsan_handle_builtin_unreachable(void *_data); | |
158 | void ubsan_linkage __ubsan_handle_load_invalid_value(void *_data, void *val); | |
159 | void ubsan_linkage __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr, | |
160 | unsigned long align, | |
161 | unsigned long offset); | |
26f15e5d | 162 | |
c6d30853 | 163 | #endif |