1/* Test STT_GNU_IFUNC symbols:
2
3 1. Direct function call.
4 2. Function pointer.
5 3. Visibility with override.
6 */
7
8#include <stdlib.h>
9
10int ret_foo;
11int ret_foo_hidden;
12int ret_foo_protected;
13
14extern int foo (void);
15extern int foo_protected (void);
16
17#ifndef FOO_P
18typedef int (*foo_p) (void);
19#endif
20
21foo_p foo_ptr = foo;
22foo_p foo_procted_ptr = foo_protected;
23
24extern foo_p get_foo_p (void);
25extern foo_p get_foo_hidden_p (void);
26extern foo_p get_foo_protected_p (void);
27
28int
29__attribute__ ((noinline))
30foo (void)
31{
32 return -30;
33}
34
35int
36__attribute__ ((noinline))
37foo_hidden (void)
38{
39 return -20;
40}
41
42int
43__attribute__ ((noinline))
44foo_protected (void)
45{
46 return -40;
47}
48
49int
50main (void)
51{
52 foo_p p;
53
54 if (foo_ptr != foo)
55 abort ();
56 if ((*foo_ptr) () != -30)
57 abort ();
58
59 if (foo_procted_ptr != foo_protected)
60 abort ();
61 if ((*foo_procted_ptr) () != -40)
62 abort ();
63
64 p = get_foo_p ();
65 if (p != foo)
66 abort ();
67 if (foo () != -30)
68 abort ();
69 if (ret_foo != -30 || (*p) () != ret_foo)
70 abort ();
71
72 p = get_foo_hidden_p ();
73 if (foo_hidden () != -20)
74 abort ();
75 if (ret_foo_hidden != 1 || (*p) () != ret_foo_hidden)
76 abort ();
77
78 p = get_foo_protected_p ();
79 if (p == foo_protected)
80 abort ();
81 if (foo_protected () != -40)
82 abort ();
83 if (ret_foo_protected != 0 || (*p) () != ret_foo_protected)
84 abort ();
85
86 return 0;
87}
88

source code of glibc/elf/ifuncmain1vis.c