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 static int
do_test(void)10 do_test (void)
11 {
12   void *handle = dlopen ("modstatic2-nonexistent.so", RTLD_LAZY);
13   if (handle == NULL)
14     printf ("nonexistent: %s\n", dlerror ());
15   else
16     exit (1);
17 
18   handle = dlopen ("modstatic2.so", RTLD_LAZY);
19   if (handle == NULL)
20     {
21       printf ("%s\n", dlerror ());
22       exit (1);
23     }
24 
25   int (*test) (FILE *, int);
26   test = dlsym (handle, "test");
27   if (test == NULL)
28     {
29       printf ("%s\n", dlerror ());
30       exit (1);
31     }
32 
33   Dl_info info;
34   int res = dladdr (test, &info);
35   if (res == 0)
36     {
37       puts ("dladdr returned 0");
38       exit (1);
39     }
40   else
41     {
42       if (strstr (info.dli_fname, "modstatic2.so") == NULL
43 	  || strcmp (info.dli_sname, "test") != 0)
44 	{
45 	  printf ("fname %s sname %s\n", info.dli_fname, info.dli_sname);
46 	  exit (1);
47 	}
48       if (info.dli_saddr != (void *) test)
49 	{
50 	  printf ("saddr %p != test %p\n", info.dli_saddr, test);
51 	  exit (1);
52 	}
53     }
54 
55   ElfW(Sym) *sym;
56   void *symp;
57   res = dladdr1 (test, &info, &symp, RTLD_DL_SYMENT);
58   if (res == 0)
59     {
60       puts ("dladdr1 returned 0");
61       exit (1);
62     }
63   else
64     {
65       if (strstr (info.dli_fname, "modstatic2.so") == NULL
66 	  || strcmp (info.dli_sname, "test") != 0)
67 	{
68 	  printf ("fname %s sname %s\n", info.dli_fname, info.dli_sname);
69 	  exit (1);
70 	}
71       if (info.dli_saddr != (void *) test)
72 	{
73 	  printf ("saddr %p != test %p\n", info.dli_saddr, test);
74 	  exit (1);
75 	}
76       sym = symp;
77       if (sym == NULL)
78 	{
79 	  puts ("sym == NULL\n");
80 	  exit (1);
81 	}
82       if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
83 	  || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
84 	{
85 	  printf ("bind %d visibility %d\n",
86 		  (int) ELF32_ST_BIND (sym->st_info),
87 		  (int) ELF32_ST_VISIBILITY (sym->st_other));
88 	  exit (1);
89 	}
90     }
91 
92   Lmid_t lmid;
93   res = dlinfo (handle, RTLD_DI_LMID, &lmid);
94   if (res != 0)
95     {
96       printf ("dlinfo returned %d %s\n", res, dlerror ());
97       exit (1);
98     }
99   else if (lmid != LM_ID_BASE)
100     {
101       printf ("lmid %d != %d\n", (int) lmid, (int) LM_ID_BASE);
102       exit (1);
103     }
104 
105   res = test (stdout, 2);
106   if (res != 4)
107     {
108       printf ("Got %i, expected 4\n", res);
109       exit (1);
110     }
111 
112   void *handle2 = dlopen (LIBDL_SO, RTLD_LAZY);
113   if (handle2 == NULL)
114     {
115       printf ("libdl.so: %s\n", dlerror ());
116       exit (1);
117     }
118 
119   /* _exit is very unlikely to receive a second symbol version.  */
120   void *exit_ptr = dlvsym (handle2, "_exit", FIRST_VERSION_libc__exit_STRING);
121   if (exit_ptr == NULL)
122     {
123       printf ("dlvsym: %s\n", dlerror ());
124       exit (1);
125     }
126   if (exit_ptr != dlsym (handle2, "_exit"))
127     {
128       printf ("dlvsym for _exit does not match dlsym\n");
129       exit (1);
130     }
131 
132   void *(*dlsymfn) (void *, const char *);
133   dlsymfn = dlsym (handle2, "dlsym");
134   if (dlsymfn == NULL)
135     {
136       printf ("dlsym \"dlsym\": %s\n", dlerror ());
137       exit (1);
138     }
139   void *test2 = dlsymfn (handle, "test");
140   if (test2 == NULL)
141     {
142       printf ("%s\n", dlerror ());
143       exit (1);
144     }
145   else if (test2 != (void *) test)
146     {
147       printf ("test %p != test2 %p\n", test, test2);
148       exit (1);
149     }
150 
151   dlclose (handle2);
152   dlclose (handle);
153 
154   handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY);
155   if (handle == NULL)
156     {
157       printf ("%s\n", dlerror ());
158       exit (1);
159     }
160   dlclose (handle);
161 
162   handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY);
163   if (handle == NULL)
164     printf ("LM_ID_NEWLM: %s\n", dlerror ());
165   else
166     {
167       puts ("LM_ID_NEWLM unexpectedly succeeded");
168       exit (1);
169     }
170 
171   return 0;
172 }
173 
174 #define TEST_FUNCTION do_test ()
175 #include "../test-skeleton.c"
176