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