1 /* Test case for early TLS initialization in dynamic linker.  */
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <dlfcn.h>
7 
8 #define MAGIC1 0xabcdef72
9 #define MAGIC2 0xd8675309
10 static __thread unsigned int magic[] = { MAGIC1, MAGIC2 };
11 static __thread int calloc_called;
12 
13 #undef calloc
14 
15 /* This calloc definition will be called by the dynamic linker itself.
16    We test that interposed calloc is called by the dynamic loader, and
17    that TLS is fully initialized by then.  */
18 
19 void *
calloc(size_t n,size_t m)20 calloc (size_t n, size_t m)
21 {
22   if (!calloc_called)
23     {
24       /* Allow our calloc to be called more than once.  */
25       calloc_called = 1;
26       if (magic[0] != MAGIC1 || magic[1] != MAGIC2)
27 	{
28 	  printf ("{%x, %x} != {%x, %x}\n",
29 		  magic[0], magic[1], MAGIC1, MAGIC2);
30 	  abort ();
31 	}
32       magic[0] = MAGIC2;
33       magic[1] = MAGIC1;
34     }
35 
36   n *= m;
37   void *ptr = malloc (n);
38   if (ptr != NULL)
39     memset (ptr, '\0', n);
40   return ptr;
41 }
42 
43 static int
do_test(void)44 do_test (void)
45 {
46   /* Make sure that our calloc is called from the dynamic linker at least
47      once.  */
48   void *h = dlopen("$ORIGIN/tst-auditmod9b.so", RTLD_LAZY);
49   if (h != NULL)
50     dlclose (h);
51   if (magic[1] != MAGIC1 || magic[0] != MAGIC2)
52     {
53       printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC2, MAGIC1);
54       return 1;
55     }
56 
57   return 0;
58 }
59 
60 #include <support/test-driver.c>
61