1 | /* Test STT_GNU_IFUNC symbols in PIE: |
2 | |
3 | 1. Direct function call. |
4 | 2. Function pointer. |
5 | 3. Reference from a shared library. |
6 | */ |
7 | |
8 | #include <stdlib.h> |
9 | #include "ifunc-sel.h" |
10 | |
11 | typedef int (*foo_p) (void); |
12 | |
13 | static int |
14 | one (void) |
15 | { |
16 | return -30; |
17 | } |
18 | |
19 | void * foo_ifunc (void) __asm__ ("foo" ); |
20 | __asm__(".type foo, %gnu_indirect_function" ); |
21 | |
22 | void * |
23 | inhibit_stack_protector |
24 | foo_ifunc (void) |
25 | { |
26 | return ifunc_one (f1: one); |
27 | } |
28 | |
29 | extern int foo (void); |
30 | extern int call_foo (void); |
31 | extern foo_p get_foo_p (void); |
32 | |
33 | foo_p foo_ptr = foo; |
34 | |
35 | int |
36 | main (void) |
37 | { |
38 | foo_p p; |
39 | |
40 | if (call_foo () != -30) |
41 | abort (); |
42 | |
43 | p = get_foo_p (); |
44 | if (p != foo) |
45 | abort (); |
46 | if ((*p) () != -30) |
47 | abort (); |
48 | |
49 | if (foo_ptr != foo) |
50 | abort (); |
51 | if ((*foo_ptr) () != -30) |
52 | abort (); |
53 | if (foo () != -30) |
54 | abort (); |
55 | |
56 | return 0; |
57 | } |
58 | |