universally apply our cflags (no vsx, no altivec..)
[glibc.git] / elf / ldconfig.c
1 /* Copyright (C) 1999-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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/>. */
16
17 #define PROCINFO_CLASS static
18 #include <assert.h>
19 #include <alloca.h>
20 #include <argp.h>
21 #include <dirent.h>
22 #include <elf.h>
23 #include <error.h>
24 #include <errno.h>
25 #include <inttypes.h>
26 #include <libintl.h>
27 #include <locale.h>
28 #include <stdbool.h>
29 #include <stdio.h>
30 #include <stdio_ext.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <stdint.h>
35 #include <sys/fcntl.h>
36 #include <sys/mman.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <glob.h>
40 #include <libgen.h>
41
42 #include <ldconfig.h>
43 #include <dl-cache.h>
44 #include <dl-hwcaps.h>
45 #include <dl-is_dso.h>
46
47 #include <dl-procinfo.h>
48
49 /* This subpath in search path entries is always supported and
50 included in the cache for backwards compatibility. */
51 #define TLS_SUBPATH "tls"
52
53 /* The MSB of the hwcap field is set for objects in TLS_SUBPATH
54 directories. There is always TLS support in glibc, so the dynamic
55 loader does not check the bit directly. But more hwcap bits make a
56 an object more preferred, so the bit still has meaning. */
57 #define TLS_HWCAP_BIT 63
58
59 #ifndef LD_SO_CONF
60 # define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
61 #endif
62
63 /* Get libc version number. */
64 #include <version.h>
65
66 #define PACKAGE _libc_intl_domainname
67
68 #ifndef PATH_MAX
69 #define PATH_MAX 1024
70 #endif
71
72 /* Get the generated information about the trusted/standard directories. */
73 #include "trusted-dirs.h"
74
75 static const char system_dirs[] = SYSTEM_DIRS;
76 static const size_t system_dirs_len[] =
77 {
78 SYSTEM_DIRS_LEN
79 };
80 #define nsystem_dirs_len \
81 (sizeof (system_dirs_len) / sizeof (system_dirs_len[0]))
82
83 static const struct
84 {
85 const char *name;
86 int flag;
87 } lib_types[] =
88 {
89 {"libc4", FLAG_LIBC4},
90 {"libc5", FLAG_ELF_LIBC5},
91 {"libc6", FLAG_ELF_LIBC6},
92 {"glibc2", FLAG_ELF_LIBC6}
93 };
94
95
96 /* List of directories to handle. */
97 struct dir_entry
98 {
99 char *path;
100 int flag;
101 ino64_t ino;
102 dev_t dev;
103 const char *from_file;
104 int from_line;
105
106 /* Non-NULL for subdirectories under a glibc-hwcaps subdirectory. */
107 struct glibc_hwcaps_subdirectory *hwcaps;
108
109 struct dir_entry *next;
110 };
111
112 /* The list is unsorted, contains no duplicates. Entries are added at
113 the end. */
114 static struct dir_entry *dir_entries;
115
116 /* Flags for different options. */
117 /* Print Cache. */
118 static int opt_print_cache;
119
120 /* Be verbose. */
121 int opt_verbose;
122
123 /* Format to support. */
124 enum opt_format opt_format = opt_format_new;
125
126 /* Build cache. */
127 static int opt_build_cache = 1;
128
129 /* Enable symbolic link processing. If set, create or update symbolic
130 links, and remove stale symbolic links. */
131 static int opt_link = 1;
132
133 /* Only process directories specified on the command line. */
134 static int opt_only_cline;
135
136 /* Path to root for chroot. */
137 static char *opt_chroot;
138
139 /* Manually link given shared libraries. */
140 static int opt_manual_link;
141
142 /* Should we ignore an old auxiliary cache file? */
143 static int opt_ignore_aux_cache;
144
145 /* Cache file to use. */
146 static char *cache_file;
147
148 /* Configuration file. */
149 static const char *config_file;
150
151 /* Mask to use for important hardware capabilities. */
152 static unsigned long int hwcap_mask = HWCAP_IMPORTANT;
153
154 /* Name and version of program. */
155 static void print_version (FILE *stream, struct argp_state *state);
156 void (*argp_program_version_hook) (FILE *, struct argp_state *)
157 = print_version;
158
159 /* Function to print some extra text in the help message. */
160 static char *more_help (int key, const char *text, void *input);
161
162 /* Definitions of arguments for argp functions. */
163 static const struct argp_option options[] =
164 {
165 { "print-cache", 'p', NULL, 0, N_("Print cache"), 0},
166 { "verbose", 'v', NULL, 0, N_("Generate verbose messages"), 0},
167 { NULL, 'N', NULL, 0, N_("Don't build cache"), 0},
168 { NULL, 'X', NULL, 0, N_("Don't update symbolic links"), 0},
169 { NULL, 'r', N_("ROOT"), 0, N_("Change to and use ROOT as root directory"), 0},
170 { NULL, 'C', N_("CACHE"), 0, N_("Use CACHE as cache file"), 0},
171 { NULL, 'f', N_("CONF"), 0, N_("Use CONF as configuration file"), 0},
172 { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0},
173 { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
174 { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new (default), old, or compat"), 0},
175 { "ignore-aux-cache", 'i', NULL, 0, N_("Ignore auxiliary cache file"), 0},
176 { NULL, 0, NULL, 0, NULL, 0 }
177 };
178
179 #define PROCINFO_CLASS static
180 #include <dl-procinfo.c>
181
182 /* Short description of program. */
183 static const char doc[] = N_("Configure Dynamic Linker Run Time Bindings.");
184
185 /* Prototype for option handler. */
186 static error_t parse_opt (int key, char *arg, struct argp_state *state);
187
188 /* Data structure to communicate with argp functions. */
189 static struct argp argp =
190 {
191 options, parse_opt, NULL, doc, NULL, more_help, NULL
192 };
193
194 /* Check if string corresponds to an important hardware capability or
195 a platform. */
196 static int
197 is_hwcap_platform (const char *name)
198 {
199 int hwcap_idx = _dl_string_hwcap (name);
200
201 /* Is this a normal hwcap for the machine like "fpu?" */
202 if (hwcap_idx != -1 && ((1 << hwcap_idx) & hwcap_mask))
203 return 1;
204
205 /* Is this a platform pseudo-hwcap like "i686?" */
206 hwcap_idx = _dl_string_platform (name);
207 if (hwcap_idx != -1)
208 return 1;
209
210 /* Backwards-compatibility for the "tls" subdirectory. */
211 if (strcmp (name, TLS_SUBPATH) == 0)
212 return 1;
213
214 return 0;
215 }
216
217 /* Get hwcap (including platform) encoding of path. */
218 static uint64_t
219 path_hwcap (const char *path)
220 {
221 char *str = xstrdup (path);
222 char *ptr;
223 uint64_t hwcap = 0;
224 uint64_t h;
225
226 size_t len;
227
228 len = strlen (str);
229 if (str[len] == '/')
230 str[len] = '\0';
231
232 /* Search pathname from the end and check for hwcap strings. */
233 for (;;)
234 {
235 ptr = strrchr (str, '/');
236
237 if (ptr == NULL)
238 break;
239
240 h = _dl_string_hwcap (ptr + 1);
241
242 if (h == (uint64_t) -1)
243 {
244 h = _dl_string_platform (ptr + 1);
245 if (h == (uint64_t) -1)
246 {
247 if (strcmp (ptr + 1, TLS_SUBPATH) == 0)
248 h = TLS_HWCAP_BIT;
249 else
250 break;
251 }
252 }
253 hwcap += 1ULL << h;
254
255 /* Search the next part of the path. */
256 *ptr = '\0';
257 }
258
259 free (str);
260 return hwcap;
261 }
262
263 /* Handle program arguments. */
264 static error_t
265 parse_opt (int key, char *arg, struct argp_state *state)
266 {
267 switch (key)
268 {
269 case 'C':
270 cache_file = arg;
271 /* Ignore auxiliary cache since we use non-standard cache. */
272 opt_ignore_aux_cache = 1;
273 break;
274 case 'f':
275 config_file = arg;
276 break;
277 case 'i':
278 opt_ignore_aux_cache = 1;
279 break;
280 case 'l':
281 opt_manual_link = 1;
282 break;
283 case 'N':
284 opt_build_cache = 0;
285 break;
286 case 'n':
287 opt_build_cache = 0;
288 opt_only_cline = 1;
289 break;
290 case 'p':
291 opt_print_cache = 1;
292 break;
293 case 'r':
294 opt_chroot = arg;
295 break;
296 case 'v':
297 opt_verbose = 1;
298 break;
299 case 'X':
300 opt_link = 0;
301 break;
302 case 'c':
303 if (strcmp (arg, "old") == 0)
304 opt_format = opt_format_old;
305 else if (strcmp (arg, "compat") == 0)
306 opt_format = opt_format_compat;
307 else if (strcmp (arg, "new") == 0)
308 opt_format = opt_format_new;
309 break;
310 default:
311 return ARGP_ERR_UNKNOWN;
312 }
313
314 return 0;
315 }
316
317 /* Print bug-reporting information in the help message. */
318 static char *
319 more_help (int key, const char *text, void *input)
320 {
321 char *tp = NULL;
322 switch (key)
323 {
324 case ARGP_KEY_HELP_EXTRA:
325 /* We print some extra information. */
326 if (asprintf (&tp, gettext ("\
327 For bug reporting instructions, please see:\n\
328 %s.\n"), REPORT_BUGS_TO) < 0)
329 return NULL;
330 return tp;
331 default:
332 break;
333 }
334 return (char *) text;
335 }
336
337 /* Print the version information. */
338 static void
339 print_version (FILE *stream, struct argp_state *state)
340 {
341 fprintf (stream, "ldconfig %s%s\n", PKGVERSION, VERSION);
342 fprintf (stream, gettext ("\
343 Copyright (C) %s Free Software Foundation, Inc.\n\
344 This is free software; see the source for copying conditions. There is NO\n\
345 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
346 "), "2022");
347 fprintf (stream, gettext ("Written by %s.\n"),
348 "Andreas Jaeger");
349 }
350
351 /* Allocate a new subdirectory with full path PATH under ENTRY, using
352 inode data from *ST. */
353 static struct dir_entry *
354 new_sub_entry (const struct dir_entry *entry, const char *path,
355 const struct stat *st)
356 {
357 struct dir_entry *new_entry = xmalloc (sizeof (struct dir_entry));
358 new_entry->from_file = entry->from_file;
359 new_entry->from_line = entry->from_line;
360 new_entry->path = xstrdup (path);
361 new_entry->flag = entry->flag;
362 new_entry->hwcaps = NULL;
363 new_entry->next = NULL;
364 new_entry->ino = st->st_ino;
365 new_entry->dev = st->st_dev;
366 return new_entry;
367 }
368
369 /* Add a single directory entry. Return true if the directory is
370 actually added (because it is not a duplicate). */
371 static bool
372 add_single_dir (struct dir_entry *entry, int verbose)
373 {
374 struct dir_entry *ptr, *prev;
375 bool added = true;
376
377 ptr = dir_entries;
378 prev = ptr;
379 while (ptr != NULL)
380 {
381 /* Check for duplicates. */
382 if (ptr->ino == entry->ino && ptr->dev == entry->dev)
383 {
384 if (opt_verbose && verbose)
385 {
386 error (0, 0, _("Path `%s' given more than once"), entry->path);
387 fprintf (stderr, _("(from %s:%d and %s:%d)\n"),
388 entry->from_file, entry->from_line,
389 ptr->from_file, ptr->from_line);
390 }
391 /* Use the newer information. */
392 ptr->flag = entry->flag;
393 free (entry->path);
394 free (entry);
395 added = false;
396 break;
397 }
398 prev = ptr;
399 ptr = ptr->next;
400 }
401 /* Is this the first entry? */
402 if (ptr == NULL && dir_entries == NULL)
403 dir_entries = entry;
404 else if (ptr == NULL)
405 prev->next = entry;
406 return added;
407 }
408
409 /* Check if PATH contains a "glibc-hwcaps" subdirectory. If so, queue
410 its subdirectories for glibc-hwcaps processing. */
411 static void
412 add_glibc_hwcaps_subdirectories (struct dir_entry *entry, const char *path)
413 {
414 /* glibc-hwcaps subdirectories do not nest. */
415 assert (entry->hwcaps == NULL);
416
417 char *glibc_hwcaps;
418 if (asprintf (&glibc_hwcaps, "%s/" GLIBC_HWCAPS_SUBDIRECTORY, path) < 0)
419 error (EXIT_FAILURE, errno, _("Could not form glibc-hwcaps path"));
420
421 DIR *dir = opendir (glibc_hwcaps);
422 if (dir != NULL)
423 {
424 while (true)
425 {
426 errno = 0;
427 struct dirent64 *e = readdir64 (dir);
428 if (e == NULL)
429 {
430 if (errno == 0)
431 break;
432 else
433 error (EXIT_FAILURE, errno, _("Listing directory %s"), path);
434 }
435
436 /* Ignore hidden subdirectories, including "." and "..", and
437 regular files. File names containing a ':' cannot be
438 looked up by the dynamic loader, so skip those as
439 well. */
440 if (e->d_name[0] == '.' || e->d_type == DT_REG
441 || strchr (e->d_name, ':') != NULL)
442 continue;
443
444 /* See if this entry eventually resolves to a directory. */
445 struct stat st;
446 if (fstatat (dirfd (dir), e->d_name, &st, 0) < 0)
447 /* Ignore unreadable entries. */
448 continue;
449
450 if (S_ISDIR (st.st_mode))
451 {
452 /* This is a directory, so it needs to be scanned for
453 libraries, associated with the hwcaps implied by the
454 subdirectory name. */
455 char *new_path;
456 if (asprintf (&new_path, "%s/" GLIBC_HWCAPS_SUBDIRECTORY "/%s",
457 /* Use non-canonicalized path here. */
458 entry->path, e->d_name) < 0)
459 error (EXIT_FAILURE, errno,
460 _("Could not form glibc-hwcaps path"));
461 struct dir_entry *new_entry = new_sub_entry (entry, new_path,
462 &st);
463 free (new_path);
464 new_entry->hwcaps = new_glibc_hwcaps_subdirectory (e->d_name);
465 add_single_dir (new_entry, 0);
466 }
467 }
468
469 closedir (dir);
470 }
471
472 free (glibc_hwcaps);
473 }
474
475 /* Add one directory to the list of directories to process. */
476 static void
477 add_dir_1 (const char *line, const char *from_file, int from_line)
478 {
479 unsigned int i;
480 struct dir_entry *entry = xmalloc (sizeof (struct dir_entry));
481 entry->hwcaps = NULL;
482 entry->next = NULL;
483
484 entry->from_file = strdup (from_file);
485 entry->from_line = from_line;
486
487 /* Search for an '=' sign. */
488 entry->path = xstrdup (line);
489 char *equal_sign = strchr (entry->path, '=');
490 if (equal_sign)
491 {
492 *equal_sign = '\0';
493 ++equal_sign;
494 entry->flag = FLAG_ANY;
495 for (i = 0; i < sizeof (lib_types) / sizeof (lib_types[0]); ++i)
496 if (strcmp (equal_sign, lib_types[i].name) == 0)
497 {
498 entry->flag = lib_types[i].flag;
499 break;
500 }
501 if (entry->flag == FLAG_ANY)
502 error (0, 0, _("%s is not a known library type"), equal_sign);
503 }
504 else
505 {
506 entry->flag = FLAG_ANY;
507 }
508
509 /* Canonify path: for now only remove leading and trailing
510 whitespace and the trailing slashes. */
511 i = strlen (entry->path);
512
513 while (i > 0 && isspace (entry->path[i - 1]))
514 entry->path[--i] = '\0';
515
516 while (i > 0 && entry->path[i - 1] == '/')
517 entry->path[--i] = '\0';
518
519 if (i == 0)
520 {
521 free (entry->path);
522 free (entry);
523 return;
524 }
525
526 char *path = entry->path;
527 if (opt_chroot != NULL)
528 path = chroot_canon (opt_chroot, path);
529
530 struct stat stat_buf;
531 if (path == NULL || stat (path, &stat_buf))
532 {
533 if (opt_verbose)
534 error (0, errno, _("Can't stat %s"), entry->path);
535 free (entry->path);
536 free (entry);
537 }
538 else
539 {
540 entry->ino = stat_buf.st_ino;
541 entry->dev = stat_buf.st_dev;
542
543 if (add_single_dir (entry, 1))
544 /* Add glibc-hwcaps subdirectories if present. */
545 add_glibc_hwcaps_subdirectories (entry, path);
546 }
547
548 if (opt_chroot != NULL)
549 free (path);
550 }
551
552 static void
553 add_dir (const char *line)
554 {
555 add_dir_1 (line, "<builtin>", 0);
556 }
557
558 static int
559 chroot_stat (const char *real_path, const char *path, struct stat *st)
560 {
561 int ret;
562 char *canon_path;
563
564 if (!opt_chroot)
565 return stat (real_path, st);
566
567 ret = lstat (real_path, st);
568 if (ret || !S_ISLNK (st->st_mode))
569 return ret;
570
571 canon_path = chroot_canon (opt_chroot, path);
572 if (canon_path == NULL)
573 return -1;
574
575 ret = stat (canon_path, st);
576 free (canon_path);
577 return ret;
578 }
579
580 static const char * const ld_sonames[] =
581 {
582 "ld-kfreebsd-x86-64.so.1",
583 "ld-linux-aarch64.so.1",
584 "ld-linux-aarch64_be.so.1",
585 "ld-linux-armhf.so.3",
586 "ld-linux-ia64.so.2",
587 "ld-linux-mipsn8.so.1",
588 "ld-linux-riscv64-lp64.so.1"
589 "ld-linux-riscv64-lp64d.so.1"
590 "ld-linux-x32.so.2",
591 "ld-linux-x86-64.so.2",
592 "ld-linux.so.2",
593 "ld-linux.so.3",
594 "ld.so.1",
595 "ld64.so.1",
596 "ld64.so.2",
597 };
598
599 /* Create a symbolic link from soname to libname in directory path. */
600 static void
601 create_links (const char *real_path, const char *path, const char *libname,
602 const char *soname)
603 {
604 char *full_libname, *full_soname;
605 char *real_full_libname, *real_full_soname;
606 struct stat stat_lib, stat_so, lstat_so;
607 int do_link = 1;
608 int do_remove = 1;
609 int i;
610 /* XXX: The logics in this function should be simplified. */
611
612 /* Get complete path. */
613 full_libname = alloca (strlen (path) + strlen (libname) + 2);
614 full_soname = alloca (strlen (path) + strlen (soname) + 2);
615 sprintf (full_libname, "%s/%s", path, libname);
616 sprintf (full_soname, "%s/%s", path, soname);
617 if (opt_chroot != NULL)
618 {
619 real_full_libname = alloca (strlen (real_path) + strlen (libname) + 2);
620 real_full_soname = alloca (strlen (real_path) + strlen (soname) + 2);
621 sprintf (real_full_libname, "%s/%s", real_path, libname);
622 sprintf (real_full_soname, "%s/%s", real_path, soname);
623 }
624 else
625 {
626 real_full_libname = full_libname;
627 real_full_soname = full_soname;
628 }
629
630 /* Does soname already exist and point to the right library? */
631 if (chroot_stat (real_full_soname, full_soname, &stat_so) == 0)
632 {
633 if (chroot_stat (real_full_libname, full_libname, &stat_lib))
634 {
635 error (0, 0, _("Can't stat %s\n"), full_libname);
636 return;
637 }
638
639 /* Do not change the symlink pointer to the dynamic linker except for
640 non-existing symlinks, as it might break multiarch systems. */
641 for (i = 0; i < sizeof (ld_sonames) / sizeof (ld_sonames[0]); i++)
642 if (__glibc_unlikely(!strcmp(soname, ld_sonames[i])))
643 {
644 if (opt_verbose)
645 error (0, 0, _("%s is the dynamic linker, ignoring\n"),
646 full_libname);
647 do_link = 0;
648 }
649
650 if (stat_lib.st_dev == stat_so.st_dev
651 && stat_lib.st_ino == stat_so.st_ino)
652 /* Link is already correct. */
653 do_link = 0;
654 else if (lstat (full_soname, &lstat_so) == 0
655 && !S_ISLNK (lstat_so.st_mode))
656 {
657 error (0, 0, _("%s is not a symbolic link\n"), full_soname);
658 do_link = 0;
659 do_remove = 0;
660 }
661 }
662 else if (lstat (real_full_soname, &lstat_so) != 0
663 || !S_ISLNK (lstat_so.st_mode))
664 /* Unless it is a stale symlink, there is no need to remove. */
665 do_remove = 0;
666
667 if (opt_verbose)
668 printf ("\t%s -> %s", soname, libname);
669
670 if (do_link && opt_link)
671 {
672 /* Remove old link. */
673 if (do_remove)
674 if (unlink (real_full_soname))
675 {
676 error (0, 0, _("Can't unlink %s"), full_soname);
677 do_link = 0;
678 }
679 /* Create symbolic link. */
680 if (do_link && symlink (libname, real_full_soname))
681 {
682 error (0, 0, _("Can't link %s to %s"), full_soname, libname);
683 do_link = 0;
684 }
685 if (opt_verbose)
686 {
687 if (do_link)
688 fputs (_(" (changed)\n"), stdout);
689 else
690 fputs (_(" (SKIPPED)\n"), stdout);
691 }
692 }
693 else if (opt_verbose)
694 fputs ("\n", stdout);
695 }
696
697 /* Manually link the given library. */
698 static void
699 manual_link (char *library)
700 {
701 char *path;
702 char *real_path;
703 char *real_library;
704 char *libname;
705 char *soname;
706 struct stat stat_buf;
707 int flag;
708 unsigned int isa_level;
709
710 /* Prepare arguments for create_links call. Split library name in
711 directory and filename first. Since path is allocated, we've got
712 to be careful to free at the end. */
713 path = xstrdup (library);
714 libname = strrchr (path, '/');
715
716 if (libname)
717 {
718 /* Successfully split names. Check if path is just "/" to avoid
719 an empty path. */
720 if (libname == path)
721 {
722 libname = library + 1;
723 path = xrealloc (path, 2);
724 strcpy (path, "/");
725 }
726 else
727 {
728 *libname = '\0';
729 ++libname;
730 }
731 }
732 else
733 {
734 /* There's no path, construct one. */
735 libname = library;
736 path = xrealloc (path, 2);
737 strcpy (path, ".");
738 }
739
740 if (opt_chroot != NULL)
741 {
742 real_path = chroot_canon (opt_chroot, path);
743 if (real_path == NULL)
744 {
745 error (0, errno, _("Can't find %s"), path);
746 free (path);
747 return;
748 }
749 real_library = alloca (strlen (real_path) + strlen (libname) + 2);
750 sprintf (real_library, "%s/%s", real_path, libname);
751 }
752 else
753 {
754 real_path = path;
755 real_library = library;
756 }
757
758 /* Do some sanity checks first. */
759 if (lstat (real_library, &stat_buf))
760 {
761 error (0, errno, _("Cannot lstat %s"), library);
762 goto out;
763 }
764 /* We don't want links here! */
765 else if (!S_ISREG (stat_buf.st_mode))
766 {
767 error (0, 0, _("Ignored file %s since it is not a regular file."),
768 library);
769 goto out;
770 }
771
772 if (process_file (real_library, library, libname, &flag, &isa_level, &soname,
773 0, &stat_buf))
774 {
775 error (0, 0, _("No link created since soname could not be found for %s"),
776 library);
777 goto out;
778 }
779 if (soname == NULL)
780 soname = implicit_soname (libname, flag);
781 create_links (real_path, path, libname, soname);
782 free (soname);
783 out:
784 if (path != real_path)
785 free (real_path);
786 free (path);
787 }
788
789
790 /* Read a whole directory and search for libraries.
791 The purpose is two-fold:
792 - search for libraries which will be added to the cache
793 - create symbolic links to the soname for each library
794
795 This has to be done separatly for each directory.
796
797 To keep track of which libraries to add to the cache and which
798 links to create, we save a list of all libraries.
799
800 The algorithm is basically:
801 for all libraries in the directory do
802 get soname of library
803 if soname is already in list
804 if new library is newer, replace entry
805 otherwise ignore this library
806 otherwise add library to list
807
808 For example, if the two libraries libxy.so.1.1 and libxy.so.1.2
809 exist and both have the same soname, e.g. libxy.so, a symbolic link
810 is created from libxy.so.1.2 (the newer one) to libxy.so.
811 libxy.so.1.2 and libxy.so are added to the cache - but not
812 libxy.so.1.1. */
813
814 /* Information for one library. */
815 struct dlib_entry
816 {
817 char *name;
818 char *soname;
819 int flag;
820 int is_link;
821 unsigned int isa_level;
822 struct dlib_entry *next;
823 };
824
825
826 static void
827 search_dir (const struct dir_entry *entry)
828 {
829 uint64_t hwcap;
830 if (entry->hwcaps == NULL)
831 {
832 hwcap = path_hwcap (entry->path);
833 if (opt_verbose)
834 {
835 if (hwcap != 0)
836 printf ("%s: (hwcap: %#.16" PRIx64 ")", entry->path, hwcap);
837 else
838 printf ("%s:", entry->path);
839 }
840 }
841 else
842 {
843 hwcap = 0;
844 if (opt_verbose)
845 printf ("%s: (hwcap: \"%s\")", entry->path,
846 glibc_hwcaps_subdirectory_name (entry->hwcaps));
847 }
848 if (opt_verbose)
849 printf (_(" (from %s:%d)\n"), entry->from_file, entry->from_line);
850
851 char *dir_name;
852 char *real_file_name;
853 size_t real_file_name_len;
854 size_t file_name_len = PATH_MAX;
855 char *file_name = alloca (file_name_len);
856 if (opt_chroot != NULL)
857 {
858 dir_name = chroot_canon (opt_chroot, entry->path);
859 real_file_name_len = PATH_MAX;
860 real_file_name = alloca (real_file_name_len);
861 }
862 else
863 {
864 dir_name = entry->path;
865 real_file_name_len = 0;
866 real_file_name = file_name;
867 }
868
869 DIR *dir;
870 if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
871 {
872 if (opt_verbose)
873 error (0, errno, _("Can't open directory %s"), entry->path);
874 if (opt_chroot != NULL && dir_name != NULL)
875 free (dir_name);
876 return;
877 }
878
879 struct dirent64 *direntry;
880 struct dlib_entry *dlibs = NULL;
881 while ((direntry = readdir64 (dir)) != NULL)
882 {
883 int flag;
884 /* We only look at links and regular files. */
885 if (direntry->d_type != DT_UNKNOWN
886 && direntry->d_type != DT_LNK
887 && direntry->d_type != DT_REG
888 && direntry->d_type != DT_DIR)
889 continue;
890 /* Does this file look like a shared library or is it a hwcap
891 subdirectory (if not already processing a glibc-hwcaps
892 subdirectory)? The dynamic linker is also considered as
893 shared library. */
894 if (!_dl_is_dso (direntry->d_name)
895 && (direntry->d_type == DT_REG
896 || (entry->hwcaps == NULL
897 && !is_hwcap_platform (direntry->d_name))))
898 continue;
899
900 size_t len = strlen (direntry->d_name);
901 /* Skip temporary files created by the prelink program. Files with
902 names like these are never really DSOs we want to look at. */
903 if (len >= sizeof (".#prelink#") - 1)
904 {
905 if (strcmp (direntry->d_name + len - sizeof (".#prelink#") + 1,
906 ".#prelink#") == 0)
907 continue;
908 if (len >= sizeof (".#prelink#.XXXXXX") - 1
909 && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX")
910 + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
911 continue;
912 }
913 len += strlen (entry->path) + 2;
914 if (len > file_name_len)
915 {
916 file_name_len = len;
917 file_name = alloca (file_name_len);
918 if (!opt_chroot)
919 real_file_name = file_name;
920 }
921 sprintf (file_name, "%s/%s", entry->path, direntry->d_name);
922 if (opt_chroot != NULL)
923 {
924 len = strlen (dir_name) + strlen (direntry->d_name) + 2;
925 if (len > real_file_name_len)
926 {
927 real_file_name_len = len;
928 real_file_name = alloca (real_file_name_len);
929 }
930 sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
931 }
932
933 struct stat lstat_buf;
934 /* We optimize and try to do the lstat call only if needed. */
935 if (direntry->d_type != DT_UNKNOWN)
936 lstat_buf.st_mode = DTTOIF (direntry->d_type);
937 else
938 if (__glibc_unlikely (lstat (real_file_name, &lstat_buf)))
939 {
940 error (0, errno, _("Cannot lstat %s"), file_name);
941 continue;
942 }
943
944 struct stat stat_buf;
945 bool is_dir;
946 int is_link = S_ISLNK (lstat_buf.st_mode);
947 if (is_link)
948 {
949 /* In case of symlink, we check if the symlink refers to
950 a directory. */
951 char *target_name = real_file_name;
952 if (opt_chroot != NULL)
953 {
954 target_name = chroot_canon (opt_chroot, file_name);
955 if (target_name == NULL)
956 {
957 if (strstr (file_name, ".so") == NULL)
958 error (0, 0, _("Input file %s not found.\n"), file_name);
959 continue;
960 }
961 }
962 if (__glibc_unlikely (stat (target_name, &stat_buf)))
963 {
964 if (opt_verbose)
965 error (0, errno, _("Cannot stat %s"), file_name);
966
967 /* Remove stale symlinks. */
968 if (opt_link && strstr (direntry->d_name, ".so."))
969 unlink (real_file_name);
970
971 if (opt_chroot != NULL)
972 free (target_name);
973
974 continue;
975 }
976
977 if (opt_chroot != NULL)
978 free (target_name);
979
980 is_dir = S_ISDIR (stat_buf.st_mode);
981
982 /* lstat_buf is later stored, update contents. */
983 lstat_buf.st_dev = stat_buf.st_dev;
984 lstat_buf.st_ino = stat_buf.st_ino;
985 lstat_buf.st_size = stat_buf.st_size;
986 lstat_buf.st_ctime = stat_buf.st_ctime;
987 }
988 else
989 is_dir = S_ISDIR (lstat_buf.st_mode);
990
991 /* No descending into subdirectories if this directory is a
992 glibc-hwcaps subdirectory (which are not recursive). */
993 if (entry->hwcaps == NULL
994 && is_dir && is_hwcap_platform (direntry->d_name))
995 {
996 if (!is_link
997 && direntry->d_type != DT_UNKNOWN
998 && __builtin_expect (lstat (real_file_name, &lstat_buf), 0))
999 {
1000 error (0, errno, _("Cannot lstat %s"), file_name);
1001 continue;
1002 }
1003
1004 /* Handle subdirectory later. */
1005 struct dir_entry *new_entry = new_sub_entry (entry, file_name,
1006 &lstat_buf);
1007 add_single_dir (new_entry, 0);
1008 continue;
1009 }
1010 else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
1011 continue;
1012
1013 char *real_name;
1014 if (opt_chroot != NULL && is_link)
1015 {
1016 real_name = chroot_canon (opt_chroot, file_name);
1017 if (real_name == NULL)
1018 {
1019 if (strstr (file_name, ".so") == NULL)
1020 error (0, 0, _("Input file %s not found.\n"), file_name);
1021 continue;
1022 }
1023 }
1024 else
1025 real_name = real_file_name;
1026
1027 /* Call lstat if not done yet. */
1028 if (!is_link
1029 && direntry->d_type != DT_UNKNOWN
1030 && __builtin_expect (lstat (real_file_name, &lstat_buf), 0))
1031 {
1032 error (0, errno, _("Cannot lstat %s"), file_name);
1033 continue;
1034 }
1035
1036 /* First search whether the auxiliary cache contains this
1037 library already and it's not changed. */
1038 char *soname;
1039 unsigned int isa_level;
1040 if (!search_aux_cache (&lstat_buf, &flag, &isa_level, &soname))
1041 {
1042 if (process_file (real_name, file_name, direntry->d_name, &flag,
1043 &isa_level, &soname, is_link, &lstat_buf))
1044 {
1045 if (real_name != real_file_name)
1046 free (real_name);
1047 continue;
1048 }
1049 else if (opt_build_cache)
1050 add_to_aux_cache (&lstat_buf, flag, isa_level, soname);
1051 }
1052
1053 if (soname == NULL)
1054 soname = implicit_soname (direntry->d_name, flag);
1055
1056 /* A link may just point to itself. */
1057 if (is_link)
1058 {
1059 /* If the path the link points to isn't its soname or it is not
1060 the .so symlink for ld(1), we treat it as a normal file.
1061
1062 You should always do this:
1063
1064 libfoo.so -> SONAME -> Arbitrary package-chosen name.
1065
1066 e.g. libfoo.so -> libfoo.so.1 -> libfooimp.so.9.99.
1067 Given a SONAME of libfoo.so.1.
1068
1069 You should *never* do this:
1070
1071 libfoo.so -> libfooimp.so.9.99
1072
1073 If you do, and your SONAME is libfoo.so.1, then libfoo.so
1074 fails to point at the SONAME. In that case ldconfig may consider
1075 libfoo.so as another implementation of SONAME and will create
1076 symlinks against it causing problems when you try to upgrade
1077 or downgrade. The problems will arise because ldconfig will,
1078 depending on directory ordering, creat symlinks against libfoo.so
1079 e.g. libfoo.so.1.2 -> libfoo.so, but when libfoo.so is removed
1080 (typically by the removal of a development pacakge not required
1081 for the runtime) it will break the libfoo.so.1.2 symlink and the
1082 application will fail to start. */
1083 const char *real_base_name = basename (real_file_name);
1084
1085 if (strcmp (real_base_name, soname) != 0)
1086 {
1087 len = strlen (real_base_name);
1088 if (len < strlen (".so")
1089 || strcmp (real_base_name + len - strlen (".so"), ".so") != 0
1090 || strncmp (real_base_name, soname, len) != 0)
1091 is_link = 0;
1092 }
1093 }
1094
1095 if (real_name != real_file_name)
1096 free (real_name);
1097
1098 if (is_link)
1099 {
1100 free (soname);
1101 soname = xstrdup (direntry->d_name);
1102 }
1103
1104 if (flag == FLAG_ELF
1105 && (entry->flag == FLAG_ELF_LIBC5
1106 || entry->flag == FLAG_ELF_LIBC6))
1107 flag = entry->flag;
1108
1109 /* Some sanity checks to print warnings. */
1110 if (opt_verbose)
1111 {
1112 if (flag == FLAG_ELF_LIBC5 && entry->flag != FLAG_ELF_LIBC5
1113 && entry->flag != FLAG_ANY)
1114 error (0, 0, _("libc5 library %s in wrong directory"), file_name);
1115 if (flag == FLAG_ELF_LIBC6 && entry->flag != FLAG_ELF_LIBC6
1116 && entry->flag != FLAG_ANY)
1117 error (0, 0, _("libc6 library %s in wrong directory"), file_name);
1118 if (flag == FLAG_LIBC4 && entry->flag != FLAG_LIBC4
1119 && entry->flag != FLAG_ANY)
1120 error (0, 0, _("libc4 library %s in wrong directory"), file_name);
1121 }
1122
1123 /* Add library to list. */
1124 struct dlib_entry *dlib_ptr;
1125 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
1126 {
1127 /* Is soname already in list? */
1128 if (strcmp (dlib_ptr->soname, soname) == 0)
1129 {
1130 /* Prefer a file to a link, otherwise check which one
1131 is newer. */
1132 if ((!is_link && dlib_ptr->is_link)
1133 || (is_link == dlib_ptr->is_link
1134 && _dl_cache_libcmp (dlib_ptr->name, direntry->d_name) < 0))
1135 {
1136 /* It's newer - add it. */
1137 /* Flag should be the same - sanity check. */
1138 if (dlib_ptr->flag != flag)
1139 {
1140 if (dlib_ptr->flag == FLAG_ELF
1141 && (flag == FLAG_ELF_LIBC5 || flag == FLAG_ELF_LIBC6))
1142 dlib_ptr->flag = flag;
1143 else if ((dlib_ptr->flag == FLAG_ELF_LIBC5
1144 || dlib_ptr->flag == FLAG_ELF_LIBC6)
1145 && flag == FLAG_ELF)
1146 dlib_ptr->flag = flag;
1147 else
1148 error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
1149 dlib_ptr->name, direntry->d_name,
1150 entry->path);
1151 }
1152 free (dlib_ptr->name);
1153 dlib_ptr->name = xstrdup (direntry->d_name);
1154 dlib_ptr->is_link = is_link;
1155 dlib_ptr->isa_level = isa_level;
1156 }
1157 /* Don't add this library, abort loop. */
1158 /* Also free soname, since it's dynamically allocated. */
1159 free (soname);
1160 break;
1161 }
1162 }
1163 /* Add the library if it's not already in. */
1164 if (dlib_ptr == NULL)
1165 {
1166 dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
1167 dlib_ptr->name = xstrdup (direntry->d_name);
1168 dlib_ptr->soname = soname;
1169 dlib_ptr->flag = flag;
1170 dlib_ptr->is_link = is_link;
1171 dlib_ptr->isa_level = isa_level;
1172 /* Add at head of list. */
1173 dlib_ptr->next = dlibs;
1174 dlibs = dlib_ptr;
1175 }
1176 }
1177
1178 closedir (dir);
1179
1180 /* Now dlibs contains a list of all libs - add those to the cache
1181 and created all symbolic links. */
1182 struct dlib_entry *dlib_ptr;
1183 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
1184 {
1185 /* The cached file name is the soname for non-glibc-hwcaps
1186 subdirectories (relying on symbolic links; this helps with
1187 library updates that change the file name), and the actual
1188 file for glibc-hwcaps subdirectories. */
1189 const char *filename;
1190 if (entry->hwcaps == NULL)
1191 {
1192 /* Don't create links to links. */
1193 if (dlib_ptr->is_link == 0)
1194 create_links (dir_name, entry->path, dlib_ptr->name,
1195 dlib_ptr->soname);
1196 filename = dlib_ptr->soname;
1197 }
1198 else
1199 {
1200 /* Do not create links in glibc-hwcaps subdirectories, but
1201 still log the cache addition. */
1202 if (opt_verbose)
1203 printf ("\t%s -> %s\n", dlib_ptr->soname, dlib_ptr->name);
1204 filename = dlib_ptr->name;
1205 }
1206 if (opt_build_cache)
1207 add_to_cache (entry->path, filename, dlib_ptr->soname,
1208 dlib_ptr->flag, dlib_ptr->isa_level, hwcap,
1209 entry->hwcaps);
1210 }
1211
1212 /* Free all resources. */
1213 while (dlibs)
1214 {
1215 dlib_ptr = dlibs;
1216 free (dlib_ptr->soname);
1217 free (dlib_ptr->name);
1218 dlibs = dlibs->next;
1219 free (dlib_ptr);
1220 }
1221
1222 if (opt_chroot != NULL && dir_name != NULL)
1223 free (dir_name);
1224 }
1225
1226 /* Search through all libraries. */
1227 static void
1228 search_dirs (void)
1229 {
1230 struct dir_entry *entry;
1231
1232 for (entry = dir_entries; entry != NULL; entry = entry->next)
1233 search_dir (entry);
1234
1235 /* Free all allocated memory. */
1236 while (dir_entries)
1237 {
1238 entry = dir_entries;
1239 dir_entries = dir_entries->next;
1240 free (entry->path);
1241 free (entry);
1242 }
1243 }
1244
1245
1246 static void parse_conf_include (const char *config_file, unsigned int lineno,
1247 bool do_chroot, const char *pattern);
1248
1249 /* Parse configuration file. */
1250 static void
1251 parse_conf (const char *filename, bool do_chroot)
1252 {
1253 FILE *file = NULL;
1254 char *line = NULL;
1255 const char *canon;
1256 size_t len = 0;
1257 unsigned int lineno;
1258
1259 if (do_chroot && opt_chroot)
1260 {
1261 canon = chroot_canon (opt_chroot, filename);
1262 if (canon)
1263 file = fopen (canon, "r");
1264 else
1265 canon = filename;
1266 }
1267 else
1268 {
1269 canon = filename;
1270 file = fopen (filename, "r");
1271 }
1272
1273 if (file == NULL)
1274 {
1275 if (errno != ENOENT)
1276 error (0, errno, _("\
1277 Warning: ignoring configuration file that cannot be opened: %s"),
1278 canon);
1279 if (canon != filename)
1280 free ((char *) canon);
1281 return;
1282 }
1283
1284 /* No threads use this stream. */
1285 __fsetlocking (file, FSETLOCKING_BYCALLER);
1286
1287 if (canon != filename)
1288 free ((char *) canon);
1289
1290 lineno = 0;
1291 do
1292 {
1293 ssize_t n = getline (&line, &len, file);
1294 if (n < 0)
1295 break;
1296
1297 ++lineno;
1298 if (line[n - 1] == '\n')
1299 line[n - 1] = '\0';
1300
1301 /* Because the file format does not know any form of quoting we
1302 can search forward for the next '#' character and if found
1303 make it terminating the line. */
1304 *strchrnul (line, '#') = '\0';
1305
1306 /* Remove leading whitespace. NUL is no whitespace character. */
1307 char *cp = line;
1308 while (isspace (*cp))
1309 ++cp;
1310
1311 /* If the line is blank it is ignored. */
1312 if (cp[0] == '\0')
1313 continue;
1314
1315 if (!strncmp (cp, "include", 7) && isblank (cp[7]))
1316 {
1317 char *dir;
1318 cp += 8;
1319 while ((dir = strsep (&cp, " \t")) != NULL)
1320 if (dir[0] != '\0')
1321 parse_conf_include (filename, lineno, do_chroot, dir);
1322 }
1323 else if (!strncasecmp (cp, "hwcap", 5) && isblank (cp[5]))
1324 error (0, 0, _("%s:%u: hwcap directive ignored"), filename, lineno);
1325 else
1326 add_dir_1 (cp, filename, lineno);
1327 }
1328 while (!feof_unlocked (file));
1329
1330 /* Free buffer and close file. */
1331 free (line);
1332 fclose (file);
1333 }
1334
1335 /* Handle one word in an `include' line, a glob pattern of additional
1336 config files to read. */
1337 static void
1338 parse_conf_include (const char *config_file, unsigned int lineno,
1339 bool do_chroot, const char *pattern)
1340 {
1341 if (opt_chroot != NULL && pattern[0] != '/')
1342 error (EXIT_FAILURE, 0,
1343 _("need absolute file name for configuration file when using -r"));
1344
1345 char *copy = NULL;
1346 if (pattern[0] != '/' && strchr (config_file, '/') != NULL)
1347 {
1348 if (asprintf (&copy, "%s/%s", dirname (strdupa (config_file)),
1349 pattern) < 0)
1350 error (EXIT_FAILURE, 0, _("memory exhausted"));
1351 pattern = copy;
1352 }
1353
1354 glob64_t gl;
1355 int result;
1356 if (do_chroot && opt_chroot)
1357 {
1358 char *canon = chroot_canon (opt_chroot, pattern);
1359 if (canon == NULL)
1360 return;
1361 result = glob64 (canon, 0, NULL, &gl);
1362 free (canon);
1363 }
1364 else
1365 result = glob64 (pattern, 0, NULL, &gl);
1366
1367 switch (result)
1368 {
1369 case 0:
1370 for (size_t i = 0; i < gl.gl_pathc; ++i)
1371 parse_conf (gl.gl_pathv[i], false);
1372 globfree64 (&gl);
1373 break;
1374
1375 case GLOB_NOMATCH:
1376 break;
1377
1378 case GLOB_NOSPACE:
1379 errno = ENOMEM;
1380 /* Fall through. */
1381 case GLOB_ABORTED:
1382 if (opt_verbose)
1383 error (0, errno, _("%s:%u: cannot read directory %s"),
1384 config_file, lineno, pattern);
1385 break;
1386
1387 default:
1388 abort ();
1389 break;
1390 }
1391
1392 free (copy);
1393 }
1394
1395 /* Honour LD_HWCAP_MASK. */
1396 static void
1397 set_hwcap (void)
1398 {
1399 char *mask = getenv ("LD_HWCAP_MASK");
1400
1401 if (mask)
1402 hwcap_mask = strtoul (mask, NULL, 0);
1403 }
1404
1405
1406 int
1407 main (int argc, char **argv)
1408 {
1409 /* Set locale via LC_ALL. */
1410 setlocale (LC_ALL, "");
1411
1412 /* But keep the C collation. That way `include' directives using
1413 globbing patterns are processed in a locale-independent order. */
1414 setlocale (LC_COLLATE, "C");
1415
1416 /* Set the text message domain. */
1417 textdomain (_libc_intl_domainname);
1418
1419 /* Parse and process arguments. */
1420 int remaining;
1421 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
1422
1423 /* Remaining arguments are additional directories if opt_manual_link
1424 is not set. */
1425 if (remaining != argc && !opt_manual_link)
1426 {
1427 int i;
1428 for (i = remaining; i < argc; ++i)
1429 if (opt_build_cache && argv[i][0] != '/')
1430 error (EXIT_FAILURE, 0,
1431 _("relative path `%s' used to build cache"),
1432 argv[i]);
1433 else
1434 add_dir_1 (argv[i], "<cmdline>", 0);
1435 }
1436
1437 set_hwcap ();
1438
1439 if (opt_chroot != NULL)
1440 {
1441 /* Normalize the path a bit, we might need it for printing later. */
1442 char *endp = rawmemchr (opt_chroot, '\0');
1443 while (endp > opt_chroot && endp[-1] == '/')
1444 --endp;
1445 *endp = '\0';
1446 if (endp == opt_chroot)
1447 opt_chroot = NULL;
1448
1449 if (opt_chroot != NULL)
1450 {
1451 /* It is faster to use chroot if we can. */
1452 if (!chroot (opt_chroot))
1453 {
1454 if (chdir ("/"))
1455 error (EXIT_FAILURE, errno, _("Can't chdir to /"));
1456 opt_chroot = NULL;
1457 }
1458 }
1459 }
1460
1461 if (cache_file == NULL)
1462 {
1463 cache_file = alloca (strlen (LD_SO_CACHE) + 1);
1464 strcpy (cache_file, LD_SO_CACHE);
1465 }
1466
1467 if (config_file == NULL)
1468 config_file = LD_SO_CONF;
1469
1470 if (opt_print_cache)
1471 {
1472 if (opt_chroot != NULL)
1473 {
1474 char *p = chroot_canon (opt_chroot, cache_file);
1475 if (p == NULL)
1476 error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
1477 cache_file);
1478 cache_file = p;
1479 }
1480 print_cache (cache_file);
1481 if (opt_chroot != NULL)
1482 free (cache_file);
1483 exit (0);
1484 }
1485
1486 if (opt_chroot != NULL)
1487 {
1488 /* Canonicalize the directory name of cache_file, not cache_file,
1489 because we'll rename a temporary cache file to it. */
1490 char *p = strrchr (cache_file, '/');
1491 char *canon = chroot_canon (opt_chroot,
1492 p ? (*p = '\0', cache_file) : "/");
1493
1494 if (canon == NULL)
1495 error (EXIT_FAILURE, errno,
1496 _("Can't open cache file directory %s\n"),
1497 p ? cache_file : "/");
1498
1499 if (p)
1500 ++p;
1501 else
1502 p = cache_file;
1503
1504 cache_file = alloca (strlen (canon) + strlen (p) + 2);
1505 sprintf (cache_file, "%s/%s", canon, p);
1506 free (canon);
1507 }
1508
1509 if (opt_manual_link)
1510 {
1511 /* Link all given libraries manually. */
1512 int i;
1513
1514 for (i = remaining; i < argc; ++i)
1515 manual_link (argv[i]);
1516
1517 exit (0);
1518 }
1519
1520
1521 if (opt_build_cache)
1522 init_cache ();
1523
1524 if (!opt_only_cline)
1525 {
1526 const char *strp = system_dirs;
1527 size_t idx = 0;
1528
1529 parse_conf (config_file, true);
1530
1531 /* Always add the standard search paths. */
1532 do
1533 {
1534 add_system_dir (strp);
1535 strp += system_dirs_len[idx] + 1;
1536 idx++;
1537 }
1538 while (idx < nsystem_dirs_len);
1539 }
1540
1541 const char *aux_cache_file = _PATH_LDCONFIG_AUX_CACHE;
1542 if (opt_chroot != NULL)
1543 aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
1544
1545 if (! opt_ignore_aux_cache && aux_cache_file)
1546 load_aux_cache (aux_cache_file);
1547 else
1548 init_aux_cache ();
1549
1550 search_dirs ();
1551
1552 if (opt_build_cache)
1553 {
1554 save_cache (cache_file);
1555 if (aux_cache_file)
1556 save_aux_cache (aux_cache_file);
1557 }
1558
1559 return 0;
1560 }