1/* Test STT_GNU_IFUNC symbols:
2
3 1. Direct function call.
4 2. Function pointer.
5 3. Visibility.
6 */
7#include "ifunc-sel.h"
8
9int global = -1;
10/* Can't use __attribute__((visibility("protected"))) until the GCC bug:
11
12 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248
13
14 is fixed. */
15asm (".protected global");
16
17static int
18one (void)
19{
20 return 1;
21}
22
23static int
24minus_one (void)
25{
26 return -1;
27}
28
29static int
30zero (void)
31{
32 return 0;
33}
34
35void * foo_ifunc (void) __asm__ ("foo");
36__asm__(".type foo, %gnu_indirect_function");
37
38void *
39inhibit_stack_protector
40foo_ifunc (void)
41{
42 return ifunc_sel (f1: one, f2: minus_one, f3: zero);
43}
44
45void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
46__asm__(".type foo_hidden, %gnu_indirect_function");
47
48void *
49inhibit_stack_protector
50foo_hidden_ifunc (void)
51{
52 return ifunc_sel (f1: minus_one, f2: one, f3: zero);
53}
54
55void * foo_protected_ifunc (void) __asm__ ("foo_protected");
56__asm__(".type foo_protected, %gnu_indirect_function");
57
58void *
59inhibit_stack_protector
60foo_protected_ifunc (void)
61{
62 return ifunc_sel (f1: one, f2: zero, f3: minus_one);
63}
64
65/* Test hidden indirect function. */
66__asm__(".hidden foo_hidden");
67
68/* Test protected indirect function. */
69__asm__(".protected foo_protected");
70
71extern int foo (void);
72extern int foo_hidden (void);
73extern int foo_protected (void);
74extern int ret_foo;
75extern int ret_foo_hidden;
76extern int ret_foo_protected;
77
78#define FOO_P
79typedef int (*foo_p) (void);
80
81foo_p
82get_foo_p (void)
83{
84 ret_foo = foo ();
85 return foo;
86}
87
88foo_p
89get_foo_hidden_p (void)
90{
91 ret_foo_hidden = foo_hidden ();
92 return foo_hidden;
93}
94
95foo_p
96get_foo_protected_p (void)
97{
98 ret_foo_protected = foo_protected ();
99 return foo_protected;
100}
101

source code of glibc/elf/ifuncmod1.c