Update install.texi, and regenerate INSTALL.
[glibc.git] / elf / cache.c
blob3d7d3a67bf4e6d2d171f985951f5874cd47f362d
1 /* Copyright (C) 1999-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published
6 by the Free Software Foundation; version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <https://www.gnu.org/licenses/>. */
17 #include <assert.h>
18 #include <errno.h>
19 #include <error.h>
20 #include <dirent.h>
21 #include <inttypes.h>
22 #include <libgen.h>
23 #include <libintl.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <stdint.h>
29 #include <sys/fcntl.h>
30 #include <sys/mman.h>
31 #include <sys/param.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
35 #include <ldconfig.h>
36 #include <dl-cache.h>
37 #include <version.h>
38 #include <stringtable.h>
40 /* Used to store library names, paths, and other strings. */
41 static struct stringtable strings;
43 /* Keeping track of "glibc-hwcaps" subdirectories. During cache
44 construction, a linear search by name is performed to deduplicate
45 entries. */
46 struct glibc_hwcaps_subdirectory
48 struct glibc_hwcaps_subdirectory *next;
50 /* Interned string with the subdirectory name. */
51 struct stringtable_entry *name;
53 /* Array index in the cache_extension_tag_glibc_hwcaps section in
54 the stored cached file. This is computed after all the
55 subdirectories have been processed, so that subdirectory names in
56 the extension section can be sorted. */
57 uint32_t section_index;
59 /* True if the subdirectory is actually used for anything. */
60 bool used;
63 const char *
64 glibc_hwcaps_subdirectory_name (const struct glibc_hwcaps_subdirectory *dir)
66 return dir->name->string;
69 /* Linked list of known hwcaps subdirecty names. */
70 static struct glibc_hwcaps_subdirectory *hwcaps;
72 struct glibc_hwcaps_subdirectory *
73 new_glibc_hwcaps_subdirectory (const char *name)
75 struct stringtable_entry *name_interned = stringtable_add (&strings, name);
76 for (struct glibc_hwcaps_subdirectory *p = hwcaps; p != NULL; p = p->next)
77 if (p->name == name_interned)
78 return p;
79 struct glibc_hwcaps_subdirectory *p = xmalloc (sizeof (*p));
80 p->next = hwcaps;
81 p->name = name_interned;
82 p->section_index = 0;
83 p->used = false;
84 hwcaps = p;
85 return p;
88 /* Helper for sorting struct glibc_hwcaps_subdirectory elements by
89 name. */
90 static int
91 assign_glibc_hwcaps_indices_compare (const void *l, const void *r)
93 const struct glibc_hwcaps_subdirectory *left
94 = *(struct glibc_hwcaps_subdirectory **)l;
95 const struct glibc_hwcaps_subdirectory *right
96 = *(struct glibc_hwcaps_subdirectory **)r;
97 return strcmp (glibc_hwcaps_subdirectory_name (left),
98 glibc_hwcaps_subdirectory_name (right));
101 /* Count the number of hwcaps subdirectories which are actually
102 used. */
103 static size_t
104 glibc_hwcaps_count (void)
106 size_t count = 0;
107 for (struct glibc_hwcaps_subdirectory *p = hwcaps; p != NULL; p = p->next)
108 if (p->used)
109 ++count;
110 return count;
113 /* Compute the section_index fields for all */
114 static void
115 assign_glibc_hwcaps_indices (void)
117 /* Convert the linked list into an array, so that we can use qsort.
118 Only copy the subdirectories which are actually used. */
119 size_t count = glibc_hwcaps_count ();
120 struct glibc_hwcaps_subdirectory **array
121 = xmalloc (sizeof (*array) * count);
123 size_t i = 0;
124 for (struct glibc_hwcaps_subdirectory *p = hwcaps; p != NULL; p = p->next)
125 if (p->used)
127 array[i] = p;
128 ++i;
130 assert (i == count);
133 qsort (array, count, sizeof (*array), assign_glibc_hwcaps_indices_compare);
135 /* Assign the array indices. */
136 for (size_t i = 0; i < count; ++i)
137 array[i]->section_index = i;
139 free (array);
142 struct cache_entry
144 struct stringtable_entry *lib; /* Library name. */
145 struct stringtable_entry *path; /* Path to find library. */
146 int flags; /* Flags to indicate kind of library. */
147 unsigned int isa_level; /* Required ISA level. */
148 uint64_t hwcap; /* Important hardware capabilities. */
149 int bits_hwcap; /* Number of bits set in hwcap. */
151 /* glibc-hwcaps subdirectory. If not NULL, hwcap must be zero. */
152 struct glibc_hwcaps_subdirectory *hwcaps;
154 struct cache_entry *next; /* Next entry in list. */
157 /* List of all cache entries. */
158 static struct cache_entry *entries;
160 static const char *flag_descr[] =
161 { "libc4", "ELF", "libc5", "libc6"};
163 /* Print a single entry. */
164 static void
165 print_entry (const char *lib, int flag, uint64_t hwcap,
166 const char *hwcap_string, const char *key)
168 printf ("\t%s (", lib);
169 switch (flag & FLAG_TYPE_MASK)
171 case FLAG_LIBC4:
172 case FLAG_ELF:
173 case FLAG_ELF_LIBC5:
174 case FLAG_ELF_LIBC6:
175 fputs (flag_descr[flag & FLAG_TYPE_MASK], stdout);
176 break;
177 default:
178 fputs (_("unknown"), stdout);
179 break;
181 switch (flag & FLAG_REQUIRED_MASK)
183 case FLAG_SPARC_LIB64:
184 fputs (",64bit", stdout);
185 break;
186 case FLAG_IA64_LIB64:
187 fputs (",IA-64", stdout);
188 break;
189 case FLAG_X8664_LIB64:
190 fputs (",x86-64", stdout);
191 break;
192 case FLAG_S390_LIB64:
193 fputs (",64bit", stdout);
194 break;
195 case FLAG_POWERPC_LIB64:
196 fputs (",64bit", stdout);
197 break;
198 case FLAG_MIPS64_LIBN32:
199 fputs (",N32", stdout);
200 break;
201 case FLAG_MIPS64_LIBN64:
202 fputs (",64bit", stdout);
203 break;
204 case FLAG_X8664_LIBX32:
205 fputs (",x32", stdout);
206 break;
207 case FLAG_ARM_LIBHF:
208 fputs (",hard-float", stdout);
209 break;
210 case FLAG_AARCH64_LIB64:
211 fputs (",AArch64", stdout);
212 break;
213 /* Uses the ARM soft-float ABI. */
214 case FLAG_ARM_LIBSF:
215 fputs (",soft-float", stdout);
216 break;
217 case FLAG_MIPS_LIB32_NAN2008:
218 fputs (",nan2008", stdout);
219 break;
220 case FLAG_MIPS64_LIBN32_NAN2008:
221 fputs (",N32,nan2008", stdout);
222 break;
223 case FLAG_MIPS64_LIBN64_NAN2008:
224 fputs (",64bit,nan2008", stdout);
225 break;
226 case FLAG_RISCV_FLOAT_ABI_SOFT:
227 fputs (",soft-float", stdout);
228 break;
229 case FLAG_RISCV_FLOAT_ABI_DOUBLE:
230 fputs (",double-float", stdout);
231 break;
232 case 0:
233 break;
234 default:
235 printf (",%d", flag & FLAG_REQUIRED_MASK);
236 break;
238 if (hwcap_string != NULL)
239 printf (", hwcap: \"%s\"", hwcap_string);
240 else if (hwcap != 0)
241 printf (", hwcap: %#.16" PRIx64, hwcap);
242 printf (") => %s\n", key);
245 /* Returns the string with the name of the glibcs-hwcaps subdirectory
246 associated with ENTRY->hwcap. file_base must be the base address
247 for string table indices. */
248 static const char *
249 glibc_hwcaps_string (struct cache_extension_all_loaded *ext,
250 const void *file_base, size_t file_size,
251 struct file_entry_new *entry)
253 const uint32_t *hwcaps_array
254 = ext->sections[cache_extension_tag_glibc_hwcaps].base;
255 if (dl_cache_hwcap_extension (entry) && hwcaps_array != NULL)
257 uint32_t index = (uint32_t) entry->hwcap;
258 if (index < ext->sections[cache_extension_tag_glibc_hwcaps].size / 4)
260 uint32_t string_table_index = hwcaps_array[index];
261 if (string_table_index < file_size)
262 return file_base + string_table_index;
265 return NULL;
268 /* Print an error and exit if the new-file cache is internally
269 inconsistent. */
270 static void
271 check_new_cache (struct cache_file_new *cache)
273 if (! cache_file_new_matches_endian (cache))
274 error (EXIT_FAILURE, 0, _("Cache file has wrong endianness.\n"));
277 /* Print the extension information in *EXT. */
278 static void
279 print_extensions (struct cache_extension_all_loaded *ext)
281 if (ext->sections[cache_extension_tag_generator].base != NULL)
283 fputs (_("Cache generated by: "), stdout);
284 fwrite (ext->sections[cache_extension_tag_generator].base, 1,
285 ext->sections[cache_extension_tag_generator].size, stdout);
286 putchar ('\n');
290 /* Print the whole cache file, if a file contains the new cache format
291 hidden in the old one, print the contents of the new format. */
292 void
293 print_cache (const char *cache_name)
295 int fd = open (cache_name, O_RDONLY);
296 if (fd < 0)
297 error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name);
299 struct stat st;
300 if (fstat (fd, &st) < 0
301 /* No need to map the file if it is empty. */
302 || st.st_size == 0)
304 close (fd);
305 return;
308 struct cache_file *cache
309 = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
310 if (cache == MAP_FAILED)
311 error (EXIT_FAILURE, errno, _("mmap of cache file failed.\n"));
313 size_t cache_size = st.st_size;
314 if (cache_size < sizeof (struct cache_file))
315 error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
317 struct cache_file_new *cache_new = NULL;
318 const char *cache_data;
319 int format = 0;
321 if (memcmp (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1))
323 /* This can only be the new format without the old one. */
324 cache_new = (struct cache_file_new *) cache;
326 if (memcmp (cache_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1)
327 || memcmp (cache_new->version, CACHE_VERSION,
328 sizeof CACHE_VERSION - 1))
329 error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
330 check_new_cache (cache_new);
331 format = 1;
332 /* This is where the strings start. */
333 cache_data = (const char *) cache_new;
335 else
337 /* Check for corruption, avoiding overflow. */
338 if ((cache_size - sizeof (struct cache_file)) / sizeof (struct file_entry)
339 < cache->nlibs)
340 error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
342 size_t offset = ALIGN_CACHE (sizeof (struct cache_file)
343 + (cache->nlibs
344 * sizeof (struct file_entry)));
345 /* This is where the strings start. */
346 cache_data = (const char *) &cache->libs[cache->nlibs];
348 /* Check for a new cache embedded in the old format. */
349 if (cache_size
350 > (offset + sizeof (struct cache_file_new)))
353 cache_new = (struct cache_file_new *) ((void *)cache + offset);
355 if (memcmp (cache_new->magic, CACHEMAGIC_NEW,
356 sizeof CACHEMAGIC_NEW - 1) == 0
357 && memcmp (cache_new->version, CACHE_VERSION,
358 sizeof CACHE_VERSION - 1) == 0)
360 check_new_cache (cache_new);
361 cache_data = (const char *) cache_new;
362 format = 1;
367 if (format == 0)
369 printf (_("%d libs found in cache `%s'\n"), cache->nlibs, cache_name);
371 /* Print everything. */
372 for (unsigned int i = 0; i < cache->nlibs; i++)
373 print_entry (cache_data + cache->libs[i].key,
374 cache->libs[i].flags, 0, NULL,
375 cache_data + cache->libs[i].value);
377 else if (format == 1)
379 struct cache_extension_all_loaded ext;
380 if (!cache_extension_load (cache_new, cache, cache_size, &ext))
381 error (EXIT_FAILURE, 0,
382 _("Malformed extension data in cache file %s\n"), cache_name);
384 printf (_("%d libs found in cache `%s'\n"),
385 cache_new->nlibs, cache_name);
387 /* Print everything. */
388 for (unsigned int i = 0; i < cache_new->nlibs; i++)
390 const char *hwcaps_string
391 = glibc_hwcaps_string (&ext, cache, cache_size,
392 &cache_new->libs[i]);
393 print_entry (cache_data + cache_new->libs[i].key,
394 cache_new->libs[i].flags,
395 cache_new->libs[i].hwcap, hwcaps_string,
396 cache_data + cache_new->libs[i].value);
398 print_extensions (&ext);
400 /* Cleanup. */
401 munmap (cache, cache_size);
402 close (fd);
405 /* Initialize cache data structures. */
406 void
407 init_cache (void)
409 entries = NULL;
412 static int
413 compare (const struct cache_entry *e1, const struct cache_entry *e2)
415 /* We need to swap entries here to get the correct sort order. */
416 int res = _dl_cache_libcmp (e2->lib->string, e1->lib->string);
417 if (res == 0)
419 if (e1->flags < e2->flags)
420 return 1;
421 else if (e1->flags > e2->flags)
422 return -1;
423 /* Keep the glibc-hwcaps extension entries before the regular
424 entries, and sort them by their names. search_cache in
425 dl-cache.c stops searching once the first non-extension entry
426 is found, so the extension entries need to come first. */
427 else if (e1->hwcaps != NULL && e2->hwcaps == NULL)
428 return -1;
429 else if (e1->hwcaps == NULL && e2->hwcaps != NULL)
430 return 1;
431 else if (e1->hwcaps != NULL && e2->hwcaps != NULL)
433 res = strcmp (glibc_hwcaps_subdirectory_name (e1->hwcaps),
434 glibc_hwcaps_subdirectory_name (e2->hwcaps));
435 if (res != 0)
436 return res;
438 /* Sort by most specific hwcap. */
439 if (e2->bits_hwcap > e1->bits_hwcap)
440 return 1;
441 else if (e2->bits_hwcap < e1->bits_hwcap)
442 return -1;
443 else if (e2->hwcap > e1->hwcap)
444 return 1;
445 else if (e2->hwcap < e1->hwcap)
446 return -1;
448 return res;
451 /* Size of the cache extension directory. All tags are assumed to be
452 present. */
453 enum
455 cache_extension_size = (offsetof (struct cache_extension, sections)
456 + (cache_extension_count
457 * sizeof (struct cache_extension_section)))
460 /* Write the cache extensions to FD. The string table is shifted by
461 STRING_TABLE_OFFSET. The extension directory is assumed to be
462 located at CACHE_EXTENSION_OFFSET. assign_glibc_hwcaps_indices
463 must have been called. */
464 static void
465 write_extensions (int fd, uint32_t str_offset,
466 uint32_t cache_extension_offset)
468 assert ((cache_extension_offset % 4) == 0);
470 /* The length and contents of the glibc-hwcaps section. */
471 uint32_t hwcaps_count = glibc_hwcaps_count ();
472 uint32_t hwcaps_offset = cache_extension_offset + cache_extension_size;
473 uint32_t hwcaps_size = hwcaps_count * sizeof (uint32_t);
474 uint32_t *hwcaps_array = xmalloc (hwcaps_size);
475 for (struct glibc_hwcaps_subdirectory *p = hwcaps; p != NULL; p = p->next)
476 if (p->used)
477 hwcaps_array[p->section_index] = str_offset + p->name->offset;
479 /* This is the offset of the generator string. */
480 uint32_t generator_offset = hwcaps_offset;
481 if (hwcaps_count == 0)
482 /* There is no section for the hwcaps subdirectories. */
483 generator_offset -= sizeof (struct cache_extension_section);
484 else
485 /* The string table indices for the hwcaps subdirectories shift
486 the generator string backwards. */
487 generator_offset += hwcaps_size;
489 struct cache_extension *ext = xmalloc (cache_extension_size);
490 ext->magic = cache_extension_magic;
492 /* Extension index current being filled. */
493 size_t xid = 0;
495 const char *generator
496 = "ldconfig " PKGVERSION RELEASE " release version " VERSION;
497 ext->sections[xid].tag = cache_extension_tag_generator;
498 ext->sections[xid].flags = 0;
499 ext->sections[xid].offset = generator_offset;
500 ext->sections[xid].size = strlen (generator);
502 if (hwcaps_count > 0)
504 ++xid;
505 ext->sections[xid].tag = cache_extension_tag_glibc_hwcaps;
506 ext->sections[xid].flags = 0;
507 ext->sections[xid].offset = hwcaps_offset;
508 ext->sections[xid].size = hwcaps_size;
511 ++xid;
512 ext->count = xid;
513 assert (xid <= cache_extension_count);
515 size_t ext_size = (offsetof (struct cache_extension, sections)
516 + xid * sizeof (struct cache_extension_section));
517 if (write (fd, ext, ext_size) != ext_size
518 || write (fd, hwcaps_array, hwcaps_size) != hwcaps_size
519 || write (fd, generator, strlen (generator)) != strlen (generator))
520 error (EXIT_FAILURE, errno, _("Writing of cache extension data failed"));
522 free (hwcaps_array);
523 free (ext);
526 /* Compute the hwcap value from ENTRY. */
527 static inline uint64_t
528 compute_hwcap_value (struct cache_entry *entry)
530 if (entry->isa_level > DL_CACHE_HWCAP_ISA_LEVEL_MASK)
531 error (EXIT_FAILURE, 0, _("%s: ISA level is too high (%d > %d)"),
532 entry->path->string, entry->isa_level,
533 DL_CACHE_HWCAP_ISA_LEVEL_MASK);
534 return (DL_CACHE_HWCAP_EXTENSION
535 | (((uint64_t) entry->isa_level) << 32)
536 | entry->hwcaps->section_index);
539 /* Save the contents of the cache. */
540 void
541 save_cache (const char *cache_name)
543 /* The cache entries are sorted already, save them in this order. */
545 assign_glibc_hwcaps_indices ();
547 struct cache_entry *entry;
548 /* Number of cache entries. */
549 int cache_entry_count = 0;
550 /* The old format doesn't contain hwcap entries and doesn't contain
551 libraries in subdirectories with hwcaps entries. Count therefore
552 also all entries with hwcap == 0. */
553 int cache_entry_old_count = 0;
555 for (entry = entries; entry != NULL; entry = entry->next)
557 ++cache_entry_count;
558 if (entry->hwcap == 0)
559 ++cache_entry_old_count;
562 struct stringtable_finalized strings_finalized;
563 stringtable_finalize (&strings, &strings_finalized);
565 /* Create the on disk cache structure. */
566 struct cache_file *file_entries = NULL;
567 size_t file_entries_size = 0;
569 if (opt_format != opt_format_new)
571 /* struct cache_file_new is 64-bit aligned on some arches while
572 only 32-bit aligned on other arches. Duplicate last old
573 cache entry so that new cache in ld.so.cache can be used by
574 both. */
575 if (opt_format != opt_format_old)
576 cache_entry_old_count = (cache_entry_old_count + 1) & ~1;
578 /* And the list of all entries in the old format. */
579 file_entries_size = sizeof (struct cache_file)
580 + cache_entry_old_count * sizeof (struct file_entry);
581 file_entries = xmalloc (file_entries_size);
583 /* Fill in the header. */
584 memset (file_entries, '\0', sizeof (struct cache_file));
585 memcpy (file_entries->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1);
587 file_entries->nlibs = cache_entry_old_count;
590 struct cache_file_new *file_entries_new = NULL;
591 size_t file_entries_new_size = 0;
593 if (opt_format != opt_format_old)
595 /* And the list of all entries in the new format. */
596 file_entries_new_size = sizeof (struct cache_file_new)
597 + cache_entry_count * sizeof (struct file_entry_new);
598 file_entries_new = xmalloc (file_entries_new_size);
600 /* Fill in the header. */
601 memset (file_entries_new, '\0', sizeof (struct cache_file_new));
602 memcpy (file_entries_new->magic, CACHEMAGIC_NEW,
603 sizeof CACHEMAGIC_NEW - 1);
604 memcpy (file_entries_new->version, CACHE_VERSION,
605 sizeof CACHE_VERSION - 1);
607 file_entries_new->nlibs = cache_entry_count;
608 file_entries_new->len_strings = strings_finalized.size;
609 file_entries_new->flags = cache_file_new_flags_endian_current;
612 /* Pad for alignment of cache_file_new. */
613 size_t pad = ALIGN_CACHE (file_entries_size) - file_entries_size;
615 /* If we have both formats, we hide the new format in the strings
616 table, we have to adjust all string indices for this so that
617 old libc5/glibc 2 dynamic linkers just ignore them. */
618 unsigned int str_offset;
619 if (opt_format != opt_format_old)
620 str_offset = file_entries_new_size;
621 else
622 str_offset = 0;
624 /* An array for all strings. */
625 int idx_old;
626 int idx_new;
628 for (idx_old = 0, idx_new = 0, entry = entries; entry != NULL;
629 entry = entry->next, ++idx_new)
631 if (opt_format != opt_format_new && entry->hwcap == 0)
633 file_entries->libs[idx_old].flags = entry->flags;
634 /* XXX: Actually we can optimize here and remove duplicates. */
635 file_entries->libs[idx_old].key = str_offset + pad;
636 file_entries->libs[idx_new].key = str_offset + entry->lib->offset;
637 file_entries->libs[idx_new].value
638 = str_offset + entry->path->offset;
640 if (opt_format != opt_format_old)
642 /* We could subtract file_entries_new_size from str_offset -
643 not doing so makes the code easier, the string table
644 always begins at the beginning of the new cache
645 struct. */
646 file_entries_new->libs[idx_new].flags = entry->flags;
647 file_entries_new->libs[idx_new].osversion_unused = 0;
648 if (entry->hwcaps == NULL)
649 file_entries_new->libs[idx_new].hwcap = entry->hwcap;
650 else
651 file_entries_new->libs[idx_new].hwcap
652 = compute_hwcap_value (entry);
653 file_entries_new->libs[idx_new].key
654 = str_offset + entry->lib->offset;
655 file_entries_new->libs[idx_new].value
656 = str_offset + entry->path->offset;
659 /* Ignore entries with hwcap for old format. */
660 if (entry->hwcap == 0)
661 ++idx_old;
664 /* Duplicate last old cache entry if needed. */
665 if (opt_format != opt_format_new
666 && idx_old < cache_entry_old_count)
667 file_entries->libs[idx_old] = file_entries->libs[idx_old - 1];
669 /* Compute the location of the extension directory. This
670 implementation puts the directory after the string table. The
671 size computation matches the write calls below. The extension
672 directory does not exist with format 0, so the value does not
673 matter. */
674 uint32_t extension_offset = 0;
675 if (opt_format != opt_format_new)
676 extension_offset += file_entries_size;
677 if (opt_format != opt_format_old)
679 if (opt_format != opt_format_new)
680 extension_offset += pad;
681 extension_offset += file_entries_new_size;
683 extension_offset += strings_finalized.size;
684 extension_offset = roundup (extension_offset, 4); /* Provide alignment. */
685 if (opt_format != opt_format_old)
686 file_entries_new->extension_offset = extension_offset;
688 /* Write out the cache. */
690 /* Write cache first to a temporary file and rename it later. */
691 char *temp_name = xmalloc (strlen (cache_name) + 2);
692 sprintf (temp_name, "%s~", cache_name);
694 /* Create file. */
695 int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
696 S_IRUSR|S_IWUSR);
697 if (fd < 0)
698 error (EXIT_FAILURE, errno, _("Can't create temporary cache file %s"),
699 temp_name);
701 /* Write contents. */
702 if (opt_format != opt_format_new)
704 if (write (fd, file_entries, file_entries_size)
705 != (ssize_t) file_entries_size)
706 error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
708 if (opt_format != opt_format_old)
710 /* Align cache. */
711 if (opt_format != opt_format_new)
713 char zero[pad];
714 memset (zero, '\0', pad);
715 if (write (fd, zero, pad) != (ssize_t) pad)
716 error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
718 if (write (fd, file_entries_new, file_entries_new_size)
719 != (ssize_t) file_entries_new_size)
720 error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
723 if (write (fd, strings_finalized.strings, strings_finalized.size)
724 != (ssize_t) strings_finalized.size)
725 error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
727 if (opt_format != opt_format_old)
729 /* Align file position to 4. */
730 __attribute__ ((unused)) off64_t old_offset
731 = lseek64 (fd, extension_offset, SEEK_SET);
732 assert ((unsigned long long int) (extension_offset - old_offset) < 4);
733 write_extensions (fd, str_offset, extension_offset);
736 /* Make sure user can always read cache file */
737 if (chmod (temp_name, S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR))
738 error (EXIT_FAILURE, errno,
739 _("Changing access rights of %s to %#o failed"), temp_name,
740 S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR);
742 /* Make sure that data is written to disk. */
743 if (fsync (fd) != 0 || close (fd) != 0)
744 error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
746 /* Move temporary to its final location. */
747 if (rename (temp_name, cache_name))
748 error (EXIT_FAILURE, errno, _("Renaming of %s to %s failed"), temp_name,
749 cache_name);
751 /* Free all allocated memory. */
752 free (file_entries_new);
753 free (file_entries);
754 free (strings_finalized.strings);
755 free (temp_name);
757 while (entries)
759 entry = entries;
760 entries = entries->next;
761 free (entry);
766 /* Add one library to the cache. */
767 void
768 add_to_cache (const char *path, const char *filename, const char *soname,
769 int flags, unsigned int isa_level, uint64_t hwcap,
770 struct glibc_hwcaps_subdirectory *hwcaps)
772 struct cache_entry *new_entry = xmalloc (sizeof (*new_entry));
774 struct stringtable_entry *path_interned;
776 char *p;
777 if (asprintf (&p, "%s/%s", path, filename) < 0)
778 error (EXIT_FAILURE, errno, _("Could not create library path"));
779 path_interned = stringtable_add (&strings, p);
780 free (p);
783 new_entry->lib = stringtable_add (&strings, soname);
784 new_entry->path = path_interned;
785 new_entry->flags = flags;
786 new_entry->isa_level = isa_level;
787 new_entry->hwcap = hwcap;
788 new_entry->hwcaps = hwcaps;
789 new_entry->bits_hwcap = 0;
791 if (hwcaps != NULL)
793 assert (hwcap == 0);
794 hwcaps->used = true;
797 /* Count the number of bits set in the masked value. */
798 for (size_t i = 0;
799 (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i)
800 if ((hwcap & (1ULL << i)) != 0)
801 ++new_entry->bits_hwcap;
804 /* Keep the list sorted - search for right place to insert. */
805 struct cache_entry *ptr = entries;
806 struct cache_entry *prev = entries;
807 while (ptr != NULL)
809 if (compare (ptr, new_entry) > 0)
810 break;
811 prev = ptr;
812 ptr = ptr->next;
814 /* Is this the first entry? */
815 if (ptr == entries)
817 new_entry->next = entries;
818 entries = new_entry;
820 else
822 new_entry->next = prev->next;
823 prev->next = new_entry;
828 /* Auxiliary cache. */
830 struct aux_cache_entry_id
832 uint64_t ino;
833 uint64_t ctime;
834 uint64_t size;
835 uint64_t dev;
838 struct aux_cache_entry
840 struct aux_cache_entry_id id;
841 int flags;
842 unsigned int isa_level;
843 int used;
844 char *soname;
845 struct aux_cache_entry *next;
848 #define AUX_CACHEMAGIC "glibc-ld.so.auxcache-1.0"
850 struct aux_cache_file_entry
852 struct aux_cache_entry_id id; /* Unique id of entry. */
853 int32_t flags; /* This is 1 for an ELF library. */
854 uint32_t soname; /* String table indice. */
855 uint32_t isa_level; /* Required ISA level. */
858 /* ldconfig maintains an auxiliary cache file that allows
859 only reading those libraries that have changed since the last iteration.
860 For this for each library some information is cached in the auxiliary
861 cache. */
862 struct aux_cache_file
864 char magic[sizeof AUX_CACHEMAGIC - 1];
865 uint32_t nlibs; /* Number of entries. */
866 uint32_t len_strings; /* Size of string table. */
867 struct aux_cache_file_entry libs[0]; /* Entries describing libraries. */
868 /* After this the string table of size len_strings is found. */
871 static const unsigned int primes[] =
873 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139,
874 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393,
875 67108859, 134217689, 268435399, 536870909, 1073741789, 2147483647
878 static size_t aux_hash_size;
879 static struct aux_cache_entry **aux_hash;
881 /* Simplistic hash function for aux_cache_entry_id. */
882 static unsigned int
883 aux_cache_entry_id_hash (struct aux_cache_entry_id *id)
885 uint64_t ret = ((id->ino * 11 + id->ctime) * 11 + id->size) * 11 + id->dev;
886 return ret ^ (ret >> 32);
889 static size_t nextprime (size_t x)
891 for (unsigned int i = 0; i < sizeof (primes) / sizeof (primes[0]); ++i)
892 if (primes[i] >= x)
893 return primes[i];
894 return x;
897 void
898 init_aux_cache (void)
900 aux_hash_size = primes[3];
901 aux_hash = xcalloc (aux_hash_size, sizeof (struct aux_cache_entry *));
905 search_aux_cache (struct stat *stat_buf, int *flags, unsigned int *isa_level,
906 char **soname)
908 struct aux_cache_entry_id id;
909 id.ino = (uint64_t) stat_buf->st_ino;
910 id.ctime = (uint64_t) stat_buf->st_ctime;
911 id.size = (uint64_t) stat_buf->st_size;
912 id.dev = (uint64_t) stat_buf->st_dev;
914 unsigned int hash = aux_cache_entry_id_hash (&id);
915 struct aux_cache_entry *entry;
916 for (entry = aux_hash[hash % aux_hash_size]; entry; entry = entry->next)
917 if (id.ino == entry->id.ino
918 && id.ctime == entry->id.ctime
919 && id.size == entry->id.size
920 && id.dev == entry->id.dev)
922 *flags = entry->flags;
923 *isa_level = entry->isa_level;
924 if (entry->soname != NULL)
925 *soname = xstrdup (entry->soname);
926 else
927 *soname = NULL;
928 entry->used = 1;
929 return 1;
932 return 0;
935 static void
936 insert_to_aux_cache (struct aux_cache_entry_id *id, int flags,
937 unsigned int isa_level, const char *soname, int used)
939 size_t hash = aux_cache_entry_id_hash (id) % aux_hash_size;
940 struct aux_cache_entry *entry;
941 for (entry = aux_hash[hash]; entry; entry = entry->next)
942 if (id->ino == entry->id.ino
943 && id->ctime == entry->id.ctime
944 && id->size == entry->id.size
945 && id->dev == entry->id.dev)
946 abort ();
948 size_t len = soname ? strlen (soname) + 1 : 0;
949 entry = xmalloc (sizeof (struct aux_cache_entry) + len);
950 entry->id = *id;
951 entry->flags = flags;
952 entry->isa_level = isa_level;
953 entry->used = used;
954 if (soname != NULL)
955 entry->soname = memcpy ((char *) (entry + 1), soname, len);
956 else
957 entry->soname = NULL;
958 entry->next = aux_hash[hash];
959 aux_hash[hash] = entry;
962 void
963 add_to_aux_cache (struct stat *stat_buf, int flags, unsigned int isa_level,
964 const char *soname)
966 struct aux_cache_entry_id id;
967 id.ino = (uint64_t) stat_buf->st_ino;
968 id.ctime = (uint64_t) stat_buf->st_ctime;
969 id.size = (uint64_t) stat_buf->st_size;
970 id.dev = (uint64_t) stat_buf->st_dev;
971 insert_to_aux_cache (&id, flags, isa_level, soname, 1);
974 /* Load auxiliary cache to search for unchanged entries. */
975 void
976 load_aux_cache (const char *aux_cache_name)
978 int fd = open (aux_cache_name, O_RDONLY);
979 if (fd < 0)
981 init_aux_cache ();
982 return;
985 struct stat st;
986 if (fstat (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file))
988 close (fd);
989 init_aux_cache ();
990 return;
993 size_t aux_cache_size = st.st_size;
994 struct aux_cache_file *aux_cache
995 = mmap (NULL, aux_cache_size, PROT_READ, MAP_PRIVATE, fd, 0);
996 if (aux_cache == MAP_FAILED
997 || aux_cache_size < sizeof (struct aux_cache_file)
998 || memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1)
999 || aux_cache_size != (sizeof (struct aux_cache_file)
1000 + aux_cache->nlibs * sizeof (struct aux_cache_file_entry)
1001 + aux_cache->len_strings))
1003 if (aux_cache != MAP_FAILED)
1004 munmap (aux_cache, aux_cache_size);
1006 close (fd);
1007 init_aux_cache ();
1008 return;
1011 aux_hash_size = nextprime (aux_cache->nlibs);
1012 aux_hash = xcalloc (aux_hash_size, sizeof (struct aux_cache_entry *));
1014 const char *aux_cache_data
1015 = (const char *) &aux_cache->libs[aux_cache->nlibs];
1016 for (unsigned int i = 0; i < aux_cache->nlibs; ++i)
1017 insert_to_aux_cache (&aux_cache->libs[i].id,
1018 aux_cache->libs[i].flags,
1019 aux_cache->libs[i].isa_level,
1020 aux_cache->libs[i].soname == 0
1021 ? NULL : aux_cache_data + aux_cache->libs[i].soname,
1024 munmap (aux_cache, aux_cache_size);
1025 close (fd);
1028 /* Save the contents of the auxiliary cache. */
1029 void
1030 save_aux_cache (const char *aux_cache_name)
1032 /* Count the length of all sonames. We start with empty string. */
1033 size_t total_strlen = 1;
1034 /* Number of cache entries. */
1035 int cache_entry_count = 0;
1037 for (size_t i = 0; i < aux_hash_size; ++i)
1038 for (struct aux_cache_entry *entry = aux_hash[i];
1039 entry != NULL; entry = entry->next)
1040 if (entry->used)
1042 ++cache_entry_count;
1043 if (entry->soname != NULL)
1044 total_strlen += strlen (entry->soname) + 1;
1047 /* Auxiliary cache. */
1048 size_t file_entries_size
1049 = sizeof (struct aux_cache_file)
1050 + cache_entry_count * sizeof (struct aux_cache_file_entry);
1051 struct aux_cache_file *file_entries
1052 = xmalloc (file_entries_size + total_strlen);
1054 /* Fill in the header of the auxiliary cache. */
1055 memset (file_entries, '\0', sizeof (struct aux_cache_file));
1056 memcpy (file_entries->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1);
1058 file_entries->nlibs = cache_entry_count;
1059 file_entries->len_strings = total_strlen;
1061 /* Initial String offset for auxiliary cache is always after the
1062 special empty string. */
1063 unsigned int str_offset = 1;
1065 /* An array for all strings. */
1066 char *str = (char *) file_entries + file_entries_size;
1067 *str++ = '\0';
1069 size_t idx = 0;
1070 for (size_t i = 0; i < aux_hash_size; ++i)
1071 for (struct aux_cache_entry *entry = aux_hash[i];
1072 entry != NULL; entry = entry->next)
1073 if (entry->used)
1075 file_entries->libs[idx].id = entry->id;
1076 file_entries->libs[idx].flags = entry->flags;
1077 if (entry->soname == NULL)
1078 file_entries->libs[idx].soname = 0;
1079 else
1081 file_entries->libs[idx].soname = str_offset;
1083 size_t len = strlen (entry->soname) + 1;
1084 str = mempcpy (str, entry->soname, len);
1085 str_offset += len;
1087 file_entries->libs[idx++].isa_level = entry->isa_level;
1090 /* Write out auxiliary cache file. */
1091 /* Write auxiliary cache first to a temporary file and rename it later. */
1093 char *temp_name = xmalloc (strlen (aux_cache_name) + 2);
1094 sprintf (temp_name, "%s~", aux_cache_name);
1096 /* Check that directory exists and create if needed. */
1097 char *dir = strdupa (aux_cache_name);
1098 dir = dirname (dir);
1100 struct stat st;
1101 if (stat (dir, &st) < 0)
1103 if (mkdir (dir, 0700) < 0)
1104 goto out_fail;
1107 /* Create file. */
1108 int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
1109 S_IRUSR|S_IWUSR);
1110 if (fd < 0)
1111 goto out_fail;
1113 bool fail = ((write (fd, file_entries, file_entries_size + total_strlen)
1114 != (ssize_t) (file_entries_size + total_strlen))
1115 || fdatasync (fd) != 0);
1117 fail |= close (fd) != 0;
1119 if (fail)
1121 unlink (temp_name);
1122 goto out_fail;
1125 /* Move temporary to its final location. */
1126 if (rename (temp_name, aux_cache_name))
1127 unlink (temp_name);
1129 out_fail:
1130 /* Free allocated memory. */
1131 free (temp_name);
1132 free (file_entries);