Exemplo n.º 1
0
/* This function parses the HWCAP/HWCAP2 fields, adding the previous supported
   ISA bits, as well as converting the AT_PLATFORM string to a number.  This
   data is stored in two global variables that can be used later by the
   powerpc-specific code to store it into the TCB.  */
void
__tcb_parse_hwcap_and_convert_at_platform (void)
{

  uint64_t h1, h2;

  /* Read AT_PLATFORM string from auxv and convert it to a number.  */
  __tcb_platform = _dl_string_platform (GLRO (dl_platform));

  /* Read HWCAP and HWCAP2 from auxv.  */
  h1 = GLRO (dl_hwcap);
  h2 = GLRO (dl_hwcap2);

  /* hwcap contains only the latest supported ISA, the code checks which is
     and fills the previous supported ones.  */

  if (h2 & PPC_FEATURE2_ARCH_2_07)
    h1 |= PPC_FEATURE_ARCH_2_06
       | PPC_FEATURE_ARCH_2_05
       | PPC_FEATURE_POWER5_PLUS
       | PPC_FEATURE_POWER5
       | PPC_FEATURE_POWER4;
  else if (h1 & PPC_FEATURE_ARCH_2_06)
    h1 |= PPC_FEATURE_ARCH_2_05
       | PPC_FEATURE_POWER5_PLUS
       | PPC_FEATURE_POWER5
       | PPC_FEATURE_POWER4;
  else if (h1 & PPC_FEATURE_ARCH_2_05)
    h1 |= PPC_FEATURE_POWER5_PLUS
       | PPC_FEATURE_POWER5
       | PPC_FEATURE_POWER4;
  else if (h1 & PPC_FEATURE_POWER5_PLUS)
    h1 |= PPC_FEATURE_POWER5
       | PPC_FEATURE_POWER4;
  else if (h1 & PPC_FEATURE_POWER5)
    h1 |= PPC_FEATURE_POWER4;

  /* Consolidate both HWCAP and HWCAP2 into a single doubleword so that
     we can read both in a single load later.  */
  __tcb_hwcap = h2;
  __tcb_hwcap = (h1 << 32) | __tcb_hwcap;

}
Exemplo n.º 2
0
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 (GLRO_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)
    {
      uint64_t platform;
      int disable_hwcap = 0;

      /* 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;

      platform = _dl_string_platform (GLRO(dl_platform));
      if (platform != (uint64_t) -1)
	platform = 1ULL << platform;

      if (__access ("/etc/ld.so.nohwcap", F_OK) == 0)
	disable_hwcap = 1;

#define _DL_HWCAP_TLS_MASK (1LL << 63)
      uint64_t hwcap_exclude = ~((GLRO(dl_hwcap) & GLRO(dl_hwcap_mask))
				 | _DL_HWCAP_PLATFORM | _DL_HWCAP_TLS_MASK);

      /* Only accept hwcap if it's for the right platform.  */
#define HWCAP_CHECK \
      if (lib->hwcap & hwcap_exclude)					      \
	continue;							      \
      if (GLRO(dl_osversion) && lib->osversion > GLRO(dl_osversion))	      \
	continue;							      \
      if (disable_hwcap && lib->hwcap != 0)				      \
	continue;							      \
      if (_DL_PLATFORMS_COUNT						      \
	  && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0			      \
	  && (lib->hwcap & _DL_HWCAP_PLATFORM) != platform)		      \
	continue
      SEARCH_CACHE (cache_new);
    }
  else
    {
      /* This is where the strings start.  */
      cache_data = (const char *) &cache->libs[cache->nlibs];

      /* Now we can compute how large the string table is.  */
      cache_data_size = (const char *) cache + cachesize - cache_data;

#undef HWCAP_CHECK
#define HWCAP_CHECK do {} while (0)
      SEARCH_CACHE (cache);
    }

  /* Print our result if wanted.  */
  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0)
      && best != NULL)
    _dl_debug_printf ("  trying file=%s\n", best);

  return best;
}