This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Roland McGrath <roland@redhat.com> writes: >> This gives a larger cache. Using 32-bit might be faster - and I don't >> see a collision probable. > > It's possible, and that's enough. Why are you worried about adding 25k to > ldconfig's RSS? Overoptimization I guess ;-) Changed already... >> Why ctime and not mtime? Do you think that any modification will not >> touch cached information? > > I don't quite understand the second question. ctime is the true change > time that cannot be reset by normal OS action. mtime can be changed to > anything. Ok. >> I'm using a separate file now (currently hardcoded to >> /etc/ld.so.cache.aux). What is the right configure variable to get >> /var/cache ? > > localstatedir is /var. Ah - but we do not use that in nscd.h either. Here comes the updated patch. Timings are: Flush filesystem cache, create from scratch: # echo 3 > /proc/sys/vm/drop_caches;time ldconfig -i real 0m24.234s user 0m0.148s sys 0m0.408s Flush filesystem cache, use auxiliary cache: # echo 3 > /proc/sys/vm/drop_caches;time ldconfig real 0m1.016s user 0m0.200s sys 0m0.072s With hot caches, the speedup is minimal: # time ldconfig -i real 0m0.330s user 0m0.144s sys 0m0.184s # time ldconfig real 0m0.255s user 0m0.184s sys 0m0.068s I compared the created ld.so.cache files and they did not change on my system. I consider the patch now in a state that I can ask: Ok to commit? Thanks, Andreas 2007-06-27 Andreas Jaeger <aj@suse.de> Michael Schroeder <mls@suse.de> * elf/ldconfig.c (opt_ignore_aux_cache): Add new option. (options): Add option. (parse_opt): Handle option. (manual_link): Adjust callers. (struct dlib_entry): Add stat_buf. (search_dir): Handle auxiliary cache. (main): Load and save auxiliary cache. * elf/readlib.c (process_file): Handle soname. * elf/cache.c (struct cache_entry_id): New. (struct cache_entry): Enhance. (struct aux_cache_file_entry): New. (struct aux_cache_file): New. (save_cache): Save auxiliary cache as well. (add_to_cache): Handle auxiliary cache. (load_aux_cache): New. (search_aux_cache): New. (free_aux_cache): New. * sysdeps/generic/ldconfig.h: Add new prototypes and adjust parameters. Index: elf/cache.c =================================================================== RCS file: /cvs/glibc/libc/elf/cache.c,v retrieving revision 1.29 diff -u -p -r1.29 cache.c --- elf/cache.c 10 Nov 2006 20:15:53 -0000 1.29 +++ elf/cache.c 27 Jun 2007 19:09:17 -0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2003,2005,2006 Free Software Foundation, Inc. +/* Copyright (C) 1999-2003,2005,2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 1999. @@ -32,6 +32,14 @@ #include <ldconfig.h> #include <dl-cache.h> +struct cache_entry_id +{ + uint64_t ino; + uint64_t ctime; + uint64_t size; + uint64_t dev; +}; + struct cache_entry { char *lib; /* Library name. */ @@ -40,12 +48,46 @@ struct cache_entry unsigned int osversion; /* Required OS version. */ uint64_t hwcap; /* Important hardware capabilities. */ int bits_hwcap; /* Number of bits set in hwcap. */ + struct cache_entry_id id; /* Unique id of entry. */ struct cache_entry *next; /* Next entry in list. */ }; + +#define AUX_CACHEMAGIC "glibc-ld.so.auxcache" +#define AUX_CACHE_VERSION "1.0" +#define AUX_CACHEMAGIC_VERSION AUX_CACHEMAGIC AUX_CACHE_VERSION + +struct aux_cache_file_entry +{ + int32_t flags; /* This is 1 for an ELF library. */ + uint32_t key, value; /* String table indices. */ + uint32_t osversion; /* Required OS version. */ + uint64_t hwcap; /* Hwcap entry. */ + struct cache_entry_id id; /* Unique id of entry. */ +}; + +/* ldconfig maintains an auxiliary cache file that allows + only reading those libraries that have changed since the last iteration. + For this for each library some information is cached in the auxiliary + cache. */ +struct aux_cache_file +{ + char magic[sizeof AUX_CACHEMAGIC - 1]; + char version[sizeof AUX_CACHE_VERSION - 1]; + uint32_t nlibs; /* Number of entries. */ + uint32_t len_strings; /* Size of string table. */ + struct cache_entry_id idldsocache; /* Info about ld.so.cache .*/ + struct aux_cache_file_entry libs[0]; /* Entries describing libraries. */ + /* After this the string table of size len_strings is found. */ +}; + + /* List of all cache entries. */ static struct cache_entry *entries; +/* List of all entries in auxiliary cache for incremental mode */ +static struct cache_entry *aux_entries; + static const char *flag_descr[] = { "libc4", "ELF", "libc5", "libc6"}; @@ -232,8 +274,8 @@ init_cache (void) -static -int compare (const struct cache_entry *e1, const struct cache_entry *e2) +static int +compare (const struct cache_entry *e1, const struct cache_entry *e2) { int res; @@ -264,17 +306,23 @@ int compare (const struct cache_entry *e /* Save the contents of the cache. */ void -save_cache (const char *cache_name) +save_cache (const char *cache_name, const char *aux_cache_name) { struct cache_entry *entry; + struct stat64 st; int fd, idx_old, idx_new; size_t total_strlen, len; char *strings, *str, *temp_name; struct cache_file *file_entries = NULL; struct cache_file_new *file_entries_new = NULL; + struct aux_cache_file *aux_file_entries = NULL; size_t file_entries_size = 0; size_t file_entries_new_size = 0; + size_t aux_file_entries_size = 0; unsigned int str_offset; + unsigned int aux_str_offset; + char *dir; + /* Number of cache entries. */ int cache_entry_count = 0; /* Number of normal cache entries. */ @@ -342,6 +390,22 @@ save_cache (const char *cache_name) file_entries_new->len_strings = total_strlen; } + /* Auxiliary cache. */ + aux_file_entries_size = sizeof (struct aux_cache_file) + + cache_entry_count * sizeof (struct aux_cache_file_entry); + aux_file_entries = + (struct aux_cache_file *) xmalloc (aux_file_entries_size); + + /* Fill in the header of the auxiliary cache. */ + memset (aux_file_entries, 0, sizeof (struct aux_cache_file)); + memcpy (aux_file_entries->magic, AUX_CACHEMAGIC, + sizeof AUX_CACHEMAGIC - 1); + memcpy (aux_file_entries->version, AUX_CACHE_VERSION, + sizeof AUX_CACHE_VERSION - 1); + + aux_file_entries->nlibs = cache_entry_count; + aux_file_entries->len_strings = total_strlen; + pad = ALIGN_CACHE (file_entries_size) - file_entries_size; /* If we have both formats, we hide the new format in the strings @@ -351,6 +415,8 @@ save_cache (const char *cache_name) str_offset = file_entries_new_size; else str_offset = 0; + /* Initial String offset for auxiliary cache is always 0. */ + aux_str_offset = 0; str = strings; for (idx_old = 0, idx_new = 0, entry = entries; entry != NULL; @@ -374,21 +440,30 @@ save_cache (const char *cache_name) file_entries_new->libs[idx_new].hwcap = entry->hwcap; file_entries_new->libs[idx_new].key = str_offset; } + aux_file_entries->libs[idx_new].flags = entry->flags; + aux_file_entries->libs[idx_new].osversion = entry->osversion; + aux_file_entries->libs[idx_new].hwcap = entry->hwcap; + aux_file_entries->libs[idx_new].id = entry->id; + aux_file_entries->libs[idx_new].key = aux_str_offset; + len = strlen (entry->lib); str = stpcpy (str, entry->lib); /* Account the final NUL. */ ++str; str_offset += len + 1; + aux_str_offset += len + 1; /* Then the path. */ if (opt_format != 2 && entry->hwcap == 0) file_entries->libs[idx_old].value = str_offset + pad; if (opt_format != 0) file_entries_new->libs[idx_new].value = str_offset; + aux_file_entries->libs[idx_new].value = aux_str_offset; len = strlen (entry->path); str = stpcpy (str, entry->path); /* Account the final NUL. */ ++str; str_offset += len + 1; + aux_str_offset += len + 1; /* Ignore entries with hwcap for old format. */ if (entry->hwcap == 0) ++idx_old; @@ -454,9 +529,66 @@ save_cache (const char *cache_name) error (EXIT_FAILURE, errno, _("Renaming of %s to %s failed"), temp_name, cache_name); + if (stat64 (cache_name, &st) < 0) + error (EXIT_FAILURE, errno, _("stat of cache file %s failed.\n"), cache_name); + + aux_file_entries->idldsocache.ino = (uint64_t) st.st_ino; + aux_file_entries->idldsocache.ctime = (uint64_t) st.st_ctime; + aux_file_entries->idldsocache.size = (uint64_t) st.st_size; + aux_file_entries->idldsocache.dev = (uint64_t) st.st_dev; + + /* Write out auxiliary cache file. */ + /* Write auxiliary cache first to a temporary file and rename it later. */ + + temp_name = xmalloc (strlen (aux_cache_name) + 2); + sprintf (temp_name, "%s~", aux_cache_name); + + /* Check that directory exists and create if needed. */ + dir = xstrdup (aux_cache_name); + dir = dirname (dir); + if (stat64 (dir, &st) < 0) + { + if (mkdir (dir, 0755) < 0) + error (EXIT_FAILURE, errno, _("Cannot create directory %s"), dir); + } + free (dir); + + /* First remove an old copy if it exists. */ + if (unlink (temp_name) && errno != ENOENT) + error (EXIT_FAILURE, errno, _("Can't remove old temporary auxiliary cache file %s"), + temp_name); + + /* Create file. */ + fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, + S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR); + if (fd < 0) + error (EXIT_FAILURE, errno, _("Can't create temporary auxiliary cache file %s"), + temp_name); + + if (write (fd, aux_file_entries, aux_file_entries_size) + != (ssize_t) aux_file_entries_size) + error (EXIT_FAILURE, errno, _("Writing of auxiliary cache data failed")); + + if (write (fd, strings, total_strlen) != (ssize_t) total_strlen) + error (EXIT_FAILURE, errno, _("Writing of auxiliary cache data failed")); + + close (fd); + + /* Make sure user can always read auxiliary cache file */ + if (chmod (temp_name, S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR)) + error (EXIT_FAILURE, errno, + _("Changing access rights of %s to %#o failed"), temp_name, + S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR); + + /* Move temporary to its final location. */ + if (rename (temp_name, aux_cache_name)) + error (EXIT_FAILURE, errno, _("Renaming of %s to %s failed"), temp_name, + aux_cache_name); + /* Free all allocated memory. */ free (file_entries_new); free (file_entries); + free (aux_file_entries); free (strings); while (entries) @@ -473,7 +605,7 @@ save_cache (const char *cache_name) /* Add one library to the cache. */ void add_to_cache (const char *path, const char *lib, int flags, - unsigned int osversion, uint64_t hwcap) + unsigned int osversion, uint64_t hwcap, struct stat64 *stat_buf) { struct cache_entry *new_entry, *ptr, *prev; char *full_path; @@ -492,6 +624,11 @@ add_to_cache (const char *path, const ch new_entry->osversion = osversion; new_entry->hwcap = hwcap; new_entry->bits_hwcap = 0; + new_entry->id.ino = (uint64_t) stat_buf->st_ino; + new_entry->id.ctime = (uint64_t) stat_buf->st_ctime; + new_entry->id.size = (uint64_t) stat_buf->st_size; + new_entry->id.dev = (uint64_t) stat_buf->st_dev; + /* Count the number of bits set in the masked value. */ for (i = 0; (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i) @@ -521,3 +658,145 @@ add_to_cache (const char *path, const ch prev->next = new_entry; } } + +/* Load auxiliary cache to search for unchanged entries. Be paraniod + about data checking, as we don't + know if the cache is from the + right architecture or currupted. */ + +void +load_aux_cache (const char *cache_name, const char *aux_cache_name) +{ + size_t aux_cache_size; + const char *aux_cache_data; + struct stat64 st; + int fd; + unsigned int i; + size_t j; + struct aux_cache_file *aux_cache; + struct cache_entry *new_entry, *last; + + uint64_t hwcap; + + fd = open (aux_cache_name, O_RDONLY); + if (fd < 0) + return; + + if (fstat64 (fd, &st) < 0 || st.st_size == 0) + { + close (fd); + return; + } + aux_cache = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (aux_cache == MAP_FAILED) + { + close (fd); + return; + } + + aux_cache_size = st.st_size; + if (aux_cache_size < sizeof (struct aux_cache_file)) + { + close (fd); + return; + } + if (memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1) + || memcmp (aux_cache->version, AUX_CACHE_VERSION, + sizeof AUX_CACHE_VERSION - 1)) + { + close (fd); + return; + } + if (aux_cache->nlibs < 0 || aux_cache->nlibs >= aux_cache_size) + { + close (fd); + return; + } + + /* Check that ld.so.cache has not been changed externally. */ + if (stat64 (cache_name, &st) < 0 || + aux_cache->idldsocache.ino != (uint64_t) st.st_ino || + aux_cache->idldsocache.ctime != (uint64_t) st.st_ctime || + aux_cache->idldsocache.size != (uint64_t) st.st_size || + aux_cache->idldsocache.dev != (uint64_t) st.st_dev) + { + close (fd); + return; + } + + aux_cache_data = (const char *) &aux_cache->libs[aux_cache->nlibs]; + last = NULL; + for (i = 0; i < aux_cache->nlibs; i++) + { + new_entry = (struct cache_entry *) xmalloc (sizeof (struct cache_entry)); + new_entry->lib = xstrdup (aux_cache_data + aux_cache->libs[i].key); + new_entry->path = xstrdup (aux_cache_data + aux_cache->libs[i].value); + new_entry->flags = aux_cache->libs[i].flags; + new_entry->osversion = aux_cache->libs[i].osversion; + hwcap = aux_cache->libs[i].hwcap; + new_entry->hwcap = hwcap; + new_entry->bits_hwcap = 0; + memcpy(&new_entry->id, &aux_cache->libs[i].id, sizeof (struct cache_entry_id)); + + /* Count the number of bits set in the masked value. */ + for (j = 0; (~((1ULL << j) - 1) & hwcap) != 0 && j < 8 * sizeof (hwcap); ++j) + if ((hwcap & (1ULL << j)) != 0) + ++new_entry->bits_hwcap; + /* Add at end of list. */ + if (last == NULL) + last = new_entry; + else + { + last->next = new_entry; + last = new_entry; + } + new_entry->next = aux_entries; + aux_entries = new_entry; + } + /* NULL terminate list. */ + if (last != NULL) + last->next = NULL; + munmap (aux_cache, aux_cache_size); + close (fd); +} + +int +search_aux_cache (const char *file, struct stat64 *stat_buf, int *flags, + unsigned int *osversion, char **soname) +{ + struct cache_entry *entry; + struct cache_entry_id id; + + id.ino = (uint64_t) stat_buf->st_ino; + id.ctime = (uint64_t) stat_buf->st_ctime; + id.size = (uint64_t) stat_buf->st_size; + id.dev = (uint64_t) stat_buf->st_dev; + for (entry = aux_entries; entry; entry = entry->next) + { + if (id.ino == entry->id.ino && + id.ctime == entry->id.ctime && + id.size == entry->id.size && + id.dev == entry->id.dev) + { + *flags = entry->flags; + *osversion = entry->osversion; + *soname = xstrdup (entry->lib); + return 1; + } + } + return 0; +} + +void +free_aux_cache (void) +{ + struct cache_entry *entry; + + while (aux_entries) + { + entry = aux_entries; + free (entry->path); + free (entry->lib); + aux_entries = entry->next; + free (entry); + } +} Index: elf/ldconfig.c =================================================================== RCS file: /cvs/glibc/libc/elf/ldconfig.c,v retrieving revision 1.59 diff -u -p -r1.59 ldconfig.c --- elf/ldconfig.c 13 Apr 2007 19:53:20 -0000 1.59 +++ elf/ldconfig.c 27 Jun 2007 19:09:17 -0000 @@ -111,6 +111,9 @@ static char *opt_chroot; /* Manually link given shared libraries. */ static int opt_manual_link; +/* Should we ignore an old auxiliary cache file? */ +static int opt_ignore_aux_cache; + /* Cache file to use. */ static char *cache_file; @@ -141,6 +144,7 @@ static const struct argp_option options[ { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0}, { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0}, { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new, old or compat (default)"), 0}, + { "ignore-aux-cache", 'i', NULL, 0, N_("Ignore auxiliary cache file"), 0}, { NULL, 0, NULL, 0, NULL, 0 } }; @@ -237,10 +241,15 @@ parse_opt (int key, char *arg, struct ar { case 'C': cache_file = arg; + /* Ignore auxiliary cache since we use non-standard cache. */ + opt_ignore_aux_cache = 1; break; case 'f': config_file = arg; break; + case 'i': + opt_ignore_aux_cache = 1; + break; case 'l': opt_manual_link = 1; break; @@ -572,7 +581,7 @@ manual_link (char *library) return; } if (process_file (real_library, library, libname, &flag, &osversion, - &soname, 0)) + &soname, 0, NULL)) { error (0, 0, _("No link created since soname could not be found for %s"), library); @@ -617,6 +626,7 @@ struct dlib_entry int flag; int is_link; unsigned int osversion; + struct stat64 stat_buf; struct dlib_entry *next; }; @@ -632,7 +642,7 @@ search_dir (const struct dir_entry *entr struct dlib_entry *dlibs; struct dlib_entry *dlib_ptr; struct stat64 lstat_buf, stat_buf; - int is_link, is_dir; + int is_link, is_dir, has_soname; uint64_t hwcap = path_hwcap (entry->path); unsigned int osversion; @@ -694,6 +704,7 @@ search_dir (const struct dir_entry *entr #endif !is_hwcap_platform (direntry->d_name))) continue; + len = strlen (direntry->d_name); /* Skip temporary files created by the prelink program. Files with names like these are never really DSOs we want to look at. */ @@ -726,16 +737,11 @@ search_dir (const struct dir_entry *entr } sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name); } -#ifdef _DIRENT_HAVE_D_TYPE - if (direntry->d_type != DT_UNKNOWN) - lstat_buf.st_mode = DTTOIF (direntry->d_type); - else -#endif - if (__builtin_expect (lstat64 (real_file_name, &lstat_buf), 0)) - { - error (0, errno, _("Cannot lstat %s"), file_name); - continue; - } + if (__builtin_expect (lstat64 (real_file_name, &lstat_buf), 0)) + { + error (0, errno, _("Cannot lstat %s"), file_name); + continue; + } is_link = S_ISLNK (lstat_buf.st_mode); if (is_link) @@ -753,6 +759,10 @@ search_dir (const struct dir_entry *entr continue; } is_dir = S_ISDIR (stat_buf.st_mode); + lstat_buf.st_ino = stat_buf.st_ino; + lstat_buf.st_ctime = stat_buf.st_ctime; + lstat_buf.st_size = stat_buf.st_size; + lstat_buf.st_dev = stat_buf.st_dev; } else is_dir = S_ISDIR (lstat_buf.st_mode); @@ -773,20 +783,6 @@ search_dir (const struct dir_entry *entr } else { -#ifdef _DIRENT_HAVE_D_TYPE - /* We have filled in lstat only #ifndef - _DIRENT_HAVE_D_TYPE. Fill it in if needed. */ - if (direntry->d_type != DT_UNKNOWN - && __builtin_expect (lstat64 (real_file_name, &lstat_buf), - 0)) - { - error (0, errno, _("Cannot lstat %s"), file_name); - free (new_entry->path); - free (new_entry); - continue; - } -#endif - new_entry->ino = lstat_buf.st_ino; new_entry->dev = lstat_buf.st_dev; } @@ -809,15 +805,19 @@ search_dir (const struct dir_entry *entr else real_name = real_file_name; - if (process_file (real_name, file_name, direntry->d_name, &flag, - &osversion, &soname, is_link)) + has_soname = 1; + if (!search_aux_cache (direntry->d_name, &lstat_buf, &flag, &osversion, + &soname)) { - if (real_name != real_file_name) - free (real_name); - continue; + if (process_file (real_name, file_name, direntry->d_name, &flag, + &osversion, &soname, is_link, &has_soname)) + { + if (real_name != real_file_name) + free (real_name); + continue; + } } - /* A link may just point to itself. */ if (is_link) { @@ -840,6 +840,8 @@ search_dir (const struct dir_entry *entr if (is_link) { + if (strcmp (soname, direntry->d_name) != 0) + has_soname = 0; free (soname); soname = xstrdup (direntry->d_name); } @@ -847,7 +849,22 @@ search_dir (const struct dir_entry *entr if (flag == FLAG_ELF && (entry->flag == FLAG_ELF_LIBC5 || entry->flag == FLAG_ELF_LIBC6)) - flag = entry->flag; + { + flag = entry->flag; + /* Invalidate id data as we changed the flag */ + has_soname = 0; + } + + if (!has_soname) + { + /* The soname or flags depend on file name of dir properties, + so invalidate id entry. */ + lstat_buf.st_ino = 0; + lstat_buf.st_ctime = 0; + lstat_buf.st_size = 0; + lstat_buf.st_dev = 0; + } + /* Some sanity checks to print warnings. */ if (opt_verbose) { @@ -886,13 +903,20 @@ search_dir (const struct dir_entry *entr && flag == FLAG_ELF) dlib_ptr->flag = flag; else - error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."), - dlib_ptr->name, direntry->d_name, entry->path); + { + error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."), + dlib_ptr->name, direntry->d_name, entry->path); + lstat_buf.st_ino = 0; + lstat_buf.st_ctime = 0; + lstat_buf.st_size = 0; + lstat_buf.st_dev = 0; + } } free (dlib_ptr->name); dlib_ptr->osversion = osversion; dlib_ptr->name = xstrdup (direntry->d_name); dlib_ptr->is_link = is_link; + dlib_ptr->stat_buf = lstat_buf; } /* Don't add this library, abort loop. */ /* Also free soname, since it's dynamically allocated. */ @@ -909,6 +933,7 @@ search_dir (const struct dir_entry *entr dlib_ptr->osversion = osversion; dlib_ptr->soname = soname; dlib_ptr->is_link = is_link; + dlib_ptr->stat_buf = lstat_buf; /* Add at head of list. */ dlib_ptr->next = dlibs; dlibs = dlib_ptr; @@ -927,7 +952,7 @@ search_dir (const struct dir_entry *entr dlib_ptr->soname); if (opt_build_cache) add_to_cache (entry->path, dlib_ptr->soname, dlib_ptr->flag, - dlib_ptr->osversion, hwcap); + dlib_ptr->osversion, hwcap, &dlib_ptr->stat_buf); } /* Free all resources. */ @@ -1292,10 +1317,15 @@ main (int argc, char **argv) add_system_dir (LIBDIR); } + if (! opt_ignore_aux_cache) + load_aux_cache (cache_file, _PATH_LDCONFIG_AUX_CACHE); + search_dirs (); + free_aux_cache (); + if (opt_build_cache) - save_cache (cache_file); + save_cache (cache_file, _PATH_LDCONFIG_AUX_CACHE); return 0; } Index: elf/readlib.c =================================================================== RCS file: /cvs/glibc/libc/elf/readlib.c,v retrieving revision 1.19 diff -u -p -r1.19 readlib.c --- elf/readlib.c 21 Dec 2005 22:16:20 -0000 1.19 +++ elf/readlib.c 27 Jun 2007 19:09:17 -0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1999-2003, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 1999 and Jakub Jelinek <jakub@redhat.com>, 1999. @@ -68,7 +68,7 @@ static struct known_names known_libs[] = int process_file (const char *real_file_name, const char *file_name, const char *lib, int *flag, unsigned int *osversion, - char **soname, int is_link) + char **soname, int is_link, int *has_soname) { FILE *file; struct stat64 statbuf; @@ -77,6 +77,9 @@ process_file (const char *real_file_name ElfW(Ehdr) *elf_header; struct exec *aout_header; + if (has_soname) + *has_soname = 0; + ret = 0; *flag = FLAG_ANY; *soname = NULL; @@ -165,9 +168,16 @@ process_file (const char *real_file_name /* Libraries have to be shared object files. */ else if (elf_header->e_type != ET_DYN) ret = 1; - else if (process_elf_file (file_name, lib, flag, osversion, soname, + else + { + if (process_elf_file (file_name, lib, flag, osversion, soname, file_contents, statbuf.st_size)) - ret = 1; + ret = 1; + else if (! *soname) + *soname = xstrdup (lib); + else if (has_soname) + *has_soname = 1; + } done: /* Clean up allocated memory and resources. */ Index: sysdeps/generic/ldconfig.h =================================================================== RCS file: /cvs/glibc/libc/sysdeps/generic/ldconfig.h,v retrieving revision 1.6 diff -u -p -r1.6 ldconfig.h --- sysdeps/generic/ldconfig.h 14 Mar 2003 05:32:49 -0000 1.6 +++ sysdeps/generic/ldconfig.h 27 Jun 2007 19:09:21 -0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 1999. @@ -35,20 +35,32 @@ #define FLAG_MIPS64_LIBN32 0x0600 #define FLAG_MIPS64_LIBN64 0x0700 +/* Name of auxiliary cache. */ +#define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/ldconfig.aux-cache" + /* Declared in cache.c. */ extern void print_cache (const char *cache_name); extern void init_cache (void); -extern void save_cache (const char *cache_name); +extern void save_cache (const char *cache_name, const char *aux_cache_name); extern void add_to_cache (const char *path, const char *lib, int flags, - unsigned int osversion, uint64_t hwcap); + unsigned int osversion, uint64_t hwcap, + struct stat64 *stat_buf); + +extern void load_aux_cache (const char *cache_name, const char *aux_cache_name); + +extern int search_aux_cache (const char *file, struct stat64 *stat_buf, + int *flags, unsigned int *osversion, + char **soname); + +extern void free_aux_cache (void); /* Declared in readlib.c. */ extern int process_file (const char *real_file_name, const char *file_name, const char *lib, int *flag, unsigned int *osversion, - char **soname, int is_link); + char **soname, int is_link, int *has_soname); /* Declared in readelflib.c. */ extern int process_elf_file (const char *file_name, const char *lib, int *flag, -- Andreas Jaeger, Director Platform/openSUSE, aj@suse.de SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126
Attachment:
pgp00000.pgp
Description: PGP signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |