]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/ldconfig.c
[BZ #2510, BZ #2830, BZ #3137, BZ #3313, BZ #3426, BZ #3465, BZ #3480, BZ #3483,...
[thirdparty/glibc.git] / elf / ldconfig.c
CommitLineData
64a0aa0f 1/* Copyright (C) 1999-2004, 2005, 2006, 2007 Free Software Foundation, Inc.
591e1ffb
UD
2 This file is part of the GNU C Library.
3 Contributed by Andreas Jaeger <aj@suse.de>, 1999.
4
43bc8ac6
UD
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation.
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
UD
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
591e1ffb 17
ee600e3f 18#define PROCINFO_CLASS static
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>
34#include <sys/fcntl.h>
35#include <sys/mman.h>
36#include <sys/stat.h>
37#include <sys/types.h>
8e115d80
RM
38#include <glob.h>
39#include <libgen.h>
591e1ffb 40
8f480b4b
RM
41#include <ldconfig.h>
42#include <dl-cache.h>
591e1ffb 43
8f480b4b 44#include <dl-procinfo.h>
591e1ffb 45
ab1d521d
RM
46#ifdef _DL_FIRST_PLATFORM
47# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
48#else
49# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
50#endif
51
591e1ffb 52#ifndef LD_SO_CONF
8ca91b36 53# define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
591e1ffb
UD
54#endif
55
56/* Get libc version number. */
57#include <version.h>
58
59#define PACKAGE _libc_intl_domainname
60
591e1ffb
UD
61static const struct
62{
63 const char *name;
64 int flag;
a986484f 65} lib_types[] =
591e1ffb
UD
66{
67 {"libc4", FLAG_LIBC4},
68 {"libc5", FLAG_ELF_LIBC5},
69 {"libc6", FLAG_ELF_LIBC6},
70 {"glibc2", FLAG_ELF_LIBC6}
45eca4d1 71};
591e1ffb
UD
72
73
74/* List of directories to handle. */
75struct dir_entry
76{
77 char *path;
78 int flag;
4ceae915
AJ
79 ino64_t ino;
80 dev_t dev;
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
UD
95/* Format to support. */
96/* 0: only libc5/glibc2; 1: both; 2: only glibc 2.2. */
97int opt_format = 1;
98
591e1ffb
UD
99/* Build cache. */
100static int opt_build_cache = 1;
101
102/* Generate links. */
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
591e1ffb 114/* Cache file to use. */
b4a555d6 115static char *cache_file;
591e1ffb
UD
116
117/* Configuration file. */
118static const char *config_file;
119
0cfbb8c6
UD
120/* Mask to use for important hardware capabilities. */
121static unsigned long int hwcap_mask = HWCAP_IMPORTANT;
122
ab1d521d
RM
123/* Configuration-defined capabilities defined in kernel vDSOs. */
124static const char *hwcap_extra[64 - _DL_FIRST_EXTRA];
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
131/* Definitions of arguments for argp functions. */
132static const struct argp_option options[] =
133{
134 { "print-cache", 'p', NULL, 0, N_("Print cache"), 0},
135 { "verbose", 'v', NULL, 0, N_("Generate verbose messages"), 0},
136 { NULL, 'N', NULL, 0, N_("Don't build cache"), 0},
137 { NULL, 'X', NULL, 0, N_("Don't generate links"), 0},
7864c09b
UD
138 { NULL, 'r', N_("ROOT"), 0, N_("Change to and use ROOT as root directory"), 0},
139 { NULL, 'C', N_("CACHE"), 0, N_("Use CACHE as cache file"), 0},
140 { NULL, 'f', N_("CONF"), 0, N_("Use CONF as configuration file"), 0},
591e1ffb 141 { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0},
b85697f6 142 { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
7864c09b 143 { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new, old or compat (default)"), 0},
591e1ffb
UD
144 { NULL, 0, NULL, 0, NULL, 0 }
145};
146
11bf8ce1
UD
147#define PROCINFO_CLASS static
148#include <dl-procinfo.c>
149
591e1ffb
UD
150/* Short description of program. */
151static const char doc[] = N_("Configure Dynamic Linker Run Time Bindings.");
152
153/* Prototype for option handler. */
154static error_t parse_opt (int key, char *arg, struct argp_state *state);
155
156/* Data structure to communicate with argp functions. */
157static struct argp argp =
158{
159 options, parse_opt, NULL, doc, NULL, NULL, NULL
160};
161
a6c1c03a
AJ
162/* Check if string corresponds to an important hardware capability or
163 a platform. */
45eca4d1 164static int
a6c1c03a 165is_hwcap_platform (const char *name)
45eca4d1
UD
166{
167 int hwcap_idx = _dl_string_hwcap (name);
8ca91b36 168
0cfbb8c6 169 if (hwcap_idx != -1 && ((1 << hwcap_idx) & hwcap_mask))
45eca4d1 170 return 1;
a6c1c03a
AJ
171
172 hwcap_idx = _dl_string_platform (name);
173 if (hwcap_idx != -1)
174 return 1;
175
ab1d521d
RM
176 for (hwcap_idx = _DL_FIRST_EXTRA; hwcap_idx < 64; ++hwcap_idx)
177 if (hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA] != NULL
178 && !strcmp (name, hwcap_extra[hwcap_idx - _DL_FIRST_EXTRA]))
179 return 1;
676fde70 180
45eca4d1
UD
181 return 0;
182}
183
a6c1c03a
AJ
184/* Get hwcap (including platform) encoding of path. */
185static uint64_t
45eca4d1
UD
186path_hwcap (const char *path)
187{
188 char *str = xstrdup (path);
189 char *ptr;
a6c1c03a
AJ
190 uint64_t hwcap = 0;
191 uint64_t h;
45eca4d1
UD
192
193 size_t len;
194
195 len = strlen (str);
196 if (str[len] == '/')
197 str[len] = '\0';
198
199 /* Search pathname from the end and check for hwcap strings. */
200 for (;;)
201 {
202 ptr = strrchr (str, '/');
203
204 if (ptr == NULL)
205 break;
206
a6c1c03a 207 h = _dl_string_hwcap (ptr + 1);
45eca4d1 208
59553897
UD
209 if (h == (uint64_t) -1)
210 {
211 h = _dl_string_platform (ptr + 1);
212 if (h == (uint64_t) -1)
676fde70 213 {
ab1d521d
RM
214 for (h = _DL_FIRST_EXTRA; h < 64; ++h)
215 if (hwcap_extra[h - _DL_FIRST_EXTRA] != NULL
216 && !strcmp (ptr + 1, hwcap_extra[h - _DL_FIRST_EXTRA]))
217 break;
218 if (h == 64)
676fde70
UD
219 break;
220 }
59553897 221 }
a6c1c03a 222 hwcap += 1ULL << h;
591e1ffb 223
45eca4d1
UD
224 /* Search the next part of the path. */
225 *ptr = '\0';
226 }
227
228 free (str);
229 return hwcap;
230}
591e1ffb
UD
231
232/* Handle program arguments. */
233static error_t
234parse_opt (int key, char *arg, struct argp_state *state)
235{
236 switch (key)
237 {
238 case 'C':
239 cache_file = arg;
240 break;
241 case 'f':
242 config_file = arg;
243 break;
b85697f6
UD
244 case 'l':
245 opt_manual_link = 1;
246 break;
591e1ffb
UD
247 case 'N':
248 opt_build_cache = 0;
249 break;
250 case 'n':
251 opt_build_cache = 0;
252 opt_only_cline = 1;
253 break;
254 case 'p':
255 opt_print_cache = 1;
256 break;
257 case 'r':
258 opt_chroot = arg;
259 break;
260 case 'v':
261 opt_verbose = 1;
262 break;
263 case 'X':
264 opt_link = 0;
265 break;
45eca4d1
UD
266 case 'c':
267 if (strcmp (arg, "old") == 0)
268 opt_format = 0;
269 else if (strcmp (arg, "compat") == 0)
270 opt_format = 1;
271 else if (strcmp (arg, "new") == 0)
272 opt_format = 2;
273 break;
591e1ffb
UD
274 default:
275 return ARGP_ERR_UNKNOWN;
276 }
277
278 return 0;
279}
280
281/* Print the version information. */
282static void
283print_version (FILE *stream, struct argp_state *state)
284{
285 fprintf (stream, "ldconfig (GNU %s) %s\n", PACKAGE, VERSION);
286 fprintf (stream, gettext ("\
287Copyright (C) %s Free Software Foundation, Inc.\n\
288This is free software; see the source for copying conditions. There is NO\n\
289warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
11bf311e 290"), "2007");
591e1ffb
UD
291 fprintf (stream, gettext ("Written by %s.\n"),
292 "Andreas Jaeger");
293}
294
a8fd59b0
AJ
295/* Add a single directory entry. */
296static void
297add_single_dir (struct dir_entry *entry, int verbose)
298{
299 struct dir_entry *ptr, *prev;
300
301 ptr = dir_entries;
302 prev = ptr;
303 while (ptr != NULL)
304 {
305 /* Check for duplicates. */
4ceae915 306 if (ptr->ino == entry->ino && ptr->dev == entry->dev)
a8fd59b0
AJ
307 {
308 if (opt_verbose && verbose)
309 error (0, 0, _("Path `%s' given more than once"), entry->path);
310 /* Use the newer information. */
311 ptr->flag = entry->flag;
4ceae915 312 free (entry->path);
a8fd59b0
AJ
313 free (entry);
314 break;
315 }
316 prev = ptr;
317 ptr = ptr->next;
318 }
319 /* Is this the first entry? */
320 if (ptr == NULL && dir_entries == NULL)
321 dir_entries = entry;
322 else if (ptr == NULL)
323 prev->next = entry;
324}
325
591e1ffb
UD
326/* Add one directory to the list of directories to process. */
327static void
328add_dir (const char *line)
329{
591e1ffb 330 unsigned int i;
539842a4 331 struct dir_entry *entry = xmalloc (sizeof (struct dir_entry));
591e1ffb 332 entry->next = NULL;
45eca4d1 333
591e1ffb
UD
334 /* Search for an '=' sign. */
335 entry->path = xstrdup (line);
539842a4 336 char *equal_sign = strchr (entry->path, '=');
591e1ffb
UD
337 if (equal_sign)
338 {
339 *equal_sign = '\0';
340 ++equal_sign;
341 entry->flag = FLAG_ANY;
a986484f 342 for (i = 0; i < sizeof (lib_types) / sizeof (lib_types[0]); ++i)
591e1ffb
UD
343 if (strcmp (equal_sign, lib_types[i].name) == 0)
344 {
345 entry->flag = lib_types[i].flag;
346 break;
347 }
348 if (entry->flag == FLAG_ANY)
349 error (0, 0, _("%s is not a known library type"), equal_sign);
350 }
351 else
352 {
353 entry->flag = FLAG_ANY;
354 }
355
69acbe9f
UD
356 /* Canonify path: for now only remove leading and trailing
357 whitespace and the trailing slashes slashes. */
591e1ffb 358 i = strlen (entry->path) - 1;
69acbe9f
UD
359
360 while (isspace (entry->path[i]) && i > 0)
361 entry->path[i--] = '\0';
362
591e1ffb 363 while (entry->path[i] == '/' && i > 0)
69acbe9f 364 entry->path[i--] = '\0';
45eca4d1 365
539842a4
UD
366 char *path = entry->path;
367 if (opt_chroot)
368 path = chroot_canon (opt_chroot, path);
369
370 struct stat64 stat_buf;
371 if (path == NULL || stat64 (path, &stat_buf))
4ceae915 372 {
8645ad47
AJ
373 if (opt_verbose)
374 error (0, errno, _("Can't stat %s"), entry->path);
4ceae915
AJ
375 free (entry->path);
376 free (entry);
4ceae915 377 }
539842a4
UD
378 else
379 {
380 entry->ino = stat_buf.st_ino;
381 entry->dev = stat_buf.st_dev;
4ceae915 382
539842a4
UD
383 add_single_dir (entry, 1);
384 }
4ceae915 385
539842a4
UD
386 if (opt_chroot)
387 free (path);
591e1ffb
UD
388}
389
390
b4a555d6
UD
391static int
392chroot_stat (const char *real_path, const char *path, struct stat64 *st)
393{
394 int ret;
395 char *canon_path;
396
397 if (!opt_chroot)
398 return stat64 (real_path, st);
399
400 ret = lstat64 (real_path, st);
401 if (ret || !S_ISLNK (st->st_mode))
402 return ret;
403
404 canon_path = chroot_canon (opt_chroot, path);
405 if (canon_path == NULL)
406 return -1;
407
408 ret = stat64 (canon_path, st);
409 free (canon_path);
410 return ret;
411}
412
591e1ffb
UD
413/* Create a symbolic link from soname to libname in directory path. */
414static void
b4a555d6
UD
415create_links (const char *real_path, const char *path, const char *libname,
416 const char *soname)
591e1ffb 417{
7b0d235c 418 char *full_libname, *full_soname;
b4a555d6
UD
419 char *real_full_libname, *real_full_soname;
420 struct stat64 stat_lib, stat_so, lstat_so;
591e1ffb
UD
421 int do_link = 1;
422 int do_remove = 1;
423 /* XXX: The logics in this function should be simplified. */
45eca4d1 424
591e1ffb 425 /* Get complete path. */
7b0d235c 426 full_libname = alloca (strlen (path) + strlen (libname) + 2);
7c545dbe 427 full_soname = alloca (strlen (path) + strlen (soname) + 2);
7b0d235c
AJ
428 sprintf (full_libname, "%s/%s", path, libname);
429 sprintf (full_soname, "%s/%s", path, soname);
b4a555d6
UD
430 if (opt_chroot)
431 {
432 real_full_libname = alloca (strlen (real_path) + strlen (libname) + 2);
7c545dbe 433 real_full_soname = alloca (strlen (real_path) + strlen (soname) + 2);
b4a555d6
UD
434 sprintf (real_full_libname, "%s/%s", real_path, libname);
435 sprintf (real_full_soname, "%s/%s", real_path, soname);
436 }
437 else
438 {
439 real_full_libname = full_libname;
440 real_full_soname = full_soname;
441 }
591e1ffb
UD
442
443 /* Does soname already exist and point to the right library? */
b4a555d6 444 if (chroot_stat (real_full_soname, full_soname, &stat_so) == 0)
591e1ffb 445 {
b4a555d6 446 if (chroot_stat (real_full_libname, full_libname, &stat_lib))
591e1ffb
UD
447 {
448 error (0, 0, _("Can't stat %s\n"), full_libname);
449 return;
450 }
451 if (stat_lib.st_dev == stat_so.st_dev
452 && stat_lib.st_ino == stat_so.st_ino)
453 /* Link is already correct. */
454 do_link = 0;
b4a555d6 455 else if (lstat64 (full_soname, &lstat_so) == 0
591e1ffb
UD
456 && !S_ISLNK (lstat_so.st_mode))
457 {
458 error (0, 0, _("%s is not a symbolic link\n"), full_soname);
459 do_link = 0;
460 do_remove = 0;
461 }
462 }
b4a555d6 463 else if (lstat64 (real_full_soname, &lstat_so) != 0
591e1ffb
UD
464 || !S_ISLNK (lstat_so.st_mode))
465 /* Unless it is a stale symlink, there is no need to remove. */
466 do_remove = 0;
467
468 if (opt_verbose)
469 printf ("\t%s -> %s", soname, libname);
470
471 if (do_link && opt_link)
472 {
473 /* Remove old link. */
474 if (do_remove)
b4a555d6 475 if (unlink (real_full_soname))
591e1ffb
UD
476 {
477 error (0, 0, _("Can't unlink %s"), full_soname);
478 do_link = 0;
479 }
480 /* Create symbolic link. */
b4a555d6 481 if (do_link && symlink (libname, real_full_soname))
591e1ffb
UD
482 {
483 error (0, 0, _("Can't link %s to %s"), full_soname, libname);
484 do_link = 0;
485 }
486 if (opt_verbose)
487 {
488 if (do_link)
489 fputs (_(" (changed)\n"), stdout);
490 else
491 fputs (_(" (SKIPPED)\n"), stdout);
492 }
493 }
494 else if (opt_verbose)
495 fputs ("\n", stdout);
496}
497
b85697f6
UD
498/* Manually link the given library. */
499static void
500manual_link (char *library)
501{
502 char *path;
b4a555d6
UD
503 char *real_path;
504 char *real_library;
b85697f6
UD
505 char *libname;
506 char *soname;
b4a555d6 507 struct stat64 stat_buf;
b85697f6 508 int flag;
a986484f 509 unsigned int osversion;
b85697f6
UD
510
511 /* Prepare arguments for create_links call. Split library name in
512 directory and filename first. Since path is allocated, we've got
513 to be careful to free at the end. */
514 path = xstrdup (library);
515 libname = strrchr (path, '/');
516
517 if (libname)
518 {
519 /* Successfully split names. Check if path is just "/" to avoid
520 an empty path. */
521 if (libname == path)
522 {
523 libname = library + 1;
524 path = xrealloc (path, 2);
525 strcpy (path, "/");
526 }
527 else
528 {
529 *libname = '\0';
530 ++libname;
531 }
532 }
533 else
534 {
535 /* There's no path, construct one. */
536 libname = library;
537 path = xrealloc (path, 2);
538 strcpy (path, ".");
539 }
540
b4a555d6
UD
541 if (opt_chroot)
542 {
543 real_path = chroot_canon (opt_chroot, path);
544 if (real_path == NULL)
545 {
546 error (0, errno, _("Can't find %s"), path);
547 free (path);
548 return;
549 }
550 real_library = alloca (strlen (real_path) + strlen (libname) + 2);
551 sprintf (real_library, "%s/%s", real_path, libname);
552 }
553 else
554 {
555 real_path = path;
556 real_library = library;
557 }
558
b85697f6 559 /* Do some sanity checks first. */
b4a555d6 560 if (lstat64 (real_library, &stat_buf))
b85697f6 561 {
11bf311e 562 error (0, errno, _("Cannot lstat %s"), library);
b85697f6
UD
563 free (path);
564 return;
565 }
566 /* We don't want links here! */
567 else if (!S_ISREG (stat_buf.st_mode))
568 {
569 error (0, 0, _("Ignored file %s since it is not a regular file."),
570 library);
571 free (path);
572 return;
573 }
a986484f
UD
574 if (process_file (real_library, library, libname, &flag, &osversion,
575 &soname, 0))
b85697f6
UD
576 {
577 error (0, 0, _("No link created since soname could not be found for %s"),
578 library);
579 free (path);
580 return;
581 }
b4a555d6 582 create_links (real_path, path, libname, soname);
b85697f6
UD
583 free (soname);
584 free (path);
585}
586
587
591e1ffb
UD
588/* Read a whole directory and search for libraries.
589 The purpose is two-fold:
590 - search for libraries which will be added to the cache
591 - create symbolic links to the soname for each library
592
593 This has to be done separatly for each directory.
45eca4d1 594
591e1ffb
UD
595 To keep track of which libraries to add to the cache and which
596 links to create, we save a list of all libraries.
597
598 The algorithm is basically:
599 for all libraries in the directory do
600 get soname of library
601 if soname is already in list
602 if new library is newer, replace entry
603 otherwise ignore this library
604 otherwise add library to list
45eca4d1 605
591e1ffb
UD
606 For example, if the two libraries libxy.so.1.1 and libxy.so.1.2
607 exist and both have the same soname, e.g. libxy.so, a symbolic link
608 is created from libxy.so.1.2 (the newer one) to libxy.so.
609 libxy.so.1.2 and libxy.so are added to the cache - but not
610 libxy.so.1.1. */
611
612/* Information for one library. */
45eca4d1 613struct dlib_entry
591e1ffb
UD
614{
615 char *name;
616 char *soname;
617 int flag;
618 int is_link;
a986484f 619 unsigned int osversion;
591e1ffb
UD
620 struct dlib_entry *next;
621};
622
623
624static void
625search_dir (const struct dir_entry *entry)
626{
627 DIR *dir;
2b510e91 628 struct dirent64 *direntry;
b4a555d6
UD
629 char *file_name, *dir_name, *real_file_name, *real_name;
630 int file_name_len, real_file_name_len, len;
591e1ffb
UD
631 char *soname;
632 struct dlib_entry *dlibs;
633 struct dlib_entry *dlib_ptr;
4ceae915
AJ
634 struct stat64 lstat_buf, stat_buf;
635 int is_link, is_dir;
a6c1c03a 636 uint64_t hwcap = path_hwcap (entry->path);
a986484f 637 unsigned int osversion;
45eca4d1 638
7b0d235c
AJ
639 file_name_len = PATH_MAX;
640 file_name = alloca (file_name_len);
f0189a54 641
591e1ffb
UD
642 dlibs = NULL;
643
644 if (opt_verbose)
45eca4d1
UD
645 {
646 if (hwcap != 0)
ab1d521d 647 printf ("%s: (hwcap: %#.16" PRIx64 ")\n", entry->path, hwcap);
45eca4d1
UD
648 else
649 printf ("%s:\n", entry->path);
650 }
651
b4a555d6
UD
652 if (opt_chroot)
653 {
654 dir_name = chroot_canon (opt_chroot, entry->path);
655 real_file_name_len = PATH_MAX;
656 real_file_name = alloca (real_file_name_len);
657 }
658 else
659 {
660 dir_name = entry->path;
661 real_file_name_len = 0;
662 real_file_name = file_name;
663 }
664
665 if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
591e1ffb
UD
666 {
667 if (opt_verbose)
668 error (0, errno, _("Can't open directory %s"), entry->path);
b4a555d6
UD
669 if (opt_chroot && dir_name)
670 free (dir_name);
591e1ffb
UD
671 return;
672 }
45eca4d1 673
2b510e91 674 while ((direntry = readdir64 (dir)) != NULL)
591e1ffb
UD
675 {
676 int flag;
677#ifdef _DIRENT_HAVE_D_TYPE
678 /* We only look at links and regular files. */
679 if (direntry->d_type != DT_UNKNOWN
680 && direntry->d_type != DT_LNK
45eca4d1
UD
681 && direntry->d_type != DT_REG
682 && direntry->d_type != DT_DIR)
591e1ffb
UD
683 continue;
684#endif /* _DIRENT_HAVE_D_TYPE */
45eca4d1
UD
685 /* Does this file look like a shared library or is it a hwcap
686 subdirectory? The dynamic linker is also considered as
687 shared library. */
688 if (((strncmp (direntry->d_name, "lib", 3) != 0
689 && strncmp (direntry->d_name, "ld-", 3) != 0)
690 || strstr (direntry->d_name, ".so") == NULL)
95ce33a5
UD
691 && (
692#ifdef _DIRENT_HAVE_D_TYPE
693 direntry->d_type == DT_REG ||
694#endif
695 !is_hwcap_platform (direntry->d_name)))
591e1ffb 696 continue;
3858bf28
RM
697 len = strlen (direntry->d_name);
698 /* Skip temporary files created by the prelink program. Files with
699 names like these are never really DSOs we want to look at. */
700 if (len >= sizeof (".#prelink#") - 1)
701 {
702 if (strcmp (direntry->d_name + len - sizeof (".#prelink#") + 1,
703 ".#prelink#") == 0)
704 continue;
705 if (len >= sizeof (".#prelink#.XXXXXX") - 1
706 && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX")
707 + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
708 continue;
709 }
11bf311e 710 len += strlen (entry->path);
7b0d235c 711 if (len > file_name_len)
591e1ffb 712 {
11bf311e 713 file_name_len = len + 1;
7b0d235c 714 file_name = alloca (file_name_len);
b4a555d6
UD
715 if (!opt_chroot)
716 real_file_name = file_name;
717 }
718 sprintf (file_name, "%s/%s", entry->path, direntry->d_name);
719 if (opt_chroot)
720 {
11bf311e 721 len = strlen (dir_name) + strlen (direntry->d_name);
b4a555d6
UD
722 if (len > real_file_name_len)
723 {
11bf311e 724 real_file_name_len = len + 1;
b4a555d6
UD
725 real_file_name = alloca (real_file_name_len);
726 }
727 sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
591e1ffb 728 }
7c3002f0
UD
729#ifdef _DIRENT_HAVE_D_TYPE
730 if (direntry->d_type != DT_UNKNOWN)
4ceae915 731 lstat_buf.st_mode = DTTOIF (direntry->d_type);
7c3002f0
UD
732 else
733#endif
95ce33a5 734 if (__builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
7c3002f0 735 {
95ce33a5 736 error (0, errno, _("Cannot lstat %s"), file_name);
7c3002f0
UD
737 continue;
738 }
739
4ceae915
AJ
740 is_link = S_ISLNK (lstat_buf.st_mode);
741 if (is_link)
742 {
743 /* In case of symlink, we check if the symlink refers to
744 a directory. */
95ce33a5 745 if (__builtin_expect (stat64 (real_file_name, &stat_buf), 0))
4ceae915 746 {
8645ad47 747 if (opt_verbose)
95ce33a5 748 error (0, errno, _("Cannot stat %s"), file_name);
647eb037
UD
749
750 /* Remove stale symlinks. */
751 if (strstr (direntry->d_name, ".so."))
752 unlink (real_file_name);
4ceae915
AJ
753 continue;
754 }
755 is_dir = S_ISDIR (stat_buf.st_mode);
756 }
757 else
758 is_dir = S_ISDIR (lstat_buf.st_mode);
759
760 if (is_dir && is_hwcap_platform (direntry->d_name))
45eca4d1 761 {
a8fd59b0
AJ
762 /* Handle subdirectory later. */
763 struct dir_entry *new_entry;
764
765 new_entry = xmalloc (sizeof (struct dir_entry));
7b0d235c 766 new_entry->path = xstrdup (file_name);
a8fd59b0
AJ
767 new_entry->flag = entry->flag;
768 new_entry->next = NULL;
4ceae915
AJ
769 if (is_link)
770 {
771 new_entry->ino = stat_buf.st_ino;
772 new_entry->dev = stat_buf.st_dev;
773 }
774 else
775 {
95ce33a5
UD
776#ifdef _DIRENT_HAVE_D_TYPE
777 /* We have filled in lstat only #ifndef
778 _DIRENT_HAVE_D_TYPE. Fill it in if needed. */
779 if (direntry->d_type != DT_UNKNOWN
780 && __builtin_expect (lstat64 (real_file_name, &lstat_buf),
781 0))
782 {
783 error (0, errno, _("Cannot lstat %s"), file_name);
784 free (new_entry->path);
785 free (new_entry);
786 continue;
787 }
788#endif
789
4ceae915
AJ
790 new_entry->ino = lstat_buf.st_ino;
791 new_entry->dev = lstat_buf.st_dev;
792 }
a8fd59b0 793 add_single_dir (new_entry, 0);
45eca4d1
UD
794 continue;
795 }
0f843f89 796 else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
591e1ffb
UD
797 continue;
798
b4a555d6
UD
799 if (opt_chroot && is_link)
800 {
801 real_name = chroot_canon (opt_chroot, file_name);
802 if (real_name == NULL)
803 {
804 if (strstr (file_name, ".so") == NULL)
805 error (0, 0, _("Input file %s not found.\n"), file_name);
806 continue;
807 }
808 }
809 else
810 real_name = real_file_name;
591e1ffb 811
b4a555d6 812 if (process_file (real_name, file_name, direntry->d_name, &flag,
a986484f 813 &osversion, &soname, is_link))
b4a555d6
UD
814 {
815 if (real_name != real_file_name)
816 free (real_name);
817 continue;
818 }
819
82d8607d
UD
820
821 /* A link may just point to itself. */
591e1ffb
UD
822 if (is_link)
823 {
82d8607d
UD
824 /* If the path the link points to isn't its soname and it is not
825 .so symlink for ld(1) only, we treat it as a normal file. */
2fe98a4a 826 const char *real_base_name = basename (real_file_name);
82d8607d
UD
827
828 if (strcmp (real_base_name, soname) != 0)
829 {
830 len = strlen (real_base_name);
831 if (len < strlen (".so")
832 || strcmp (real_base_name + len - strlen (".so"), ".so") != 0
833 || strncmp (real_base_name, soname, len) != 0)
834 is_link = 0;
835 }
836 }
45eca4d1 837
395412a0
UD
838 if (real_name != real_file_name)
839 free (real_name);
840
82d8607d
UD
841 if (is_link)
842 {
843 free (soname);
844 soname = xstrdup (direntry->d_name);
845 }
846
591e1ffb
UD
847 if (flag == FLAG_ELF
848 && (entry->flag == FLAG_ELF_LIBC5
849 || entry->flag == FLAG_ELF_LIBC6))
850 flag = entry->flag;
851 /* Some sanity checks to print warnings. */
852 if (opt_verbose)
853 {
854 if (flag == FLAG_ELF_LIBC5 && entry->flag != FLAG_ELF_LIBC5
855 && entry->flag != FLAG_ANY)
7b0d235c 856 error (0, 0, _("libc5 library %s in wrong directory"), file_name);
591e1ffb
UD
857 if (flag == FLAG_ELF_LIBC6 && entry->flag != FLAG_ELF_LIBC6
858 && entry->flag != FLAG_ANY)
7b0d235c 859 error (0, 0, _("libc6 library %s in wrong directory"), file_name);
591e1ffb
UD
860 if (flag == FLAG_LIBC4 && entry->flag != FLAG_LIBC4
861 && entry->flag != FLAG_ANY)
7b0d235c 862 error (0, 0, _("libc4 library %s in wrong directory"), file_name);
591e1ffb 863 }
45eca4d1 864
591e1ffb
UD
865 /* Add library to list. */
866 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
867 {
868 /* Is soname already in list? */
869 if (strcmp (dlib_ptr->soname, soname) == 0)
870 {
871 /* Prefer a file to a link, otherwise check which one
872 is newer. */
873 if ((!is_link && dlib_ptr->is_link)
874 || (is_link == dlib_ptr->is_link
45eca4d1 875 && _dl_cache_libcmp (dlib_ptr->name, direntry->d_name) < 0))
591e1ffb
UD
876 {
877 /* It's newer - add it. */
878 /* Flag should be the same - sanity check. */
879 if (dlib_ptr->flag != flag)
880 {
881 if (dlib_ptr->flag == FLAG_ELF
882 && (flag == FLAG_ELF_LIBC5 || flag == FLAG_ELF_LIBC6))
883 dlib_ptr->flag = flag;
884 else if ((dlib_ptr->flag == FLAG_ELF_LIBC5
885 || dlib_ptr->flag == FLAG_ELF_LIBC6)
886 && flag == FLAG_ELF)
887 dlib_ptr->flag = flag;
888 else
889 error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
890 dlib_ptr->name, direntry->d_name, entry->path);
891 }
892 free (dlib_ptr->name);
b15ff9d6 893 dlib_ptr->osversion = osversion;
591e1ffb
UD
894 dlib_ptr->name = xstrdup (direntry->d_name);
895 dlib_ptr->is_link = is_link;
896 }
897 /* Don't add this library, abort loop. */
898 /* Also free soname, since it's dynamically allocated. */
899 free (soname);
900 break;
901 }
902 }
903 /* Add the library if it's not already in. */
904 if (dlib_ptr == NULL)
905 {
906 dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
907 dlib_ptr->name = xstrdup (direntry->d_name);
908 dlib_ptr->flag = flag;
a986484f 909 dlib_ptr->osversion = osversion;
591e1ffb
UD
910 dlib_ptr->soname = soname;
911 dlib_ptr->is_link = is_link;
912 /* Add at head of list. */
913 dlib_ptr->next = dlibs;
914 dlibs = dlib_ptr;
915 }
916 }
917
918 closedir (dir);
919
920 /* Now dlibs contains a list of all libs - add those to the cache
921 and created all symbolic links. */
922 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
923 {
924 /* Don't create links to links. */
925 if (dlib_ptr->is_link == 0)
b4a555d6
UD
926 create_links (dir_name, entry->path, dlib_ptr->name,
927 dlib_ptr->soname);
591e1ffb 928 if (opt_build_cache)
a986484f
UD
929 add_to_cache (entry->path, dlib_ptr->soname, dlib_ptr->flag,
930 dlib_ptr->osversion, hwcap);
591e1ffb
UD
931 }
932
933 /* Free all resources. */
45eca4d1 934 while (dlibs)
591e1ffb
UD
935 {
936 dlib_ptr = dlibs;
937 free (dlib_ptr->soname);
938 free (dlib_ptr->name);
939 dlibs = dlibs->next;
940 free (dlib_ptr);
941 }
b4a555d6
UD
942
943 if (opt_chroot && dir_name)
944 free (dir_name);
591e1ffb
UD
945}
946
947/* Search through all libraries. */
948static void
949search_dirs (void)
950{
951 struct dir_entry *entry;
952
953 for (entry = dir_entries; entry != NULL; entry = entry->next)
954 search_dir (entry);
955
956 /* Free all allocated memory. */
957 while (dir_entries)
958 {
959 entry = dir_entries;
960 dir_entries = dir_entries->next;
961 free (entry->path);
962 free (entry);
963 }
964}
965
966
8e115d80 967static void parse_conf_include (const char *config_file, unsigned int lineno,
a334319f 968 bool do_chroot, const char *pattern);
8e115d80 969
591e1ffb
UD
970/* Parse configuration file. */
971static void
a334319f 972parse_conf (const char *filename, bool do_chroot)
591e1ffb 973{
b4a555d6 974 FILE *file = NULL;
591e1ffb 975 char *line = NULL;
b4a555d6 976 const char *canon;
591e1ffb 977 size_t len = 0;
8e115d80 978 unsigned int lineno;
45eca4d1 979
8e115d80 980 if (do_chroot && opt_chroot)
b4a555d6
UD
981 {
982 canon = chroot_canon (opt_chroot, filename);
983 if (canon)
984 file = fopen (canon, "r");
985 else
986 canon = filename;
987 }
988 else
989 {
990 canon = filename;
991 file = fopen (filename, "r");
992 }
591e1ffb
UD
993
994 if (file == NULL)
995 {
b4a555d6
UD
996 error (0, errno, _("Can't open configuration file %s"), canon);
997 if (canon != filename)
998 free ((char *) canon);
591e1ffb
UD
999 return;
1000 }
1001
c96873d7
UD
1002 /* No threads use this stream. */
1003 __fsetlocking (file, FSETLOCKING_BYCALLER);
1004
b4a555d6
UD
1005 if (canon != filename)
1006 free ((char *) canon);
1007
8e115d80 1008 lineno = 0;
591e1ffb
UD
1009 do
1010 {
1011 ssize_t n = getline (&line, &len, file);
1012 if (n < 0)
1013 break;
1014
8e115d80 1015 ++lineno;
591e1ffb
UD
1016 if (line[n - 1] == '\n')
1017 line[n - 1] = '\0';
1018
1019 /* Because the file format does not know any form of quoting we
1020 can search forward for the next '#' character and if found
1021 make it terminating the line. */
1022 *strchrnul (line, '#') = '\0';
1023
69acbe9f
UD
1024 /* Remove leading whitespace. NUL is no whitespace character. */
1025 char *cp = line;
1026 while (isspace (*cp))
1027 ++cp;
1028
591e1ffb 1029 /* If the line is blank it is ignored. */
69acbe9f 1030 if (cp[0] == '\0')
591e1ffb
UD
1031 continue;
1032
8e115d80
RM
1033 if (!strncmp (cp, "include", 7) && isblank (cp[7]))
1034 {
1035 char *dir;
1036 cp += 8;
1037 while ((dir = strsep (&cp, " \t")) != NULL)
1038 if (dir[0] != '\0')
a334319f 1039 parse_conf_include (filename, lineno, do_chroot, dir);
8e115d80 1040 }
ab1d521d
RM
1041 else if (!strncasecmp (cp, "hwcap", 5) && isblank (cp[5]))
1042 {
1043 cp += 6;
1044 char *p, *name = NULL;
1045 unsigned long int n = strtoul (cp, &cp, 0);
1046 if (cp != NULL && isblank (*cp))
1047 while ((p = strsep (&cp, " \t")) != NULL)
1048 if (p[0] != '\0')
1049 {
1050 if (name == NULL)
1051 name = p;
1052 else
1053 {
1054 name = NULL;
1055 break;
1056 }
1057 }
1058 if (name == NULL)
1059 {
1060 error (EXIT_FAILURE, 0, _("%s:%u: bad syntax in hwcap line"),
1061 filename, lineno);
1062 break;
1063 }
1064 if (n >= (64 - _DL_FIRST_EXTRA))
1065 error (EXIT_FAILURE, 0,
1066 _("%s:%u: hwcap index %lu above maximum %u"),
1067 filename, lineno, n, 64 - _DL_FIRST_EXTRA - 1);
1068 if (hwcap_extra[n] == NULL)
1069 {
1070 for (unsigned long int h = 0; h < (64 - _DL_FIRST_EXTRA); ++h)
1071 if (hwcap_extra[h] != NULL && !strcmp (name, hwcap_extra[h]))
1072 error (EXIT_FAILURE, 0,
1073 _("%s:%u: hwcap index %lu already defined as %s"),
1074 filename, lineno, h, name);
1075 hwcap_extra[n] = xstrdup (name);
1076 }
1077 else
1078 {
1079 if (strcmp (name, hwcap_extra[n]))
1080 error (EXIT_FAILURE, 0,
1081 _("%s:%u: hwcap index %lu already defined as %s"),
1082 filename, lineno, n, hwcap_extra[n]);
1083 if (opt_verbose)
1084 error (0, 0, _("%s:%u: duplicate hwcap %lu %s"),
1085 filename, lineno, n, name);
1086 }
1087 }
8e115d80
RM
1088 else
1089 add_dir (cp);
69acbe9f
UD
1090 }
1091 while (!feof_unlocked (file));
591e1ffb
UD
1092
1093 /* Free buffer and close file. */
1094 free (line);
1095 fclose (file);
1096}
1097
8e115d80
RM
1098/* Handle one word in an `include' line, a glob pattern of additional
1099 config files to read. */
1100static void
1101parse_conf_include (const char *config_file, unsigned int lineno,
a334319f 1102 bool do_chroot, const char *pattern)
8e115d80
RM
1103{
1104 if (opt_chroot && pattern[0] != '/')
1105 error (EXIT_FAILURE, 0,
1106 _("need absolute file name for configuration file when using -r"));
1107
1108 char *copy = NULL;
1109 if (pattern[0] != '/' && strchr (config_file, '/') != NULL)
1110 {
322861e8
UD
1111 if (asprintf (&copy, "%s/%s", dirname (strdupa (config_file)),
1112 pattern) < 0)
1113 error (EXIT_FAILURE, 0, _("memory exhausted"));
8e115d80
RM
1114 pattern = copy;
1115 }
1116
1117 glob64_t gl;
1118 int result;
1119 if (do_chroot && opt_chroot)
1120 {
1121 char *canon = chroot_canon (opt_chroot, pattern);
1122 result = glob64 (canon ?: pattern, 0, NULL, &gl);
1123 free (canon);
1124 }
1125 else
1126 result = glob64 (pattern, 0, NULL, &gl);
1127
1128 switch (result)
1129 {
1130 case 0:
1131 for (size_t i = 0; i < gl.gl_pathc; ++i)
a334319f 1132 parse_conf (gl.gl_pathv[i], false);
8e115d80
RM
1133 globfree64 (&gl);
1134 break;
1135
1136 case GLOB_NOMATCH:
1137 break;
1138
1139 case GLOB_NOSPACE:
1140 errno = ENOMEM;
1141 case GLOB_ABORTED:
1142 if (opt_verbose)
1143 error (0, errno, _("%s:%u: cannot read directory %s"),
1144 config_file, lineno, pattern);
1145 break;
1146
1147 default:
1148 abort ();
1149 break;
1150 }
1151
1152 if (copy)
1153 free (copy);
1154}
1155
0cfbb8c6
UD
1156/* Honour LD_HWCAP_MASK. */
1157static void
1158set_hwcap (void)
1159{
1160 char *mask = getenv ("LD_HWCAP_MASK");
1161
1162 if (mask)
1163 hwcap_mask = strtoul (mask, NULL, 0);
1164}
1165
591e1ffb
UD
1166
1167int
1168main (int argc, char **argv)
1169{
11bf311e
UD
1170 /* Set locale via LC_ALL. */
1171 setlocale (LC_ALL, "");
1172
1173 /* Set the text message domain. */
1174 textdomain (_libc_intl_domainname);
45eca4d1 1175
591e1ffb 1176 /* Parse and process arguments. */
11bf311e 1177 int remaining;
591e1ffb
UD
1178 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
1179
11bf8ce1 1180 /* Remaining arguments are additional directories if opt_manual_link
b85697f6
UD
1181 is not set. */
1182 if (remaining != argc && !opt_manual_link)
591e1ffb
UD
1183 {
1184 int i;
1185 for (i = remaining; i < argc; ++i)
11bf8ce1
UD
1186 if (opt_build_cache && argv[i][0] != '/')
1187 error (EXIT_FAILURE, 0,
1188 _("relative path `%s' used to build cache"),
1189 argv[i]);
1190 else
1191 add_dir (argv[i]);
591e1ffb
UD
1192 }
1193
ab1d521d 1194 hwcap_extra[63 - _DL_FIRST_EXTRA] = "tls";
ab1d521d 1195
0cfbb8c6
UD
1196 set_hwcap ();
1197
591e1ffb
UD
1198 if (opt_chroot)
1199 {
f0189a54 1200 /* Normalize the path a bit, we might need it for printing later. */
616d9133 1201 char *endp = rawmemchr (opt_chroot, '\0');
b4a555d6 1202 while (endp > opt_chroot && endp[-1] == '/')
f0189a54
UD
1203 --endp;
1204 *endp = '\0';
b4a555d6
UD
1205 if (endp == opt_chroot)
1206 opt_chroot = NULL;
f0189a54 1207
b4a555d6
UD
1208 if (opt_chroot)
1209 {
1210 /* It is faster to use chroot if we can. */
1211 if (!chroot (opt_chroot))
1212 {
1213 if (chdir ("/"))
1214 error (EXIT_FAILURE, errno, _("Can't chdir to /"));
1215 opt_chroot = NULL;
1216 }
1217 }
1218 }
1219
1220 if (cache_file == NULL)
1221 {
1222 cache_file = alloca (strlen (LD_SO_CACHE) + 1);
1223 strcpy (cache_file, LD_SO_CACHE);
591e1ffb
UD
1224 }
1225
b4a555d6
UD
1226 if (config_file == NULL)
1227 config_file = LD_SO_CONF;
1228
591e1ffb
UD
1229 if (opt_print_cache)
1230 {
b4a555d6
UD
1231 if (opt_chroot)
1232 {
1233 char *p = chroot_canon (opt_chroot, cache_file);
1234 if (p == NULL)
1235 error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
1236 cache_file);
1237 cache_file = p;
1238 }
591e1ffb 1239 print_cache (cache_file);
b4a555d6
UD
1240 if (opt_chroot)
1241 free (cache_file);
591e1ffb
UD
1242 exit (0);
1243 }
1244
b4a555d6
UD
1245 if (opt_chroot)
1246 {
1247 /* Canonicalize the directory name of cache_file, not cache_file,
1248 because we'll rename a temporary cache file to it. */
1249 char *p = strrchr (cache_file, '/');
1250 char *canon = chroot_canon (opt_chroot,
1251 p ? (*p = '\0', cache_file) : "/");
1252
1253 if (canon == NULL)
1254 {
1255 error (EXIT_FAILURE, errno,
1256 _("Can't open cache file directory %s\n"),
1257 p ? cache_file : "/");
1258 }
1259
1260 if (p)
1261 ++p;
1262 else
1263 p = cache_file;
1264
1265 cache_file = alloca (strlen (canon) + strlen (p) + 2);
1266 sprintf (cache_file, "%s/%s", canon, p);
1267 free (canon);
1268 }
1269
b85697f6
UD
1270 if (opt_manual_link)
1271 {
1272 /* Link all given libraries manually. */
1273 int i;
1274
1275 for (i = remaining; i < argc; ++i)
a986484f 1276 manual_link (argv[i]);
b85697f6
UD
1277
1278 exit (0);
1279 }
45eca4d1
UD
1280
1281
591e1ffb
UD
1282 if (opt_build_cache)
1283 init_cache ();
1284
1285 if (!opt_only_cline)
1286 {
a334319f 1287 parse_conf (config_file, true);
334fcf2a 1288
591e1ffb 1289 /* Always add the standard search paths. */
bd89c0b5 1290 add_system_dir (SLIBDIR);
8ca91b36 1291 if (strcmp (SLIBDIR, LIBDIR))
bd89c0b5 1292 add_system_dir (LIBDIR);
591e1ffb 1293 }
45eca4d1 1294
591e1ffb
UD
1295 search_dirs ();
1296
1297 if (opt_build_cache)
1298 save_cache (cache_file);
1299
1300 return 0;
1301}