From 40b07f5b942d6af4d575274853331590d2ee8ab3 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 8 Nov 2001 01:48:57 +0000 Subject: Update. * sysdeps/generic/dl-cache.c: Optimize SEARCH_CACHE and HWCAP_CHECK macro code. * elf/dl-misc.c (_dl_sysdep_read_whole_file): Optimize code a bit. Now returns MAP_FAILED on error. * elf/rtld.c: Adjust caller. * sysdeps/generic/dl-cache.c: Likewise. * sysdeps/generic/ldsodefs.h: Adjust description. --- ChangeLog | 9 ++ elf/dl-misc.c | 38 ++++----- elf/rtld.c | 2 +- sysdeps/generic/dl-cache.c | 209 ++++++++++++++++++++++----------------------- sysdeps/generic/ldsodefs.h | 5 +- 5 files changed, 135 insertions(+), 128 deletions(-) diff --git a/ChangeLog b/ChangeLog index 933c7f726b..11c8f611e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2001-11-07 Ulrich Drepper + * sysdeps/generic/dl-cache.c: Optimize SEARCH_CACHE and + HWCAP_CHECK macro code. + + * elf/dl-misc.c (_dl_sysdep_read_whole_file): Optimize code a bit. + Now returns MAP_FAILED on error. + * elf/rtld.c: Adjust caller. + * sysdeps/generic/dl-cache.c: Likewise. + * sysdeps/generic/ldsodefs.h: Adjust description. + * elf/dl-version.c (match_symbol): Optimize error handling for size. (_dl_check_map_versions): Likewise. diff --git a/elf/dl-misc.c b/elf/dl-misc.c index f1abfb7f29..a96689edf7 100644 --- a/elf/dl-misc.c +++ b/elf/dl-misc.c @@ -44,40 +44,38 @@ _dl_sysdep_open_zero_fill (void) #endif /* Read the whole contents of FILE into new mmap'd space with given - protections. *SIZEP gets the size of the file. */ + protections. *SIZEP gets the size of the file. On error MAP_FAILED + is returned. */ void * internal_function _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) { - void *result; + void *result = MAP_FAILED; struct stat64 st; int fd = __open (file, O_RDONLY); - if (fd < 0) - return NULL; - if (__fxstat64 (_STAT_VER, fd, &st) < 0 - /* No need to map the file if it is empty. */ - || st.st_size == 0) - result = NULL; - else + if (fd >= 0) { - /* Map a copy of the file contents. */ - result = __mmap (0, st.st_size, prot, + if (__fxstat64 (_STAT_VER, fd, &st) >= 0) + { + *sizep = st.st_size; + + /* No need to map the file if it is empty. */ + if (*sizep != 0) + /* Map a copy of the file contents. */ + result = __mmap (NULL, *sizep, prot, #ifdef MAP_COPY - MAP_COPY + MAP_COPY #else - MAP_PRIVATE + MAP_PRIVATE #endif #ifdef MAP_FILE - | MAP_FILE + | MAP_FILE #endif - , fd, 0); - if (result == MAP_FAILED) - result = NULL; - else - *sizep = st.st_size; + , fd, 0); + } + __close (fd); } - __close (fd); return result; } diff --git a/elf/rtld.c b/elf/rtld.c index 2d2befc627..8ed86eaedb 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -710,7 +710,7 @@ of this helper program; chances are you did not intend to run this program.\n\ /* Read the contents of the file. */ file = _dl_sysdep_read_whole_file ("/etc/ld.so.preload", &file_size, PROT_READ | PROT_WRITE); - if (__builtin_expect (file != NULL, 0)) + if (__builtin_expect (file != MAP_FAILED, 0)) { /* Parse the file. It contains names of libraries to be loaded, separated by white spaces or `:'. It may also contain diff --git a/sysdeps/generic/dl-cache.c b/sysdeps/generic/dl-cache.c index bc2f9d92d2..6ed26a3b7b 100644 --- a/sysdeps/generic/dl-cache.c +++ b/sysdeps/generic/dl-cache.c @@ -44,98 +44,98 @@ static size_t cachesize; 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; \ - middle = (left + right) / 2; \ - cmpres = 1; \ - \ - while (left <= right) \ - { \ - /* Make sure string table indices are not bogus before using \ - them. */ \ - if (! _dl_cache_verify_ptr (cache->libs[middle].key)) \ - { \ - cmpres = 1; \ - break; \ - } \ - \ - /* Actually compare the entry with the key. */ \ - cmpres = _dl_cache_libcmp (name, \ - cache_data + cache->libs[middle].key); \ - if (cmpres == 0) \ - /* Found it. */ \ - break; \ - \ - if (cmpres < 0) \ - left = middle + 1; \ - else \ - right = middle - 1; \ - \ - middle = (left + right) / 2; \ - } \ - \ - if (cmpres == 0) \ - { \ - /* 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 \ - /* Make sure string table indices are not bogus before \ - using them. */ \ - && _dl_cache_verify_ptr (cache->libs[middle - 1].key) \ - /* Actually compare the entry. */ \ - && (_dl_cache_libcmp (name, \ - cache_data \ - + cache->libs[middle - 1].key) \ - == 0)) \ - --middle; \ - \ - do \ - { \ - int flags; \ - \ - /* 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 (cache->libs[middle].key) \ - || (_dl_cache_libcmp (name, \ - cache_data \ - + cache->libs[middle].key) \ - != 0))) \ - break; \ - \ - flags = cache->libs[middle].flags; \ - if (_dl_cache_check_flags (flags) \ - && _dl_cache_verify_ptr (cache->libs[middle].value)) \ - { \ - if (best == NULL || flags == _dl_correct_cache_id) \ - { \ - HWCAP_CHECK; \ - best = cache_data + cache->libs[middle].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); \ - } \ - } \ +#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) @@ -168,7 +168,7 @@ _dl_load_cache_lookup (const char *name) - 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 != NULL && cachesize > sizeof *cache + if (file != MAP_FAILED && cachesize > sizeof *cache && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0) { size_t offset; @@ -185,7 +185,7 @@ _dl_load_cache_lookup (const char *name) sizeof CACHEMAGIC_VERSION_NEW - 1) != 0) cache_new = (void *) -1; } - else if (file != NULL && cachesize > sizeof *cache_new + else if (file != MAP_FAILED && cachesize > sizeof *cache_new && memcmp (file, CACHEMAGIC_VERSION_NEW, sizeof CACHEMAGIC_VERSION_NEW - 1) == 0) { @@ -194,7 +194,7 @@ _dl_load_cache_lookup (const char *name) } else { - if (file != NULL) + if (file != MAP_FAILED) __munmap (file, cachesize); cache = (void *) -1; } @@ -227,16 +227,15 @@ _dl_load_cache_lookup (const char *name) 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 \ - && (cache_new->libs[middle].hwcap & _DL_HWCAP_PLATFORM) != 0 \ - && (cache_new->libs[middle].hwcap & _DL_HWCAP_PLATFORM) != platform) \ - continue; \ - if (hwcap \ - && ((cache_new->libs[middle].hwcap & *hwcap & ~_DL_HWCAP_PLATFORM) \ - > *hwcap)) \ +#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); } diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 64e5a16b6b..2a4491d1f9 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -495,8 +495,9 @@ extern const char *_dl_load_cache_lookup (const char *name) once needed. */ extern void _dl_unload_cache (void); -/* System-dependent function to read a file's whole contents - in the most convenient manner available. */ +/* System-dependent function to read a file's whole contents in the + most convenient manner available. *SIZEP gets the size of the + file. On error MAP_FAILED is returned. */ extern void *_dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) internal_function; -- cgit 1.4.1