| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 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 | 
|  | 27 | main (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 | } |