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