OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-newlib/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [dl/] [dl-cache.c] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 jlechner
/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
2
   Copyright (C) 1996,1997,1998,1999,2000,2001 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 Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the 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
   Lesser General Public License for more details.
14
 
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, write to the Free
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
   02111-1307 USA.  */
19
 
20
#include <assert.h>
21
#include <unistd.h>
22
#include <ldsodefs.h>
23
#include <sys/mman.h>
24
#include <dl-cache.h>
25
#include <machine/dl-procinfo.h>
26
#include <machine/weakalias.h>
27
 
28
extern const char *_dl_platform;
29
 
30
#ifndef _DL_PLATFORMS_COUNT
31
# define _DL_PLATFORMS_COUNT 0
32
#endif
33
 
34
/* This is the starting address and the size of the mmap()ed file.  */
35
static struct cache_file *cache;
36
static struct cache_file_new *cache_new;
37
static size_t cachesize;
38
 
39
/* 1 if cache_data + PTR points into the cache.  */
40
#define _dl_cache_verify_ptr(ptr) (ptr < cache_data_size)
41
 
42
/* This is the cache ID we expect.  Normally it is 3 for glibc linked
43
   binaries.  */
44
int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
45
 
46
#define SEARCH_CACHE(cache) \
47
/* We use binary search since the table is sorted in the cache file.          \
48
   The first matching entry in the table is returned.                         \
49
   It is important to use the same algorithm as used while generating         \
50
   the cache file.  */                                                        \
51
do                                                                            \
52
  {                                                                           \
53
    left = 0;                                                                  \
54
    right = cache->nlibs - 1;                                                 \
55
                                                                              \
56
    while (left <= right)                                                     \
57
      {                                                                       \
58
        __typeof__ (cache->libs[0].key) key;                                   \
59
                                                                              \
60
        middle = (left + right) / 2;                                          \
61
                                                                              \
62
        key = cache->libs[middle].key;                                        \
63
                                                                              \
64
        /* Make sure string table indices are not bogus before using          \
65
           them.  */                                                          \
66
        if (! _dl_cache_verify_ptr (key))                                     \
67
          {                                                                   \
68
            cmpres = 1;                                                       \
69
            break;                                                            \
70
          }                                                                   \
71
                                                                              \
72
        /* Actually compare the entry with the key.  */                       \
73
        cmpres = _dl_cache_libcmp (name, cache_data + key);                   \
74
        if (__builtin_expect (cmpres == 0, 0))                                  \
75
          {                                                                   \
76
            /* Found it.  LEFT now marks the last entry for which we          \
77
               know the name is correct.  */                                  \
78
            left = middle;                                                    \
79
                                                                              \
80
            /* There might be entries with this name before the one we        \
81
               found.  So we have to find the beginning.  */                  \
82
            while (middle > 0)                                                 \
83
              {                                                               \
84
                __typeof__ (cache->libs[0].key) key;                           \
85
                                                                              \
86
                key = cache->libs[middle - 1].key;                            \
87
                /* Make sure string table indices are not bogus before        \
88
                   using them.  */                                            \
89
                if (! _dl_cache_verify_ptr (key)                              \
90
                    /* Actually compare the entry.  */                        \
91
                    || _dl_cache_libcmp (name, cache_data + key) != 0)         \
92
                  break;                                                      \
93
                --middle;                                                     \
94
              }                                                               \
95
                                                                              \
96
            do                                                                \
97
              {                                                               \
98
                int flags;                                                    \
99
                __typeof__ (cache->libs[0]) *lib = &cache->libs[middle];      \
100
                                                                              \
101
                /* Only perform the name test if necessary.  */               \
102
                if (middle > left                                             \
103
                    /* We haven't seen this string so far.  Test whether the  \
104
                       index is ok and whether the name matches.  Otherwise   \
105
                       we are done.  */                                       \
106
                    && (! _dl_cache_verify_ptr (lib->key)                     \
107
                        || (_dl_cache_libcmp (name, cache_data + lib->key)    \
108
                            != 0)))                                            \
109
                  break;                                                      \
110
                                                                              \
111
                flags = lib->flags;                                           \
112
                if (_dl_cache_check_flags (flags)                             \
113
                    && _dl_cache_verify_ptr (lib->value))                     \
114
                  {                                                           \
115
                    if (best == NULL || flags == _dl_correct_cache_id)        \
116
                      {                                                       \
117
                        HWCAP_CHECK;                                          \
118
                        best = cache_data + lib->value;                       \
119
                                                                              \
120
                        if (flags == _dl_correct_cache_id)                    \
121
                          /* We've found an exact match for the shared        \
122
                             object and no general `ELF' release.  Stop       \
123
                             searching.  */                                   \
124
                          break;                                              \
125
                      }                                                       \
126
                  }                                                           \
127
              }                                                               \
128
            while (++middle <= right);                                        \
129
            break;                                                            \
130
        }                                                                     \
131
                                                                              \
132
        if (cmpres < 0)                                                        \
133
          left = middle + 1;                                                  \
134
        else                                                                  \
135
          right = middle - 1;                                                 \
136
      }                                                                       \
137
  }                                                                           \
138
while (0)
139
 
140
 
141
 
142
/* Look up NAME in ld.so.cache and return the file name stored there,
143
   or null if none is found.  */
144
 
145
const char *
146
internal_function
147
_dl_load_cache_lookup (const char *name)
148
{
149
  int left, right, middle;
150
  int cmpres;
151
  const char *cache_data;
152
  uint32_t cache_data_size;
153
  const char *best;
154
 
155
  if (cache == NULL)
156
    {
157
      /* Read the contents of the file.  */
158
      void *file = _dl_sysdep_read_whole_file (LD_SO_CACHE, &cachesize,
159
                                               PROT_READ);
160
 
161
      /* We can handle three different cache file formats here:
162
         - the old libc5/glibc2.0/2.1 format
163
         - the old format with the new format in it
164
         - only the new format
165
         The following checks if the cache contains any of these formats.  */
166
      if (file != MAP_FAILED && cachesize > sizeof *cache
167
          && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0)
168
        {
169
          size_t offset;
170
          /* Looks ok.  */
171
          cache = file;
172
 
173
          /* Check for new version.  */
174
          offset = ALIGN_CACHE (sizeof (struct cache_file)
175
                                + cache->nlibs * sizeof (struct file_entry));
176
 
177
          cache_new = (struct cache_file_new *) ((void *) cache + offset);
178
          if (cachesize < (offset + sizeof (struct cache_file_new))
179
              || memcmp (cache_new->magic, CACHEMAGIC_VERSION_NEW,
180
                         sizeof CACHEMAGIC_VERSION_NEW - 1) != 0)
181
            cache_new = (void *) -1;
182
        }
183
      else if (file != MAP_FAILED && cachesize > sizeof *cache_new
184
               && memcmp (file, CACHEMAGIC_VERSION_NEW,
185
                          sizeof CACHEMAGIC_VERSION_NEW - 1) == 0)
186
        {
187
          cache_new = file;
188
          cache = file;
189
        }
190
      else
191
        {
192
          if (file != MAP_FAILED)
193
            munmap (file, cachesize);
194
          cache = (void *) -1;
195
        }
196
 
197
      assert (cache != NULL);
198
    }
199
 
200
  if (cache == (void *) -1)
201
    /* Previously looked for the cache file and didn't find it.  */
202
    return NULL;
203
 
204
  best = NULL;
205
 
206
  if (cache_new != (void *) -1)
207
    {
208
      /* This file ends in static libraries where we don't have a hwcap.  */
209
      unsigned long int *hwcap;
210
      uint64_t platform;
211
      #pragma weak _dl_hwcap
212
 
213
      /* This is where the strings start.  */
214
      cache_data = (const char *) cache_new;
215
 
216
      /* Now we can compute how large the string table is.  */
217
      cache_data_size = (const char *) cache + cachesize - cache_data;
218
 
219
      hwcap = &_dl_hwcap;
220
      platform = _dl_string_platform (_dl_platform);
221
      if (platform != -1)
222
        platform = 1ULL << platform;
223
 
224
      /* Only accept hwcap if it's for the right platform.  */
225
#define HWCAP_CHECK \
226
      if (_dl_osversion && cache_new->libs[middle].osversion > _dl_osversion) \
227
        continue;                                                             \
228
      if (_DL_PLATFORMS_COUNT && platform != -1                               \
229
          && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0                            \
230
          && (lib->hwcap & _DL_HWCAP_PLATFORM) != platform)                   \
231
        continue;                                                             \
232
      if (hwcap                                                               \
233
          && ((lib->hwcap & *hwcap & ~_DL_HWCAP_PLATFORM) > *hwcap))          \
234
        continue
235
      SEARCH_CACHE (cache_new);
236
    }
237
  else
238
    {
239
      /* This is where the strings start.  */
240
      cache_data = (const char *) &cache->libs[cache->nlibs];
241
 
242
      /* Now we can compute how large the string table is.  */
243
      cache_data_size = (const char *) cache + cachesize - cache_data;
244
 
245
#undef HWCAP_CHECK
246
#define HWCAP_CHECK do {} while (0)
247
      SEARCH_CACHE (cache);
248
    }
249
 
250
  /* Print our result if wanted.  */
251
  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0) && best != NULL)
252
    _dl_debug_printf ("  trying file=%s\n", best);
253
 
254
  return best;
255
}
256
 
257
#ifndef MAP_COPY
258
/* If the system does not support MAP_COPY we cannot leave the file open
259
   all the time since this would create problems when the file is replaced.
260
   Therefore we provide this function to close the file and open it again
261
   once needed.  */
262
void
263
_dl_unload_cache (void)
264
{
265
  if (cache != NULL && cache != (struct cache_file *) -1)
266
    {
267
      munmap (cache, cachesize);
268
      cache = NULL;
269
    }
270
}
271
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.