source: mainline/uspace/lib/c/generic/ubsan.c@ 1be7bee

Last change on this file since 1be7bee was a4cf312, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 6 years ago

Fix build with -fsanitize=undefined

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[2f7d77c6]1// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright (c) 2016, Linaro Limited
4 */
5
6/* Modified for HelenOS use by Jiří Zárevúcky. */
7
8#include <stdbool.h>
9#include <inttypes.h>
10#include <stdlib.h>
11#include <stddef.h>
12#include <mem.h>
13#include <io/kio.h>
14
15#define PRINTF(...) kio_printf(__VA_ARGS__)
16#define ubsan_panic() abort()
17
18struct source_location {
19 const char *file_name;
20 uint32_t line;
21 uint32_t column;
22};
23
24struct type_descriptor {
25 uint16_t type_kind;
26 uint16_t type_info;
27 char type_name[];
28};
29
30struct type_mismatch_data {
31 struct source_location loc;
32 struct type_descriptor *type;
33 unsigned long alignment;
34 unsigned char type_check_kind;
35};
36
[a4cf312]37struct type_mismatch_data_v1 {
38 struct source_location loc;
39 struct type_descriptor *type;
40 unsigned char log_alignment;
41 unsigned char type_check_kind;
42};
43
[2f7d77c6]44struct overflow_data {
45 struct source_location loc;
46 struct type_descriptor *type;
47};
48
49struct shift_out_of_bounds_data {
50 struct source_location loc;
51 struct type_descriptor *lhs_type;
52 struct type_descriptor *rhs_type;
53};
54
55struct out_of_bounds_data {
56 struct source_location loc;
57 struct type_descriptor *array_type;
58 struct type_descriptor *index_type;
59};
60
61struct unreachable_data {
62 struct source_location loc;
63};
64
65struct vla_bound_data {
66 struct source_location loc;
67 struct type_descriptor *type;
68};
69
70struct invalid_value_data {
71 struct source_location loc;
72 struct type_descriptor *type;
73};
74
75struct nonnull_arg_data {
76 struct source_location loc;
77};
78
79struct nonnull_return_data {
80 struct source_location loc;
81 struct source_location attr_loc;
82};
83
[a4cf312]84struct pointer_overflow_data {
85 struct source_location loc;
86};
87
[2f7d77c6]88/*
89 * When compiling with -fsanitize=undefined the compiler expects functions
90 * with the following signatures. The functions are never called directly,
91 * only when undefined behavior is detected in instrumented code.
92 */
93void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, unsigned long ptr);
[a4cf312]94void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data, unsigned long ptr);
[2f7d77c6]95void __ubsan_handle_add_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
96void __ubsan_handle_sub_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
97void __ubsan_handle_mul_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
98void __ubsan_handle_negate_overflow(struct overflow_data *data, unsigned long old_val);
99void __ubsan_handle_divrem_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
100void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data, unsigned long lhs, unsigned long rhs);
101void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data, unsigned long idx);
102void __ubsan_handle_unreachable(struct unreachable_data *data);
103void __ubsan_handle_missing_return(struct unreachable_data *data);
104void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data, unsigned long bound);
105void __ubsan_handle_load_invalid_value(struct invalid_value_data *data, unsigned long val);
106#if __GCC_VERSION < 60000
107void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data, size_t arg_no);
108#else
109void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data);
110#endif
111void __ubsan_handle_nonnull_return(struct nonnull_return_data *data);
[831aa466]112void __ubsan_handle_builtin_unreachable(struct unreachable_data *data);
[a4cf312]113void __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
114 unsigned long base, unsigned long result);
[2f7d77c6]115
116static void print_loc(const char *func, struct source_location *loc)
117{
118 const char *f = func;
119 const char func_prefix[] = "__ubsan_handle";
120
121 if (!memcmp(f, func_prefix, sizeof(func_prefix) - 1))
122 f += sizeof(func_prefix);
123
[831aa466]124 PRINTF("####### Undefined behavior %s at %s:%" PRIu32 " col %" PRIu32 "\n",
[2f7d77c6]125 f, loc->file_name, loc->line, loc->column);
126}
127
128void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
129 unsigned long ptr)
130{
131 print_loc(__func__, &data->loc);
[831aa466]132 PRINTF("Type: %s, alignment: %lu, type_check_kind: %hhu\n",
133 data->type->type_name, data->alignment, data->type_check_kind);
[2f7d77c6]134 ubsan_panic();
135}
136
[a4cf312]137void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
138 unsigned long ptr)
139{
140 print_loc(__func__, &data->loc);
141 PRINTF("Type: %s, alignment: %hhu, type_check_kind: %hhu\n",
142 data->type->type_name, data->log_alignment, data->type_check_kind);
143 ubsan_panic();
144}
145
[2f7d77c6]146void __ubsan_handle_add_overflow(struct overflow_data *data,
147 unsigned long lhs,
148 unsigned long rhs)
149{
150 print_loc(__func__, &data->loc);
151 ubsan_panic();
152}
153
154void __ubsan_handle_sub_overflow(struct overflow_data *data,
155 unsigned long lhs,
156 unsigned long rhs)
157{
158 print_loc(__func__, &data->loc);
159 ubsan_panic();
160}
161
162void __ubsan_handle_mul_overflow(struct overflow_data *data,
163 unsigned long lhs,
164 unsigned long rhs)
165{
166 print_loc(__func__, &data->loc);
167 ubsan_panic();
168}
169
170void __ubsan_handle_negate_overflow(struct overflow_data *data,
171 unsigned long old_val)
172{
173 print_loc(__func__, &data->loc);
174 ubsan_panic();
175}
176
177void __ubsan_handle_divrem_overflow(struct overflow_data *data,
178 unsigned long lhs,
179 unsigned long rhs)
180{
181 print_loc(__func__, &data->loc);
182 ubsan_panic();
183}
184
185void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
186 unsigned long lhs,
187 unsigned long rhs)
188{
189 print_loc(__func__, &data->loc);
190 PRINTF("LHS type: %s, value: %lu, RHS type: %s, value: %lu\n",
191 data->lhs_type->type_name, lhs, data->rhs_type->type_name, rhs);
192 ubsan_panic();
193}
194
195void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
196 unsigned long idx)
197{
198 print_loc(__func__, &data->loc);
199 ubsan_panic();
200}
201
202void __ubsan_handle_unreachable(struct unreachable_data *data)
203{
204 print_loc(__func__, &data->loc);
205 ubsan_panic();
206}
207
208void __ubsan_handle_missing_return(struct unreachable_data *data)
209{
210 print_loc(__func__, &data->loc);
211 ubsan_panic();
212}
213
214void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
215 unsigned long bound)
216{
217 print_loc(__func__, &data->loc);
218 ubsan_panic();
219}
220
221void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
222 unsigned long val)
223{
224 print_loc(__func__, &data->loc);
225 ubsan_panic();
226}
227
228#if __GCC_VERSION < 60000
229void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data, size_t arg_no)
230{
231 print_loc(__func__, &data->loc);
232 ubsan_panic();
233}
234#else
235void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data)
236{
237 print_loc(__func__, &data->loc);
238 ubsan_panic();
239}
240#endif
241
242void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
243{
244 print_loc(__func__, &data->loc);
245 ubsan_panic();
246}
[831aa466]247
248void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
249{
250 print_loc(__func__, &data->loc);
251 ubsan_panic();
252}
[a4cf312]253
254void __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
255 unsigned long base, unsigned long result)
256{
257 print_loc(__func__, &data->loc);
258 ubsan_panic();
259}
Note: See TracBrowser for help on using the repository browser.