1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
36
37
42
43
48
49
55
56
62
63
67
68
73
74
79
80
83
84
88
89
93
94
97
98
102
103
106
107
111
112
113
114
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
174
175
176
182
183
184
185
191
192
193
194
200
201
202
203
209
210
211
217
218
219
220
226
227
228
229
230
231
232
233
236
237
238
239
240
241
247
248
254
255
256
262
263
264
270
271
277
278
284
285
291
292
293
294
300
301
307
308
309
#include <stdbool.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "esp_rom_sys.h"
#include "esp_cpu.h"9 includes
struct source_location {
const char *file_name;
uint32_t line;
uint32_t column;
}{ ... };
struct type_descriptor {
uint16_t type_kind;
uint16_t type_info;
char type_name[];
}{ ... };
struct type_mismatch_data {
struct source_location loc;
struct type_descriptor *type;
unsigned long alignment;
unsigned char type_check_kind;
}{ ... };
struct type_mismatch_data_v1 {
struct source_location loc;
struct type_descriptor *type;
unsigned char log_alignment;
unsigned char type_check_kind;
}{ ... };
struct overflow_data {
struct source_location loc;
struct type_descriptor *type;
}{ ... };
struct shift_out_of_bounds_data {
struct source_location loc;
struct type_descriptor *lhs_type;
struct type_descriptor *rhs_type;
}{ ... };
struct out_of_bounds_data {
struct source_location loc;
struct type_descriptor *array_type;
struct type_descriptor *index_type;
}{ ... };
struct unreachable_data {
struct source_location loc;
}{ ... };
struct vla_bound_data {
struct source_location loc;
struct type_descriptor *type;
}{ ... };
struct invalid_value_data {
struct source_location loc;
struct type_descriptor *type;
}{ ... };
struct nonnull_arg_data {
struct source_location loc;
}{ ... };
struct nonnull_return_data {
struct source_location loc;
struct source_location attr_loc;
}{ ... };
struct pointer_overflow_data {
struct source_location loc;
}{ ... };
struct invalid_builtin_data {
struct source_location loc;
unsigned char kind;
}{ ... };
static void __ubsan_default_handler(struct source_location *loc, const char *func) __attribute__((noreturn));
/* ... */
void __ubsan_handle_type_mismatch(void *data_, void *ptr_);
void __ubsan_handle_type_mismatch_v1(void *data_, void *ptr_);
void __ubsan_handle_add_overflow(void *data_, void *lhs_, void *rhs_);
void __ubsan_handle_sub_overflow(void *data_, void *lhs_, void *rhs_);
void __ubsan_handle_mul_overflow(void *data_, void *lhs_, void *rhs_);
void __ubsan_handle_negate_overflow(void *data_, void *old_val_);
void __ubsan_handle_divrem_overflow(void *data_, void *lhs_, void *rhs_);
void __ubsan_handle_shift_out_of_bounds(void *data_, void *lhs_, void *rhs_);
void __ubsan_handle_out_of_bounds(void *data_, void *idx_);
void __ubsan_handle_missing_return(void *data_);
void __ubsan_handle_vla_bound_not_positive(void *data_, void *bound_);
void __ubsan_handle_load_invalid_value(void *data_, void *val_);
void __ubsan_handle_nonnull_arg(void *data_);
void __ubsan_handle_nonnull_return(void *data_);
void __ubsan_handle_builtin_unreachable(void *data_);
void __ubsan_handle_pointer_overflow(void *data_, void *base_, void *result_);
void __ubsan_handle_invalid_builtin(void *data_);
static void __ubsan_maybe_debugbreak(void)
{
if (esp_cpu_dbgr_is_attached()) {
esp_cpu_dbgr_break();
}{...}
}{ ... }
static void __ubsan_default_handler(struct source_location *loc, const char *func)
{
/* ... */
char msg[60] = {};
(void) strlcat(msg, "Undefined behavior of type ", sizeof(msg));
(void) strlcat(msg, func + strlen("__ubsan_handle_"), sizeof(msg));
esp_system_abort(msg);
}{ ... }
void __ubsan_handle_type_mismatch(void *data_,
void *ptr_)
{
struct type_mismatch_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_type_mismatch_v1(void *data_,
void *ptr)
{
struct type_mismatch_data_v1 *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_add_overflow(void *data_,
void *lhs_,
void *rhs_)
{
struct overflow_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_sub_overflow(void *data_,
void *lhs_,
void *rhs_)
{
struct overflow_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_mul_overflow(void *data_,
void *lhs_,
void *rhs_)
{
struct overflow_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_negate_overflow(void *data_,
void *old_val_)
{
struct overflow_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_divrem_overflow(void *data_,
void *lhs_,
void *rhs_)
{
struct overflow_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_shift_out_of_bounds(void *data_,
void *lhs_,
void *rhs_)
{
struct shift_out_of_bounds_data *data = data_;
unsigned int rhs = (unsigned int)rhs_;
if (rhs == 32) {
return;
}{...}
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_out_of_bounds(void *data_,
void *idx_)
{
struct out_of_bounds_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_missing_return(void *data_)
{
struct unreachable_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_vla_bound_not_positive(void *data_,
void *bound_)
{
struct vla_bound_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_load_invalid_value(void *data_,
void *val_)
{
struct invalid_value_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_nonnull_arg(void *data_)
{
struct nonnull_arg_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_nonnull_return(void *data_)
{
struct nonnull_return_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_builtin_unreachable(void *data_)
{
struct unreachable_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_pointer_overflow(void *data_,
void *base_,
void *result_)
{
struct pointer_overflow_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_handle_invalid_builtin(void *data_)
{
struct invalid_builtin_data *data = data_;
__ubsan_maybe_debugbreak();
__ubsan_default_handler(&data->loc, __func__);
}{ ... }
void __ubsan_include(void)
{
}{ ... }