Commit | Line | Data |
---|---|---|
7223e9ca ILT |
1 | /* Test local STT_GNU_IFUNC symbols: |
2 | ||
3 | 1. Direct function call. | |
4 | 2. Function pointer. | |
5 | */ | |
6 | ||
7 | #include <stdlib.h> | |
8 | #include "ifunc-sel.h" | |
9 | ||
10 | extern int foo (void); | |
11 | ||
12 | static int | |
13 | one (void) | |
14 | { | |
15 | return -30; | |
16 | } | |
17 | ||
6695e4b3 | 18 | static void * __attribute__ ((used)) foo_ifunc (void) __asm__ ("foo"); |
7223e9ca ILT |
19 | __asm__(".type foo, %gnu_indirect_function"); |
20 | ||
21 | static void * | |
22 | __attribute__ ((used)) | |
23 | foo_ifunc (void) | |
24 | { | |
25 | return ifunc_one (one); | |
26 | } | |
27 | ||
28 | typedef int (*foo_p) (void); | |
29 | ||
30 | extern foo_p __attribute__ ((noinline)) get_foo_p (void); | |
31 | extern foo_p __attribute__ ((noinline)) get_foo (void); | |
32 | ||
33 | foo_p foo_ptr = foo; | |
34 | ||
35 | foo_p | |
36 | __attribute__ ((noinline)) | |
37 | get_foo_p (void) | |
38 | { | |
39 | return foo_ptr; | |
40 | } | |
41 | ||
42 | foo_p | |
43 | __attribute__ ((noinline)) | |
44 | get_foo (void) | |
45 | { | |
46 | return foo; | |
47 | } | |
48 | ||
49 | int | |
50 | main (void) | |
51 | { | |
52 | foo_p p; | |
53 | ||
54 | p = get_foo (); | |
55 | if (p != foo) | |
56 | abort (); | |
57 | if ((*p) () != -30) | |
58 | abort (); | |
59 | ||
60 | p = get_foo_p (); | |
61 | if (p != foo) | |
62 | abort (); | |
63 | if ((*p) () != -30) | |
64 | abort (); | |
65 | ||
66 | if (foo_ptr != foo) | |
67 | abort (); | |
68 | if ((*foo_ptr) () != -30) | |
69 | abort (); | |
70 | if (foo () != -30) | |
71 | abort (); | |
72 | ||
73 | return 0; | |
74 | } |