Test program for atexit registering in atexit handler.
[kopensolaris-gnu/glibc.git] / dlfcn / modstatic2.c
1 #include <dlfcn.h>
2 #include <link.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <gnu/lib-names.h>
7
8 int test (FILE *out, int a);
9
10 int
11 test (FILE *out, int a)
12 {
13   fputs ("in modstatic2.c (test)\n", out);
14
15   void *handle = dlopen ("modstatic2-nonexistent.so", RTLD_LAZY);
16   if (handle == NULL)
17     fprintf (out, "nonexistent: %s\n", dlerror ());
18   else
19     exit (1);
20
21   handle = dlopen ("modstatic2.so", RTLD_LAZY);
22   if (handle == NULL)
23     {
24       fprintf (out, "%s\n", dlerror ());
25       exit (1);
26     }
27
28   int (*test2) (FILE *, int);
29   test2 = dlsym (handle, "test");
30   if (test2 == NULL)
31     {
32       fprintf (out, "%s\n", dlerror ());
33       exit (1);
34     }
35   if (test2 != test)
36     {
37       fprintf (out, "test %p != test2 %p\n", test, test2);
38       exit (1);
39     }
40
41   Dl_info info;
42   int res = dladdr (test2, &info);
43   if (res == 0)
44     {
45       fputs ("dladdr returned 0\n", out);
46       exit (1);
47     }
48   else
49     {
50       if (strstr (info.dli_fname, "modstatic2.so") == NULL
51           || strcmp (info.dli_sname, "test") != 0)
52         {
53           fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
54           exit (1);
55         }
56       if (info.dli_saddr != (void *) test2)
57         {
58           fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2);
59           exit (1);
60         }
61     }
62
63   ElfW(Sym) *sym;
64   void *symp;
65   res = dladdr1 (test2, &info, &symp, RTLD_DL_SYMENT);
66   if (res == 0)
67     {
68       fputs ("dladdr1 returned 0\n", out);
69       exit (1);
70     }
71   else
72     {
73       if (strstr (info.dli_fname, "modstatic2.so") == NULL
74           || strcmp (info.dli_sname, "test") != 0)
75         {
76           fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
77           exit (1);
78         }
79       if (info.dli_saddr != (void *) test2)
80         {
81           fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2);
82           exit (1);
83         }
84       sym = symp;
85       if (sym == NULL)
86         {
87           fputs ("sym == NULL\n", out);
88           exit (1);
89         }
90       if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
91           || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
92         {
93           fprintf (out, "bind %d visibility %d\n",
94                    (int) ELF32_ST_BIND (sym->st_info),
95                    (int) ELF32_ST_VISIBILITY (sym->st_other));
96           exit (1);
97         }
98     }
99
100   Lmid_t lmid;
101   res = dlinfo (handle, RTLD_DI_LMID, &lmid);
102   if (res != 0)
103     {
104       fprintf (out, "dlinfo returned %d %s\n", res, dlerror ());
105       exit (1);
106     }
107   else if (lmid != LM_ID_BASE)
108     {
109       fprintf (out, "lmid %d != %d\n", (int) lmid, (int) LM_ID_BASE);
110       exit (1);
111     }
112
113   void *handle2 = dlopen (LIBDL_SO, RTLD_LAZY);
114   if (handle2 == NULL)
115     {
116       fprintf (out, "libdl.so: %s\n", dlerror ());
117       exit (1);
118     }
119
120 #ifdef DO_VERSIONING
121   if (dlvsym (handle2, "_dlfcn_hook", "GLIBC_PRIVATE") == NULL)
122     {
123       fprintf (out, "dlvsym: %s\n", dlerror ());
124       exit (1);
125     }
126 #endif
127
128   void *(*dlsymfn) (void *, const char *);
129   dlsymfn = dlsym (handle2, "dlsym");
130   if (dlsymfn == NULL)
131     {
132       fprintf (out, "dlsym \"dlsym\": %s\n", dlerror ());
133       exit (1);
134     }
135   void *test3 = dlsymfn (handle, "test");
136   if (test3 == NULL)
137     {
138       fprintf (out, "%s\n", dlerror ());
139       exit (1);
140     }
141   else if (test3 != (void *) test2)
142     {
143       fprintf (out, "test2 %p != test3 %p\n", test2, test3);
144       exit (1);
145     }
146
147   dlclose (handle2);
148   dlclose (handle);
149
150   handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY);
151   if (handle == NULL)
152     {
153       fprintf (out, "%s\n", dlerror ());
154       exit (1);
155     }
156   dlclose (handle);
157
158   handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY);
159   if (handle == NULL)
160     fprintf (out, "LM_ID_NEWLM: %s\n", dlerror ());
161   else
162     {
163       fputs ("LM_ID_NEWLM unexpectedly succeeded\n", out);
164       exit (1);
165     }
166
167   handle = dlopen ("modstatic.so", RTLD_LAZY);
168   if (handle == NULL)
169     {
170       fprintf (out, "%s\n", dlerror ());
171       exit (1);
172     }
173
174   int (*test4) (int);
175   test4 = dlsym (handle, "test");
176   if (test4 == NULL)
177     {
178       fprintf (out, "%s\n", dlerror ());
179       exit (1);
180     }
181
182   res = test4 (16);
183   if (res != 16 + 16)
184     {
185       fprintf (out, "modstatic.so (test) returned %d\n", res);
186       exit (1);
187     }
188
189   res = dladdr1 (test4, &info, &symp, RTLD_DL_SYMENT);
190   if (res == 0)
191     {
192       fputs ("dladdr1 returned 0\n", out);
193       exit (1);
194     }
195   else
196     {
197       if (strstr (info.dli_fname, "modstatic.so") == NULL
198           || strcmp (info.dli_sname, "test") != 0)
199         {
200           fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
201           exit (1);
202         }
203       if (info.dli_saddr != (void *) test4)
204         {
205           fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test4);
206           exit (1);
207         }
208       sym = symp;
209       if (sym == NULL)
210         {
211           fputs ("sym == NULL\n", out);
212           exit (1);
213         }
214       if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
215           || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
216         {
217           fprintf (out, "bind %d visibility %d\n",
218                    (int) ELF32_ST_BIND (sym->st_info),
219                    (int) ELF32_ST_VISIBILITY (sym->st_other));
220           exit (1);
221         }
222     }
223
224   dlclose (handle);
225
226   fputs ("leaving modstatic2.c (test)\n", out);
227   return a + a;
228 }