hwcap = &_dl_hwcap; platform = _dl_string_platform (_dl_platform);
hwcap = &GL(dl_hwcap); platform = _dl_string_platform (GL(dl_platform));
static struct cache_file *cache;static struct cache_file_new *cache_new;static size_t cachesize;/* 1 if cache_data + PTR points into the cache.  */#define _dl_cache_verify_ptr(ptr) (ptr < cache_data_size)/* This is the cache ID we expect.  Normally it is 3 for glibc linked   binaries.  */int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;#define SEARCH_CACHE(cache) \/* We use binary search since the table is sorted in the cache file.	      \   The first matching entry in the table is returned.			      \   It is important to use the same algorithm as used while generating	      \   the cache file.  */							      \do									      \  {									      \    left = 0;								      \    right = cache->nlibs - 1;						      \									      \    while (left <= right)						      \      {									      \	__typeof__ (cache->libs[0].key) key;				      \									      \	middle = (left + right) / 2;					      \									      \	key = cache->libs[middle].key;					      \									      \	/* Make sure string table indices are not bogus before using	      \	   them.  */							      \	if (! _dl_cache_verify_ptr (key))				      \	  {								      \	    cmpres = 1;							      \	    break;							      \	  }								      \									      \	/* Actually compare the entry with the key.  */			      \	cmpres = _dl_cache_libcmp (name, cache_data + key);		      \	if (__builtin_expect (cmpres == 0, 0))				      \	  {								      \	    /* Found it.  LEFT now marks the last entry for which we	      \	       know the name is correct.  */				      \	    left = middle;						      \									      \	    /* There might be entries with this name before the one we	      \	       found.  So we have to find the beginning.  */		      \	    while (middle > 0)						      \	      {								      \		__typeof__ (cache->libs[0].key) key;			      \									      \		key = cache->libs[middle - 1].key;			      \		/* Make sure string table indices are not bogus before	      \		   using them.  */					      \		if (! _dl_cache_verify_ptr (key)			      \		    /* Actually compare the entry.  */			      \		    || _dl_cache_libcmp (name, cache_data + key) != 0)	      \		  break;						      \		--middle;						      \	      }								      \									      \	    do								      \	      {								      \		int flags;						      \		__typeof__ (cache->libs[0]) *lib = &cache->libs[middle];      \									      \		/* Only perform the name test if necessary.  */		      \		if (middle > left					      \		    /* We haven't seen this string so far.  Test whether the  \		       index is ok and whether the name matches.  Otherwise   \		       we are done.  */					      \		    && (! _dl_cache_verify_ptr (lib->key)		      \			|| (_dl_cache_libcmp (name, cache_data + lib->key)    \			    != 0)))					      \		  break;						      \									      \		flags = lib->flags;					      \		if (_dl_cache_check_flags (flags)			      \		    && _dl_cache_verify_ptr (lib->value))		      \		  {							      \		    if (best == NULL || flags == _dl_correct_cache_id)	      \		      {							      \			HWCAP_CHECK;					      \			best = cache_data + lib->value;			      \									      \			if (flags == _dl_correct_cache_id)		      \			  /* We've found an exact match for the shared	      \			     object and no general `ELF' release.  Stop	      \			     searching.  */				      \			  break;					      \		      }							      \		  }							      \	      }								      \	    while (++middle <= right);					      \	    break;							      \	}								      \									      \	if (cmpres < 0)							      \	  left = middle + 1;						      \	else								      \	  right = middle - 1;						      \      }									      \  }									      \while (0)/* Look up NAME in ld.so.cache and return the file name stored there,   or null if none is found.  */const char *internal_function_dl_load_cache_lookup (const char *name){  int left, right, middle;  int cmpres;  const char *cache_data;  uint32_t cache_data_size;  const char *best;  /* Print a message if the loading of libs is traced.  */  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0))    _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE);  if (cache == NULL)    {      /* Read the contents of the file.  */      void *file = _dl_sysdep_read_whole_file (LD_SO_CACHE, &cachesize,					       PROT_READ);      /* We can handle three different cache file formats here:	 - the old libc5/glibc2.0/2.1 format	 - the old format with the new format in it	 - only the new format	 The following checks if the cache contains any of these formats.  */      if (file != MAP_FAILED && cachesize > sizeof *cache	  && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0)	{	  size_t offset;	  /* Looks ok.  */	  cache = file;	  /* Check for new version.  */	  offset = ALIGN_CACHE (sizeof (struct cache_file)				+ cache->nlibs * sizeof (struct file_entry));	  cache_new = (struct cache_file_new *) ((void *) cache + offset);	  if (cachesize < (offset + sizeof (struct cache_file_new))	      || memcmp (cache_new->magic, CACHEMAGIC_VERSION_NEW,			 sizeof CACHEMAGIC_VERSION_NEW - 1) != 0)	    cache_new = (void *) -1;	}      else if (file != MAP_FAILED && cachesize > sizeof *cache_new	       && memcmp (file, CACHEMAGIC_VERSION_NEW,			  sizeof CACHEMAGIC_VERSION_NEW - 1) == 0)	{	  cache_new = file;	  cache = file;	}      else	{	  if (file != MAP_FAILED)	    __munmap (file, cachesize);	  cache = (void *) -1;	}      assert (cache != NULL);    }  if (cache == (void *) -1)    /* Previously looked for the cache file and didn't find it.  */    return NULL;  best = NULL;  if (cache_new != (void *) -1)    {      /* This file ends in static libraries where we don't have a hwcap.  */      unsigned long int *hwcap;      uint64_t platform;      weak_extern (_dl_hwcap);      /* This is where the strings start.  */      cache_data = (const char *) cache_new;      /* Now we can compute how large the string table is.  */      cache_data_size = (const char *) cache + cachesize - cache_data;      hwcap = &_dl_hwcap;      platform = _dl_string_platform (_dl_platform);      if (platform != -1)	platform = 1ULL << platform;      /* Only accept hwcap if it's for the right platform.  */#define HWCAP_CHECK \      if (_dl_osversion	&& cache_new->libs[middle].osversion > _dl_osversion) \	continue;							      \      if (_DL_PLATFORMS_COUNT && platform != -1				      \	  && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0			      \	  && (lib->hwcap & _DL_HWCAP_PLATFORM) != platform)		      \	continue;							      \      if (hwcap								      \	  && ((lib->hwcap & *hwcap & ~_DL_HWCAP_PLATFORM) > *hwcap))	      \	continue      SEARCH_CACHE (cache_new);    }