]> xenbits.xensource.com Git - people/iwj/xen.git/commitdiff
ubsan: add clang 5.0 support
authorRoger Pau Monné <roger.pau@citrix.com>
Fri, 20 Oct 2017 07:30:13 +0000 (09:30 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 20 Oct 2017 07:30:13 +0000 (09:30 +0200)
clang 5.0 changed the layout of the type_mismatch_data structure and
introduced __ubsan_handle_type_mismatch_v1 and
__ubsan_handle_pointer_overflow.

This commit adds support for the new structure layout, adds the
missing handlers and the new types for type_check_kinds.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
[jb: unconditionally emit always the same message in
     __ubsan_handle_pointer_overflow()]
Acked-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Release-acked-by: Julien Grall <julien.grall@linaro.org>
xen/common/ubsan/ubsan.c
xen/common/ubsan/ubsan.h

index fbe568562a875a64098e2c608a689811b718612d..fddd6be7232ade0cc9a682b19c9c5977f33f3238 100644 (file)
@@ -33,7 +33,10 @@ const char *type_check_kinds[] = {
        "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
@@ -333,6 +336,26 @@ void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
 }
 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;
@@ -478,3 +501,20 @@ void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
        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);
+}
index b2d18d4a53f5a274d73d31bda8cae876ba7ddc34..2710cd423ee405c38769518636ea926f54ef836f 100644 (file)
@@ -36,6 +36,13 @@ struct type_mismatch_data {
        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;
@@ -73,6 +80,10 @@ struct invalid_value_data {
        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;