This is the mail archive of the
libc-alpha@sourceware.cygnus.com
mailing list for the glibc project.
Re: Problem with new ld.so.cache format on 64-bit machines
- To: Andreas Jaeger <aj at suse dot de>
- Subject: Re: Problem with new ld.so.cache format on 64-bit machines
- From: David Huggins-Daines <dhd at linuxcare dot com>
- Date: 12 May 2000 14:35:35 -0400
- Cc: libc-alpha at sourceware dot cygnus dot com
- References: <87k8h0znf7.fsf@linuxcare.com> <hosnvotfiu.fsf@maclaurin.suse.de>
Andreas Jaeger <aj@suse.de> writes:
> Can you send a patch that works for you on alpha, please?
No problem...
One other thing I noticed when writing this patch is that it appears
that _dl_load_cache_lookup() would not actually have worked in the
case where there is only the new-style index in the cache, because
cache_data was always calculated using 'cache' (which would be NULL in
the case where no old-style cache index was present). I think (but
I'm not sure) that this should fix that as well.
--- glibc-cvs/sysdeps/generic/dl-cache.c Fri May 12 14:20:11 2000
+++ glibc-cvs/sysdeps/generic/dl-cache.c.patched Fri May 12 14:09:50 2000
@@ -166,14 +166,24 @@
if (file && cachesize > sizeof *cache &&
!memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1))
{
+ /* Alignment pad between old and new, used in calculations below */
+ int pad;
+
/* Looks ok. */
cache = file;
+ pad = (sizeof (unsigned long)
+ - (cache->nlibs * sizeof (struct file_entry)
+ % sizeof (unsigned long))) % sizeof (unsigned long);
+
/* Check for new version. */
- cache_new = (struct cache_file_new *) &cache->libs[cache->nlibs];
+ cache_new = (struct cache_file_new *)
+ ((char *) &cache->libs[cache->nlibs] + pad);
+
if (cachesize <
- (sizeof (struct cache_file) + cache->nlibs * sizeof (struct file_entry)
- + sizeof (struct cache_file_new))
+ (sizeof (struct cache_file)
+ + cache->nlibs * sizeof (struct file_entry)
+ + pad + sizeof (struct cache_file_new))
|| memcmp (cache_new->magic, CACHEMAGIC_NEW,
sizeof CACHEMAGIC_NEW - 1)
|| memcmp (cache_new->version, CACHE_VERSION,
@@ -202,15 +212,14 @@
/* 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)
{
/* This file ends in static libraries where we don't have a hwcap. */
unsigned long int *hwcap;
+
+ cache_data = (const char *) cache_new;
weak_extern (_dl_hwcap);
hwcap = &_dl_hwcap;
@@ -221,9 +230,12 @@
SEARCH_CACHE (cache_new);
}
else
+ {
+ 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)
--- glibc-cvs/elf/cache.c Fri May 12 14:20:11 2000
+++ glibc-cvs/elf/cache.c.patched Fri May 12 14:04:22 2000
@@ -134,14 +134,19 @@
}
else
{
+ /* Alignment pad between old and new, used in calculations below */
+ int pad = (sizeof (unsigned long)
+ - (cache->nlibs * sizeof (struct file_entry)
+ % sizeof (unsigned long))) % sizeof (unsigned long);
+
/* This is where the strings start. */
- cache_data = (const char *) &cache->libs[cache->nlibs];
+ cache_data = (const char *) &cache->libs[cache->nlibs] + pad;
/* Check for a new cache embedded in the old format. */
if (cache_size >
(sizeof (struct cache_file)
+ cache->nlibs * sizeof (struct file_entry)
- + sizeof (struct cache_file_new)))
+ + pad + sizeof (struct cache_file_new)))
{
cache_new = (struct cache_file_new *) cache_data;
@@ -354,6 +359,15 @@
}
if (opt_format != 0)
{
+ /* The new style cache must be aligned to sizeof(unsigned long) */
+ int pad = ((sizeof (unsigned long)
+ - file_entries_size % sizeof (unsigned long))
+ % sizeof (unsigned long));
+ if (pad) {
+ char zero[sizeof(unsigned long)];
+ memset(zero, 0, sizeof(zero));
+ write(fd, zero, pad);
+ }
if (write (fd, file_entries_new, file_entries_new_size)
!= (ssize_t)file_entries_new_size)
error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
--
David Huggins-Daines, Senior GNU/Linux Consultant, Linuxcare, Inc.
613.562.1239 desk, 613.223.0225 mobile
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.