1 // SPDX-License-Identifier: BSD-2-Clause
3 * Copyright (c) 2016, Linaro Limited
6 /* Modified for HelenOS use by Jiří Zárevúcky. */
15 #define PRINTF(...) kio_printf(__VA_ARGS__)
16 #define ubsan_panic() abort()
18 struct source_location
{
19 const char *file_name
;
24 struct type_descriptor
{
30 struct type_mismatch_data
{
31 struct source_location loc
;
32 struct type_descriptor
*type
;
33 unsigned long alignment
;
34 unsigned char type_check_kind
;
37 struct overflow_data
{
38 struct source_location loc
;
39 struct type_descriptor
*type
;
42 struct shift_out_of_bounds_data
{
43 struct source_location loc
;
44 struct type_descriptor
*lhs_type
;
45 struct type_descriptor
*rhs_type
;
48 struct out_of_bounds_data
{
49 struct source_location loc
;
50 struct type_descriptor
*array_type
;
51 struct type_descriptor
*index_type
;
54 struct unreachable_data
{
55 struct source_location loc
;
58 struct vla_bound_data
{
59 struct source_location loc
;
60 struct type_descriptor
*type
;
63 struct invalid_value_data
{
64 struct source_location loc
;
65 struct type_descriptor
*type
;
68 struct nonnull_arg_data
{
69 struct source_location loc
;
72 struct nonnull_return_data
{
73 struct source_location loc
;
74 struct source_location attr_loc
;
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.
82 void __ubsan_handle_type_mismatch(struct type_mismatch_data
*data
, unsigned long ptr
);
83 void __ubsan_handle_add_overflow(struct overflow_data
*data
, unsigned long lhs
, unsigned long rhs
);
84 void __ubsan_handle_sub_overflow(struct overflow_data
*data
, unsigned long lhs
, unsigned long rhs
);
85 void __ubsan_handle_mul_overflow(struct overflow_data
*data
, unsigned long lhs
, unsigned long rhs
);
86 void __ubsan_handle_negate_overflow(struct overflow_data
*data
, unsigned long old_val
);
87 void __ubsan_handle_divrem_overflow(struct overflow_data
*data
, unsigned long lhs
, unsigned long rhs
);
88 void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data
*data
, unsigned long lhs
, unsigned long rhs
);
89 void __ubsan_handle_out_of_bounds(struct out_of_bounds_data
*data
, unsigned long idx
);
90 void __ubsan_handle_unreachable(struct unreachable_data
*data
);
91 void __ubsan_handle_missing_return(struct unreachable_data
*data
);
92 void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data
*data
, unsigned long bound
);
93 void __ubsan_handle_load_invalid_value(struct invalid_value_data
*data
, unsigned long val
);
94 #if __GCC_VERSION < 60000
95 void __ubsan_handle_nonnull_arg(struct nonnull_arg_data
*data
, size_t arg_no
);
97 void __ubsan_handle_nonnull_arg(struct nonnull_arg_data
*data
);
99 void __ubsan_handle_nonnull_return(struct nonnull_return_data
*data
);
101 static void print_loc(const char *func
, struct source_location
*loc
)
103 const char *f
= func
;
104 const char func_prefix
[] = "__ubsan_handle";
106 if (!memcmp(f
, func_prefix
, sizeof(func_prefix
) - 1))
107 f
+= sizeof(func_prefix
);
109 PRINTF("Undefined behavior %s at %s:%" PRIu32
" col %" PRIu32
"\n",
110 f
, loc
->file_name
, loc
->line
, loc
->column
);
113 void __ubsan_handle_type_mismatch(struct type_mismatch_data
*data
,
116 print_loc(__func__
, &data
->loc
);
120 void __ubsan_handle_add_overflow(struct overflow_data
*data
,
124 print_loc(__func__
, &data
->loc
);
128 void __ubsan_handle_sub_overflow(struct overflow_data
*data
,
132 print_loc(__func__
, &data
->loc
);
136 void __ubsan_handle_mul_overflow(struct overflow_data
*data
,
140 print_loc(__func__
, &data
->loc
);
144 void __ubsan_handle_negate_overflow(struct overflow_data
*data
,
145 unsigned long old_val
)
147 print_loc(__func__
, &data
->loc
);
151 void __ubsan_handle_divrem_overflow(struct overflow_data
*data
,
155 print_loc(__func__
, &data
->loc
);
159 void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data
*data
,
163 print_loc(__func__
, &data
->loc
);
164 PRINTF("LHS type: %s, value: %lu, RHS type: %s, value: %lu\n",
165 data
->lhs_type
->type_name
, lhs
, data
->rhs_type
->type_name
, rhs
);
169 void __ubsan_handle_out_of_bounds(struct out_of_bounds_data
*data
,
172 print_loc(__func__
, &data
->loc
);
176 void __ubsan_handle_unreachable(struct unreachable_data
*data
)
178 print_loc(__func__
, &data
->loc
);
182 void __ubsan_handle_missing_return(struct unreachable_data
*data
)
184 print_loc(__func__
, &data
->loc
);
188 void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data
*data
,
191 print_loc(__func__
, &data
->loc
);
195 void __ubsan_handle_load_invalid_value(struct invalid_value_data
*data
,
198 print_loc(__func__
, &data
->loc
);
202 #if __GCC_VERSION < 60000
203 void __ubsan_handle_nonnull_arg(struct nonnull_arg_data
*data
, size_t arg_no
)
205 print_loc(__func__
, &data
->loc
);
209 void __ubsan_handle_nonnull_arg(struct nonnull_arg_data
*data
)
211 print_loc(__func__
, &data
->loc
);
216 void __ubsan_handle_nonnull_return(struct nonnull_return_data
*data
)
218 print_loc(__func__
, &data
->loc
);