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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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