Blame elf/unload.c

Packit 6c4009
/* Test for unloading (really unmapping) of objects.  By Franz Sirl.
Packit 6c4009
   This test does not have to passed in all dlopen() et.al. implementation
Packit 6c4009
   since it is not required the unloading actually happens.  But we
Packit 6c4009
   require it for glibc.  */
Packit 6c4009
Packit 6c4009
#include <dlfcn.h>
Packit 6c4009
#include <link.h>
Packit 6c4009
#include <mcheck.h>
Packit 6c4009
#include <stdio.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
Packit 6c4009
#define MAPS ((struct link_map *) _r_debug.r_map)
Packit 6c4009
Packit 6c4009
#define OUT \
Packit 6c4009
  for (map = MAPS; map != NULL; map = map->l_next)			      \
Packit 6c4009
    if (map->l_type == lt_loaded)					      \
Packit 6c4009
      printf ("name = \"%s\", direct_opencount = %d\n",			      \
Packit 6c4009
	      map->l_name, (int) map->l_direct_opencount);		      \
Packit 6c4009
  fflush (stdout)
Packit 6c4009
Packit 6c4009
typedef struct
Packit 6c4009
{
Packit 6c4009
  void *next;
Packit 6c4009
} strct;
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
main (void)
Packit 6c4009
{
Packit 6c4009
   void *sohandle;
Packit 6c4009
   strct *testdat;
Packit 6c4009
   int ret;
Packit 6c4009
   int result = 0;
Packit 6c4009
   struct link_map *map;
Packit 6c4009
Packit 6c4009
   mtrace ();
Packit 6c4009
Packit 6c4009
   puts ("\nBefore");
Packit 6c4009
   OUT;
Packit 6c4009
Packit 6c4009
   sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL);
Packit 6c4009
   if (sohandle == NULL)
Packit 6c4009
     {
Packit 6c4009
       printf ("*** first dlopen failed: %s\n", dlerror ());
Packit 6c4009
       exit (1);
Packit 6c4009
     }
Packit 6c4009
Packit 6c4009
   puts ("\nAfter loading unloadmod.so");
Packit 6c4009
   OUT;
Packit 6c4009
Packit 6c4009
   testdat = dlsym (sohandle, "testdat");
Packit 6c4009
   testdat->next = (void *) -1;
Packit 6c4009
Packit 6c4009
   ret = dlclose (sohandle);
Packit 6c4009
   if (ret != 0)
Packit 6c4009
     {
Packit 6c4009
       puts ("*** first dlclose failed");
Packit 6c4009
       result = 1;
Packit 6c4009
     }
Packit 6c4009
Packit 6c4009
   puts ("\nAfter closing unloadmod.so");
Packit 6c4009
   OUT;
Packit 6c4009
Packit 6c4009
   sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL);
Packit 6c4009
   if (sohandle == NULL)
Packit 6c4009
     {
Packit 6c4009
       printf ("*** second dlopen failed: %s\n", dlerror ());
Packit 6c4009
       exit (1);
Packit 6c4009
     }
Packit 6c4009
Packit 6c4009
   puts ("\nAfter loading unloadmod.so the second time");
Packit 6c4009
   OUT;
Packit 6c4009
Packit 6c4009
   testdat = dlsym (sohandle, "testdat");
Packit 6c4009
   if (testdat->next == (void *) -1)
Packit 6c4009
     {
Packit 6c4009
       puts ("*** testdat->next == (void *) -1");
Packit 6c4009
       result = 1;
Packit 6c4009
     }
Packit 6c4009
Packit 6c4009
   ret = dlclose (sohandle);
Packit 6c4009
   if (ret != 0)
Packit 6c4009
     {
Packit 6c4009
       puts ("*** second dlclose failed");
Packit 6c4009
       result = 1;
Packit 6c4009
     }
Packit 6c4009
Packit 6c4009
   puts ("\nAfter closing unloadmod.so again");
Packit 6c4009
   OUT;
Packit 6c4009
Packit 6c4009
   return result;
Packit 6c4009
}