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