Back to index

glibc  2.9
modstatic2.c
Go to the documentation of this file.
00001 #include <dlfcn.h>
00002 #include <link.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <gnu/lib-names.h>
00007 
00008 int test (FILE *out, int a);
00009 
00010 int
00011 test (FILE *out, int a)
00012 {
00013   fputs ("in modstatic2.c (test)\n", out);
00014 
00015   void *handle = dlopen ("modstatic2-nonexistent.so", RTLD_LAZY);
00016   if (handle == NULL)
00017     fprintf (out, "nonexistent: %s\n", dlerror ());
00018   else
00019     exit (1);
00020 
00021   handle = dlopen ("modstatic2.so", RTLD_LAZY);
00022   if (handle == NULL)
00023     {
00024       fprintf (out, "%s\n", dlerror ());
00025       exit (1);
00026     }
00027 
00028   int (*test2) (FILE *, int);
00029   test2 = dlsym (handle, "test");
00030   if (test2 == NULL)
00031     {
00032       fprintf (out, "%s\n", dlerror ());
00033       exit (1);
00034     }
00035   if (test2 != test)
00036     {
00037       fprintf (out, "test %p != test2 %p\n", test, test2);
00038       exit (1);
00039     }
00040 
00041   Dl_info info;
00042   int res = dladdr (test2, &info);
00043   if (res == 0)
00044     {
00045       fputs ("dladdr returned 0\n", out);
00046       exit (1);
00047     }
00048   else
00049     {
00050       if (strstr (info.dli_fname, "modstatic2.so") == NULL
00051          || strcmp (info.dli_sname, "test") != 0)
00052        {
00053          fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
00054          exit (1);
00055        }
00056       if (info.dli_saddr != (void *) test2)
00057        {
00058          fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2);
00059          exit (1);
00060        }
00061     }
00062 
00063   ElfW(Sym) *sym;
00064   void *symp;
00065   res = dladdr1 (test2, &info, &symp, RTLD_DL_SYMENT);
00066   if (res == 0)
00067     {
00068       fputs ("dladdr1 returned 0\n", out);
00069       exit (1);
00070     }
00071   else
00072     {
00073       if (strstr (info.dli_fname, "modstatic2.so") == NULL
00074          || strcmp (info.dli_sname, "test") != 0)
00075        {
00076          fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
00077          exit (1);
00078        }
00079       if (info.dli_saddr != (void *) test2)
00080        {
00081          fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2);
00082          exit (1);
00083        }
00084       sym = symp;
00085       if (sym == NULL)
00086        {
00087          fputs ("sym == NULL\n", out);
00088          exit (1);
00089        }
00090       if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
00091          || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
00092        {
00093          fprintf (out, "bind %d visibility %d\n",
00094                  (int) ELF32_ST_BIND (sym->st_info),
00095                  (int) ELF32_ST_VISIBILITY (sym->st_other));
00096          exit (1);
00097        }
00098     }
00099 
00100   Lmid_t lmid;
00101   res = dlinfo (handle, RTLD_DI_LMID, &lmid);
00102   if (res != 0)
00103     {
00104       fprintf (out, "dlinfo returned %d %s\n", res, dlerror ());
00105       exit (1);
00106     }
00107   else if (lmid != LM_ID_BASE)
00108     {
00109       fprintf (out, "lmid %d != %d\n", (int) lmid, (int) LM_ID_BASE);
00110       exit (1);
00111     }
00112 
00113   void *handle2 = dlopen (LIBDL_SO, RTLD_LAZY);
00114   if (handle2 == NULL)
00115     {
00116       fprintf (out, "libdl.so: %s\n", dlerror ());
00117       exit (1);
00118     }
00119 
00120 #ifdef DO_VERSIONING
00121   if (dlvsym (handle2, "_dlfcn_hook", "GLIBC_PRIVATE") == NULL)
00122     {
00123       fprintf (out, "dlvsym: %s\n", dlerror ());
00124       exit (1);
00125     }
00126 #endif
00127 
00128   void *(*dlsymfn) (void *, const char *);
00129   dlsymfn = dlsym (handle2, "dlsym");
00130   if (dlsymfn == NULL)
00131     {
00132       fprintf (out, "dlsym \"dlsym\": %s\n", dlerror ());
00133       exit (1);
00134     }
00135   void *test3 = dlsymfn (handle, "test");
00136   if (test3 == NULL)
00137     {
00138       fprintf (out, "%s\n", dlerror ());
00139       exit (1);
00140     }
00141   else if (test3 != (void *) test2)
00142     {
00143       fprintf (out, "test2 %p != test3 %p\n", test2, test3);
00144       exit (1);
00145     }
00146 
00147   dlclose (handle2);
00148   dlclose (handle);
00149 
00150   handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY);
00151   if (handle == NULL)
00152     {
00153       fprintf (out, "%s\n", dlerror ());
00154       exit (1);
00155     }
00156   dlclose (handle);
00157 
00158   handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY);
00159   if (handle == NULL)
00160     fprintf (out, "LM_ID_NEWLM: %s\n", dlerror ());
00161   else
00162     {
00163       fputs ("LM_ID_NEWLM unexpectedly succeeded\n", out);
00164       exit (1);
00165     }
00166 
00167   handle = dlopen ("modstatic.so", RTLD_LAZY);
00168   if (handle == NULL)
00169     {
00170       fprintf (out, "%s\n", dlerror ());
00171       exit (1);
00172     }
00173 
00174   int (*test4) (int);
00175   test4 = dlsym (handle, "test");
00176   if (test4 == NULL)
00177     {
00178       fprintf (out, "%s\n", dlerror ());
00179       exit (1);
00180     }
00181 
00182   res = test4 (16);
00183   if (res != 16 + 16)
00184     {
00185       fprintf (out, "modstatic.so (test) returned %d\n", res);
00186       exit (1);
00187     }
00188 
00189   res = dladdr1 (test4, &info, &symp, RTLD_DL_SYMENT);
00190   if (res == 0)
00191     {
00192       fputs ("dladdr1 returned 0\n", out);
00193       exit (1);
00194     }
00195   else
00196     {
00197       if (strstr (info.dli_fname, "modstatic.so") == NULL
00198          || strcmp (info.dli_sname, "test") != 0)
00199        {
00200          fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
00201          exit (1);
00202        }
00203       if (info.dli_saddr != (void *) test4)
00204        {
00205          fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test4);
00206          exit (1);
00207        }
00208       sym = symp;
00209       if (sym == NULL)
00210        {
00211          fputs ("sym == NULL\n", out);
00212          exit (1);
00213        }
00214       if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
00215          || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
00216        {
00217          fprintf (out, "bind %d visibility %d\n",
00218                  (int) ELF32_ST_BIND (sym->st_info),
00219                  (int) ELF32_ST_VISIBILITY (sym->st_other));
00220          exit (1);
00221        }
00222     }
00223 
00224   dlclose (handle);
00225 
00226   fputs ("leaving modstatic2.c (test)\n", out);
00227   return a + a;
00228 }