1 /* Test STT_GNU_IFUNC symbols: 2 3 1. Direct function call. 4 2. Function pointer. 5 3. Visibility with override. 6 */ 7 8 #include <stdlib.h> 9 10 int __attribute__ ((noinline)) foo_hidden (void); 11 12 int ret_foo; 13 int ret_foo_hidden; 14 int ret_foo_protected; 15 16 extern int foo (void); 17 extern int foo_protected (void); 18 19 #ifndef FOO_P 20 typedef int (*foo_p) (void); 21 #endif 22 23 foo_p foo_ptr = foo; 24 foo_p foo_procted_ptr = foo_protected; 25 26 extern foo_p get_foo_p (void); 27 extern foo_p get_foo_hidden_p (void); 28 extern foo_p get_foo_protected_p (void); 29 30 int 31 __attribute__ ((noinline)) 32 foo (void) 33 { 34 return -30; 35 } 36 37 int 38 __attribute__ ((noinline)) 39 foo_hidden (void) 40 { 41 return -20; 42 } 43 44 int 45 __attribute__ ((noinline)) 46 foo_protected (void) 47 { 48 return -40; 49 } 50 51 int 52 main (void) 53 { 54 foo_p p; 55 56 if (foo_ptr != foo) 57 abort (); 58 if ((*foo_ptr) () != -30) 59 abort (); 60 61 if (foo_procted_ptr != foo_protected) 62 abort (); 63 if ((*foo_procted_ptr) () != -40) 64 abort (); 65 66 p = get_foo_p (); 67 if (p != foo) 68 abort (); 69 if (foo () != -30) 70 abort (); 71 if (ret_foo != -30 || (*p) () != ret_foo) 72 abort (); 73 74 p = get_foo_hidden_p (); 75 if (foo_hidden () != -20) 76 abort (); 77 if (ret_foo_hidden != 1 || (*p) () != ret_foo_hidden) 78 abort (); 79 80 p = get_foo_protected_p (); 81 if (p == foo_protected) 82 abort (); 83 if (foo_protected () != -40) 84 abort (); 85 if (ret_foo_protected != 0 || (*p) () != ret_foo_protected) 86 abort (); 87 88 return 0; 89 } 90