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