(root)/
binutils-2.41/
gold/
testsuite/
ifuncmain3.c
       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  }