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