Upload Tizen:Base source
[external/binutils.git] / gold / testsuite / ifuncmain3.c
1 /* Test STT_GNU_IFUNC symbols with dlopen:
2
3    1. Direct function call.
4    2. Function pointer.
5    3. Visibility with override.
6  */
7
8 #include <dlfcn.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11
12 extern int __attribute__ ((noinline)) foo (void);
13 extern int __attribute__ ((noinline)) foo_hidden (void);
14 extern int __attribute__ ((noinline)) foo_protected (void);
15
16 typedef int (*foo_p) (void);
17
18 int
19 __attribute__ ((noinline))
20 foo (void)
21 {
22   return -30;
23 }
24
25 int
26 __attribute__ ((noinline))
27 foo_hidden (void)
28 {
29   return -20;
30 }
31
32 int
33 __attribute__ ((noinline))
34 foo_protected (void)
35 {
36   return -40;
37 }
38
39 int
40 main (void)
41 {
42   foo_p p;
43   foo_p (*f) (void);
44   int *ret;
45
46   void *h = dlopen ("ifuncmod3.so", RTLD_LAZY);
47   if (h == NULL)
48     {
49       printf ("cannot load: %s\n", dlerror ());
50       return 1;
51     }
52
53   p = dlsym (h, "foo");
54   if (p == NULL)
55     {
56       printf ("symbol not found: %s\n", dlerror ());
57       return 1;
58     }
59   if ((*p) () != -1)
60     abort ();
61
62   f = dlsym (h, "get_foo_p");
63   if (f == NULL)
64     {
65       printf ("symbol not found: %s\n", dlerror ());
66       return 1;
67     }
68
69   ret = dlsym (h, "ret_foo");
70   if (ret == NULL)
71     {
72       printf ("symbol not found: %s\n", dlerror ());
73       return 1;
74     }
75
76   p = (*f) ();
77   if (p != foo)
78     abort ();
79   if (foo () != -30)
80     abort ();
81   if (*ret != -30 || (*p) () != *ret)
82     abort ();
83
84   f = dlsym (h, "get_foo_hidden_p");
85   if (f == NULL)
86     {
87       printf ("symbol not found: %s\n", dlerror ());
88       return 1;
89     }
90
91   ret = dlsym (h, "ret_foo_hidden");
92   if (ret == NULL)
93     {
94       printf ("symbol not found: %s\n", dlerror ());
95       return 1;
96     }
97
98   p = (*f) ();
99   if (foo_hidden () != -20)
100     abort ();
101   if (*ret != 1 || (*p) () != *ret)
102     abort ();
103
104   f = dlsym (h, "get_foo_protected_p");
105   if (f == NULL)
106     {
107       printf ("symbol not found: %s\n", dlerror ());
108       return 1;
109     }
110
111   ret = dlsym (h, "ret_foo_protected");
112   if (ret == NULL)
113     {
114       printf ("symbol not found: %s\n", dlerror ());
115       return 1;
116     }
117
118   p = (*f) ();
119   if (p == foo_protected)
120     abort ();
121   if (foo_protected () != -40)
122     abort ();
123   if (*ret != 0 || (*p) () != *ret)
124     abort ();
125
126   if (dlclose (h) != 0)
127     {
128       printf ("cannot close: %s\n", dlerror ());
129       return 1;
130     }
131
132   return 0;
133 }