Add more checks for valid ld.so.cache file (bug 18093)
[platform/upstream/glibc.git] / elf / tst-tls8.c
1 #include <dlfcn.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include <link.h>
6
7
8 static int
9 do_test (void)
10 {
11   static const char modname1[] = "$ORIGIN/tst-tlsmod3.so";
12   static const char modname2[] = "$ORIGIN/tst-tlsmod4.so";
13   int result = 0;
14   int (*fp1) (void);
15   int (*fp2) (int, int *);
16   void *h1;
17   void *h2;
18   int i;
19   size_t modid1 = (size_t) -1;
20   size_t modid2 = (size_t) -1;
21   int *bazp;
22
23   for (i = 0; i < 10; ++i)
24     {
25       h1 = dlopen (modname1, RTLD_LAZY);
26       if (h1 == NULL)
27         {
28           printf ("cannot open '%s': %s\n", modname1, dlerror ());
29           exit (1);
30         }
31
32       /* Dirty test code here: we peek into a private data structure.
33          We make sure that the module gets assigned the same ID every
34          time.  The value of the first round is used.  */
35       if (modid1 == (size_t) -1)
36         modid1 = ((struct link_map *) h1)->l_tls_modid;
37       else if (((struct link_map *) h1)->l_tls_modid != modid1)
38         {
39           printf ("round %d: modid now %zd, initially %zd\n",
40                   i, ((struct link_map *) h1)->l_tls_modid, modid1);
41           result = 1;
42         }
43
44       fp1 = dlsym (h1, "in_dso2");
45       if (fp1 == NULL)
46         {
47           printf ("cannot get symbol 'in_dso2' in %s\n", modname1);
48           exit (1);
49         }
50
51       result |= fp1 ();
52
53
54
55       h2 = dlopen (modname2, RTLD_LAZY);
56       if (h2 == NULL)
57         {
58           printf ("cannot open '%s': %s\n", modname2, dlerror ());
59           exit (1);
60         }
61
62       /* Dirty test code here: we peek into a private data structure.
63          We make sure that the module gets assigned the same ID every
64          time.  The value of the first round is used.  */
65       if (modid2 == (size_t) -1)
66         modid2 = ((struct link_map *) h1)->l_tls_modid;
67       else if (((struct link_map *) h1)->l_tls_modid != modid2)
68         {
69           printf ("round %d: modid now %zd, initially %zd\n",
70                   i, ((struct link_map *) h1)->l_tls_modid, modid2);
71           result = 1;
72         }
73
74       bazp = dlsym (h2, "baz");
75       if (bazp == NULL)
76         {
77           printf ("cannot get symbol 'baz' in %s\n", modname2);
78           exit (1);
79         }
80
81       *bazp = 42 + i;
82
83       fp2 = dlsym (h2, "in_dso");
84       if (fp2 == NULL)
85         {
86           printf ("cannot get symbol 'in_dso' in %s\n", modname2);
87           exit (1);
88         }
89
90       result |= fp2 (42 + i, bazp);
91
92       dlclose (h1);
93       dlclose (h2);
94
95
96       h1 = dlopen (modname1, RTLD_LAZY);
97       if (h1 == NULL)
98         {
99           printf ("cannot open '%s': %s\n", modname1, dlerror ());
100           exit (1);
101         }
102
103       /* Dirty test code here: we peek into a private data structure.
104          We make sure that the module gets assigned the same ID every
105          time.  The value of the first round is used.  */
106       if (((struct link_map *) h1)->l_tls_modid != modid1)
107         {
108           printf ("round %d: modid now %zd, initially %zd\n",
109                   i, ((struct link_map *) h1)->l_tls_modid, modid1);
110           result = 1;
111         }
112
113       fp1 = dlsym (h1, "in_dso2");
114       if (fp1 == NULL)
115         {
116           printf ("cannot get symbol 'in_dso2' in %s\n", modname1);
117           exit (1);
118         }
119
120       result |= fp1 ();
121
122
123
124       h2 = dlopen (modname2, RTLD_LAZY);
125       if (h2 == NULL)
126         {
127           printf ("cannot open '%s': %s\n", modname2, dlerror ());
128           exit (1);
129         }
130
131       /* Dirty test code here: we peek into a private data structure.
132          We make sure that the module gets assigned the same ID every
133          time.  The value of the first round is used.  */
134       if (((struct link_map *) h1)->l_tls_modid != modid2)
135         {
136           printf ("round %d: modid now %zd, initially %zd\n",
137                   i, ((struct link_map *) h1)->l_tls_modid, modid2);
138           result = 1;
139         }
140
141       bazp = dlsym (h2, "baz");
142       if (bazp == NULL)
143         {
144           printf ("cannot get symbol 'baz' in %s\n", modname2);
145           exit (1);
146         }
147
148       *bazp = 62 + i;
149
150       fp2 = dlsym (h2, "in_dso");
151       if (fp2 == NULL)
152         {
153           printf ("cannot get symbol 'in_dso' in %s\n", modname2);
154           exit (1);
155         }
156
157       result |= fp2 (62 + i, bazp);
158
159       /* This time the dlclose calls are in reverse order.  */
160       dlclose (h2);
161       dlclose (h1);
162     }
163
164   return result;
165 }
166
167 #include <support/test-driver.c>