diff options
Diffstat (limited to 'sysdeps/generic')
-rw-r--r-- | sysdeps/generic/dl-cache.c | 26 | ||||
-rw-r--r-- | sysdeps/generic/dl-cache.h | 20 |
2 files changed, 31 insertions, 15 deletions
diff --git a/sysdeps/generic/dl-cache.c b/sysdeps/generic/dl-cache.c index 28fab0b..85db10e 100644 --- a/sysdeps/generic/dl-cache.c +++ b/sysdeps/generic/dl-cache.c @@ -52,7 +52,7 @@ do \ right = cache->nlibs - 1; \ middle = (left + right) / 2; \ cmpres = 1; \ - \ + \ while (left <= right) \ { \ /* Make sure string table indices are not bogus before using \ @@ -121,7 +121,7 @@ do \ { \ 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 \ @@ -166,14 +166,16 @@ _dl_load_cache_lookup (const char *name) if (file && cachesize > sizeof *cache && !memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1)) { + size_t offset; /* Looks ok. */ cache = file; /* Check for new version. */ - cache_new = (struct cache_file_new *) &cache->libs[cache->nlibs]; - if (cachesize < - (sizeof (struct cache_file) + cache->nlibs * sizeof (struct file_entry) - + sizeof (struct cache_file_new)) + 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_NEW, sizeof CACHEMAGIC_NEW - 1) || memcmp (cache_new->version, CACHE_VERSION, @@ -202,9 +204,6 @@ _dl_load_cache_lookup (const char *name) /* Previously looked for the cache file and didn't find it. */ return NULL; - /* This is where the strings start. */ - cache_data = (const char *) &cache->libs[cache->nlibs]; - best = NULL; if (cache_new != (void *) -1) @@ -213,6 +212,9 @@ _dl_load_cache_lookup (const char *name) unsigned long int *hwcap; weak_extern (_dl_hwcap); + /* This is where the strings start. */ + cache_data = (const char *) cache_new; + hwcap = &_dl_hwcap; #define HWCAP_CHECK \ @@ -221,9 +223,13 @@ _dl_load_cache_lookup (const char *name) SEARCH_CACHE (cache_new); } else + { + /* This is where the strings start. */ + cache_data = (const char *) &cache->libs[cache->nlibs]; #undef HWCAP_CHECK #define HWCAP_CHECK do {} while (0) - SEARCH_CACHE (cache); + SEARCH_CACHE (cache); + } /* Print our result if wanted. */ if (_dl_debug_libs && best != NULL) diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h index 4eb64cf..197638b 100644 --- a/sysdeps/generic/dl-cache.h +++ b/sysdeps/generic/dl-cache.h @@ -17,11 +17,14 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define _DL_CACHE_DEFAULT_ID 3 +#ifndef _DL_CACHE_DEFAULT_ID +# define _DL_CACHE_DEFAULT_ID 3 +#endif -#define _dl_cache_check_flags(flags) \ +#ifndef _dl_cache_check_flags +# define _dl_cache_check_flags(flags) \ ((flags) == 1 || (flags) == _DL_CACHE_DEFAULT_ID) - +#endif #ifndef LD_SO_CACHE # define LD_SO_CACHE "/etc/ld.so.cache" @@ -32,12 +35,14 @@ /* libc5 and glibc 2.0/2.1 use the same format. For glibc 2.2 another format has been added in a compatible way: The beginning of the string table is used for the new table: - old_magic + old_magic nlibs libs[0] ... libs[nlibs-1] - new magic + pad, new magic needs to be aligned + - this is string[0] for the old format + new magic - this is string[0] for the new format newnlibs ... newlibs[0] @@ -82,6 +87,11 @@ struct cache_file_new /* After this the string table of size len_strings is found. */ }; +/* Used to align cache_file_new. */ +#define ALIGN_CACHE(addr) \ +(((addr) + __alignof__ (struct cache_file_new) -1) \ + & (~(__alignof__ (struct cache_file_new) - 1))) + static int _dl_cache_libcmp (const char *p1, const char *p2) { |