rtld: properly handle root directory in load path (bug 30435)
[platform/upstream/glibc.git] / elf / reldep.c
1 #include <dlfcn.h>
2 #include <mcheck.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 int
7 main (void)
8 {
9   void *h1;
10   void *h2;
11   int (*fp) (void);
12   int *vp;
13
14   mtrace ();
15
16   /* Open the two objects.  */
17   h1 = dlopen ("reldepmod1.so", RTLD_LAZY | RTLD_GLOBAL);
18   if (h1 == NULL)
19     {
20       printf ("cannot open reldepmod1.so: %s\n", dlerror ());
21       exit (1);
22     }
23   h2 = dlopen ("reldepmod2.so", RTLD_LAZY);
24   if (h2 == NULL)
25     {
26       printf ("cannot open reldepmod2.so: %s\n", dlerror ());
27       exit (1);
28     }
29
30   /* Get the address of the variable in reldepmod1.so.  */
31   vp = dlsym (h1, "some_var");
32   if (vp == NULL)
33     {
34       printf ("cannot get address of \"some_var\": %s\n", dlerror ());
35       exit (1);
36     }
37
38   *vp = 42;
39
40   /* Get the function `call_me' in the second object.  This has a
41      dependency which is resolved by a definition in reldepmod1.so.  */
42   fp = dlsym (h2, "call_me");
43   if (fp == NULL)
44     {
45       printf ("cannot get address of \"call_me\": %s\n", dlerror ());
46       exit (1);
47     }
48
49   /* Call the function.  */
50   if (fp () != 0)
51     {
52       puts ("function \"call_me\" returned wrong result");
53       exit (1);
54     }
55
56   /* Now close the first object.  If must still be around since we have
57      an implicit dependency.  */
58   if (dlclose (h1) != 0)
59     {
60       printf ("closing h1 failed: %s\n", dlerror ());
61       exit (1);
62     }
63
64   /* Try calling the function again.  This will fail if the first object
65      got unloaded.  */
66   if (fp () != 0)
67     {
68       puts ("second call of function \"call_me\" returned wrong result");
69       exit (1);
70     }
71
72   /* Now close the second file as well.  */
73   if (dlclose (h2) != 0)
74     {
75       printf ("closing h2 failed: %s\n", dlerror ());
76       exit (1);
77     }
78
79   /* Finally, open the first object again.   */
80   h1 = dlopen ("reldepmod1.so", RTLD_LAZY | RTLD_GLOBAL);
81   if (h1 == NULL)
82     {
83       printf ("cannot open reldepmod1.so the second time: %s\n", dlerror ());
84       exit (1);
85     }
86
87   /* And get the variable address again.  */
88   vp = dlsym (h1, "some_var");
89   if (vp == NULL)
90     {
91       printf ("cannot get address of \"some_var\" the second time: %s\n",
92               dlerror ());
93       exit (1);
94     }
95
96   /* The variable now must have its originial value.  */
97   if (*vp != 0)
98     {
99       puts ("variable \"some_var\" not reset");
100       exit (1);
101     }
102
103   /* Close the first object again, we are done.  */
104   if (dlclose (h1) != 0)
105     {
106       printf ("closing h1 failed: %s\n", dlerror ());
107       exit (1);
108     }
109
110   return 0;
111 }