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