1 #include <dlfcn.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 
5 #include <link.h>
6 
7 
8 static int
do_test(void)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>
168