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 } 134