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 * |
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 (format: "{%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 (size: n); |
38 | if (ptr != NULL) |
39 | memset (s: ptr, c: '\0', n: n); |
40 | return ptr; |
41 | } |
42 | |
43 | static int |
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(file: "$ORIGIN/tst-auditmod9b.so" , RTLD_LAZY); |
49 | if (h != NULL) |
50 | dlclose (handle: h); |
51 | if (magic[1] != MAGIC1 || magic[0] != MAGIC2) |
52 | { |
53 | printf (format: "{%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 | |