Back to index

glibc  2.9
nodelete.c
Go to the documentation of this file.
00001 #include <dlfcn.h>
00002 #include <setjmp.h>
00003 #include <signal.h>
00004 #include <stdio.h>
00005 
00006 
00007 static sigjmp_buf jmpbuf;
00008 
00009 
00010 int fini_ran;
00011 
00012 
00013 static void
00014 __attribute__ ((noreturn))
00015 handler (int sig)
00016 {
00017   siglongjmp (jmpbuf, 1);
00018 }
00019 
00020 
00021 #define TEST_FUNCTION do_test ()
00022 static int
00023 do_test (void)
00024 {
00025   /* We are testing the two possibilities to mark an object as not deletable:
00026      - marked on the linker commandline with `-z nodelete'
00027      - with the RTLD_NODELETE flag at dlopen()-time.
00028 
00029      The test we are performing should be safe.  We are loading the objects,
00030      get the address of variables in the respective object, unload the object
00031      and then try to read the variable.  If the object is unloaded this
00032      should lead to an segmentation fault.  */
00033   int result = 0;
00034   void *p;
00035   struct sigaction sa;
00036 
00037   sa.sa_handler = handler;
00038   sigfillset (&sa.sa_mask);
00039   sa.sa_flags = SA_RESTART;
00040 
00041   if (sigaction (SIGSEGV, &sa, NULL) == -1)
00042     printf ("cannot install signal handler: %m\n");
00043 
00044   p = dlopen ("nodelmod1.so", RTLD_LAZY);
00045   if (p == NULL)
00046     {
00047       printf ("failed to load \"nodelmod1.so\": %s\n", dlerror ());
00048       result = 1;
00049     }
00050   else
00051     {
00052       int *varp;
00053 
00054       puts ("succeeded loading \"nodelmod1.so\"");
00055 
00056       varp = dlsym (p, "var1");
00057       if (varp == NULL)
00058        {
00059          puts ("failed to get address of \"var1\" in \"nodelmod1.so\"");
00060          result = 1;
00061        }
00062       else
00063        {
00064          *varp = 20000720;
00065 
00066          /* Now close the object.  */
00067          fini_ran = 0;
00068          if (dlclose (p) != 0)
00069            {
00070              puts ("failed to close \"nodelmod1.so\"");
00071              result = 1;
00072            }
00073          else if (! sigsetjmp (jmpbuf, 1))
00074            {
00075              /* Access the variable again.  */
00076              if (*varp != 20000720)
00077               {
00078                 puts ("\"var1\" value not correct");
00079                 result = 1;
00080               }
00081              else if (fini_ran != 0)
00082               {
00083                 puts ("destructor of \"nodelmod1.so\" ran");
00084                 result = 1;
00085               }
00086              else
00087               puts ("-z nodelete test succeeded");
00088            }
00089          else
00090            {
00091              /* We caught an segmentation fault.  */
00092              puts ("\"nodelmod1.so\" got deleted");
00093              result = 1;
00094            }
00095        }
00096     }
00097 
00098   p = dlopen ("nodelmod2.so", RTLD_LAZY | RTLD_NODELETE);
00099   if (p == NULL)
00100     {
00101       printf ("failed to load \"nodelmod2.so\": %s\n", dlerror ());
00102       result = 1;
00103     }
00104   else
00105     {
00106       int *varp;
00107 
00108       puts ("succeeded loading \"nodelmod2.so\"");
00109 
00110       varp = dlsym (p, "var2");
00111       if (varp == NULL)
00112        {
00113          puts ("failed to get address of \"var2\" in \"nodelmod2.so\"");
00114          result = 1;
00115        }
00116       else
00117        {
00118          *varp = 42;
00119 
00120          /* Now close the object.  */
00121          fini_ran = 0;
00122          if (dlclose (p) != 0)
00123            {
00124              puts ("failed to close \"nodelmod2.so\"");
00125              result = 1;
00126            }
00127          else if (! sigsetjmp (jmpbuf, 1))
00128            {
00129              /* Access the variable again.  */
00130              if (*varp != 42)
00131               {
00132                 puts ("\"var2\" value not correct");
00133                 result = 1;
00134               }
00135              else if (fini_ran != 0)
00136               {
00137                 puts ("destructor of \"nodelmod2.so\" ran");
00138                 result = 1;
00139               }
00140              else
00141               puts ("RTLD_NODELETE test succeeded");
00142            }
00143          else
00144            {
00145              /* We caught an segmentation fault.  */
00146              puts ("\"nodelmod2.so\" got deleted");
00147              result = 1;
00148            }
00149        }
00150     }
00151 
00152   p = dlopen ("nodelmod3.so", RTLD_LAZY);
00153   if (p == NULL)
00154     {
00155       printf ("failed to load \"nodelmod3.so\": %s\n", dlerror ());
00156       result = 1;
00157     }
00158   else
00159     {
00160       int *(*fctp) (void);
00161 
00162       puts ("succeeded loading \"nodelmod3.so\"");
00163 
00164       fctp = dlsym (p, "addr");
00165       if (fctp == NULL)
00166        {
00167          puts ("failed to get address of \"addr\" in \"nodelmod3.so\"");
00168          result = 1;
00169        }
00170       else
00171        {
00172          int *varp = fctp ();
00173 
00174          *varp = -1;
00175 
00176          /* Now close the object.  */
00177          fini_ran = 0;
00178          if (dlclose (p) != 0)
00179            {
00180              puts ("failed to close \"nodelmod3.so\"");
00181              result = 1;
00182            }
00183          else if (! sigsetjmp (jmpbuf, 1))
00184            {
00185              /* Access the variable again.  */
00186              if (*varp != -1)
00187               {
00188                 puts ("\"var_in_mod4\" value not correct");
00189                 result = 1;
00190               }
00191              else if (fini_ran != 0)
00192               {
00193                 puts ("destructor of \"nodelmod4.so\" ran");
00194                 result = 1;
00195               }
00196              else
00197               puts ("-z nodelete in dependency succeeded");
00198            }
00199          else
00200            {
00201              /* We caught an segmentation fault.  */
00202              puts ("\"nodelmod4.so\" got deleted");
00203              result = 1;
00204            }
00205        }
00206     }
00207 
00208   return result;
00209 }
00210 
00211 #include "../test-skeleton.c"