(root)/
glibc-2.38/
elf/
ifuncmod1.c
       1  /* Test STT_GNU_IFUNC symbols:
       2  
       3     1. Direct function call.
       4     2. Function pointer.
       5     3. Visibility.
       6   */
       7  #include "ifunc-sel.h"
       8  
       9  int global = -1;
      10  /* Can't use __attribute__((visibility("protected"))) until the GCC bug:
      11  
      12     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248
      13  
      14     is fixed.  */
      15  asm (".protected global");
      16  
      17  static int
      18  one (void)
      19  {
      20    return 1;
      21  }
      22  
      23  static int
      24  minus_one (void)
      25  {
      26    return -1;
      27  }
      28  
      29  static int
      30  zero (void)
      31  {
      32    return 0;
      33  }
      34  
      35  void * foo_ifunc (void) __asm__ ("foo");
      36  __asm__(".type foo, %gnu_indirect_function");
      37  
      38  void *
      39  inhibit_stack_protector
      40  foo_ifunc (void)
      41  {
      42    return ifunc_sel (one, minus_one, zero);
      43  }
      44  
      45  void * foo_hidden_ifunc (void) __asm__ ("foo_hidden");
      46  __asm__(".type foo_hidden, %gnu_indirect_function");
      47  
      48  void *
      49  inhibit_stack_protector
      50  foo_hidden_ifunc (void)
      51  {
      52    return ifunc_sel (minus_one, one, zero);
      53  }
      54  
      55  void * foo_protected_ifunc (void) __asm__ ("foo_protected");
      56  __asm__(".type foo_protected, %gnu_indirect_function");
      57  
      58  void *
      59  inhibit_stack_protector
      60  foo_protected_ifunc (void)
      61  {
      62    return ifunc_sel (one, zero, minus_one);
      63  }
      64  
      65  /* Test hidden indirect function.  */
      66  __asm__(".hidden foo_hidden");
      67  
      68  /* Test protected indirect function.  */
      69  __asm__(".protected foo_protected");
      70  
      71  extern int foo (void);
      72  extern int foo_hidden (void);
      73  extern int foo_protected (void);
      74  extern int ret_foo;
      75  extern int ret_foo_hidden;
      76  extern int ret_foo_protected;
      77  
      78  #define FOO_P
      79  typedef int (*foo_p) (void);
      80  
      81  foo_p
      82  get_foo_p (void)
      83  {
      84    ret_foo = foo ();
      85    return foo;
      86  }
      87  
      88  foo_p
      89  get_foo_hidden_p (void)
      90  {
      91    ret_foo_hidden = foo_hidden ();
      92    return foo_hidden;
      93  }
      94  
      95  foo_p
      96  get_foo_protected_p (void)
      97  {
      98    ret_foo_protected = foo_protected ();
      99    return foo_protected;
     100  }