Home | History | Annotate | Download | only in msan
      1 // ParamTLS has limited size. Everything that does not fit is considered fully
      2 // initialized.
      3 
      4 // RUN: %clangxx_msan -O0 %s -o %t && %run %t
      5 // RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && %run %t
      6 // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 %s -o %t && %run %t
      7 //
      8 // AArch64 fails with:
      9 // void f801(S<801>): Assertion `__msan_test_shadow(&s, sizeof(s)) == -1' failed
     10 // XFAIL: aarch64
     11 
     12 #include <sanitizer/msan_interface.h>
     13 #include <assert.h>
     14 
     15 // This test assumes that ParamTLS size is 800 bytes.
     16 
     17 // This test passes poisoned values through function argument list.
     18 // In case of overflow, argument is unpoisoned.
     19 #define OVERFLOW(x) assert(__msan_test_shadow(&x, sizeof(x)) == -1)
     20 // In case of no overflow, it is still poisoned.
     21 #define NO_OVERFLOW(x) assert(__msan_test_shadow(&x, sizeof(x)) == 0)
     22 
     23 #if defined(__x86_64__)
     24 // In x86_64, if argument is partially outside tls, it is considered completly
     25 // unpoisoned
     26 #define PARTIAL_OVERFLOW(x) OVERFLOW(x)
     27 #else
     28 // In other archs, bigger arguments are splitted in multiple IR arguments, so
     29 // they are considered poisoned till tls limit. Checking last byte of such arg:
     30 #define PARTIAL_OVERFLOW(x) assert(__msan_test_shadow((char *)(&(x) + 1) - 1, 1) == -1)
     31 #endif
     32 
     33 
     34 template<int N>
     35 struct S {
     36   char x[N];
     37 };
     38 
     39 void f100(S<100> s) {
     40   NO_OVERFLOW(s);
     41 }
     42 
     43 void f800(S<800> s) {
     44   NO_OVERFLOW(s);
     45 }
     46 
     47 void f801(S<801> s) {
     48   PARTIAL_OVERFLOW(s);
     49 }
     50 
     51 void f1000(S<1000> s) {
     52   PARTIAL_OVERFLOW(s);
     53 }
     54 
     55 void f_many(int a, double b, S<800> s, int c, double d) {
     56   NO_OVERFLOW(a);
     57   NO_OVERFLOW(b);
     58   PARTIAL_OVERFLOW(s);
     59   OVERFLOW(c);
     60   OVERFLOW(d);
     61 }
     62 
     63 // -8 bytes for "int a", aligned by 8
     64 // -2 to make "int c" a partial fit
     65 void f_many2(int a, S<800 - 8 - 2> s, int c, double d) {
     66   NO_OVERFLOW(a);
     67   NO_OVERFLOW(s);
     68   PARTIAL_OVERFLOW(c);
     69   OVERFLOW(d);
     70 }
     71 
     72 int main(void) {
     73   S<100> s100;
     74   S<800> s800;
     75   S<801> s801;
     76   S<1000> s1000;
     77   f100(s100);
     78   f800(s800);
     79   f801(s801);
     80   f1000(s1000);
     81 
     82   int i;
     83   double d;
     84   f_many(i, d, s800, i, d);
     85 
     86   S<800 - 8 - 2> s788;
     87   f_many2(i, s788, i, d);
     88   return 0;
     89 }
     90