diff options
-rw-r--r-- | ChangeLog | 34 | ||||
-rw-r--r-- | elf/ldconfig.c | 35 | ||||
-rw-r--r-- | elf/ldconfig.h | 2 | ||||
-rw-r--r-- | sysdeps/generic/dl-cache.c | 21 | ||||
-rw-r--r-- | sysdeps/generic/dl-procinfo.h | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/dl-procinfo.h | 36 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h | 8 |
8 files changed, 135 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog index ff2a6900ac..70ddeac4ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,37 @@ +2000-11-15 Andreas Jaeger <aj@suse.de> + + * elf/cache.c (struct cache_entry): Use uint64_t for hwcap. + (print_entry): Likewise. + (add_to_cache): Likewise. + + * elf/ldconfig.h (add_to_cache): Change prototype for hwcap change. + + * elf/ldconfig.c (struct lib_entry): Use uint64_t for hwcap. + (path_hwcap): Likewise. + (search_dir): Likewise. + + * sysdeps/generic/dl-cache.c (HWCAP_CHECK): Handle platform. + + * elf/cache.c (add_to_cache): Handle 64 bit hwcap entry. + + * sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h + (_dl_platform_string): New. + (_DL_HWCAP_PLATFORM): New. + (_dl_string_platform): New. + * sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h: Likewise. + + * sysdeps/generic/dl-procinfo.h (_DL_HWCAP_COUNT): New. + (_dl_string_platform): New. + (_DL_HWCAP_PLATFORM): New. + (_dl_platform_string): New. + + * sysdeps/unix/sysv/linux/i386/dl-procinfo.h: Added x86 platform + recognition. + (_DL_HWCAP_COUNT): New. + (_dl_string_platform): New. + (_DL_HWCAP_PLATFORM): New. + (_dl_platform_string): New. + 2000-11-14 Ulrich Drepper <drepper@redhat.com> * iconvdata/gconv-modules: Add CP936 as alias for GBK. diff --git a/elf/ldconfig.c b/elf/ldconfig.c index 8b6a3d478d..068f43e1b9 100644 --- a/elf/ldconfig.c +++ b/elf/ldconfig.c @@ -28,6 +28,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <stdint.h> #include <sys/fcntl.h> #include <sys/mman.h> #include <sys/stat.h> @@ -53,7 +54,7 @@ struct lib_entry { int flags; - unsigned long int hwcap; + uint64_t hwcap; char *lib; char *path; }; @@ -148,25 +149,31 @@ static struct argp argp = options, parse_opt, NULL, doc, NULL, NULL, NULL }; -/* Check if string corresponds to an important hardware capability. */ +/* Check if string corresponds to an important hardware capability or + a platform. */ static int -is_hwcap (const char *name) +is_hwcap_platform (const char *name) { int hwcap_idx = _dl_string_hwcap (name); if (hwcap_idx != -1 && ((1 << hwcap_idx) & HWCAP_IMPORTANT)) return 1; + + hwcap_idx = _dl_string_platform (name); + if (hwcap_idx != -1) + return 1; + return 0; } -/* Get hwcap encoding of path. */ -static unsigned long int +/* Get hwcap (including platform) encoding of path. */ +static uint64_t path_hwcap (const char *path) { char *str = xstrdup (path); char *ptr; - unsigned long int hwcap = 0; - unsigned long int h; + uint64_t hwcap = 0; + uint64_t h; size_t len; @@ -182,11 +189,13 @@ path_hwcap (const char *path) if (ptr == NULL) break; - h = _dl_string_hwcap (ptr+1); + h = _dl_string_hwcap (ptr + 1); if (h == -1) + h = _dl_string_platform (ptr + 1); + if (h == -1) break; - hwcap += 1 << h; + hwcap += 1ULL << h; /* Search the next part of the path. */ *ptr = '\0'; @@ -576,7 +585,7 @@ search_dir (const struct dir_entry *entry) struct dlib_entry *dlib_ptr; struct stat64 stat_buf; int is_link; - unsigned long int hwcap = path_hwcap (entry->path); + uint64_t hwcap = path_hwcap (entry->path); file_name_len = PATH_MAX; file_name = alloca (file_name_len); @@ -586,7 +595,7 @@ search_dir (const struct dir_entry *entry) if (opt_verbose) { if (hwcap != 0) - printf ("%s: (hwcap: 0x%lx)\n", entry->path, hwcap); + printf ("%s: (hwcap: 0x%Lx)\n", entry->path, hwcap); else printf ("%s:\n", entry->path); } @@ -630,7 +639,7 @@ search_dir (const struct dir_entry *entry) if (((strncmp (direntry->d_name, "lib", 3) != 0 && strncmp (direntry->d_name, "ld-", 3) != 0) || strstr (direntry->d_name, ".so") == NULL) - && !is_hwcap (direntry->d_name)) + && !is_hwcap_platform (direntry->d_name)) continue; len = strlen (entry->path) + strlen (direntry->d_name); if (len > file_name_len) @@ -662,7 +671,7 @@ search_dir (const struct dir_entry *entry) continue; } - if (S_ISDIR (stat_buf.st_mode) && is_hwcap (direntry->d_name)) + if (S_ISDIR (stat_buf.st_mode) && is_hwcap_platform (direntry->d_name)) { /* Handle subdirectory later. */ struct dir_entry *new_entry; diff --git a/elf/ldconfig.h b/elf/ldconfig.h index 336b8e51f5..aaad06de5d 100644 --- a/elf/ldconfig.h +++ b/elf/ldconfig.h @@ -39,7 +39,7 @@ extern void init_cache (void); extern void save_cache (const char *cache_name); extern void add_to_cache (const char *path, const char *lib, int flags, - unsigned long int hwcap); + uint64_t hwcap); /* Declared in readlib.c. */ extern int process_file (const char *real_file_name, const char *file_name, diff --git a/sysdeps/generic/dl-cache.c b/sysdeps/generic/dl-cache.c index 8206171f94..4ece370f27 100644 --- a/sysdeps/generic/dl-cache.c +++ b/sysdeps/generic/dl-cache.c @@ -22,7 +22,9 @@ #include <ldsodefs.h> #include <sys/mman.h> #include <dl-cache.h> +#include <dl-procinfo.h> +#include <stdio-common/_itoa.h> /* System-dependent function to read a file's whole contents in the most convenient manner available. */ @@ -30,6 +32,8 @@ extern void *_dl_sysdep_read_whole_file (const char *filename, size_t *filesize_ptr, int mmap_prot); +extern const char *_dl_platform; + /* This is the starting address and the size of the mmap()ed file. */ static struct cache_file *cache; static struct cache_file_new *cache_new; @@ -209,6 +213,7 @@ _dl_load_cache_lookup (const char *name) { /* This file ends in static libraries where we don't have a hwcap. */ unsigned long int *hwcap; + uint64_t platform; weak_extern (_dl_hwcap); /* This is where the strings start. */ @@ -218,9 +223,19 @@ _dl_load_cache_lookup (const char *name) cache_data_size = (const char *) cache + cachesize - cache_data; hwcap = &_dl_hwcap; - -#define HWCAP_CHECK \ - if (hwcap && (cache_new->libs[middle].hwcap & *hwcap) > *hwcap) \ + platform = _dl_string_platform (_dl_platform); + if (platform != -1) + platform = 1ULL << platform; + + /* Only accept hwcap if it's for the right platform. */ +#define HWCAP_CHECK \ + 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)) \ continue SEARCH_CACHE (cache_new); } diff --git a/sysdeps/generic/dl-procinfo.h b/sysdeps/generic/dl-procinfo.h index 180a08b7c2..902eddd559 100644 --- a/sysdeps/generic/dl-procinfo.h +++ b/sysdeps/generic/dl-procinfo.h @@ -27,12 +27,20 @@ /* There are no hardware capabilities defined. */ #define _dl_hwcap_string(idx) "" +/* There are no different platforms defined. */ +#define _dl_platform_string(idx) "" + /* By default there is no important hardware capability. */ #define HWCAP_IMPORTANT (0) +/* There're no platforms to filter out. */ +#define _DL_HWCAP_PLATFORM 0 + /* We don't have any hardware capabilities. */ #define _DL_HWCAP_COUNT 0 #define _dl_string_hwcap(str) (-1) +#define _dl_string_platform(str) (-1) + #endif /* dl-procinfo.h */ diff --git a/sysdeps/unix/sysv/linux/i386/dl-procinfo.h b/sysdeps/unix/sysv/linux/i386/dl-procinfo.h index c4a4e324e6..55bd830011 100644 --- a/sysdeps/unix/sysv/linux/i386/dl-procinfo.h +++ b/sysdeps/unix/sysv/linux/i386/dl-procinfo.h @@ -32,6 +32,18 @@ static const char x86_cap_flags[][7] = }; #define _DL_HWCAP_COUNT 32 +static const char x86_platforms[][5] = + { + "i386", "i486", "i586", "i686" + }; +#define _DL_PLATFORMS_COUNT 4 + +/* Start at 48 to reserve some space. */ +#define _DL_FIRST_PLATFORM 48 +/* Mask to filter out platforms. */ +#define _DL_HWCAP_PLATFORM (7ULL << _DL_FIRST_PLATFORM) + + static inline int __attribute__ ((unused)) _dl_procinfo (int word) @@ -58,6 +70,13 @@ _dl_hwcap_string (int idx) return x86_cap_flags[idx]; }; +static inline const char * +__attribute__ ((unused)) +_dl_platform_string (int idx) +{ + return x86_platforms [idx - _DL_FIRST_PLATFORM]; +}; + enum { HWCAP_I386_FPU = 1 << 0, @@ -82,6 +101,7 @@ enum /* XXX Which others to add here? */ HWCAP_IMPORTANT = (HWCAP_I386_MMX) + }; static inline int @@ -98,4 +118,20 @@ _dl_string_hwcap (const char *str) return -1; }; + +static inline int +__attribute__ ((unused)) +_dl_string_platform (const char *str) +{ + int i; + + if (str != NULL) + for (i = 0; i < _DL_PLATFORMS_COUNT; ++i) + { + if (strcmp (str, x86_platforms[i]) == 0) + return _DL_FIRST_PLATFORM + i; + } + return -1; +}; + #endif /* dl-procinfo.h */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h b/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h index 8a825a64c5..adfe4be05c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h @@ -68,4 +68,12 @@ _dl_string_hwcap (const char *str) #define HWCAP_IMPORTANT (HWCAP_SPARC_V9) +/* There are no different platforms defined. */ +#define _dl_platform_string(idx) "" + +/* There're no platforms to filter out. */ +#define _DL_HWCAP_PLATFORM 0 + +#define _dl_string_platform(str) (-1) + #endif /* dl-procinfo.h */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h b/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h index 7825937733..78bd5c883c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h @@ -69,4 +69,12 @@ _dl_string_hwcap (const char *str) #define HWCAP_IMPORTANT (0) +/* There are no different platforms defined. */ +#define _dl_platform_string(idx) "" + +/* There're no platforms to filter out. */ +#define _DL_HWCAP_PLATFORM 0 + +#define _dl_string_platform(str) (-1) + #endif /* dl-procinfo.h */ |