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