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 18 static void * __attribute__ ((used)) foo_ifunc (void) __asm__ ("foo"); 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 } 75