xref: /aosp_15_r20/external/compiler-rt/test/msan/dtls_test.c (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot /* RUN: %clang_msan -g %s -o %t
2*7c3d14c8STreehugger Robot    RUN: %clang_msan -g %s -DBUILD_SO -fPIC -o %t-so.so -shared
3*7c3d14c8STreehugger Robot    RUN: %run %t 2>&1
4*7c3d14c8STreehugger Robot 
5*7c3d14c8STreehugger Robot    Regression test for a bug in msan/glibc integration,
6*7c3d14c8STreehugger Robot    see https://sourceware.org/bugzilla/show_bug.cgi?id=16291
7*7c3d14c8STreehugger Robot    and https://github.com/google/sanitizers/issues/547
8*7c3d14c8STreehugger Robot */
9*7c3d14c8STreehugger Robot 
10*7c3d14c8STreehugger Robot #ifndef BUILD_SO
11*7c3d14c8STreehugger Robot #include <assert.h>
12*7c3d14c8STreehugger Robot #include <dlfcn.h>
13*7c3d14c8STreehugger Robot #include <stdio.h>
14*7c3d14c8STreehugger Robot #include <stdlib.h>
15*7c3d14c8STreehugger Robot #include <pthread.h>
16*7c3d14c8STreehugger Robot 
17*7c3d14c8STreehugger Robot typedef long *(* get_t)();
18*7c3d14c8STreehugger Robot get_t GetTls;
Thread1(void * unused)19*7c3d14c8STreehugger Robot void *Thread1(void *unused) {
20*7c3d14c8STreehugger Robot   long uninitialized;
21*7c3d14c8STreehugger Robot   long *x = GetTls();
22*7c3d14c8STreehugger Robot   if (*x)
23*7c3d14c8STreehugger Robot     fprintf(stderr, "bar\n");
24*7c3d14c8STreehugger Robot   *x = uninitialized;
25*7c3d14c8STreehugger Robot   fprintf(stderr, "stack: %p dtls: %p\n", &x, x);
26*7c3d14c8STreehugger Robot   return 0;
27*7c3d14c8STreehugger Robot }
28*7c3d14c8STreehugger Robot 
Thread2(void * unused)29*7c3d14c8STreehugger Robot void *Thread2(void *unused) {
30*7c3d14c8STreehugger Robot   long *x = GetTls();
31*7c3d14c8STreehugger Robot   fprintf(stderr, "stack: %p dtls: %p\n", &x, x);
32*7c3d14c8STreehugger Robot   if (*x)
33*7c3d14c8STreehugger Robot     fprintf(stderr, "foo\n");   // False negative here.
34*7c3d14c8STreehugger Robot   return 0;
35*7c3d14c8STreehugger Robot }
36*7c3d14c8STreehugger Robot 
main(int argc,char * argv[])37*7c3d14c8STreehugger Robot int main(int argc, char *argv[]) {
38*7c3d14c8STreehugger Robot   char path[4096];
39*7c3d14c8STreehugger Robot   snprintf(path, sizeof(path), "%s-so.so", argv[0]);
40*7c3d14c8STreehugger Robot   int i;
41*7c3d14c8STreehugger Robot 
42*7c3d14c8STreehugger Robot   void *handle = dlopen(path, RTLD_LAZY);
43*7c3d14c8STreehugger Robot   if (!handle) fprintf(stderr, "%s\n", dlerror());
44*7c3d14c8STreehugger Robot   assert(handle != 0);
45*7c3d14c8STreehugger Robot   GetTls = (get_t)dlsym(handle, "GetTls");
46*7c3d14c8STreehugger Robot   assert(dlerror() == 0);
47*7c3d14c8STreehugger Robot 
48*7c3d14c8STreehugger Robot   pthread_t t;
49*7c3d14c8STreehugger Robot   pthread_create(&t, 0, Thread1, 0);
50*7c3d14c8STreehugger Robot   pthread_join(t, 0);
51*7c3d14c8STreehugger Robot   pthread_create(&t, 0, Thread2, 0);
52*7c3d14c8STreehugger Robot   pthread_join(t, 0);
53*7c3d14c8STreehugger Robot   return 0;
54*7c3d14c8STreehugger Robot }
55*7c3d14c8STreehugger Robot #else  // BUILD_SO
56*7c3d14c8STreehugger Robot __thread long huge_thread_local_array[1 << 17];
GetTls()57*7c3d14c8STreehugger Robot long *GetTls() {
58*7c3d14c8STreehugger Robot   return &huge_thread_local_array[0];
59*7c3d14c8STreehugger Robot }
60*7c3d14c8STreehugger Robot #endif
61