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