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