2015-02-13 Steve Ellcey <sellcey@imgtec.com>
[glibc.git] / elf / ifuncmain3.c
blob1574dd5cbe461efbb6852bc3b89d743d56dfdce3
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 typedef int (*foo_p) (void);
14 int
15 __attribute__ ((noinline))
16 foo (void)
18 return -30;
21 int
22 __attribute__ ((noinline))
23 foo_hidden (void)
25 return -20;
28 int
29 __attribute__ ((noinline))
30 foo_protected (void)
32 return -40;
35 int
36 main (void)
38 foo_p p;
39 foo_p (*f) (void);
40 int *ret;
42 void *h = dlopen ("ifuncmod3.so", RTLD_LAZY);
43 if (h == NULL)
45 printf ("cannot load: %s\n", dlerror ());
46 return 1;
49 p = dlsym (h, "foo");
50 if (p == NULL)
52 printf ("symbol not found: %s\n", dlerror ());
53 return 1;
55 if ((*p) () != -1)
56 abort ();
58 f = dlsym (h, "get_foo_p");
59 if (f == NULL)
61 printf ("symbol not found: %s\n", dlerror ());
62 return 1;
65 ret = dlsym (h, "ret_foo");
66 if (ret == NULL)
68 printf ("symbol not found: %s\n", dlerror ());
69 return 1;
72 p = (*f) ();
73 if (p != foo)
74 abort ();
75 if (foo () != -30)
76 abort ();
77 if (*ret != -30 || (*p) () != *ret)
78 abort ();
80 f = dlsym (h, "get_foo_hidden_p");
81 if (f == NULL)
83 printf ("symbol not found: %s\n", dlerror ());
84 return 1;
87 ret = dlsym (h, "ret_foo_hidden");
88 if (ret == NULL)
90 printf ("symbol not found: %s\n", dlerror ());
91 return 1;
94 p = (*f) ();
95 if (foo_hidden () != -20)
96 abort ();
97 if (*ret != 1 || (*p) () != *ret)
98 abort ();
100 f = dlsym (h, "get_foo_protected_p");
101 if (f == NULL)
103 printf ("symbol not found: %s\n", dlerror ());
104 return 1;
107 ret = dlsym (h, "ret_foo_protected");
108 if (ret == NULL)
110 printf ("symbol not found: %s\n", dlerror ());
111 return 1;
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 ();
122 if (dlclose (h) != 0)
124 printf ("cannot close: %s\n", dlerror ());
125 return 1;
128 return 0;