Commit | Line | Data |
---|---|---|
7223e9ca ILT |
1 | /* Test STT_GNU_IFUNC symbols with dlopen: |
2 | ||
3 | 1. Direct function call. | |
4 | 2. Function pointer. | |
5 | 3. Visibility with override. | |
6 | */ | |
7 | ||
8 | #include <dlfcn.h> | |
9 | #include <stdlib.h> | |
10 | #include <stdio.h> | |
11 | ||
12 | extern int __attribute__ ((noinline)) foo (void); | |
13 | extern int __attribute__ ((noinline)) foo_hidden (void); | |
14 | extern int __attribute__ ((noinline)) foo_protected (void); | |
15 | ||
16 | typedef int (*foo_p) (void); | |
17 | ||
18 | int | |
19 | __attribute__ ((noinline)) | |
20 | foo (void) | |
21 | { | |
22 | return -30; | |
23 | } | |
24 | ||
25 | int | |
26 | __attribute__ ((noinline)) | |
27 | foo_hidden (void) | |
28 | { | |
29 | return -20; | |
30 | } | |
31 | ||
32 | int | |
33 | __attribute__ ((noinline)) | |
34 | foo_protected (void) | |
35 | { | |
36 | return -40; | |
37 | } | |
38 | ||
39 | int | |
40 | main (void) | |
41 | { | |
42 | foo_p p; | |
43 | foo_p (*f) (void); | |
44 | int *ret; | |
45 | ||
46 | void *h = dlopen ("ifuncmod3.so", RTLD_LAZY); | |
47 | if (h == NULL) | |
48 | { | |
49 | printf ("cannot load: %s\n", dlerror ()); | |
50 | return 1; | |
51 | } | |
52 | ||
53 | p = dlsym (h, "foo"); | |
54 | if (p == NULL) | |
55 | { | |
56 | printf ("symbol not found: %s\n", dlerror ()); | |
57 | return 1; | |
58 | } | |
59 | if ((*p) () != -1) | |
60 | abort (); | |
61 | ||
62 | f = dlsym (h, "get_foo_p"); | |
63 | if (f == NULL) | |
64 | { | |
65 | printf ("symbol not found: %s\n", dlerror ()); | |
66 | return 1; | |
67 | } | |
68 | ||
69 | ret = dlsym (h, "ret_foo"); | |
70 | if (ret == NULL) | |
71 | { | |
72 | printf ("symbol not found: %s\n", dlerror ()); | |
73 | return 1; | |
74 | } | |
75 | ||
76 | p = (*f) (); | |
77 | if (p != foo) | |
78 | abort (); | |
79 | if (foo () != -30) | |
80 | abort (); | |
81 | if (*ret != -30 || (*p) () != *ret) | |
82 | abort (); | |
83 | ||
84 | f = dlsym (h, "get_foo_hidden_p"); | |
85 | if (f == NULL) | |
86 | { | |
87 | printf ("symbol not found: %s\n", dlerror ()); | |
88 | return 1; | |
89 | } | |
90 | ||
91 | ret = dlsym (h, "ret_foo_hidden"); | |
92 | if (ret == NULL) | |
93 | { | |
94 | printf ("symbol not found: %s\n", dlerror ()); | |
95 | return 1; | |
96 | } | |
97 | ||
98 | p = (*f) (); | |
99 | if (foo_hidden () != -20) | |
100 | abort (); | |
101 | if (*ret != 1 || (*p) () != *ret) | |
102 | abort (); | |
103 | ||
104 | f = dlsym (h, "get_foo_protected_p"); | |
105 | if (f == NULL) | |
106 | { | |
107 | printf ("symbol not found: %s\n", dlerror ()); | |
108 | return 1; | |
109 | } | |
110 | ||
111 | ret = dlsym (h, "ret_foo_protected"); | |
112 | if (ret == NULL) | |
113 | { | |
114 | printf ("symbol not found: %s\n", dlerror ()); | |
115 | return 1; | |
116 | } | |
117 | ||
118 | p = (*f) (); | |
119 | if (p == foo_protected) | |
120 | abort (); | |
121 | if (foo_protected () != -40) | |
122 | abort (); | |
123 | if (*ret != 0 || (*p) () != *ret) | |
124 | abort (); | |
125 | ||
126 | if (dlclose (h) != 0) | |
127 | { | |
128 | printf ("cannot close: %s\n", dlerror ()); | |
129 | return 1; | |
130 | } | |
131 | ||
132 | return 0; | |
133 | } |