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  inhibit_stack_protector
      24  foo_ifunc (void)
      25  {
      26    return ifunc_one (one);
      27  }
      28  
      29  typedef int (*foo_p) (void);
      30  
      31  foo_p foo_ptr = foo;
      32  
      33  foo_p
      34  __attribute__ ((noinline))
      35  get_foo_p (void)
      36  {
      37    return foo_ptr;
      38  }
      39  
      40  foo_p
      41  __attribute__ ((noinline))
      42  get_foo (void)
      43  {
      44    return foo;
      45  }
      46  
      47  int
      48  main (void)
      49  {
      50    foo_p p;
      51  
      52    p = get_foo ();
      53    if (p != foo)
      54      abort ();
      55    if ((*p) () != -30)
      56      abort ();
      57  
      58    p = get_foo_p ();
      59    if (p != foo)
      60      abort ();
      61    if ((*p) () != -30)
      62      abort ();
      63  
      64    if (foo_ptr != foo)
      65      abort ();
      66    if ((*foo_ptr) () != -30)
      67      abort ();
      68    if (foo () != -30)
      69      abort ();
      70  
      71    return 0;
      72  }