source: mainline/uspace/lib/c/generic/ubsan.c@ 8aea932

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8aea932 was 09ab0a9a, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix vertical spacing with new Ccheck revision.

  • Property mode set to 100644
File size: 5.9 KB
Line 
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
37struct overflow_data {
38 struct source_location loc;
39 struct type_descriptor *type;
40};
41
42struct shift_out_of_bounds_data {
43 struct source_location loc;
44 struct type_descriptor *lhs_type;
45 struct type_descriptor *rhs_type;
46};
47
48struct out_of_bounds_data {
49 struct source_location loc;
50 struct type_descriptor *array_type;
51 struct type_descriptor *index_type;
52};
53
54struct unreachable_data {
55 struct source_location loc;
56};
57
58struct vla_bound_data {
59 struct source_location loc;
60 struct type_descriptor *type;
61};
62
63struct invalid_value_data {
64 struct source_location loc;
65 struct type_descriptor *type;
66};
67
68struct nonnull_arg_data {
69 struct source_location loc;
70};
71
72struct nonnull_return_data {
73 struct source_location loc;
74 struct source_location attr_loc;
75};
76
77/*
78 * When compiling with -fsanitize=undefined the compiler expects functions
79 * with the following signatures. The functions are never called directly,
80 * only when undefined behavior is detected in instrumented code.
81 */
82void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, unsigned long ptr);
83void __ubsan_handle_add_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
84void __ubsan_handle_sub_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
85void __ubsan_handle_mul_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
86void __ubsan_handle_negate_overflow(struct overflow_data *data, unsigned long old_val);
87void __ubsan_handle_divrem_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
88void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data, unsigned long lhs, unsigned long rhs);
89void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data, unsigned long idx);
90void __ubsan_handle_unreachable(struct unreachable_data *data);
91void __ubsan_handle_missing_return(struct unreachable_data *data);
92void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data, unsigned long bound);
93void __ubsan_handle_load_invalid_value(struct invalid_value_data *data, unsigned long val);
94#if __GCC_VERSION < 60000
95void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data, size_t arg_no);
96#else
97void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data);
98#endif
99void __ubsan_handle_nonnull_return(struct nonnull_return_data *data);
100void __ubsan_handle_builtin_unreachable(struct unreachable_data *data);
101
102static void print_loc(const char *func, struct source_location *loc)
103{
104 const char *f = func;
105 const char func_prefix[] = "__ubsan_handle";
106
107 if (!memcmp(f, func_prefix, sizeof(func_prefix) - 1))
108 f += sizeof(func_prefix);
109
110 PRINTF("####### Undefined behavior %s at %s:%" PRIu32 " col %" PRIu32 "\n",
111 f, loc->file_name, loc->line, loc->column);
112}
113
114void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
115 unsigned long ptr)
116{
117 print_loc(__func__, &data->loc);
118 PRINTF("Type: %s, alignment: %lu, type_check_kind: %hhu\n",
119 data->type->type_name, data->alignment, data->type_check_kind);
120 ubsan_panic();
121}
122
123void __ubsan_handle_add_overflow(struct overflow_data *data,
124 unsigned long lhs,
125 unsigned long rhs)
126{
127 print_loc(__func__, &data->loc);
128 ubsan_panic();
129}
130
131void __ubsan_handle_sub_overflow(struct overflow_data *data,
132 unsigned long lhs,
133 unsigned long rhs)
134{
135 print_loc(__func__, &data->loc);
136 ubsan_panic();
137}
138
139void __ubsan_handle_mul_overflow(struct overflow_data *data,
140 unsigned long lhs,
141 unsigned long rhs)
142{
143 print_loc(__func__, &data->loc);
144 ubsan_panic();
145}
146
147void __ubsan_handle_negate_overflow(struct overflow_data *data,
148 unsigned long old_val)
149{
150 print_loc(__func__, &data->loc);
151 ubsan_panic();
152}
153
154void __ubsan_handle_divrem_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_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
163 unsigned long lhs,
164 unsigned long rhs)
165{
166 print_loc(__func__, &data->loc);
167 PRINTF("LHS type: %s, value: %lu, RHS type: %s, value: %lu\n",
168 data->lhs_type->type_name, lhs, data->rhs_type->type_name, rhs);
169 ubsan_panic();
170}
171
172void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
173 unsigned long idx)
174{
175 print_loc(__func__, &data->loc);
176 ubsan_panic();
177}
178
179void __ubsan_handle_unreachable(struct unreachable_data *data)
180{
181 print_loc(__func__, &data->loc);
182 ubsan_panic();
183}
184
185void __ubsan_handle_missing_return(struct unreachable_data *data)
186{
187 print_loc(__func__, &data->loc);
188 ubsan_panic();
189}
190
191void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
192 unsigned long bound)
193{
194 print_loc(__func__, &data->loc);
195 ubsan_panic();
196}
197
198void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
199 unsigned long val)
200{
201 print_loc(__func__, &data->loc);
202 ubsan_panic();
203}
204
205#if __GCC_VERSION < 60000
206void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data, size_t arg_no)
207{
208 print_loc(__func__, &data->loc);
209 ubsan_panic();
210}
211#else
212void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data)
213{
214 print_loc(__func__, &data->loc);
215 ubsan_panic();
216}
217#endif
218
219void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
220{
221 print_loc(__func__, &data->loc);
222 ubsan_panic();
223}
224
225void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
226{
227 print_loc(__func__, &data->loc);
228 ubsan_panic();
229}
Note: See TracBrowser for help on using the repository browser.