(root)/
glibc-2.38/
elf/
circleload1.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  static int
      67  load_dso (const char **loading, int undef, int flag)
      68  {
      69    void *obj;
      70    const char *loaded[] = { NULL, NULL, NULL, NULL };
      71    int errors = 0;
      72    const char *errstring;
      73  
      74    printf ("\nThis is what is in memory now:\n");
      75    errors += check_loaded_objects (loaded);
      76  
      77    printf ("Loading shared object %s: %s\n", loading[0],
      78  	 flag == RTLD_LAZY ? "RTLD_LAZY" : "RTLD_NOW");
      79    obj = dlopen (loading[0], flag);
      80    if (obj == NULL)
      81      {
      82        if (flag == RTLD_LAZY)
      83  	{
      84  	  ++errors;
      85  	  printf ("ERRORS: dlopen shouldn't fail for RTLD_LAZY\n");
      86  	}
      87  
      88        errstring = dlerror ();
      89        if (strstr (errstring, "undefined symbol") == 0
      90  	  || strstr (errstring, "circlemod2_undefined") == 0)
      91  	{
      92  	  ++errors;
      93  	  printf ("ERRORS: dlopen: `%s': Invalid error string\n",
      94  		  errstring);
      95  	}
      96        else
      97  	printf ("dlopen: %s\n", errstring);
      98      }
      99    else
     100      {
     101        if (undef && flag == RTLD_NOW)
     102  	{
     103  	  ++errors;
     104  	  printf ("ERRORS: dlopen shouldn't work for RTLD_NOW\n");
     105  	}
     106  
     107        if (!undef)
     108  	{
     109  	  int (*func) (void);
     110  
     111  	  func = dlsym (obj, "circlemod1");
     112  	  if (func == NULL)
     113  	    {
     114  	      ++errors;
     115  	      printf ("ERRORS: cannot get address of \"circlemod1\": %s\n",
     116  		      dlerror ());
     117  	    }
     118  	  else if (func () != 3)
     119  	    {
     120  	      ++errors;
     121  	      printf ("ERRORS: function \"circlemod1\" returned wrong result\n");
     122  	    }
     123  	}
     124  
     125        loaded[0] = loading[0];
     126        loaded[1] = loading[1];
     127        loaded[2] = loading[2];
     128      }
     129    errors += check_loaded_objects (loaded);
     130  
     131    if (obj)
     132      {
     133        printf ("UnLoading shared object %s\n", loading[0]);
     134        dlclose (obj);
     135        loaded[0] = NULL;
     136        loaded[1] = NULL;
     137        loaded[2] = NULL;
     138        errors += check_loaded_objects (loaded);
     139      }
     140  
     141    return errors;
     142  }
     143  
     144  int
     145  main (void)
     146  {
     147    int errors = 0;
     148    const char *loading[3];
     149  
     150    loading[0] = "circlemod1a.so";
     151    loading[1] = "circlemod2a.so";
     152    loading[2] = "circlemod3a.so";
     153    errors += load_dso (loading, 0, RTLD_LAZY);
     154    errors += load_dso (loading, 0, RTLD_NOW);
     155  
     156    loading[0] = "circlemod1.so";
     157    loading[1] = "circlemod2.so";
     158    loading[2] = "circlemod3.so";
     159    errors += load_dso (loading, 1, RTLD_LAZY);
     160    errors += load_dso (loading, 1, RTLD_NOW);
     161  
     162    if (errors != 0)
     163      printf ("%d errors found\n", errors);
     164  
     165    return errors;
     166  }