1 /* Test for unloading (really unmapping) of objects. By Franz Sirl. 2 This test does not have to passed in all dlopen() et.al. implementation 3 since it is not required the unloading actually happens. But we 4 require it for glibc. */ 5 6 #include <dlfcn.h> 7 #include <link.h> 8 #include <mcheck.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 12 #define MAPS ((struct link_map *) _r_debug.r_map) 13 14 #define OUT \ 15 for (map = MAPS; map != NULL; map = map->l_next) \ 16 if (map->l_type == lt_loaded) \ 17 printf ("name = \"%s\", direct_opencount = %d\n", \ 18 map->l_name, (int) map->l_direct_opencount); \ 19 fflush (stdout) 20 21 typedef struct 22 { 23 void *next; 24 } strct; 25 26 int main(void)27main (void) 28 { 29 void *sohandle; 30 strct *testdat; 31 int ret; 32 int result = 0; 33 struct link_map *map; 34 35 mtrace (); 36 37 puts ("\nBefore"); 38 OUT; 39 40 sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL); 41 if (sohandle == NULL) 42 { 43 printf ("*** first dlopen failed: %s\n", dlerror ()); 44 exit (1); 45 } 46 47 puts ("\nAfter loading unloadmod.so"); 48 OUT; 49 50 testdat = dlsym (sohandle, "testdat"); 51 testdat->next = (void *) -1; 52 53 ret = dlclose (sohandle); 54 if (ret != 0) 55 { 56 puts ("*** first dlclose failed"); 57 result = 1; 58 } 59 60 puts ("\nAfter closing unloadmod.so"); 61 OUT; 62 63 sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL); 64 if (sohandle == NULL) 65 { 66 printf ("*** second dlopen failed: %s\n", dlerror ()); 67 exit (1); 68 } 69 70 puts ("\nAfter loading unloadmod.so the second time"); 71 OUT; 72 73 testdat = dlsym (sohandle, "testdat"); 74 if (testdat->next == (void *) -1) 75 { 76 puts ("*** testdat->next == (void *) -1"); 77 result = 1; 78 } 79 80 ret = dlclose (sohandle); 81 if (ret != 0) 82 { 83 puts ("*** second dlclose failed"); 84 result = 1; 85 } 86 87 puts ("\nAfter closing unloadmod.so again"); 88 OUT; 89 90 return result; 91 } 92