modstatic2.c 5.1 KB

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