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