| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | /* Test STT_GNU_IFUNC symbols in PIE: | 
|  | 2 |  | 
|  | 3 | 1. Direct function call. | 
|  | 4 | 2. Function pointer. | 
|  | 5 | 3. Reference from a shared library. | 
|  | 6 | */ | 
|  | 7 |  | 
|  | 8 | #include <stdlib.h> | 
|  | 9 | #include "ifunc-sel.h" | 
|  | 10 |  | 
|  | 11 | typedef int (*foo_p) (void); | 
|  | 12 | extern foo_p foo_ptr; | 
|  | 13 |  | 
|  | 14 | static int | 
|  | 15 | one (void) | 
|  | 16 | { | 
|  | 17 | return -30; | 
|  | 18 | } | 
|  | 19 |  | 
|  | 20 | void * foo_ifunc (void) __asm__ ("foo"); | 
|  | 21 | __asm__(".type foo, %gnu_indirect_function"); | 
|  | 22 |  | 
|  | 23 | void * | 
|  | 24 | foo_ifunc (void) | 
|  | 25 | { | 
|  | 26 | return ifunc_one (one); | 
|  | 27 | } | 
|  | 28 |  | 
|  | 29 | extern int foo (void); | 
|  | 30 | extern foo_p get_foo (void); | 
|  | 31 | extern foo_p get_foo_p (void); | 
|  | 32 |  | 
|  | 33 | foo_p my_foo_ptr = foo; | 
|  | 34 |  | 
|  | 35 | int | 
|  | 36 | main (void) | 
|  | 37 | { | 
|  | 38 | foo_p p; | 
|  | 39 |  | 
|  | 40 | p = get_foo (); | 
|  | 41 | if (p != foo) | 
|  | 42 | abort (); | 
|  | 43 | if ((*p) () != -30) | 
|  | 44 | abort (); | 
|  | 45 |  | 
|  | 46 | p = get_foo_p (); | 
|  | 47 | if (p != foo) | 
|  | 48 | abort (); | 
|  | 49 | if ((*p) () != -30) | 
|  | 50 | abort (); | 
|  | 51 |  | 
|  | 52 | if (foo_ptr != foo) | 
|  | 53 | abort (); | 
|  | 54 | if (my_foo_ptr != foo) | 
|  | 55 | abort (); | 
|  | 56 | if ((*foo_ptr) () != -30) | 
|  | 57 | abort (); | 
|  | 58 | if ((*my_foo_ptr) () != -30) | 
|  | 59 | abort (); | 
|  | 60 | if (foo () != -30) | 
|  | 61 | abort (); | 
|  | 62 |  | 
|  | 63 | return 0; | 
|  | 64 | } |