(root)/
glibc-2.38/
elf/
nodelete.c
       1  #include <dlfcn.h>
       2  #include <setjmp.h>
       3  #include <signal.h>
       4  #include <stdio.h>
       5  
       6  
       7  static sigjmp_buf jmpbuf;
       8  
       9  
      10  int fini_ran;
      11  
      12  
      13  static void
      14  __attribute__ ((noreturn))
      15  handler (int sig)
      16  {
      17    siglongjmp (jmpbuf, 1);
      18  }
      19  
      20  
      21  static int
      22  do_test (void)
      23  {
      24    /* We are testing the two possibilities to mark an object as not deletable:
      25       - marked on the linker commandline with `-z nodelete'
      26       - with the RTLD_NODELETE flag at dlopen()-time.
      27  
      28       The test we are performing should be safe.  We are loading the objects,
      29       get the address of variables in the respective object, unload the object
      30       and then try to read the variable.  If the object is unloaded this
      31       should lead to an segmentation fault.  */
      32    int result = 0;
      33    void *p;
      34    struct sigaction sa;
      35  
      36    sa.sa_handler = handler;
      37    sigfillset (&sa.sa_mask);
      38    sa.sa_flags = SA_RESTART;
      39  
      40    if (sigaction (SIGSEGV, &sa, NULL) == -1)
      41      printf ("cannot install signal handler: %m\n");
      42  
      43    p = dlopen ("nodelmod1.so", RTLD_LAZY);
      44    if (p == NULL)
      45      {
      46        printf ("failed to load \"nodelmod1.so\": %s\n", dlerror ());
      47        result = 1;
      48      }
      49    else
      50      {
      51        int *varp;
      52  
      53        puts ("succeeded loading \"nodelmod1.so\"");
      54  
      55        varp = dlsym (p, "var1");
      56        if (varp == NULL)
      57  	{
      58  	  puts ("failed to get address of \"var1\" in \"nodelmod1.so\"");
      59  	  result = 1;
      60  	}
      61        else
      62  	{
      63  	  *varp = 20000720;
      64  
      65  	  /* Now close the object.  */
      66  	  fini_ran = 0;
      67  	  if (dlclose (p) != 0)
      68  	    {
      69  	      puts ("failed to close \"nodelmod1.so\"");
      70  	      result = 1;
      71  	    }
      72  	  else if (! sigsetjmp (jmpbuf, 1))
      73  	    {
      74  	      /* Access the variable again.  */
      75  	      if (*varp != 20000720)
      76  		{
      77  		  puts ("\"var1\" value not correct");
      78  		  result = 1;
      79  		}
      80  	      else if (fini_ran != 0)
      81  		{
      82  		  puts ("destructor of \"nodelmod1.so\" ran");
      83  		  result = 1;
      84  		}
      85  	      else
      86  		puts ("-z nodelete test succeeded");
      87  	    }
      88  	  else
      89  	    {
      90  	      /* We caught an segmentation fault.  */
      91  	      puts ("\"nodelmod1.so\" got deleted");
      92  	      result = 1;
      93  	    }
      94  	}
      95      }
      96  
      97    p = dlopen ("nodelmod2.so", RTLD_LAZY | RTLD_NODELETE);
      98    if (p == NULL)
      99      {
     100        printf ("failed to load \"nodelmod2.so\": %s\n", dlerror ());
     101        result = 1;
     102      }
     103    else
     104      {
     105        int *varp;
     106  
     107        puts ("succeeded loading \"nodelmod2.so\"");
     108  
     109        varp = dlsym (p, "var2");
     110        if (varp == NULL)
     111  	{
     112  	  puts ("failed to get address of \"var2\" in \"nodelmod2.so\"");
     113  	  result = 1;
     114  	}
     115        else
     116  	{
     117  	  *varp = 42;
     118  
     119  	  /* Now close the object.  */
     120  	  fini_ran = 0;
     121  	  if (dlclose (p) != 0)
     122  	    {
     123  	      puts ("failed to close \"nodelmod2.so\"");
     124  	      result = 1;
     125  	    }
     126  	  else if (! sigsetjmp (jmpbuf, 1))
     127  	    {
     128  	      /* Access the variable again.  */
     129  	      if (*varp != 42)
     130  		{
     131  		  puts ("\"var2\" value not correct");
     132  		  result = 1;
     133  		}
     134  	      else if (fini_ran != 0)
     135  		{
     136  		  puts ("destructor of \"nodelmod2.so\" ran");
     137  		  result = 1;
     138  		}
     139  	      else
     140  		puts ("RTLD_NODELETE test succeeded");
     141  	    }
     142  	  else
     143  	    {
     144  	      /* We caught an segmentation fault.  */
     145  	      puts ("\"nodelmod2.so\" got deleted");
     146  	      result = 1;
     147  	    }
     148  	}
     149      }
     150  
     151    p = dlopen ("nodelmod3.so", RTLD_LAZY);
     152    if (p == NULL)
     153      {
     154        printf ("failed to load \"nodelmod3.so\": %s\n", dlerror ());
     155        result = 1;
     156      }
     157    else
     158      {
     159        int *(*fctp) (void);
     160  
     161        puts ("succeeded loading \"nodelmod3.so\"");
     162  
     163        fctp = dlsym (p, "addr");
     164        if (fctp == NULL)
     165  	{
     166  	  puts ("failed to get address of \"addr\" in \"nodelmod3.so\"");
     167  	  result = 1;
     168  	}
     169        else
     170  	{
     171  	  int *varp = fctp ();
     172  
     173  	  *varp = -1;
     174  
     175  	  /* Now close the object.  */
     176  	  fini_ran = 0;
     177  	  if (dlclose (p) != 0)
     178  	    {
     179  	      puts ("failed to close \"nodelmod3.so\"");
     180  	      result = 1;
     181  	    }
     182  	  else if (! sigsetjmp (jmpbuf, 1))
     183  	    {
     184  	      /* Access the variable again.  */
     185  	      if (*varp != -1)
     186  		{
     187  		  puts ("\"var_in_mod4\" value not correct");
     188  		  result = 1;
     189  		}
     190  	      else if (fini_ran != 0)
     191  		{
     192  		  puts ("destructor of \"nodelmod4.so\" ran");
     193  		  result = 1;
     194  		}
     195  	      else
     196  		puts ("-z nodelete in dependency succeeded");
     197  	    }
     198  	  else
     199  	    {
     200  	      /* We caught an segmentation fault.  */
     201  	      puts ("\"nodelmod4.so\" got deleted");
     202  	      result = 1;
     203  	    }
     204  	}
     205      }
     206  
     207    return result;
     208  }
     209  
     210  #include <support/test-driver.c>