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 typedef int (*foo_p) (void);
13
14 int
15 __attribute__ ((noinline))
foo(void)16 foo (void)
17 {
18 return -30;
19 }
20
21 int
22 __attribute__ ((noinline))
foo_hidden(void)23 foo_hidden (void)
24 {
25 return -20;
26 }
27
28 int
29 __attribute__ ((noinline))
foo_protected(void)30 foo_protected (void)
31 {
32 return -40;
33 }
34
35 int
main(void)36 main (void)
37 {
38 foo_p p;
39 foo_p (*f) (void);
40 int *ret;
41
42 void *h = dlopen ("ifuncmod3.so", RTLD_LAZY);
43 if (h == NULL)
44 {
45 printf ("cannot load: %s\n", dlerror ());
46 return 1;
47 }
48
49 p = dlsym (h, "foo");
50 if (p == NULL)
51 {
52 printf ("symbol not found: %s\n", dlerror ());
53 return 1;
54 }
55 if ((*p) () != -1)
56 abort ();
57
58 f = dlsym (h, "get_foo_p");
59 if (f == NULL)
60 {
61 printf ("symbol not found: %s\n", dlerror ());
62 return 1;
63 }
64
65 ret = dlsym (h, "ret_foo");
66 if (ret == NULL)
67 {
68 printf ("symbol not found: %s\n", dlerror ());
69 return 1;
70 }
71
72 p = (*f) ();
73 if (p != foo)
74 abort ();
75 if (foo () != -30)
76 abort ();
77 if (*ret != -30 || (*p) () != *ret)
78 abort ();
79
80 f = dlsym (h, "get_foo_hidden_p");
81 if (f == NULL)
82 {
83 printf ("symbol not found: %s\n", dlerror ());
84 return 1;
85 }
86
87 ret = dlsym (h, "ret_foo_hidden");
88 if (ret == NULL)
89 {
90 printf ("symbol not found: %s\n", dlerror ());
91 return 1;
92 }
93
94 p = (*f) ();
95 if (foo_hidden () != -20)
96 abort ();
97 if (*ret != 1 || (*p) () != *ret)
98 abort ();
99
100 f = dlsym (h, "get_foo_protected_p");
101 if (f == NULL)
102 {
103 printf ("symbol not found: %s\n", dlerror ());
104 return 1;
105 }
106
107 ret = dlsym (h, "ret_foo_protected");
108 if (ret == NULL)
109 {
110 printf ("symbol not found: %s\n", dlerror ());
111 return 1;
112 }
113
114 p = (*f) ();
115 if (p == foo_protected)
116 abort ();
117 if (foo_protected () != -40)
118 abort ();
119 if (*ret != 0 || (*p) () != *ret)
120 abort ();
121
122 if (dlclose (h) != 0)
123 {
124 printf ("cannot close: %s\n", dlerror ());
125 return 1;
126 }
127
128 return 0;
129 }
130