Commit | Line | Data |
---|---|---|
7223e9ca ILT |
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 | extern foo_p foo_ptr; | |
13 | ||
14 | static int | |
15 | one (void) | |
16 | { | |
17 | return -30; | |
18 | } | |
19 | ||
20 | void * foo_ifunc (void) __asm__ ("foo"); | |
21 | __asm__(".type foo, %gnu_indirect_function"); | |
22 | ||
23 | void * | |
24 | foo_ifunc (void) | |
25 | { | |
26 | return ifunc_one (one); | |
27 | } | |
28 | ||
29 | extern int foo (void); | |
30 | extern foo_p get_foo (void); | |
31 | extern foo_p get_foo_p (void); | |
32 | ||
33 | foo_p my_foo_ptr = foo; | |
34 | ||
35 | int | |
36 | main (void) | |
37 | { | |
38 | foo_p p; | |
39 | ||
40 | p = get_foo (); | |
41 | if (p != foo) | |
42 | abort (); | |
43 | if ((*p) () != -30) | |
44 | abort (); | |
45 | ||
46 | p = get_foo_p (); | |
47 | if (p != foo) | |
48 | abort (); | |
49 | if ((*p) () != -30) | |
50 | abort (); | |
51 | ||
52 | if (foo_ptr != foo) | |
53 | abort (); | |
54 | if (my_foo_ptr != foo) | |
55 | abort (); | |
56 | if ((*foo_ptr) () != -30) | |
57 | abort (); | |
58 | if ((*my_foo_ptr) () != -30) | |
59 | abort (); | |
60 | if (foo () != -30) | |
61 | abort (); | |
62 | ||
63 | return 0; | |
64 | } |