Home | History | Annotate | Download | only in testsuite
      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 }
     75