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  
      13  static int
      14  one (void)
      15  {
      16    return -30;
      17  }
      18  
      19  void * foo_ifunc (void) __asm__ ("foo");
      20  __asm__(".type foo, %gnu_indirect_function");
      21  
      22  void *
      23  foo_ifunc (void)
      24  {
      25    return ifunc_one (one);
      26  }
      27  
      28  extern int foo (void);
      29  extern int call_foo (void);
      30  extern foo_p get_foo_p (void);
      31  
      32  foo_p foo_ptr = foo;
      33  
      34  int
      35  main (void)
      36  {
      37    foo_p p;
      38  
      39    if (call_foo () != -30)
      40      abort ();
      41  
      42    p = get_foo_p ();
      43    if (p != foo)
      44      abort ();
      45    if ((*p) () != -30)
      46      abort ();
      47  
      48    if (foo_ptr != foo)
      49      abort ();
      50    if ((*foo_ptr) () != -30)
      51      abort ();
      52    if (foo () != -30)
      53      abort ();
      54  
      55    return 0;
      56  }