if (_dl_sysdep_start == NULL)  __libc_multiple_libcs = 1;
dl_open_worker (void *a){  struct dl_open_args *args = a;  const char *file = args->file;  int mode = args->mode;  struct link_map *new, *l;  const char *dst;  int lazy;  unsigned int i;  /* Maybe we have to expand a DST.  */  dst = strchr (file, '$');  if (dst != NULL)    {      const void *caller = args->caller;      size_t len = strlen (file);      size_t required;      struct link_map *call_map;      char *new_file;      /* DSTs must not appear in SUID/SGID programs.  */      if (__libc_enable_secure)	/* This is an error.  */	_dl_signal_error (0, "dlopen", NULL,			  N_("DST not allowed in SUID/SGID programs"));      /* We have to find out from which object the caller is calling.  */      call_map = NULL;      for (l = GL(dl_loaded); l; l = l->l_next)	if (caller >= (const void *) l->l_map_start	    && caller < (const void *) l->l_map_end)	  {	    /* There must be exactly one DSO for the range of the virtual	       memory.  Otherwise something is really broken.  */	    call_map = l;	    break;	  }      if (call_map == NULL)	/* In this case we assume this is the main application.  */	call_map = GL(dl_loaded);      /* Determine how much space we need.  We have to allocate the	 memory locally.  */      required = DL_DST_REQUIRED (call_map, file, len, _dl_dst_count (dst, 0));      /* Get space for the new file name.  */      new_file = (char *) alloca (required + 1);      /* Generate the new file name.  */      DL_DST_SUBSTITUTE (call_map, file, new_file, 0);      /* If the substitution failed don't try to load.  */      if (*new_file == '\0')	_dl_signal_error (0, "dlopen", NULL,			  N_("empty dynamic string token substitution"));      /* Now we have a new file name.  */      file = new_file;    }  /* Load the named object.  */  args->map = new = _dl_map_object (NULL, file, 0, lt_loaded, 0,				    mode);  /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is     set and the object is not already loaded.  */  if (new == NULL)    {      assert (mode & RTLD_NOLOAD);      return;    }  if (__builtin_expect (mode & __RTLD_SPROF, 0))    /* This happens only if we load a DSO for 'sprof'.  */    return;  /* It was already open.  */  if (new->l_searchlist.r_list != NULL)    {      /* Let the user know about the opencount.  */      if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))	_dl_debug_printf ("opening file=%s; opencount == %u\n\n",			  new->l_name, new->l_opencount);      /* If the user requested the object to be in the global namespace	 but it is not so far, add it now.  */      if ((mode & RTLD_GLOBAL) && new->l_global == 0)	(void) add_to_global (new);      /* Increment just the reference counter of the object.  */      ++new->l_opencount;      return;    }  /* Load that object's dependencies.  */  _dl_map_object_deps (new, NULL, 0, 0);  /* So far, so good.  Now check the versions.  */  for (i = 0; i < new->l_searchlist.r_nlist; ++i)    if (new->l_searchlist.r_list[i]->l_versions == NULL)      (void) _dl_check_map_versions (new->l_searchlist.r_list[i], 0, 0);#ifdef SCOPE_DEBUG  show_scope (new);#endif  /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */  lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && GL(dl_lazy);  /* Relocate the objects loaded.  We do this in reverse order so that copy     relocs of earlier objects overwrite the data written by later objects.  */  l = new;  while (l->l_next)    l = l->l_next;  while (1)    {      if (! l->l_relocated)	{#ifdef SHARED	  if (GL(dl_profile) != NULL)	    {	      /* If this here is the shared object which we want to profile		 make sure the profile is started.  We can find out whether	         this is necessary or not by observing the `_dl_profile_map'	         variable.  If was NULL but is not NULL afterwars we must		 start the profiling.  */	      struct link_map *old_profile_map = GL(dl_profile_map);	      _dl_relocate_object (l, l->l_scope, 1, 1);	      if (old_profile_map == NULL && GL(dl_profile_map) != NULL)		/* We must prepare the profiling.  */		_dl_start_profile (GL(dl_profile_map), GL(dl_profile_output));	    }	  else#endif	    _dl_relocate_object (l, l->l_scope, lazy, 0);	}      if (l == new)	break;      l = l->l_prev;    }  /* Increment the open count for all dependencies.  If the file is     not loaded as a dependency here add the search list of the newly     loaded object to the scope.  */  for (i = 0; i < new->l_searchlist.r_nlist; ++i)    if (++new->l_searchlist.r_list[i]->l_opencount > 1	&& new->l_searchlist.r_list[i]->l_type == lt_loaded)      {	struct link_map *imap = new->l_searchlist.r_list[i];	struct r_scope_elem **runp = imap->l_scope;	size_t cnt = 0;	while (*runp != NULL)	  {	    /* This can happen if imap was just loaded, but during	       relocation had l_opencount bumped because of relocation	       dependency.  Avoid duplicates in l_scope.  */	    if (__builtin_expect (*runp == &new->l_searchlist, 0))	      break;	    ++cnt;	    ++runp;	  }	if (*runp != NULL)	  /* Avoid duplicates.  */	  continue;	if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))	  {	    /* The 'r_scope' array is too small.  Allocate a new one	       dynamically.  */	    struct r_scope_elem **newp;	    size_t new_size = imap->l_scope_max * 2;	    if (imap->l_scope == imap->l_scope_mem)	      {		newp = (struct r_scope_elem **)		  malloc (new_size * sizeof (struct r_scope_elem *));		if (newp == NULL)		  _dl_signal_error (ENOMEM, "dlopen", NULL,				    N_("cannot create scope list"));		imap->l_scope = memcpy (newp, imap->l_scope,					cnt * sizeof (imap->l_scope[0]));	      }	    else	      {		newp = (struct r_scope_elem **)		  realloc (imap->l_scope,			   new_size * sizeof (struct r_scope_elem *));		if (newp == NULL)		  _dl_signal_error (ENOMEM, "dlopen", NULL,				    N_("cannot create scope list"));		imap->l_scope = newp;	      }	    imap->l_scope_max = new_size;	  }	imap->l_scope[cnt++] = &new->l_searchlist;	imap->l_scope[cnt] = NULL;      }  /* Run the initializer functions of new objects.  */  _dl_init (new, __libc_argc, __libc_argv, __environ);  /* Now we can make the new map available in the global scope.  */  if (mode & RTLD_GLOBAL)    /* Move the object in the global namespace.  */    if (add_to_global (new) != 0)      /* It failed.  */      return;  /* Mark the object as not deletable if the RTLD_NODELETE flags was     passed.  */  if (__builtin_expect (mode & RTLD_NODELETE, 0))    new->l_flags_1 |= DF_1_NODELETE;  if (_dl_sysdep_start == NULL)    /* We must be the static _dl_open in libc.a.  A static program that       has loaded a dynamic object now has competition.  */    __libc_multiple_libcs = 1;  /* Let the user know about the opencount.  */  if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))    _dl_debug_printf ("opening file=%s; opencount == %u\n\n",		      new->l_name, new->l_opencount);}