(linenum→info "unix/slp.c:2238")

glibc/2.7/elf/cache.c

    1: /* Copyright (C) 1999-2003,2005,2006,2007 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: #include <errno.h>
   20: #include <error.h>
   21: #include <dirent.h>
   22: #include <inttypes.h>
   23: #include <libgen.h>
   24: #include <libintl.h>
   25: #include <stdio.h>
   26: #include <stdlib.h>
   27: #include <string.h>
   28: #include <unistd.h>
   29: #include <sys/fcntl.h>
   30: #include <sys/mman.h>
   31: #include <sys/stat.h>
   32: #include <sys/types.h>
   33: 
   34: #include <ldconfig.h>
   35: #include <dl-cache.h>
   36: 
   37: struct cache_entry
   38: {
   39:   char *lib;                    /* Library name.  */
   40:   char *path;                   /* Path to find library.  */
   41:   int flags;                    /* Flags to indicate kind of library.  */
   42:   unsigned int osversion;       /* Required OS version.  */
   43:   uint64_t hwcap;               /* Important hardware capabilities.  */
   44:   int bits_hwcap;               /* Number of bits set in hwcap.  */
   45:   struct cache_entry *next;     /* Next entry in list.  */
   46: };
   47: 
   48: /* List of all cache entries.  */
   49: static struct cache_entry *entries;
   50: 
   51: static const char *flag_descr[] =
   52: { "libc4", "ELF", "libc5", "libc6"};
   53: 
   54: /* Print a single entry.  */
   55: static void
   56: print_entry (const char *lib, int flag, unsigned int osversion,
   57:              uint64_t hwcap, const char *key)
   58: {
   59:   printf ("\t%s (", lib);
   60:   switch (flag & FLAG_TYPE_MASK)
   61:     {
   62:     case FLAG_LIBC4:
   63:     case FLAG_ELF:
   64:     case FLAG_ELF_LIBC5:
   65:     case FLAG_ELF_LIBC6:
   66:       fputs (flag_descr[flag & FLAG_TYPE_MASK], stdout);
   67:       break;
   68:     default:
   69:       fputs (_("unknown"), stdout);
   70:       break;
   71:     }
   72:   switch (flag & FLAG_REQUIRED_MASK)
   73:     {
   74:     case FLAG_SPARC_LIB64:
   75:       fputs (",64bit", stdout);
   76:       break;
   77:     case FLAG_IA64_LIB64:
   78:       fputs (",IA-64", stdout);
   79:       break;
   80:     case FLAG_X8664_LIB64:
   81:       fputs (",x86-64", stdout);
   82:       break;
   83:     case FLAG_S390_LIB64:
   84:       fputs (",64bit", stdout);
   85:       break;
   86:     case FLAG_POWERPC_LIB64:
   87:       fputs (",64bit", stdout);
   88:       break;
   89:     case FLAG_MIPS64_LIBN32:
   90:       fputs (",N32", stdout);
   91:       break;
   92:     case FLAG_MIPS64_LIBN64:
   93:       fputs (",64bit", stdout);
   94:     case 0:
   95:       break;
   96:     default:
   97:       printf (",%d", flag & FLAG_REQUIRED_MASK);
   98:       break;
   99:     }
  100:   if (hwcap != 0)
  101:     printf (", hwcap: %#.16" PRIx64, hwcap);
  102:   if (osversion != 0)
  103:     {
  104:       static const char *const abi_tag_os[] =
  105:       {
  106:         [0] = "Linux",
  107:         [1] = "Hurd",
  108:         [2] = "Solaris",
  109:         [3] = "FreeBSD",
  110:         [4] = "kNetBSD",
  111:         [5] = "Syllable",
  112:         [6] = N_("Unknown OS")
  113:       };
  114: #define MAXTAG (sizeof abi_tag_os / sizeof abi_tag_os[0] - 1)
  115:       unsigned int os = osversion >> 24;
  116: 
  117:       printf (_(", OS ABI: %s %d.%d.%d"),
  118:               _(abi_tag_os[os > MAXTAG ? MAXTAG : os]),
  119:               (osversion >> 16) & 0xff,
  120:               (osversion >> 8) & 0xff,
  121:               osversion & 0xff);
  122:     }
  123:   printf (") => %s\n", key);
  124: }
  125: 
  126: 
  127: /* Print the whole cache file, if a file contains the new cache format
  128:    hidden in the old one, print the contents of the new format.  */
  129: void
  130: print_cache (const char *cache_name)
  131: {
  132:   int fd = open (cache_name, O_RDONLY);
  133:   if (fd < 0)
  134:     error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name);
  135: 
  136:   struct stat64 st;
  137:   if (fstat64 (fd, &st) < 0
  138:       /* No need to map the file if it is empty.  */
  139:       || st.st_size == 0)
  140:     {
  141:       close (fd);
  142:       return;
  143:     }
  144: 
  145:   struct cache_file *cache
  146:     = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  147:   if (cache == MAP_FAILED)
  148:     error (EXIT_FAILURE, errno, _("mmap of cache file failed.\n"));
  149: 
  150:   size_t cache_size = st.st_size;
  151:   if (cache_size < sizeof (struct cache_file))
  152:     error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
  153: 
  154:   struct cache_file_new *cache_new = NULL;
  155:   const char *cache_data;
  156:   int format = 0;
  157: 
  158:   if (memcmp (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1))
  159:     {
  160:       /* This can only be the new format without the old one.  */
  161:       cache_new = (struct cache_file_new *) cache;
  162: 
  163:       if (memcmp (cache_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1)
  164:           || memcmp (cache_new->version, CACHE_VERSION,
  165:                       sizeof CACHE_VERSION - 1))
  166:         error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
  167:       format = 1;
  168:       /* This is where the strings start.  */
  169:       cache_data = (const char *) cache_new;
  170:     }
  171:   else
  172:     {
  173:       size_t offset = ALIGN_CACHE (sizeof (struct cache_file)
  174:                                    + (cache->nlibs
  175:                                       * sizeof (struct file_entry)));
  176:       /* This is where the strings start.  */
  177:       cache_data = (const char *) &cache->libs[cache->nlibs];
  178: 
  179:       /* Check for a new cache embedded in the old format.  */
  180:       if (cache_size >
  181:           (offset + sizeof (struct cache_file_new)))
  182:         {
  183: 
  184:           cache_new = (struct cache_file_new *) ((void *)cache + offset);
  185: 
  186:           if (memcmp (cache_new->magic, CACHEMAGIC_NEW,
  187:                       sizeof CACHEMAGIC_NEW - 1) == 0
  188:               && memcmp (cache_new->version, CACHE_VERSION,
  189:                          sizeof CACHE_VERSION - 1) == 0)
  190:             {
  191:               cache_data = (const char *) cache_new;
  192:               format = 1;
  193:             }
  194:         }
  195:     }
  196: 
  197:   if (format == 0)
  198:     {
  199:       printf (_("%d libs found in cache `%s'\n"), cache->nlibs, cache_name);
  200: 
  201:       /* Print everything.  */
  202:       for (unsigned int i = 0; i < cache->nlibs; i++)
  203:         print_entry (cache_data + cache->libs[i].key,
  204:                      cache->libs[i].flags, 0, 0,
  205:                      cache_data + cache->libs[i].value);
  206:     }
  207:   else if (format == 1)
  208:     {
  209:       printf (_("%d libs found in cache `%s'\n"),
  210:               cache_new->nlibs, cache_name);
  211: 
  212:       /* Print everything.  */
  213:       for (unsigned int i = 0; i < cache_new->nlibs; i++)
  214:         print_entry (cache_data + cache_new->libs[i].key,
  215:                      cache_new->libs[i].flags,
  216:                      cache_new->libs[i].osversion,
  217:                      cache_new->libs[i].hwcap,
  218:                      cache_data + cache_new->libs[i].value);
  219:     }
  220:   /* Cleanup.  */
  221:   munmap (cache, cache_size);
  222:   close (fd);
  223: }
  224: 
  225: /* Initialize cache data structures.  */
  226: void
  227: init_cache (void)
  228: {
  229:   entries = NULL;
  230: }
  231: 
  232: static int
  233: compare (const struct cache_entry *e1, const struct cache_entry *e2)
  234: {
  235:   /* We need to swap entries here to get the correct sort order.  */
  236:   int res = _dl_cache_libcmp (e2->lib, e1->lib);
  237:   if (res == 0)
  238:     {
  239:       if (e1->flags < e2->flags)
  240:         return 1;
  241:       else if (e1->flags > e2->flags)
  242:         return -1;
  243:       /* Sort by most specific hwcap.  */
  244:       else if (e2->bits_hwcap > e1->bits_hwcap)
  245:         return 1;
  246:       else if (e2->bits_hwcap < e1->bits_hwcap)
  247:         return -1;
  248:       else if (e2->hwcap > e1->hwcap)
  249:         return 1;
  250:       else if (e2->hwcap < e1->hwcap)
  251:         return -1;
  252:       if (e2->osversion > e1->osversion)
  253:         return 1;
  254:       if (e2->osversion < e1->osversion)
  255:         return -1;
  256:     }
  257:   return res;
  258: }
  259: 
  260: /* Save the contents of the cache.  */
  261: void
  262: save_cache (const char *cache_name)
  263: {
  264:   /* The cache entries are sorted already, save them in this order. */
  265: 
  266:   /* Count the length of all strings.  */
  267:   /* The old format doesn't contain hwcap entries and doesn't contain
  268:      libraries in subdirectories with hwcaps entries.  Count therefore
  269:      also all entries with hwcap == 0.  */
  270:   size_t total_strlen = 0;
  271:   struct cache_entry *entry;
  272:   /* Number of cache entries.  */
  273:   int cache_entry_count = 0;
  274:   /* Number of normal cache entries.  */
  275:   int cache_entry_old_count = 0;
  276: 
  277:   for (entry = entries; entry != NULL; entry = entry->next)
  278:     {
  279:       /* Account the final NULs.  */
  280:       total_strlen += strlen (entry->lib) + strlen (entry->path) + 2;
  281:       ++cache_entry_count;
  282:       if (entry->hwcap == 0)
  283:         ++cache_entry_old_count;
  284:     }
  285: 
  286:   /* Create the on disk cache structure.  */
  287:   struct cache_file *file_entries = NULL;
  288:   size_t file_entries_size = 0;
  289: 
  290:   if (opt_format != 2)
  291:     {
  292:       /* struct cache_file_new is 64-bit aligned on some arches while
  293:          only 32-bit aligned on other arches.  Duplicate last old
  294:          cache entry so that new cache in ld.so.cache can be used by
  295:          both.  */
  296:       if (opt_format != 0)
  297:         cache_entry_old_count = (cache_entry_old_count + 1) & ~1;
  298: 
  299:       /* And the list of all entries in the old format.  */
  300:       file_entries_size = sizeof (struct cache_file)
  301:         + cache_entry_old_count * sizeof (struct file_entry);
  302:       file_entries = xmalloc (file_entries_size);
  303: 
  304:       /* Fill in the header.  */
  305:       memset (file_entries, '\0', sizeof (struct cache_file));
  306:       memcpy (file_entries->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1);
  307: 
  308:       file_entries->nlibs = cache_entry_old_count;
  309:     }
  310: 
  311:   struct cache_file_new *file_entries_new = NULL;
  312:   size_t file_entries_new_size = 0;
  313: 
  314:   if (opt_format != 0)
  315:     {
  316:       /* And the list of all entries in the new format.  */
  317:       file_entries_new_size = sizeof (struct cache_file_new)
  318:         + cache_entry_count * sizeof (struct file_entry_new);
  319:       file_entries_new = xmalloc (file_entries_new_size);
  320: 
  321:       /* Fill in the header.  */
  322:       memset (file_entries_new, '\0', sizeof (struct cache_file_new));
  323:       memcpy (file_entries_new->magic, CACHEMAGIC_NEW,
  324:               sizeof CACHEMAGIC_NEW - 1);
  325:       memcpy (file_entries_new->version, CACHE_VERSION,
  326:               sizeof CACHE_VERSION - 1);
  327: 
  328:       file_entries_new->nlibs = cache_entry_count;
  329:       file_entries_new->len_strings = total_strlen;
  330:     }
  331: 
  332:   /* Pad for alignment of cache_file_new.  */
  333:   size_t pad = ALIGN_CACHE (file_entries_size) - file_entries_size;
  334: 
  335:   /* If we have both formats, we hide the new format in the strings
  336:      table, we have to adjust all string indices for this so that
  337:      old libc5/glibc 2 dynamic linkers just ignore them.  */
  338:   unsigned int str_offset;
  339:   if (opt_format != 0)
  340:     str_offset = file_entries_new_size;
  341:   else
  342:     str_offset = 0;
  343: 
  344:   /* An array for all strings.  */
  345:   char *strings = xmalloc (total_strlen);
  346:   char *str = strings;
  347:   int idx_old;
  348:   int idx_new;
  349: 
  350:   for (idx_old = 0, idx_new = 0, entry = entries; entry != NULL;
  351:        entry = entry->next, ++idx_new)
  352:     {
  353:       /* First the library.  */
  354:       if (opt_format != 2 && entry->hwcap == 0)
  355:         {
  356:           file_entries->libs[idx_old].flags = entry->flags;
  357:           /* XXX: Actually we can optimize here and remove duplicates.  */
  358:           file_entries->libs[idx_old].key = str_offset + pad;
  359:         }
  360:       if (opt_format != 0)
  361:         {
  362:           /* We could subtract file_entries_new_size from str_offset -
  363:              not doing so makes the code easier, the string table
  364:              always begins at the beginning of the the new cache
  365:              struct.  */
  366:           file_entries_new->libs[idx_new].flags = entry->flags;
  367:           file_entries_new->libs[idx_new].osversion = entry->osversion;
  368:           file_entries_new->libs[idx_new].hwcap = entry->hwcap;
  369:           file_entries_new->libs[idx_new].key = str_offset;
  370:         }
  371: 
  372:       size_t len = strlen (entry->lib) + 1;
  373:       str = mempcpy (str, entry->lib, len);
  374:       str_offset += len;
  375:       /* Then the path.  */
  376:       if (opt_format != 2 && entry->hwcap == 0)
  377:         file_entries->libs[idx_old].value = str_offset + pad;
  378:       if (opt_format != 0)
  379:         file_entries_new->libs[idx_new].value = str_offset;
  380:       len = strlen (entry->path) + 1;
  381:       str = mempcpy (str, entry->path, len);
  382:       str_offset += len;
  383:       /* Ignore entries with hwcap for old format.  */
  384:       if (entry->hwcap == 0)
  385:         ++idx_old;
  386:     }
  387: 
  388:   /* Duplicate last old cache entry if needed.  */
  389:   if (opt_format != 2
  390:       && idx_old < cache_entry_old_count)
  391:     file_entries->libs[idx_old] = file_entries->libs[idx_old - 1];
  392: 
  393:   /* Write out the cache.  */
  394: 
  395:   /* Write cache first to a temporary file and rename it later.  */
  396:   char *temp_name = xmalloc (strlen (cache_name) + 2);
  397:   sprintf (temp_name, "%s~", cache_name);
  398: 
  399:   /* Create file.  */
  400:   int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
  401:                  S_IRUSR|S_IWUSR);
  402:   if (fd < 0)
  403:     error (EXIT_FAILURE, errno, _("Can't create temporary cache file %s"),
  404:            temp_name);
  405: 
  406:   /* Write contents.  */
  407:   if (opt_format != 2)
  408:     {
  409:       if (write (fd, file_entries, file_entries_size)
  410:           != (ssize_t) file_entries_size)
  411:         error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
  412:     }
  413:   if (opt_format != 0)
  414:     {
  415:       /* Align cache.  */
  416:       if (opt_format != 2)
  417:         {
  418:           char zero[pad];
  419:           memset (zero, '\0', pad);
  420:           if (write (fd, zero, pad) != (ssize_t) pad)
  421:             error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
  422:         }
  423:       if (write (fd, file_entries_new, file_entries_new_size)
  424:           != (ssize_t) file_entries_new_size)
  425:         error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
  426:     }
  427: 
  428:   if (write (fd, strings, total_strlen) != (ssize_t) total_strlen
  429:       || close (fd))
  430:     error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
  431: 
  432:   /* Make sure user can always read cache file */
  433:   if (chmod (temp_name, S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR))
  434:     error (EXIT_FAILURE, errno,
  435:            _("Changing access rights of %s to %#o failed"), temp_name,
  436:            S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR);
  437: 
  438:   /* Move temporary to its final location.  */
  439:   if (rename (temp_name, cache_name))
  440:     error (EXIT_FAILURE, errno, _("Renaming of %s to %s failed"), temp_name,
  441:            cache_name);
  442: 
  443:   /* Free all allocated memory.  */
  444:   free (file_entries_new);
  445:   free (file_entries);
  446:   free (strings);
  447: 
  448:   while (entries)
  449:     {
  450:       entry = entries;
  451:       entries = entries->next;
  452:       free (entry);
  453:     }
  454: }
  455: 
  456: 
  457: /* Add one library to the cache.  */
  458: void
  459: add_to_cache (const char *path, const char *lib, int flags,
  460:               unsigned int osversion, uint64_t hwcap)
  461: {
  462:   size_t liblen = strlen (lib) + 1;
  463:   size_t len = liblen + strlen (path) + 1;
  464:   struct cache_entry *new_entry
  465:     = xmalloc (sizeof (struct cache_entry) + liblen + len);
  466: 
  467:   new_entry->lib = memcpy ((char *) (new_entry + 1), lib, liblen);
  468:   new_entry->path = new_entry->lib + liblen;
  469:   snprintf (new_entry->path, len, "%s/%s", path, lib);
  470:   new_entry->flags = flags;
  471:   new_entry->osversion = osversion;
  472:   new_entry->hwcap = hwcap;
  473:   new_entry->bits_hwcap = 0;
  474: 
  475:   /* Count the number of bits set in the masked value.  */
  476:   for (size_t i = 0;
  477:        (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i)
  478:     if ((hwcap & (1ULL << i)) != 0)
  479:       ++new_entry->bits_hwcap;
  480: 
  481: 
  482:   /* Keep the list sorted - search for right place to insert.  */
  483:   struct cache_entry *ptr = entries;
  484:   struct cache_entry *prev = entries;
  485:   while (ptr != NULL)
  486:     {
  487:       if (compare (ptr, new_entry) > 0)
  488:         break;
  489:       prev = ptr;
  490:       ptr = ptr->next;
  491:     }
  492:   /* Is this the first entry?  */
  493:   if (ptr == entries)
  494:     {
  495:       new_entry->next = entries;
  496:       entries = new_entry;
  497:     }
  498:   else
  499:     {
  500:       new_entry->next = prev->next;
  501:       prev->next = new_entry;
  502:     }
  503: }
  504: 
  505: 
  506: /* Auxiliary cache.  */
  507: 
  508: struct aux_cache_entry_id
  509: {
  510:   uint64_t ino;
  511:   uint64_t ctime;
  512:   uint64_t size;
  513:   uint64_t dev;
  514: };
  515: 
  516: struct aux_cache_entry
  517: {
  518:   struct aux_cache_entry_id id;
  519:   int flags;
  520:   unsigned int osversion;
  521:   int used;
  522:   char *soname;
  523:   struct aux_cache_entry *next;
  524: };
  525: 
  526: #define AUX_CACHEMAGIC          "glibc-ld.so.auxcache-1.0"
  527: 
  528: struct aux_cache_file_entry
  529: {
  530:   struct aux_cache_entry_id id; /* Unique id of entry.  */
  531:   int32_t flags;                /* This is 1 for an ELF library.  */
  532:   uint32_t soname;              /* String table indice.  */
  533:   uint32_t osversion;           /* Required OS version.   */
  534:   int32_t pad;
  535: };
  536: 
  537: /* ldconfig maintains an auxiliary cache file that allows
  538:    only reading those libraries that have changed since the last iteration.
  539:    For this for each library some information is cached in the auxiliary
  540:    cache.  */
  541: struct aux_cache_file
  542: {
  543:   char magic[sizeof AUX_CACHEMAGIC - 1];
  544:   uint32_t nlibs;               /* Number of entries.  */
  545:   uint32_t len_strings;         /* Size of string table. */
  546:   struct aux_cache_file_entry libs[0]; /* Entries describing libraries.  */
  547:   /* After this the string table of size len_strings is found.  */
  548: };
  549: 
  550: static const unsigned int primes[] =
  551: {
  552:   1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139,
  553:   524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393,
  554:   67108859, 134217689, 268435399, 536870909, 1073741789, 2147483647
  555: };
  556: 
  557: static size_t aux_hash_size;
  558: static struct aux_cache_entry **aux_hash;
  559: 
  560: /* Simplistic hash function for aux_cache_entry_id.  */
  561: static unsigned int
  562: aux_cache_entry_id_hash (struct aux_cache_entry_id *id)
  563: {
  564:   uint64_t ret = ((id->ino * 11 + id->ctime) * 11 + id->size) * 11 + id->dev;
  565:   return ret ^ (ret >> 32);
  566: }
  567: 
  568: static size_t nextprime (size_t x)
  569: {
  570:   for (unsigned int i = 0; i < sizeof (primes) / sizeof (primes[0]); ++i)
  571:     if (primes[i] >= x)
  572: