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