PR binutils/12467
[binutils.git] / gold / testsuite / ifuncmain3.c
blob8e543e59537a2c74b0bfa803d0cd9ebe6ec4840d
1 /* Test STT_GNU_IFUNC symbols with dlopen:
3 1. Direct function call.
4 2. Function pointer.
5 3. Visibility with override.
6 */
8 #include <dlfcn.h>
9 #include <stdlib.h>
10 #include <stdio.h>
12 extern int __attribute__ ((noinline)) foo (void);
13 extern int __attribute__ ((noinline)) foo_hidden (void);
14 extern int __attribute__ ((noinline)) foo_protected (void);
16 typedef int (*foo_p) (void);
18 int
19 __attribute__ ((noinline))
20 foo (void)
22 return -30;
25 int
26 __attribute__ ((noinline))
27 foo_hidden (void)
29 return -20;
32 int
33 __attribute__ ((noinline))
34 foo_protected (void)
36 return -40;
39 int
40 main (void)
42 foo_p p;
43 foo_p (*f) (void);
44 int *ret;
46 void *h = dlopen ("ifuncmod3.so", RTLD_LAZY);
47 if (h == NULL)
49 printf ("cannot load: %s\n", dlerror ());
50 return 1;
53 p = dlsym (h, "foo");
54 if (p == NULL)
56 printf ("symbol not found: %s\n", dlerror ());
57 return 1;
59 if ((*p) () != -1)
60 abort ();
62 f = dlsym (h, "get_foo_p");
63 if (f == NULL)
65 printf ("symbol not found: %s\n", dlerror ());
66 return 1;
69 ret = dlsym (h, "ret_foo");
70 if (ret == NULL)
72 printf ("symbol not found: %s\n", dlerror ());
73 return 1;
76 p = (*f) ();
77 if (p != foo)
78 abort ();
79 if (foo () != -30)
80 abort ();
81 if (*ret != -30 || (*p) () != *ret)
82 abort ();
84 f = dlsym (h, "get_foo_hidden_p");
85 if (f == NULL)
87 printf ("symbol not found: %s\n", dlerror ());
88 return 1;
91 ret = dlsym (h, "ret_foo_hidden");
92 if (ret == NULL)
94 printf ("symbol not found: %s\n", dlerror ());
95 return 1;
98 p = (*f) ();
99 if (foo_hidden () != -20)
100 abort ();
101 if (*ret != 1 || (*p) () != *ret)
102 abort ();
104 f = dlsym (h, "get_foo_protected_p");
105 if (f == NULL)
107 printf ("symbol not found: %s\n", dlerror ());
108 return 1;
111 ret = dlsym (h, "ret_foo_protected");
112 if (ret == NULL)
114 printf ("symbol not found: %s\n", dlerror ());
115 return 1;
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 ();
126 if (dlclose (h) != 0)
128 printf ("cannot close: %s\n", dlerror ());
129 return 1;
132 return 0;