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 #define PROCINFO_CLASS static
30 #include <stdio_ext.h>
35 #include <sys/fcntl.h>
38 #include <sys/types.h>
44 #include <dl-hwcaps.h>
45 #include <dl-is_dso.h>
47 #include <dl-procinfo.h>
49 /* This subpath in search path entries is always supported and
50 included in the cache for backwards compatibility. */
51 #define TLS_SUBPATH "tls"
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
60 # define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
63 /* Get libc version number. */
66 #define PACKAGE _libc_intl_domainname
72 /* Get the generated information about the trusted/standard directories. */
73 #include "trusted-dirs.h"
75 static const char system_dirs
[] = SYSTEM_DIRS
;
76 static const size_t system_dirs_len
[] =
80 #define nsystem_dirs_len \
81 (sizeof (system_dirs_len) / sizeof (system_dirs_len[0]))
89 {"libc4", FLAG_LIBC4
},
90 {"libc5", FLAG_ELF_LIBC5
},
91 {"libc6", FLAG_ELF_LIBC6
},
92 {"glibc2", FLAG_ELF_LIBC6
}
96 /* List of directories to handle. */
103 const char *from_file
;
106 /* Non-NULL for subdirectories under a glibc-hwcaps subdirectory. */
107 struct glibc_hwcaps_subdirectory
*hwcaps
;
109 struct dir_entry
*next
;
112 /* The list is unsorted, contains no duplicates. Entries are added at
114 static struct dir_entry
*dir_entries
;
116 /* Flags for different options. */
118 static int opt_print_cache
;
123 /* Format to support. */
124 enum opt_format opt_format
= opt_format_new
;
127 static int opt_build_cache
= 1;
129 /* Enable symbolic link processing. If set, create or update symbolic
130 links, and remove stale symbolic links. */
131 static int opt_link
= 1;
133 /* Only process directories specified on the command line. */
134 static int opt_only_cline
;
136 /* Path to root for chroot. */
137 static char *opt_chroot
;
139 /* Manually link given shared libraries. */
140 static int opt_manual_link
;
142 /* Should we ignore an old auxiliary cache file? */
143 static int opt_ignore_aux_cache
;
145 /* Cache file to use. */
146 static char *cache_file
;
148 /* Configuration file. */
149 static const char *config_file
;
151 /* Mask to use for important hardware capabilities. */
152 static unsigned long int hwcap_mask
= HWCAP_IMPORTANT
;
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
*)
159 /* Function to print some extra text in the help message. */
160 static char *more_help (int key
, const char *text
, void *input
);
162 /* Definitions of arguments for argp functions. */
163 static const struct argp_option options
[] =
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 }
179 #define PROCINFO_CLASS static
180 #include <dl-procinfo.c>
182 /* Short description of program. */
183 static const char doc
[] = N_("Configure Dynamic Linker Run Time Bindings.");
185 /* Prototype for option handler. */
186 static error_t
parse_opt (int key
, char *arg
, struct argp_state
*state
);
188 /* Data structure to communicate with argp functions. */
189 static struct argp argp
=
191 options
, parse_opt
, NULL
, doc
, NULL
, more_help
, NULL
194 /* Check if string corresponds to an important hardware capability or
197 is_hwcap_platform (const char *name
)
199 int hwcap_idx
= _dl_string_hwcap (name
);
201 /* Is this a normal hwcap for the machine like "fpu?" */
202 if (hwcap_idx
!= -1 && ((1 << hwcap_idx
) & hwcap_mask
))
205 /* Is this a platform pseudo-hwcap like "i686?" */
206 hwcap_idx
= _dl_string_platform (name
);
210 /* Backwards-compatibility for the "tls" subdirectory. */
211 if (strcmp (name
, TLS_SUBPATH
) == 0)
217 /* Get hwcap (including platform) encoding of path. */
219 path_hwcap (const char *path
)
221 char *str
= xstrdup (path
);
232 /* Search pathname from the end and check for hwcap strings. */
235 ptr
= strrchr (str
, '/');
240 h
= _dl_string_hwcap (ptr
+ 1);
242 if (h
== (uint64_t) -1)
244 h
= _dl_string_platform (ptr
+ 1);
245 if (h
== (uint64_t) -1)
247 if (strcmp (ptr
+ 1, TLS_SUBPATH
) == 0)
255 /* Search the next part of the path. */
263 /* Handle program arguments. */
265 parse_opt (int key
, char *arg
, struct argp_state
*state
)
271 /* Ignore auxiliary cache since we use non-standard cache. */
272 opt_ignore_aux_cache
= 1;
278 opt_ignore_aux_cache
= 1;
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
;
311 return ARGP_ERR_UNKNOWN
;
317 /* Print bug-reporting information in the help message. */
319 more_help (int key
, const char *text
, void *input
)
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)
334 return (char *) text
;
337 /* Print the version information. */
339 print_version (FILE *stream
, struct argp_state
*state
)
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\
347 fprintf (stream
, gettext ("Written by %s.\n"),
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
)
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
;
369 /* Add a single directory entry. Return true if the directory is
370 actually added (because it is not a duplicate). */
372 add_single_dir (struct dir_entry
*entry
, int verbose
)
374 struct dir_entry
*ptr
, *prev
;
381 /* Check for duplicates. */
382 if (ptr
->ino
== entry
->ino
&& ptr
->dev
== entry
->dev
)
384 if (opt_verbose
&& verbose
)
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
);
391 /* Use the newer information. */
392 ptr
->flag
= entry
->flag
;
401 /* Is this the first entry? */
402 if (ptr
== NULL
&& dir_entries
== NULL
)
404 else if (ptr
== NULL
)
409 /* Check if PATH contains a "glibc-hwcaps" subdirectory. If so, queue
410 its subdirectories for glibc-hwcaps processing. */
412 add_glibc_hwcaps_subdirectories (struct dir_entry
*entry
, const char *path
)
414 /* glibc-hwcaps subdirectories do not nest. */
415 assert (entry
->hwcaps
== NULL
);
418 if (asprintf (&glibc_hwcaps
, "%s/" GLIBC_HWCAPS_SUBDIRECTORY
, path
) < 0)
419 error (EXIT_FAILURE
, errno
, _("Could not form glibc-hwcaps path"));
421 DIR *dir
= opendir (glibc_hwcaps
);
427 struct dirent64
*e
= readdir64 (dir
);
433 error (EXIT_FAILURE
, errno
, _("Listing directory %s"), path
);
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
440 if (e
->d_name
[0] == '.' || e
->d_type
== DT_REG
441 || strchr (e
->d_name
, ':') != NULL
)
444 /* See if this entry eventually resolves to a directory. */
446 if (fstatat (dirfd (dir
), e
->d_name
, &st
, 0) < 0)
447 /* Ignore unreadable entries. */
450 if (S_ISDIR (st
.st_mode
))
452 /* This is a directory, so it needs to be scanned for
453 libraries, associated with the hwcaps implied by the
454 subdirectory name. */
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
,
464 new_entry
->hwcaps
= new_glibc_hwcaps_subdirectory (e
->d_name
);
465 add_single_dir (new_entry
, 0);
475 /* Add one directory to the list of directories to process. */
477 add_dir_1 (const char *line
, const char *from_file
, int from_line
)
480 struct dir_entry
*entry
= xmalloc (sizeof (struct dir_entry
));
481 entry
->hwcaps
= NULL
;
484 entry
->from_file
= strdup (from_file
);
485 entry
->from_line
= from_line
;
487 /* Search for an '=' sign. */
488 entry
->path
= xstrdup (line
);
489 char *equal_sign
= strchr (entry
->path
, '=');
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)
498 entry
->flag
= lib_types
[i
].flag
;
501 if (entry
->flag
== FLAG_ANY
)
502 error (0, 0, _("%s is not a known library type"), equal_sign
);
506 entry
->flag
= FLAG_ANY
;
509 /* Canonify path: for now only remove leading and trailing
510 whitespace and the trailing slashes. */
511 i
= strlen (entry
->path
);
513 while (i
> 0 && isspace (entry
->path
[i
- 1]))
514 entry
->path
[--i
] = '\0';
516 while (i
> 0 && entry
->path
[i
- 1] == '/')
517 entry
->path
[--i
] = '\0';
526 char *path
= entry
->path
;
527 if (opt_chroot
!= NULL
)
528 path
= chroot_canon (opt_chroot
, path
);
530 struct stat stat_buf
;
531 if (path
== NULL
|| stat (path
, &stat_buf
))
534 error (0, errno
, _("Can't stat %s"), entry
->path
);
540 entry
->ino
= stat_buf
.st_ino
;
541 entry
->dev
= stat_buf
.st_dev
;
543 if (add_single_dir (entry
, 1))
544 /* Add glibc-hwcaps subdirectories if present. */
545 add_glibc_hwcaps_subdirectories (entry
, path
);
548 if (opt_chroot
!= NULL
)
553 add_dir (const char *line
)
555 add_dir_1 (line
, "<builtin>", 0);
559 chroot_stat (const char *real_path
, const char *path
, struct stat
*st
)
565 return stat (real_path
, st
);
567 ret
= lstat (real_path
, st
);
568 if (ret
|| !S_ISLNK (st
->st_mode
))
571 canon_path
= chroot_canon (opt_chroot
, path
);
572 if (canon_path
== NULL
)
575 ret
= stat (canon_path
, st
);
580 static const char * const ld_sonames
[] =
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"
591 "ld-linux-x86-64.so.2",
599 /* Create a symbolic link from soname to libname in directory path. */
601 create_links (const char *real_path
, const char *path
, const char *libname
,
604 char *full_libname
, *full_soname
;
605 char *real_full_libname
, *real_full_soname
;
606 struct stat stat_lib
, stat_so
, lstat_so
;
610 /* XXX: The logics in this function should be simplified. */
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
)
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
);
626 real_full_libname
= full_libname
;
627 real_full_soname
= full_soname
;
630 /* Does soname already exist and point to the right library? */
631 if (chroot_stat (real_full_soname
, full_soname
, &stat_so
) == 0)
633 if (chroot_stat (real_full_libname
, full_libname
, &stat_lib
))
635 error (0, 0, _("Can't stat %s\n"), full_libname
);
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
])))
645 error (0, 0, _("%s is the dynamic linker, ignoring\n"),
650 if (stat_lib
.st_dev
== stat_so
.st_dev
651 && stat_lib
.st_ino
== stat_so
.st_ino
)
652 /* Link is already correct. */
654 else if (lstat (full_soname
, &lstat_so
) == 0
655 && !S_ISLNK (lstat_so
.st_mode
))
657 error (0, 0, _("%s is not a symbolic link\n"), full_soname
);
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. */
668 printf ("\t%s -> %s", soname
, libname
);
670 if (do_link
&& opt_link
)
672 /* Remove old link. */
674 if (unlink (real_full_soname
))
676 error (0, 0, _("Can't unlink %s"), full_soname
);
679 /* Create symbolic link. */
680 if (do_link
&& symlink (libname
, real_full_soname
))
682 error (0, 0, _("Can't link %s to %s"), full_soname
, libname
);
688 fputs (_(" (changed)\n"), stdout
);
690 fputs (_(" (SKIPPED)\n"), stdout
);
693 else if (opt_verbose
)
694 fputs ("\n", stdout
);
697 /* Manually link the given library. */
699 manual_link (char *library
)
706 struct stat stat_buf
;
708 unsigned int isa_level
;
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
, '/');
718 /* Successfully split names. Check if path is just "/" to avoid
722 libname
= library
+ 1;
723 path
= xrealloc (path
, 2);
734 /* There's no path, construct one. */
736 path
= xrealloc (path
, 2);
740 if (opt_chroot
!= NULL
)
742 real_path
= chroot_canon (opt_chroot
, path
);
743 if (real_path
== NULL
)
745 error (0, errno
, _("Can't find %s"), path
);
749 real_library
= alloca (strlen (real_path
) + strlen (libname
) + 2);
750 sprintf (real_library
, "%s/%s", real_path
, libname
);
755 real_library
= library
;
758 /* Do some sanity checks first. */
759 if (lstat (real_library
, &stat_buf
))
761 error (0, errno
, _("Cannot lstat %s"), library
);
764 /* We don't want links here! */
765 else if (!S_ISREG (stat_buf
.st_mode
))
767 error (0, 0, _("Ignored file %s since it is not a regular file."),
772 if (process_file (real_library
, library
, libname
, &flag
, &isa_level
, &soname
,
775 error (0, 0, _("No link created since soname could not be found for %s"),
780 soname
= implicit_soname (libname
, flag
);
781 create_links (real_path
, path
, libname
, soname
);
784 if (path
!= real_path
)
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
795 This has to be done separatly for each directory.
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.
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
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
814 /* Information for one library. */
821 unsigned int isa_level
;
822 struct dlib_entry
*next
;
827 search_dir (const struct dir_entry
*entry
)
830 if (entry
->hwcaps
== NULL
)
832 hwcap
= path_hwcap (entry
->path
);
836 printf ("%s: (hwcap: %#.16" PRIx64
")", entry
->path
, hwcap
);
838 printf ("%s:", entry
->path
);
845 printf ("%s: (hwcap: \"%s\")", entry
->path
,
846 glibc_hwcaps_subdirectory_name (entry
->hwcaps
));
849 printf (_(" (from %s:%d)\n"), entry
->from_file
, entry
->from_line
);
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
)
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
);
864 dir_name
= entry
->path
;
865 real_file_name_len
= 0;
866 real_file_name
= file_name
;
870 if (dir_name
== NULL
|| (dir
= opendir (dir_name
)) == NULL
)
873 error (0, errno
, _("Can't open directory %s"), entry
->path
);
874 if (opt_chroot
!= NULL
&& dir_name
!= NULL
)
879 struct dirent64
*direntry
;
880 struct dlib_entry
*dlibs
= NULL
;
881 while ((direntry
= readdir64 (dir
)) != NULL
)
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
)
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
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
))))
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)
905 if (strcmp (direntry
->d_name
+ len
- sizeof (".#prelink#") + 1,
908 if (len
>= sizeof (".#prelink#.XXXXXX") - 1
909 && memcmp (direntry
->d_name
+ len
- sizeof (".#prelink#.XXXXXX")
910 + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
913 len
+= strlen (entry
->path
) + 2;
914 if (len
> file_name_len
)
917 file_name
= alloca (file_name_len
);
919 real_file_name
= file_name
;
921 sprintf (file_name
, "%s/%s", entry
->path
, direntry
->d_name
);
922 if (opt_chroot
!= NULL
)
924 len
= strlen (dir_name
) + strlen (direntry
->d_name
) + 2;
925 if (len
> real_file_name_len
)
927 real_file_name_len
= len
;
928 real_file_name
= alloca (real_file_name_len
);
930 sprintf (real_file_name
, "%s/%s", dir_name
, direntry
->d_name
);
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
);
938 if (__glibc_unlikely (lstat (real_file_name
, &lstat_buf
)))
940 error (0, errno
, _("Cannot lstat %s"), file_name
);
944 struct stat stat_buf
;
946 int is_link
= S_ISLNK (lstat_buf
.st_mode
);
949 /* In case of symlink, we check if the symlink refers to
951 char *target_name
= real_file_name
;
952 if (opt_chroot
!= NULL
)
954 target_name
= chroot_canon (opt_chroot
, file_name
);
955 if (target_name
== NULL
)
957 if (strstr (file_name
, ".so") == NULL
)
958 error (0, 0, _("Input file %s not found.\n"), file_name
);
962 if (__glibc_unlikely (stat (target_name
, &stat_buf
)))
965 error (0, errno
, _("Cannot stat %s"), file_name
);
967 /* Remove stale symlinks. */
968 if (opt_link
&& strstr (direntry
->d_name
, ".so."))
969 unlink (real_file_name
);
971 if (opt_chroot
!= NULL
)
977 if (opt_chroot
!= NULL
)
980 is_dir
= S_ISDIR (stat_buf
.st_mode
);
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
;
989 is_dir
= S_ISDIR (lstat_buf
.st_mode
);
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
))
997 && direntry
->d_type
!= DT_UNKNOWN
998 && __builtin_expect (lstat (real_file_name
, &lstat_buf
), 0))
1000 error (0, errno
, _("Cannot lstat %s"), file_name
);
1004 /* Handle subdirectory later. */
1005 struct dir_entry
*new_entry
= new_sub_entry (entry
, file_name
,
1007 add_single_dir (new_entry
, 0);
1010 else if (!S_ISREG (lstat_buf
.st_mode
) && !is_link
)
1014 if (opt_chroot
!= NULL
&& is_link
)
1016 real_name
= chroot_canon (opt_chroot
, file_name
);
1017 if (real_name
== NULL
)
1019 if (strstr (file_name
, ".so") == NULL
)
1020 error (0, 0, _("Input file %s not found.\n"), file_name
);
1025 real_name
= real_file_name
;
1027 /* Call lstat if not done yet. */
1029 && direntry
->d_type
!= DT_UNKNOWN
1030 && __builtin_expect (lstat (real_file_name
, &lstat_buf
), 0))
1032 error (0, errno
, _("Cannot lstat %s"), file_name
);
1036 /* First search whether the auxiliary cache contains this
1037 library already and it's not changed. */
1039 unsigned int isa_level
;
1040 if (!search_aux_cache (&lstat_buf
, &flag
, &isa_level
, &soname
))
1042 if (process_file (real_name
, file_name
, direntry
->d_name
, &flag
,
1043 &isa_level
, &soname
, is_link
, &lstat_buf
))
1045 if (real_name
!= real_file_name
)
1049 else if (opt_build_cache
)
1050 add_to_aux_cache (&lstat_buf
, flag
, isa_level
, soname
);
1054 soname
= implicit_soname (direntry
->d_name
, flag
);
1056 /* A link may just point to itself. */
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.
1062 You should always do this:
1064 libfoo.so -> SONAME -> Arbitrary package-chosen name.
1066 e.g. libfoo.so -> libfoo.so.1 -> libfooimp.so.9.99.
1067 Given a SONAME of libfoo.so.1.
1069 You should *never* do this:
1071 libfoo.so -> libfooimp.so.9.99
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
);
1085 if (strcmp (real_base_name
, soname
) != 0)
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)
1095 if (real_name
!= real_file_name
)
1101 soname
= xstrdup (direntry
->d_name
);
1104 if (flag
== FLAG_ELF
1105 && (entry
->flag
== FLAG_ELF_LIBC5
1106 || entry
->flag
== FLAG_ELF_LIBC6
))
1109 /* Some sanity checks to print warnings. */
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
);
1123 /* Add library to list. */
1124 struct dlib_entry
*dlib_ptr
;
1125 for (dlib_ptr
= dlibs
; dlib_ptr
!= NULL
; dlib_ptr
= dlib_ptr
->next
)
1127 /* Is soname already in list? */
1128 if (strcmp (dlib_ptr
->soname
, soname
) == 0)
1130 /* Prefer a file to a link, otherwise check which one
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))
1136 /* It's newer - add it. */
1137 /* Flag should be the same - sanity check. */
1138 if (dlib_ptr
->flag
!= flag
)
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
;
1148 error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
1149 dlib_ptr
->name
, direntry
->d_name
,
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
;
1157 /* Don't add this library, abort loop. */
1158 /* Also free soname, since it's dynamically allocated. */
1163 /* Add the library if it's not already in. */
1164 if (dlib_ptr
== NULL
)
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
;
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
)
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
)
1192 /* Don't create links to links. */
1193 if (dlib_ptr
->is_link
== 0)
1194 create_links (dir_name
, entry
->path
, dlib_ptr
->name
,
1196 filename
= dlib_ptr
->soname
;
1200 /* Do not create links in glibc-hwcaps subdirectories, but
1201 still log the cache addition. */
1203 printf ("\t%s -> %s\n", dlib_ptr
->soname
, dlib_ptr
->name
);
1204 filename
= dlib_ptr
->name
;
1206 if (opt_build_cache
)
1207 add_to_cache (entry
->path
, filename
, dlib_ptr
->soname
,
1208 dlib_ptr
->flag
, dlib_ptr
->isa_level
, hwcap
,
1212 /* Free all resources. */
1216 free (dlib_ptr
->soname
);
1217 free (dlib_ptr
->name
);
1218 dlibs
= dlibs
->next
;
1222 if (opt_chroot
!= NULL
&& dir_name
!= NULL
)
1226 /* Search through all libraries. */
1230 struct dir_entry
*entry
;
1232 for (entry
= dir_entries
; entry
!= NULL
; entry
= entry
->next
)
1235 /* Free all allocated memory. */
1238 entry
= dir_entries
;
1239 dir_entries
= dir_entries
->next
;
1246 static void parse_conf_include (const char *config_file
, unsigned int lineno
,
1247 bool do_chroot
, const char *pattern
);
1249 /* Parse configuration file. */
1251 parse_conf (const char *filename
, bool do_chroot
)
1257 unsigned int lineno
;
1259 if (do_chroot
&& opt_chroot
)
1261 canon
= chroot_canon (opt_chroot
, filename
);
1263 file
= fopen (canon
, "r");
1270 file
= fopen (filename
, "r");
1275 if (errno
!= ENOENT
)
1276 error (0, errno
, _("\
1277 Warning: ignoring configuration file that cannot be opened: %s"),
1279 if (canon
!= filename
)
1280 free ((char *) canon
);
1284 /* No threads use this stream. */
1285 __fsetlocking (file
, FSETLOCKING_BYCALLER
);
1287 if (canon
!= filename
)
1288 free ((char *) canon
);
1293 ssize_t n
= getline (&line
, &len
, file
);
1298 if (line
[n
- 1] == '\n')
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';
1306 /* Remove leading whitespace. NUL is no whitespace character. */
1308 while (isspace (*cp
))
1311 /* If the line is blank it is ignored. */
1315 if (!strncmp (cp
, "include", 7) && isblank (cp
[7]))
1319 while ((dir
= strsep (&cp
, " \t")) != NULL
)
1321 parse_conf_include (filename
, lineno
, do_chroot
, dir
);
1323 else if (!strncasecmp (cp
, "hwcap", 5) && isblank (cp
[5]))
1324 error (0, 0, _("%s:%u: hwcap directive ignored"), filename
, lineno
);
1326 add_dir_1 (cp
, filename
, lineno
);
1328 while (!feof_unlocked (file
));
1330 /* Free buffer and close file. */
1335 /* Handle one word in an `include' line, a glob pattern of additional
1336 config files to read. */
1338 parse_conf_include (const char *config_file
, unsigned int lineno
,
1339 bool do_chroot
, const char *pattern
)
1341 if (opt_chroot
!= NULL
&& pattern
[0] != '/')
1342 error (EXIT_FAILURE
, 0,
1343 _("need absolute file name for configuration file when using -r"));
1346 if (pattern
[0] != '/' && strchr (config_file
, '/') != NULL
)
1348 if (asprintf (©
, "%s/%s", dirname (strdupa (config_file
)),
1350 error (EXIT_FAILURE
, 0, _("memory exhausted"));
1356 if (do_chroot
&& opt_chroot
)
1358 char *canon
= chroot_canon (opt_chroot
, pattern
);
1361 result
= glob64 (canon
, 0, NULL
, &gl
);
1365 result
= glob64 (pattern
, 0, NULL
, &gl
);
1370 for (size_t i
= 0; i
< gl
.gl_pathc
; ++i
)
1371 parse_conf (gl
.gl_pathv
[i
], false);
1383 error (0, errno
, _("%s:%u: cannot read directory %s"),
1384 config_file
, lineno
, pattern
);
1395 /* Honour LD_HWCAP_MASK. */
1399 char *mask
= getenv ("LD_HWCAP_MASK");
1402 hwcap_mask
= strtoul (mask
, NULL
, 0);
1407 main (int argc
, char **argv
)
1409 /* Set locale via LC_ALL. */
1410 setlocale (LC_ALL
, "");
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");
1416 /* Set the text message domain. */
1417 textdomain (_libc_intl_domainname
);
1419 /* Parse and process arguments. */
1421 argp_parse (&argp
, argc
, argv
, 0, &remaining
, NULL
);
1423 /* Remaining arguments are additional directories if opt_manual_link
1425 if (remaining
!= argc
&& !opt_manual_link
)
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"),
1434 add_dir_1 (argv
[i
], "<cmdline>", 0);
1439 if (opt_chroot
!= NULL
)
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] == '/')
1446 if (endp
== opt_chroot
)
1449 if (opt_chroot
!= NULL
)
1451 /* It is faster to use chroot if we can. */
1452 if (!chroot (opt_chroot
))
1455 error (EXIT_FAILURE
, errno
, _("Can't chdir to /"));
1461 if (cache_file
== NULL
)
1463 cache_file
= alloca (strlen (LD_SO_CACHE
) + 1);
1464 strcpy (cache_file
, LD_SO_CACHE
);
1467 if (config_file
== NULL
)
1468 config_file
= LD_SO_CONF
;
1470 if (opt_print_cache
)
1472 if (opt_chroot
!= NULL
)
1474 char *p
= chroot_canon (opt_chroot
, cache_file
);
1476 error (EXIT_FAILURE
, errno
, _("Can't open cache file %s\n"),
1480 print_cache (cache_file
);
1481 if (opt_chroot
!= NULL
)
1486 if (opt_chroot
!= NULL
)
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
) : "/");
1495 error (EXIT_FAILURE
, errno
,
1496 _("Can't open cache file directory %s\n"),
1497 p
? cache_file
: "/");
1504 cache_file
= alloca (strlen (canon
) + strlen (p
) + 2);
1505 sprintf (cache_file
, "%s/%s", canon
, p
);
1509 if (opt_manual_link
)
1511 /* Link all given libraries manually. */
1514 for (i
= remaining
; i
< argc
; ++i
)
1515 manual_link (argv
[i
]);
1521 if (opt_build_cache
)
1524 if (!opt_only_cline
)
1526 const char *strp
= system_dirs
;
1529 parse_conf (config_file
, true);
1531 /* Always add the standard search paths. */
1534 add_system_dir (strp
);
1535 strp
+= system_dirs_len
[idx
] + 1;
1538 while (idx
< nsystem_dirs_len
);
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
);
1545 if (! opt_ignore_aux_cache
&& aux_cache_file
)
1546 load_aux_cache (aux_cache_file
);
1552 if (opt_build_cache
)
1554 save_cache (cache_file
);
1556 save_aux_cache (aux_cache_file
);