Wed Jul 17 21:53:45 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
[platform/upstream/glibc.git] / elf / dl-cache.c
1 /* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
2 Copyright (C) 1996 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library 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 GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB.  If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA.  */
19
20 #include <link.h>
21 #include <sys/mman.h>
22
23 /* System-dependent function to read a file's whole contents
24    in the most convenient manner available.  */
25 extern void *_dl_sysdep_read_whole_file (const char *filename,
26                                          size_t *filesize_ptr,
27                                          int mmap_prot);
28
29 #define CACHEMAGIC "ld.so-1.7.0"
30
31 struct cache_file
32   {
33     char magic[sizeof CACHEMAGIC - 1];
34     unsigned int nlibs;
35     struct
36       {
37         int flags;              /* This is 1 for an ELF library.  */
38         unsigned int key, value; /* String table indices.  */
39       } libs[0];
40   };
41
42 /* Look up NAME in ld.so.cache and return the file name stored there,
43    or null if none is found.  */
44
45 const char *
46 _dl_load_cache_lookup (const char *name)
47 {
48   static struct cache_file *cache;
49   static size_t cachesize;
50   unsigned int i;
51
52   if (cache == (void *) -1)
53     /* Previously looked for the cache file and didn't find it.  */
54     return NULL;
55
56   if (cache == NULL)
57     {
58       /* Read the contents of the file.  */
59       void *file = _dl_sysdep_read_whole_file ("/etc/ld.so.cache", &cachesize,
60                                                PROT_READ);
61       if (file && cachesize > sizeof *cache &&
62           !memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1))
63         /* Looks ok.  */
64         cache = file;
65       else
66         {
67           if (file)
68             __munmap (file, cachesize);
69           cache = (void *) -1;
70           return NULL;
71         }
72     }
73
74   for (i = 0; i < cache->nlibs; ++i)
75     if (cache->libs[i].flags == 1 && /* ELF library entry.  */
76         /* Make sure string table indices are not bogus before using them.  */
77         cache->libs[i].key < cachesize - sizeof *cache &&
78         cache->libs[i].value < cachesize - sizeof *cache &&
79         /* Does the name match?  */
80         ! strcmp (name, ((const char *) &cache->libs[cache->nlibs] +
81                          cache->libs[i].key)))
82       return (const char *) &cache->libs[cache->nlibs] + cache->libs[i].value;
83
84   return NULL;
85 }