(root)/
glibc-2.38/
elf/
neededtest.c
       1  #include <dlfcn.h>
       2  #include <libintl.h>
       3  #include <link.h>
       4  #include <stdio.h>
       5  #include <stdlib.h>
       6  #include <string.h>
       7  
       8  #define MAPS ((struct link_map *) _r_debug.r_map)
       9  
      10  static int
      11  check_loaded_objects (const char **loaded)
      12  {
      13    struct link_map *lm;
      14    int n;
      15    int *found = NULL;
      16    int errors = 0;
      17  
      18    for (n = 0; loaded[n]; n++)
      19      /* NOTHING */;
      20  
      21    if (n)
      22      {
      23        found = (int *) alloca (sizeof (int) * n);
      24        memset (found, 0, sizeof (int) * n);
      25      }
      26  
      27    printf("   Name\n");
      28    printf(" --------------------------------------------------------\n");
      29    for (lm = MAPS; lm; lm = lm->l_next)
      30      {
      31        if (lm->l_name && lm->l_name[0])
      32  	printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount);
      33        if (lm->l_type == lt_loaded && lm->l_name)
      34  	{
      35  	  int match = 0;
      36  	  for (n = 0; loaded[n] != NULL; n++)
      37  	    {
      38  	      if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
      39  	        {
      40  		  found[n] = 1;
      41  		  match = 1;
      42  		  break;
      43  		}
      44  	    }
      45  
      46  	  if (match == 0)
      47  	    {
      48  	      ++errors;
      49  	      printf ("ERRORS: %s is not unloaded\n", lm->l_name);
      50  	    }
      51  	}
      52      }
      53  
      54    for (n = 0; loaded[n] != NULL; n++)
      55      {
      56        if (found[n] == 0)
      57          {
      58  	  ++errors;
      59  	  printf ("ERRORS: %s is not loaded\n", loaded[n]);
      60  	}
      61      }
      62  
      63    return errors;
      64  }
      65  
      66  int
      67  main (void)
      68  {
      69    void *obj2[2];
      70    void *obj3;
      71    const char *loaded[] = { NULL, NULL, NULL, NULL };
      72    int errors = 0;
      73  
      74    printf ("\nThis is what is in memory now:\n");
      75    errors += check_loaded_objects (loaded);
      76  
      77    printf( "Loading shared object neededobj3.so\n");
      78    obj3 = dlopen( "neededobj3.so", RTLD_LAZY);
      79    if (obj3 == NULL)
      80      {
      81        printf ("%s\n", dlerror ());
      82        exit (1);
      83      }
      84    loaded[0] = "neededobj1.so";
      85    loaded[1] = "neededobj2.so";
      86    loaded[2] = "neededobj3.so";
      87    errors += check_loaded_objects (loaded);
      88  
      89    printf ("Now loading shared object neededobj2.so\n");
      90    obj2[0] = dlopen ("neededobj2.so", RTLD_LAZY);
      91    if (obj2[0] == NULL)
      92      {
      93        printf ("%s\n", dlerror ());
      94        exit (1);
      95      }
      96    errors += check_loaded_objects (loaded);
      97  
      98    printf ("And loading shared object neededobj2.so again\n");
      99    obj2[1] = dlopen ("neededobj2.so", RTLD_LAZY);
     100    if (obj2[1] == NULL)
     101      {
     102        printf ("%s\n", dlerror ());
     103        exit (1);
     104      }
     105    errors += check_loaded_objects (loaded);
     106  
     107    printf ("Closing neededobj2.so for the first time\n");
     108    dlclose (obj2[0]);
     109    errors += check_loaded_objects (loaded);
     110  
     111    printf ("Closing neededobj3.so\n");
     112    dlclose (obj3);
     113    loaded[2] = NULL;
     114    errors += check_loaded_objects (loaded);
     115  
     116    printf ("Closing neededobj2.so for the second time\n");
     117    dlclose (obj2[1]);
     118    loaded[0] = NULL;
     119    loaded[1] = NULL;
     120    errors += check_loaded_objects (loaded);
     121  
     122    if (errors != 0)
     123      printf ("%d errors found\n", errors);
     124    return errors;
     125  }