packaging: add 64bit libs on 32bit build env
[platform/upstream/linaro-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   if (dlvsym (handle2, "_dlfcn_hook", "GLIBC_PRIVATE") == NULL)
121     {
122       fprintf (out, "dlvsym: %s\n", dlerror ());
123       exit (1);
124     }
125
126   void *(*dlsymfn) (void *, const char *);
127   dlsymfn = dlsym (handle2, "dlsym");
128   if (dlsymfn == NULL)
129     {
130       fprintf (out, "dlsym \"dlsym\": %s\n", dlerror ());
131       exit (1);
132     }
133   void *test3 = dlsymfn (handle, "test");
134   if (test3 == NULL)
135     {
136       fprintf (out, "%s\n", dlerror ());
137       exit (1);
138     }
139   else if (test3 != (void *) test2)
140     {
141       fprintf (out, "test2 %p != test3 %p\n", test2, test3);
142       exit (1);
143     }
144
145   dlclose (handle2);
146   dlclose (handle);
147
148   handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY);
149   if (handle == NULL)
150     {
151       fprintf (out, "%s\n", dlerror ());
152       exit (1);
153     }
154   dlclose (handle);
155
156   handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY);
157   if (handle == NULL)
158     fprintf (out, "LM_ID_NEWLM: %s\n", dlerror ());
159   else
160     {
161       fputs ("LM_ID_NEWLM unexpectedly succeeded\n", out);
162       exit (1);
163     }
164
165   handle = dlopen ("modstatic.so", RTLD_LAZY);
166   if (handle == NULL)
167     {
168       fprintf (out, "%s\n", dlerror ());
169       exit (1);
170     }
171
172   int (*test4) (int);
173   test4 = dlsym (handle, "test");
174   if (test4 == NULL)
175     {
176       fprintf (out, "%s\n", dlerror ());
177       exit (1);
178     }
179
180   res = test4 (16);
181   if (res != 16 + 16)
182     {
183       fprintf (out, "modstatic.so (test) returned %d\n", res);
184       exit (1);
185     }
186
187   res = dladdr1 (test4, &info, &symp, RTLD_DL_SYMENT);
188   if (res == 0)
189     {
190       fputs ("dladdr1 returned 0\n", out);
191       exit (1);
192     }
193   else
194     {
195       if (strstr (info.dli_fname, "modstatic.so") == NULL
196           || strcmp (info.dli_sname, "test") != 0)
197         {
198           fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
199           exit (1);
200         }
201       if (info.dli_saddr != (void *) test4)
202         {
203           fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test4);
204           exit (1);
205         }
206       sym = symp;
207       if (sym == NULL)
208         {
209           fputs ("sym == NULL\n", out);
210           exit (1);
211         }
212       if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
213           || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
214         {
215           fprintf (out, "bind %d visibility %d\n",
216                    (int) ELF32_ST_BIND (sym->st_info),
217                    (int) ELF32_ST_VISIBILITY (sym->st_other));
218           exit (1);
219         }
220     }
221
222   dlclose (handle);
223
224   fputs ("leaving modstatic2.c (test)\n", out);
225   return a + a;
226 }