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