| /* Test STT_GNU_IFUNC symbols: | |
| 1. Direct function call. | |
| 2. Function pointer. | |
| 3. Visibility. | |
| */ | |
| #include "ifunc-sel.h" | |
| int global __attribute__ ((visibility ("hidden"))) = -1; | |
| static int | |
| one (void) | |
| { | |
| return 1; | |
| } | |
| static int | |
| minus_one (void) | |
| { | |
| return -1; | |
| } | |
| static int | |
| zero (void) | |
| { | |
| return 0; | |
| } | |
| void * foo_ifunc (void) __asm__ ("foo"); | |
| __asm__(".type foo, %gnu_indirect_function"); | |
| void * | |
| foo_ifunc (void) | |
| { | |
| return ifunc_sel (one, minus_one, zero); | |
| } | |
| void * foo_hidden_ifunc (void) __asm__ ("foo_hidden"); | |
| __asm__(".type foo_hidden, %gnu_indirect_function"); | |
| void * | |
| foo_hidden_ifunc (void) | |
| { | |
| return ifunc_sel (minus_one, one, zero); | |
| } | |
| void * foo_protected_ifunc (void) __asm__ ("foo_protected"); | |
| __asm__(".type foo_protected, %gnu_indirect_function"); | |
| void * | |
| foo_protected_ifunc (void) | |
| { | |
| return ifunc_sel (one, zero, minus_one); | |
| } | |
| /* Test hidden indirect function. */ | |
| __asm__(".hidden foo_hidden"); | |
| /* Test protected indirect function. */ | |
| __asm__(".protected foo_protected"); | |
| extern int foo (void); | |
| extern int foo_hidden (void); | |
| extern int foo_protected (void); | |
| extern int ret_foo; | |
| extern int ret_foo_hidden; | |
| extern int ret_foo_protected; | |
| #define FOO_P | |
| typedef int (*foo_p) (void); | |
| extern foo_p get_foo_p (void); | |
| extern foo_p get_foo_hidden_p (void); | |
| extern foo_p get_foo_protected_p (void); | |
| foo_p | |
| get_foo_p (void) | |
| { | |
| ret_foo = foo (); | |
| return foo; | |
| } | |
| foo_p | |
| get_foo_hidden_p (void) | |
| { | |
| ret_foo_hidden = foo_hidden (); | |
| return foo_hidden; | |
| } | |
| foo_p | |
| get_foo_protected_p (void) | |
| { | |
| ret_foo_protected = foo_protected (); | |
| return foo_protected; | |
| } |