ubsan.c 5.8 KB

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