1*1f461979SJustin Chadwell /*
2*1f461979SJustin Chadwell * Copyright (c) 2016, Linaro Limited
3*1f461979SJustin Chadwell * Copyright (c) 2019, ARM Limited. All rights reserved.
4*1f461979SJustin Chadwell *
5*1f461979SJustin Chadwell * SPDX-License-Identifier: BSD-2-Clause
6*1f461979SJustin Chadwell */
7*1f461979SJustin Chadwell
8*1f461979SJustin Chadwell #include <arch_helpers.h>
9*1f461979SJustin Chadwell #include <context.h>
10*1f461979SJustin Chadwell #include <common/debug.h>
11*1f461979SJustin Chadwell #include <plat/common/platform.h>
12*1f461979SJustin Chadwell
13*1f461979SJustin Chadwell struct source_location {
14*1f461979SJustin Chadwell const char *file_name;
15*1f461979SJustin Chadwell uint32_t line;
16*1f461979SJustin Chadwell uint32_t column;
17*1f461979SJustin Chadwell };
18*1f461979SJustin Chadwell
19*1f461979SJustin Chadwell struct type_descriptor {
20*1f461979SJustin Chadwell uint16_t type_kind;
21*1f461979SJustin Chadwell uint16_t type_info;
22*1f461979SJustin Chadwell char type_name[1];
23*1f461979SJustin Chadwell };
24*1f461979SJustin Chadwell
25*1f461979SJustin Chadwell struct type_mismatch_data {
26*1f461979SJustin Chadwell struct source_location loc;
27*1f461979SJustin Chadwell struct type_descriptor *type;
28*1f461979SJustin Chadwell unsigned long alignment;
29*1f461979SJustin Chadwell unsigned char type_check_kind;
30*1f461979SJustin Chadwell };
31*1f461979SJustin Chadwell
32*1f461979SJustin Chadwell struct overflow_data {
33*1f461979SJustin Chadwell struct source_location loc;
34*1f461979SJustin Chadwell struct type_descriptor *type;
35*1f461979SJustin Chadwell };
36*1f461979SJustin Chadwell
37*1f461979SJustin Chadwell struct shift_out_of_bounds_data {
38*1f461979SJustin Chadwell struct source_location loc;
39*1f461979SJustin Chadwell struct type_descriptor *lhs_type;
40*1f461979SJustin Chadwell struct type_descriptor *rhs_type;
41*1f461979SJustin Chadwell };
42*1f461979SJustin Chadwell
43*1f461979SJustin Chadwell struct out_of_bounds_data {
44*1f461979SJustin Chadwell struct source_location loc;
45*1f461979SJustin Chadwell struct type_descriptor *array_type;
46*1f461979SJustin Chadwell struct type_descriptor *index_type;
47*1f461979SJustin Chadwell };
48*1f461979SJustin Chadwell
49*1f461979SJustin Chadwell struct unreachable_data {
50*1f461979SJustin Chadwell struct source_location loc;
51*1f461979SJustin Chadwell };
52*1f461979SJustin Chadwell
53*1f461979SJustin Chadwell struct vla_bound_data {
54*1f461979SJustin Chadwell struct source_location loc;
55*1f461979SJustin Chadwell struct type_descriptor *type;
56*1f461979SJustin Chadwell };
57*1f461979SJustin Chadwell
58*1f461979SJustin Chadwell struct invalid_value_data {
59*1f461979SJustin Chadwell struct source_location loc;
60*1f461979SJustin Chadwell struct type_descriptor *type;
61*1f461979SJustin Chadwell };
62*1f461979SJustin Chadwell
63*1f461979SJustin Chadwell struct nonnull_arg_data {
64*1f461979SJustin Chadwell struct source_location loc;
65*1f461979SJustin Chadwell };
66*1f461979SJustin Chadwell
67*1f461979SJustin Chadwell /*
68*1f461979SJustin Chadwell * When compiling with -fsanitize=undefined the compiler expects functions
69*1f461979SJustin Chadwell * with the following signatures. The functions are never called directly,
70*1f461979SJustin Chadwell * only when undefined behavior is detected in instrumented code.
71*1f461979SJustin Chadwell */
72*1f461979SJustin Chadwell void __ubsan_handle_type_mismatch_abort(struct type_mismatch_data *data,
73*1f461979SJustin Chadwell unsigned long ptr);
74*1f461979SJustin Chadwell void __ubsan_handle_type_mismatch_v1_abort(struct type_mismatch_data *data,
75*1f461979SJustin Chadwell unsigned long ptr);
76*1f461979SJustin Chadwell void __ubsan_handle_add_overflow_abort(struct overflow_data *data,
77*1f461979SJustin Chadwell unsigned long lhs, unsigned long rhs);
78*1f461979SJustin Chadwell void __ubsan_handle_sub_overflow_abort(struct overflow_data *data,
79*1f461979SJustin Chadwell unsigned long lhs, unsigned long rhs);
80*1f461979SJustin Chadwell void __ubsan_handle_mul_overflow_abort(struct overflow_data *data,
81*1f461979SJustin Chadwell unsigned long lhs, unsigned long rhs);
82*1f461979SJustin Chadwell void __ubsan_handle_negate_overflow_abort(struct overflow_data *data,
83*1f461979SJustin Chadwell unsigned long old_val);
84*1f461979SJustin Chadwell void __ubsan_handle_pointer_overflow_abort(struct overflow_data *data,
85*1f461979SJustin Chadwell unsigned long old_val);
86*1f461979SJustin Chadwell void __ubsan_handle_divrem_overflow_abort(struct overflow_data *data,
87*1f461979SJustin Chadwell unsigned long lhs, unsigned long rhs);
88*1f461979SJustin Chadwell void __ubsan_handle_shift_out_of_bounds_abort(struct shift_out_of_bounds_data *data,
89*1f461979SJustin Chadwell unsigned long lhs, unsigned long rhs);
90*1f461979SJustin Chadwell void __ubsan_handle_out_of_bounds_abort(struct out_of_bounds_data *data,
91*1f461979SJustin Chadwell unsigned long idx);
92*1f461979SJustin Chadwell void __ubsan_handle_unreachable_abort(struct unreachable_data *data);
93*1f461979SJustin Chadwell void __ubsan_handle_missing_return_abort(struct unreachable_data *data);
94*1f461979SJustin Chadwell void __ubsan_handle_vla_bound_not_positive_abort(struct vla_bound_data *data,
95*1f461979SJustin Chadwell unsigned long bound);
96*1f461979SJustin Chadwell void __ubsan_handle_load_invalid_value_abort(struct invalid_value_data *data,
97*1f461979SJustin Chadwell unsigned long val);
98*1f461979SJustin Chadwell void __ubsan_handle_nonnull_arg_abort(struct nonnull_arg_data *data
99*1f461979SJustin Chadwell #if __GCC_VERSION < 60000
100*1f461979SJustin Chadwell , size_t arg_no
101*1f461979SJustin Chadwell #endif
102*1f461979SJustin Chadwell );
103*1f461979SJustin Chadwell
print_loc(const char * func,struct source_location * loc)104*1f461979SJustin Chadwell static void print_loc(const char *func, struct source_location *loc)
105*1f461979SJustin Chadwell {
106*1f461979SJustin Chadwell ERROR("Undefined behavior at %s:%d col %d (%s)",
107*1f461979SJustin Chadwell loc->file_name, loc->line, loc->column, func);
108*1f461979SJustin Chadwell }
109*1f461979SJustin Chadwell
110*1f461979SJustin Chadwell
__ubsan_handle_type_mismatch_abort(struct type_mismatch_data * data,unsigned long ptr __unused)111*1f461979SJustin Chadwell void __ubsan_handle_type_mismatch_abort(struct type_mismatch_data *data,
112*1f461979SJustin Chadwell unsigned long ptr __unused)
113*1f461979SJustin Chadwell {
114*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
115*1f461979SJustin Chadwell plat_panic_handler();
116*1f461979SJustin Chadwell }
117*1f461979SJustin Chadwell
__ubsan_handle_type_mismatch_v1_abort(struct type_mismatch_data * data,unsigned long ptr __unused)118*1f461979SJustin Chadwell void __ubsan_handle_type_mismatch_v1_abort(struct type_mismatch_data *data,
119*1f461979SJustin Chadwell unsigned long ptr __unused)
120*1f461979SJustin Chadwell {
121*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
122*1f461979SJustin Chadwell plat_panic_handler();
123*1f461979SJustin Chadwell }
124*1f461979SJustin Chadwell
__ubsan_handle_add_overflow_abort(struct overflow_data * data,unsigned long lhs __unused,unsigned long rhs __unused)125*1f461979SJustin Chadwell void __ubsan_handle_add_overflow_abort(struct overflow_data *data,
126*1f461979SJustin Chadwell unsigned long lhs __unused,
127*1f461979SJustin Chadwell unsigned long rhs __unused)
128*1f461979SJustin Chadwell {
129*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
130*1f461979SJustin Chadwell plat_panic_handler();
131*1f461979SJustin Chadwell }
132*1f461979SJustin Chadwell
__ubsan_handle_sub_overflow_abort(struct overflow_data * data,unsigned long lhs __unused,unsigned long rhs __unused)133*1f461979SJustin Chadwell void __ubsan_handle_sub_overflow_abort(struct overflow_data *data,
134*1f461979SJustin Chadwell unsigned long lhs __unused,
135*1f461979SJustin Chadwell unsigned long rhs __unused)
136*1f461979SJustin Chadwell {
137*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
138*1f461979SJustin Chadwell plat_panic_handler();
139*1f461979SJustin Chadwell }
140*1f461979SJustin Chadwell
__ubsan_handle_mul_overflow_abort(struct overflow_data * data,unsigned long lhs __unused,unsigned long rhs __unused)141*1f461979SJustin Chadwell void __ubsan_handle_mul_overflow_abort(struct overflow_data *data,
142*1f461979SJustin Chadwell unsigned long lhs __unused,
143*1f461979SJustin Chadwell unsigned long rhs __unused)
144*1f461979SJustin Chadwell {
145*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
146*1f461979SJustin Chadwell plat_panic_handler();
147*1f461979SJustin Chadwell }
148*1f461979SJustin Chadwell
__ubsan_handle_negate_overflow_abort(struct overflow_data * data,unsigned long old_val __unused)149*1f461979SJustin Chadwell void __ubsan_handle_negate_overflow_abort(struct overflow_data *data,
150*1f461979SJustin Chadwell unsigned long old_val __unused)
151*1f461979SJustin Chadwell {
152*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
153*1f461979SJustin Chadwell plat_panic_handler();
154*1f461979SJustin Chadwell }
155*1f461979SJustin Chadwell
__ubsan_handle_pointer_overflow_abort(struct overflow_data * data,unsigned long old_val __unused)156*1f461979SJustin Chadwell void __ubsan_handle_pointer_overflow_abort(struct overflow_data *data,
157*1f461979SJustin Chadwell unsigned long old_val __unused)
158*1f461979SJustin Chadwell {
159*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
160*1f461979SJustin Chadwell plat_panic_handler();
161*1f461979SJustin Chadwell }
162*1f461979SJustin Chadwell
__ubsan_handle_divrem_overflow_abort(struct overflow_data * data,unsigned long lhs __unused,unsigned long rhs __unused)163*1f461979SJustin Chadwell void __ubsan_handle_divrem_overflow_abort(struct overflow_data *data,
164*1f461979SJustin Chadwell unsigned long lhs __unused,
165*1f461979SJustin Chadwell unsigned long rhs __unused)
166*1f461979SJustin Chadwell {
167*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
168*1f461979SJustin Chadwell plat_panic_handler();
169*1f461979SJustin Chadwell }
170*1f461979SJustin Chadwell
__ubsan_handle_shift_out_of_bounds_abort(struct shift_out_of_bounds_data * data,unsigned long lhs __unused,unsigned long rhs __unused)171*1f461979SJustin Chadwell void __ubsan_handle_shift_out_of_bounds_abort(struct shift_out_of_bounds_data *data,
172*1f461979SJustin Chadwell unsigned long lhs __unused,
173*1f461979SJustin Chadwell unsigned long rhs __unused)
174*1f461979SJustin Chadwell {
175*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
176*1f461979SJustin Chadwell plat_panic_handler();
177*1f461979SJustin Chadwell }
178*1f461979SJustin Chadwell
__ubsan_handle_out_of_bounds_abort(struct out_of_bounds_data * data,unsigned long idx __unused)179*1f461979SJustin Chadwell void __ubsan_handle_out_of_bounds_abort(struct out_of_bounds_data *data,
180*1f461979SJustin Chadwell unsigned long idx __unused)
181*1f461979SJustin Chadwell {
182*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
183*1f461979SJustin Chadwell plat_panic_handler();
184*1f461979SJustin Chadwell }
185*1f461979SJustin Chadwell
__ubsan_handle_unreachable_abort(struct unreachable_data * data)186*1f461979SJustin Chadwell void __ubsan_handle_unreachable_abort(struct unreachable_data *data)
187*1f461979SJustin Chadwell {
188*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
189*1f461979SJustin Chadwell plat_panic_handler();
190*1f461979SJustin Chadwell }
191*1f461979SJustin Chadwell
__ubsan_handle_missing_return_abort(struct unreachable_data * data)192*1f461979SJustin Chadwell void __ubsan_handle_missing_return_abort(struct unreachable_data *data)
193*1f461979SJustin Chadwell {
194*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
195*1f461979SJustin Chadwell plat_panic_handler();
196*1f461979SJustin Chadwell }
197*1f461979SJustin Chadwell
__ubsan_handle_vla_bound_not_positive_abort(struct vla_bound_data * data,unsigned long bound __unused)198*1f461979SJustin Chadwell void __ubsan_handle_vla_bound_not_positive_abort(struct vla_bound_data *data,
199*1f461979SJustin Chadwell unsigned long bound __unused)
200*1f461979SJustin Chadwell {
201*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
202*1f461979SJustin Chadwell plat_panic_handler();
203*1f461979SJustin Chadwell }
204*1f461979SJustin Chadwell
__ubsan_handle_load_invalid_value_abort(struct invalid_value_data * data,unsigned long val __unused)205*1f461979SJustin Chadwell void __ubsan_handle_load_invalid_value_abort(struct invalid_value_data *data,
206*1f461979SJustin Chadwell unsigned long val __unused)
207*1f461979SJustin Chadwell {
208*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
209*1f461979SJustin Chadwell plat_panic_handler();
210*1f461979SJustin Chadwell }
211*1f461979SJustin Chadwell
__ubsan_handle_nonnull_arg_abort(struct nonnull_arg_data * data,size_t arg_no __unused)212*1f461979SJustin Chadwell void __ubsan_handle_nonnull_arg_abort(struct nonnull_arg_data *data
213*1f461979SJustin Chadwell #if __GCC_VERSION < 60000
214*1f461979SJustin Chadwell , size_t arg_no __unused
215*1f461979SJustin Chadwell #endif
216*1f461979SJustin Chadwell )
217*1f461979SJustin Chadwell {
218*1f461979SJustin Chadwell print_loc(__func__, &data->loc);
219*1f461979SJustin Chadwell plat_panic_handler();
220*1f461979SJustin Chadwell }
221