if (__builtin_expect (_dl_debug_libs, 0))
if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0))
open_verify (const char *name, struct filebuf *fbp){  /* This is the expected ELF header.  */#define ELF32_CLASS ELFCLASS32#define ELF64_CLASS ELFCLASS64#ifndef VALID_ELF_HEADER# define VALID_ELF_HEADER(hdr,exp,size)	(memcmp (hdr, exp, size) == 0)# define VALID_ELF_OSABI(osabi)		(osabi == ELFOSABI_SYSV)# define VALID_ELF_ABIVERSION(ver)	(ver == 0)#endif  static const unsigned char expected[EI_PAD] =  {    [EI_MAG0] = ELFMAG0,    [EI_MAG1] = ELFMAG1,    [EI_MAG2] = ELFMAG2,    [EI_MAG3] = ELFMAG3,    [EI_CLASS] = ELFW(CLASS),    [EI_DATA] = byteorder,    [EI_VERSION] = EV_CURRENT,    [EI_OSABI] = ELFOSABI_SYSV,    [EI_ABIVERSION] = 0  };  int fd;  /* Open the file.  We always open files read-only.  */  fd = __open (name, O_RDONLY);  if (fd != -1)    {      ElfW(Ehdr) *ehdr;      /* We successfully openened the file.  Now verify it is a file	 we can use.  */      __set_errno (0);      fbp->len = __libc_read (fd, fbp->buf, sizeof (fbp->buf));      /* This is where the ELF header is loaded.  */      assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr)));      ehdr = (ElfW(Ehdr) *) fbp->buf;      /* Now run the tests.  */      if (__builtin_expect (fbp->len < (ssize_t) sizeof (ElfW(Ehdr)), 0))	lose (errno, fd, name, NULL, NULL,	      errno == 0 ? N_("file too short") : N_("cannot read file data"));      /* See whether the ELF header is what we expect.  */      if (__builtin_expect (! VALID_ELF_HEADER (ehdr->e_ident, expected,						EI_PAD), 0))	{	  /* Something is wrong.  */	  if (*(Elf32_Word *) &ehdr->e_ident !=#if BYTE_ORDER == LITTLE_ENDIAN	      ((ELFMAG0 << (EI_MAG0 * 8)) |	       (ELFMAG1 << (EI_MAG1 * 8)) |	       (ELFMAG2 << (EI_MAG2 * 8)) |	       (ELFMAG3 << (EI_MAG3 * 8)))#else	      ((ELFMAG0 << (EI_MAG3 * 8)) |	       (ELFMAG1 << (EI_MAG2 * 8)) |	       (ELFMAG2 << (EI_MAG1 * 8)) |	       (ELFMAG3 << (EI_MAG0 * 8)))#endif	      )	    lose (0, fd, name, NULL, NULL, N_("invalid ELF header"));	  if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS))	    /* This is not a fatal error.  On architectures where	       32-bit and 64-bit binaries can be run this might	       happen.  */	    goto close_and_out;	  if (ehdr->e_ident[EI_DATA] != byteorder)	    {	      if (BYTE_ORDER == BIG_ENDIAN)		lose (0, fd, name, NULL, NULL,		      "ELF file data encoding not big-endian");	      else		lose (0, fd, name, NULL, NULL,		      "ELF file data encoding not little-endian");	    }	  if (ehdr->e_ident[EI_VERSION] != EV_CURRENT)	    lose (0, fd, name, NULL, NULL,		  N_("ELF file version ident does not match current one"));	  /* XXX We should be able so set system specific versions which are	     allowed here.  */	  if (!VALID_ELF_OSABI (ehdr->e_ident[EI_OSABI]))	    lose (0, fd, name, NULL, NULL, N_("ELF file OS ABI invalid"));	  if (!VALID_ELF_ABIVERSION (ehdr->e_ident[EI_ABIVERSION]))	    lose (0, fd, name, NULL, NULL,		  N_("ELF file ABI version invalid"));	  lose (0, fd, name, NULL, NULL, N_("internal error"));	}      if (__builtin_expect (ehdr->e_version, EV_CURRENT) != EV_CURRENT)	lose (0, fd, name, NULL, NULL,	      N_("ELF file version does not match current one"));      if (! __builtin_expect (elf_machine_matches_host (ehdr), 1))	{	close_and_out:	  __close (fd);	  __set_errno (ENOENT);	  fd = -1;	}      else if (__builtin_expect (ehdr->e_phentsize, sizeof (ElfW(Phdr)))	       != sizeof (ElfW(Phdr)))	lose (0, fd, name, NULL, NULL,	      N_("ELF file's phentsize not the expected size"));      else if (__builtin_expect (ehdr->e_type, ET_DYN) != ET_DYN	       && __builtin_expect (ehdr->e_type, ET_EXEC) != ET_EXEC)	lose (0, fd, name, NULL, NULL,	      N_("only ET_DYN and ET_EXEC can be loaded"));    }  return fd;}/* Try to open NAME in one of the directories in *DIRSP.   Return the fd, or -1.  If successful, fill in *REALNAME   with the malloc'd full directory name.  If it turns out   that none of the directories in *DIRSP exists, *DIRSP is   replaced with (void *) -1, and the old value is free()d   if MAY_FREE_DIRS is true.  */static intopen_path (const char *name, size_t namelen, int preloaded,	   struct r_search_path_struct *sps, char **realname,	   struct filebuf *fbp){  struct r_search_path_elem **dirs = sps->dirs;  char *buf;  int fd = -1;  const char *current_what = NULL;  int any = 0;  buf = alloca (max_dirnamelen + max_capstrlen + namelen);  do    {      struct r_search_path_elem *this_dir = *dirs;      size_t buflen = 0;      size_t cnt;      char *edp;      int here_any = 0;      /* If we are debugging the search for libraries print the path	 now if it hasn't happened now.  */      if (__builtin_expect (_dl_debug_libs, 0)	  && current_what != this_dir->what)	{	  current_what = this_dir->what;	  print_search_path (dirs, current_what, this_dir->where);	}      edp = (char *) __mempcpy (buf, this_dir->dirname, this_dir->dirnamelen);      for (cnt = 0; fd == -1 && cnt < ncapstr; ++cnt)	{	  /* Skip this directory if we know it does not exist.  */	  if (this_dir->status[cnt] == nonexisting)	    continue;	  buflen =	    ((char *) __mempcpy (__mempcpy (edp,					    capstr[cnt].str, capstr[cnt].len),				 name, namelen)	     - buf);	  /* Print name we try if this is wanted.  */	  if (__builtin_expect (_dl_debug_libs, 0))	    _dl_debug_message (1, "  trying file=", buf, "\n", NULL);	  fd = open_verify (buf, fbp);	  if (this_dir->status[cnt] == unknown)	    {	      if (fd != -1)		this_dir->status[cnt] = existing;	      else		{		  /* We failed to open machine dependent library.  Let's		     test whether there is any directory at all.  */		  struct stat64 st;		  buf[buflen - namelen - 1] = '\0';		  if (__xstat64 (_STAT_VER, buf, &st) != 0		      || ! S_ISDIR (st.st_mode))		    /* The directory does not exist or it is no directory.  */		    this_dir->status[cnt] = nonexisting;		  else		    this_dir->status[cnt] = existing;		}	    }	  /* Remember whether we found any existing directory.  */	  here_any |= this_dir->status[cnt] == existing;	  if (fd != -1 && preloaded && __libc_enable_secure)	    {	      /* This is an extra security effort to make sure nobody can		 preload broken shared objects which are in the trusted		 directories and so exploit the bugs.  */	      struct stat64 st;	      if (__fxstat64 (_STAT_VER, fd, &st) != 0		  || (st.st_mode & S_ISUID) == 0)		{		  /* The shared object cannot be tested for being SUID		     or this bit is not set.  In this case we must not		     use this object.  */		  __close (fd);		  fd = -1;		  /* We simply ignore the file, signal this by setting		     the error value which would have been set by `open'.  */		  errno = ENOENT;		}	    }	}      if (fd != -1)	{	  *realname = malloc (buflen);	  if (*realname != NULL)	    {	      memcpy (*realname, buf, buflen);	      return fd;	    }	  else	    {	      /* No memory for the name, we certainly won't be able		 to load and link it.  */	      __close (fd);	      return -1;	    }	}      if (here_any && errno != ENOENT && errno != EACCES)	/* The file exists and is readable, but something went wrong.  */	return -1;      /* Remember whether we found anything.  */      any |= here_any;    }  while (*++dirs != NULL);  /* Remove the whole path if none of the directories exists.  */  if (! any)    {      /* Paths which were allocated using the minimal malloc() in ld.so	 must not be freed using the general free() in libc.  */      if (sps->malloced)	free (sps->dirs);      sps->dirs = (void *) -1;    }  return -1;}/* Map in the shared object file NAME.  */struct link_map *internal_function_dl_map_object (struct link_map *loader, const char *name, int preloaded,		int type, int trace_mode, int mode){  int fd;  char *realname;  char *name_copy;  struct link_map *l;  struct filebuf fb;  /* Look for this name among those already loaded.  */  for (l = _dl_loaded; l; l = l->l_next)    {      /* If the requested name matches the soname of a loaded object,	 use that object.  Elide this check for names that have not	 yet been opened.  */      /* XXX Is this test still correct after the reference counter	 handling rewrite?  */      if (l->l_opencount == 0)	continue;      if (!_dl_name_match_p (name, l))	{	  const char *soname;	  if (__builtin_expect (l->l_soname_added, 1)	      || l->l_info[DT_SONAME] == NULL)	    continue;	  soname = ((const char *) D_PTR (l, l_info[DT_STRTAB])		    + l->l_info[DT_SONAME]->d_un.d_val);	  if (strcmp (name, soname) != 0)	    continue;	  /* We have a match on a new name -- cache it.  */	  add_name_to_object (l, soname);	  l->l_soname_added = 1;	}      /* We have a match.  */      return l;    }  /* Display information if we are debugging.  */  if (__builtin_expect (_dl_debug_files, 0) && loader != NULL)    _dl_debug_message (1, "\nfile=", name, ";  needed by ",		       loader->l_name[0] ? loader->l_name : _dl_argv[0],		       "\n", NULL);  if (strchr (name, '/') == NULL)    {      /* Search for NAME in several places.  */      size_t namelen = strlen (name) + 1;      if (__builtin_expect (_dl_debug_libs, 0))	_dl_debug_message (1, "find library=", name, "; searching\n", NULL);      fd = -1;      /* When the object has the RUNPATH information we don't use any         RPATHs.  */      if (loader == NULL || loader->l_info[DT_RUNPATH] == NULL)	{	  /* First try the DT_RPATH of the dependent object that caused NAME	     to be loaded.  Then that object's dependent, and on up.  */	  for (l = loader; fd == -1 && l; l = l->l_loader)	    {	      if (l->l_rpath_dirs.dirs == NULL)		{		  if (l->l_info[DT_RPATH] == NULL)		    /* There is no path.  */		    l->l_rpath_dirs.dirs = (void *) -1;		  else		    {		      /* Make sure the cache information is available.  */		      size_t ptrval = (D_PTR (l, l_info[DT_STRTAB])				       + l->l_info[DT_RPATH]->d_un.d_val);		      decompose_rpath (&l->l_rpath_dirs,				       (const char *) ptrval, l, "RPATH");		      if (l->l_rpath_dirs.dirs != (void *) -1)			fd = open_path (name, namelen, preloaded,					&l->l_rpath_dirs, &realname, &fb);		    }		}	      else if (l->l_rpath_dirs.dirs != (void *) -1)		fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,				&realname, &fb);	    }	  /* If dynamically linked, try the DT_RPATH of the executable             itself.  */	  l = _dl_loaded;	  if (fd == -1 && l && l->l_type != lt_loaded && l != loader	      && l->l_rpath_dirs.dirs != (void *) -1)	    fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,			    &realname, &fb);	}      /* Try the LD_LIBRARY_PATH environment variable.  */      if (fd == -1 && env_path_list.dirs != (void *) -1)	fd = open_path (name, namelen, preloaded, &env_path_list,			&realname, &fb);      /* Look at the RUNPATH information for this binary.  */      if (loader != NULL && loader->l_runpath_dirs.dirs != (void *) -1)	{	  if (loader->l_runpath_dirs.dirs == NULL)	    {	      if (loader->l_info[DT_RUNPATH] == NULL)		/* No RUNPATH.  */		loader->l_runpath_dirs.dirs = (void *) -1;	      else		{		  /* Make sure the cache information is available.  */		  size_t ptrval = (D_PTR (loader, l_info[DT_STRTAB])				   + loader->l_info[DT_RUNPATH]->d_un.d_val);		  decompose_rpath (&loader->l_runpath_dirs,				   (const char *) ptrval, loader, "RUNPATH");		  if (loader->l_runpath_dirs.dirs != (void *) -1)		    fd = open_path (name, namelen, preloaded,				    &loader->l_runpath_dirs, &realname, &fb);		}	    }	  else if (loader->l_runpath_dirs.dirs != (void *) -1)	    fd = open_path (name, namelen, preloaded,			    &loader->l_runpath_dirs, &realname, &fb);	}      if (fd == -1 && (! preloaded || ! __libc_enable_secure))	{	  /* Check the list of libraries in the file /etc/ld.so.cache,	     for compatibility with Linux's ldconfig program.  */	  const char *cached = _dl_load_cache_lookup (name);#ifdef SHARED	  l = loader ?: _dl_loaded;#else	  l = loader;#endif	  if (cached)	    {	      /* If the loader has the DF_1_NODEFLIB flag set we must not		 use a cache entry from any of these directories.  */	      if (l && __builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0))		{		  const char *dirp = system_dirs;		  unsigned int cnt = 0;		  do		    {		      if (memcmp (cached, dirp, system_dirs_len[cnt]) == 0)			{			  /* The prefix matches.  Don't use the entry.  */			  cached = NULL;			  break;			}		      dirp += system_dirs_len[cnt] + 1;		      ++cnt;		    }		  while (cnt < nsystem_dirs_len);		}	      if (cached)		{		  fd = open_verify (cached, &fb);		  if (fd != -1)		    {		      realname = local_strdup (cached);		      if (realname == NULL)			{			  __close (fd);			  fd = -1;			}		    }		}	    }	}      /* Finally, try the default path.  */      if (fd == -1	  && (l == NULL ||	      __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))	  && rtld_search_dirs.dirs != (void *) -1)	fd = open_path (name, namelen, preloaded, &rtld_search_dirs,			&realname, &fb);      /* Add another newline when we a tracing the library loading.  */      if (__builtin_expect (_dl_debug_libs, 0))        _dl_debug_message (1, "\n", NULL);    }  else    {      /* The path may contain dynamic string tokens.  */      realname = (loader		  ? expand_dynamic_string_token (loader, name)		  : local_strdup (name));      if (realname == NULL)	fd = -1;      else	{	  fd = open_verify (realname, &fb);	  if (fd == -1)	    free (realname);	}    }  if (fd == -1)    {      if (trace_mode)	{	  /* We haven't found an appropriate library.  But since we	     are only interested in the list of libraries this isn't	     so severe.  Fake an entry with all the information we	     have.  */	  static const Elf_Symndx dummy_bucket = STN_UNDEF;	  /* Enter the new object in the list of loaded objects.  */	  if ((name_copy = local_strdup (name)) == NULL	      || (l = _dl_new_object (name_copy, name, type, loader)) == NULL)	    _dl_signal_error (ENOMEM, name,			      N_("cannot create shared object descriptor"));	  /* Signal that this is a faked entry.  */	  l->l_faked = 1;	  /* Since the descriptor is initialized with zero we do not	     have do this here.	  l->l_reserved = 0; */	  l->l_buckets = &dummy_bucket;	  l->l_nbuckets = 1;	  l->l_relocated = 1;	  return l;	}      else	_dl_signal_error (errno, name, N_("cannot open shared object file"));    }  return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode);}