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