"member call on",
"constructor call on",
"downcast of",
- "downcast of"
+ "downcast of",
+ "upcast of",
+ "cast to virtual base of",
+ "_Nonnull binding to",
};
#define REPORTED_BIT 31
}
EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
+void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
+ unsigned long ptr)
+{
+ struct type_mismatch_data d = {
+ .location = data->location,
+ .type = data->type,
+ .alignment = 1ul << data->log_alignment,
+ .type_check_kind = data->type_check_kind,
+ };
+
+ /*
+ * NB: do the check with data->location, d->location is just a local
+ * copy and the modifications will be lost.
+ */
+ if (suppress_report(&data->location))
+ return;
+
+ __ubsan_handle_type_mismatch(&d, ptr);
+}
+
void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data)
{
unsigned long flags;
ubsan_epilogue(&flags);
}
EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);
+
+void __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
+ unsigned long base, unsigned long result)
+{
+ unsigned long flags;
+
+ if (suppress_report(&data->location))
+ return;
+
+ ubsan_prologue(&data->location, &flags);
+
+ pr_err("pointer operation %s %p to %p\n",
+ base > result ? "underflowed" : "overflowed",
+ _p(base), _p(result));
+
+ ubsan_epilogue(&flags);
+}
unsigned char type_check_kind;
};
+struct type_mismatch_data_v1 {
+ struct source_location location;
+ struct type_descriptor *type;
+ unsigned char log_alignment;
+ unsigned char type_check_kind;
+};
+
struct nonnull_arg_data {
struct source_location location;
struct source_location attr_location;
struct type_descriptor *type;
};
+struct pointer_overflow_data {
+ struct source_location location;
+};
+
#if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
typedef __int128 s_max;
typedef unsigned __int128 u_max;