about summary refs log tree commit diff
path: root/elf/unload.c
blob: 2789abd5bb00fe884420508f3b5be52e6adb1936 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/* Test for unloading (really unmapping) of objects.  By Franz Sirl.
   This test does not have to passed in all dlopen() et.al. implementation
   since it is not required the unloading actually happens.  But we
   require it for glibc.  */

#include <dlfcn.h>
#include <mcheck.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
  void *next;
} strct;

int
main (void)
{
   void *sohandle;
   strct *testdat;
   int ret;
   int result = 0;

   mtrace ();

   sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL);
   if (sohandle == NULL)
     {
       printf ("first dlopen failed: %s\n", dlerror ());
       exit (1);
     }

   testdat = dlsym (sohandle, "testdat");
   testdat->next = (void *) -1;

   ret = dlclose (sohandle);
   if (ret != 0)
     {
       puts ("first dlclose failed");
       result = 1;
     }

   sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL);
   if (sohandle == NULL)
     {
       printf ("second dlopen failed: %s\n", dlerror ());
       exit (1);
     }

   testdat = dlsym (sohandle, "testdat");
   if (testdat->next == (void *) -1)
     {
       puts ("testdat->next == (void *) -1");
       result = 1;
     }

   ret = dlclose (sohandle);
   if (ret != 0)
     {
       puts ("second dlclose failed");
       result = 1;
     }

   return result;
}