| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 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 * 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 | foo_p foo_ptr = foo; | 
|  | 31 |  | 
|  | 32 | foo_p | 
|  | 33 | __attribute__ ((noinline)) | 
|  | 34 | get_foo_p (void) | 
|  | 35 | { | 
|  | 36 | return foo_ptr; | 
|  | 37 | } | 
|  | 38 |  | 
|  | 39 | foo_p | 
|  | 40 | __attribute__ ((noinline)) | 
|  | 41 | get_foo (void) | 
|  | 42 | { | 
|  | 43 | return foo; | 
|  | 44 | } | 
|  | 45 |  | 
|  | 46 | int | 
|  | 47 | main (void) | 
|  | 48 | { | 
|  | 49 | foo_p p; | 
|  | 50 |  | 
|  | 51 | p = get_foo (); | 
|  | 52 | if (p != foo) | 
|  | 53 | abort (); | 
|  | 54 | if ((*p) () != -30) | 
|  | 55 | abort (); | 
|  | 56 |  | 
|  | 57 | p = get_foo_p (); | 
|  | 58 | if (p != foo) | 
|  | 59 | abort (); | 
|  | 60 | if ((*p) () != -30) | 
|  | 61 | abort (); | 
|  | 62 |  | 
|  | 63 | if (foo_ptr != foo) | 
|  | 64 | abort (); | 
|  | 65 | if ((*foo_ptr) () != -30) | 
|  | 66 | abort (); | 
|  | 67 | if (foo () != -30) | 
|  | 68 | abort (); | 
|  | 69 |  | 
|  | 70 | return 0; | 
|  | 71 | } |