.
[kopensolaris-gnu/glibc.git] / locale / loadarchive.c
1 /* Code to load locale data from the locale archive file.
2    Copyright (C) 2002, 2003, 2005 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 <locale.h>
21 #include <stddef.h>
22 #include <stdlib.h>
23 #include <stdbool.h>
24 #include <errno.h>
25 #include <assert.h>
26 #include <string.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <sys/mman.h>
30 #include <sys/stat.h>
31 #include <sys/param.h>
32
33 #include "localeinfo.h"
34 #include "locarchive.h"
35 #include <not-cancel.h>
36
37 /* Define the hash function.  We define the function as static inline.  */
38 #define compute_hashval static inline compute_hashval
39 #define hashval_t uint32_t
40 #include "hashval.h"
41 #undef compute_hashval
42
43
44 /* Name of the locale archive file.  */
45 static const char archfname[] = LOCALEDIR "/locale-archive";
46
47 /* Size of initial mapping window, optimal if large enough to
48    cover the header plus the initial locale.  */
49 #define ARCHIVE_MAPPING_WINDOW  (2 * 1024 * 1024)
50
51 #ifndef MAP_COPY
52 /* This is not quite as good as MAP_COPY since unexamined pages
53    can change out from under us and give us inconsistent data.
54    But we rely on the user not to diddle the system's live archive.
55    Even though we only ever use PROT_READ, using MAP_SHARED would
56    not give the system sufficient freedom to e.g. let the on disk
57    file go away because it doesn't know we won't call mprotect later.  */
58 # define MAP_COPY MAP_PRIVATE
59 #endif
60 #ifndef MAP_FILE
61  /* Some systems do not have this flag; it is superfluous.  */
62 # define MAP_FILE 0
63 #endif
64
65 /* Record of contiguous pages already mapped from the locale archive.  */
66 struct archmapped
67 {
68   void *ptr;
69   uint32_t from;
70   uint32_t len;
71   struct archmapped *next;
72 };
73 static struct archmapped *archmapped;
74
75 /* This describes the mapping at the beginning of the file that contains
76    the header data.  There could be data in the following partial page,
77    so this is searched like any other.  Once the archive has been used,
78    ARCHMAPPED points to this; if mapping the archive header failed,
79    then headmap.ptr is null.  */
80 static struct archmapped headmap;
81 static struct stat64 archive_stat; /* stat of archive when header mapped.  */
82
83 /* Record of locales that we have already loaded from the archive.  */
84 struct locale_in_archive
85 {
86   struct locale_in_archive *next;
87   char *name;
88   struct locale_data *data[__LC_LAST];
89 };
90 static struct locale_in_archive *archloaded;
91
92
93 /* Local structure and subroutine of _nl_load_archive, see below.  */
94 struct range
95 {
96   uint32_t from;
97   uint32_t len;
98   int category;
99   void *result;
100 };
101
102 static int
103 rangecmp (const void *p1, const void *p2)
104 {
105   return ((struct range *) p1)->from - ((struct range *) p2)->from;
106 }
107
108
109 /* Calculate the amount of space needed for all the tables described
110    by the given header.  Note we do not include the empty table space
111    that has been preallocated in the file, so our mapping may not be
112    large enough if localedef adds data to the file in place.  However,
113    doing that would permute the header fields while we are accessing
114    them and thus not be safe anyway, so we don't allow for that.  */
115 static inline off_t
116 calculate_head_size (const struct locarhead *h)
117 {
118   off_t namehash_end = (h->namehash_offset
119                         + h->namehash_size * sizeof (struct namehashent));
120   off_t string_end =  h->string_offset + h->string_used;
121   off_t locrectab_end = (h->locrectab_offset
122                          + h->locrectab_used * sizeof (struct locrecent));
123   return MAX (namehash_end, MAX (string_end, locrectab_end));
124 }
125
126
127 /* Find the locale *NAMEP in the locale archive, and return the
128    internalized data structure for its CATEGORY data.  If this locale has
129    already been loaded from the archive, just returns the existing data
130    structure.  If successful, sets *NAMEP to point directly into the mapped
131    archive string table; that way, the next call can short-circuit strcmp.  */
132 struct locale_data *
133 internal_function
134 _nl_load_locale_from_archive (int category, const char **namep)
135 {
136   const char *name = *namep;
137   struct
138   {
139     void *addr;
140     size_t len;
141   } results[__LC_LAST];
142   struct locale_in_archive *lia;
143   struct locarhead *head;
144   struct namehashent *namehashtab;
145   struct locrecent *locrec;
146   struct archmapped *mapped;
147   struct archmapped *last;
148   unsigned long int hval;
149   size_t idx;
150   size_t incr;
151   struct range ranges[__LC_LAST - 1];
152   int nranges;
153   int cnt;
154   size_t ps = __sysconf (_SC_PAGE_SIZE);
155   int fd = -1;
156
157   /* Check if we have already loaded this locale from the archive.
158      If we previously loaded the locale but found bogons in the data,
159      then we will have stored a null pointer to return here.  */
160   for (lia = archloaded; lia != NULL; lia = lia->next)
161     if (name == lia->name || !strcmp (name, lia->name))
162       {
163         *namep = lia->name;
164         return lia->data[category];
165       }
166
167   {
168     /* If the name contains a codeset, then we normalize the name before
169        doing the lookup.  */
170     const char *p = strchr (name, '.');
171     if (p != NULL && p[1] != '@' && p[1] != '\0')
172       {
173         const char *rest = __strchrnul (++p, '@');
174         const char *normalized_codeset = _nl_normalize_codeset (p, rest - p);
175         if (normalized_codeset == NULL) /* malloc failure */
176           return NULL;
177         if (strncmp (normalized_codeset, p, rest - p) != 0
178             || normalized_codeset[rest - p] != '\0')
179           {
180             /* There is a normalized codeset name that is different from
181                what was specified; reconstruct a new locale name using it.  */
182             size_t normlen = strlen (normalized_codeset);
183             size_t restlen = strlen (rest) + 1;
184             char *newname = alloca (p - name + normlen + restlen);
185             memcpy (__mempcpy (__mempcpy (newname, name, p - name),
186                                normalized_codeset, normlen),
187                     rest, restlen);
188             name = newname;
189           }
190         free ((char *) normalized_codeset);
191       }
192   }
193
194   /* Make sure the archive is loaded.  */
195   if (archmapped == NULL)
196     {
197       void *result;
198       size_t headsize, mapsize;
199
200       /* We do this early as a sign that we have tried to open the archive.
201          If headmap.ptr remains null, that's an indication that we tried
202          and failed, so we won't try again.  */
203       archmapped = &headmap;
204
205       /* The archive has never been opened.  */
206       fd = open_not_cancel_2 (archfname, O_RDONLY|O_LARGEFILE);
207       if (fd < 0)
208         /* Cannot open the archive, for whatever reason.  */
209         return NULL;
210
211       if (__fxstat64 (_STAT_VER, fd, &archive_stat) == -1)
212         {
213           /* stat failed, very strange.  */
214         close_and_out:
215           if (fd >= 0)
216             close_not_cancel_no_status (fd);
217           return NULL;
218         }
219
220
221       /* Map an initial window probably large enough to cover the header
222          and the first locale's data.  With a large address space, we can
223          just map the whole file and be sure everything is covered.  */
224
225       mapsize = (sizeof (void *) > 4 ? archive_stat.st_size
226                  : MIN (archive_stat.st_size, ARCHIVE_MAPPING_WINDOW));
227
228       result = __mmap64 (NULL, mapsize, PROT_READ, MAP_FILE|MAP_COPY, fd, 0);
229       if (result == MAP_FAILED)
230         goto close_and_out;
231
232       /* Check whether the file is large enough for the sizes given in
233          the header.  Theoretically an archive could be so large that
234          just the header fails to fit in our initial mapping window.  */
235       headsize = calculate_head_size ((const struct locarhead *) result);
236       if (headsize > mapsize)
237         {
238           (void) __munmap (result, mapsize);
239           if (sizeof (void *) > 4 || headsize > archive_stat.st_size)
240             /* The file is not big enough for the header.  Bogus.  */
241             goto close_and_out;
242
243           /* Freakishly long header.  */
244           /* XXX could use mremap when available */
245           mapsize = (headsize + ps - 1) & ~(ps - 1);
246           result = __mmap64 (NULL, mapsize, PROT_READ, MAP_FILE|MAP_COPY,
247                              fd, 0);
248           if (result == MAP_FAILED)
249             goto close_and_out;
250         }
251
252       if (sizeof (void *) > 4 || mapsize >= archive_stat.st_size)
253         {
254           /* We've mapped the whole file already, so we can be
255              sure we won't need this file descriptor later.  */
256           close_not_cancel_no_status (fd);
257           fd = -1;
258         }
259
260       headmap.ptr = result;
261       /* headmap.from already initialized to zero.  */
262       headmap.len = mapsize;
263     }
264
265   /* If there is no archive or it cannot be loaded for some reason fail.  */
266   if (__builtin_expect (headmap.ptr == NULL, 0))
267     goto close_and_out;
268
269   /* We have the archive available.  To find the name we first have to
270      determine its hash value.  */
271   hval = compute_hashval (name, strlen (name));
272
273   head = headmap.ptr;
274   namehashtab = (struct namehashent *) ((char *) head
275                                         + head->namehash_offset);
276
277   idx = hval % head->namehash_size;
278   incr = 1 + hval % (head->namehash_size - 2);
279
280   /* If the name_offset field is zero this means this is a
281      deleted entry and therefore no entry can be found.  */
282   while (1)
283     {
284       if (namehashtab[idx].name_offset == 0)
285         /* Not found.  */
286         goto close_and_out;
287
288       if (namehashtab[idx].hashval == hval
289           && strcmp (name, headmap.ptr + namehashtab[idx].name_offset) == 0)
290         /* Found the entry.  */
291         break;
292
293       idx += incr;
294       if (idx >= head->namehash_size)
295         idx -= head->namehash_size;
296     }
297
298   /* We found an entry.  It might be a placeholder for a removed one.  */
299   if (namehashtab[idx].locrec_offset == 0)
300     goto close_and_out;
301
302   locrec = (struct locrecent *) (headmap.ptr + namehashtab[idx].locrec_offset);
303
304   if (sizeof (void *) > 4 /* || headmap.len == archive_stat.st_size */)
305     {
306       /* We already have the whole locale archive mapped in.  */
307       assert (headmap.len == archive_stat.st_size);
308       for (cnt = 0; cnt < __LC_LAST; ++cnt)
309         if (cnt != LC_ALL)
310           {
311             if (locrec->record[cnt].offset + locrec->record[cnt].len
312                 > headmap.len)
313               /* The archive locrectab contains bogus offsets.  */
314               goto close_and_out;
315             results[cnt].addr = headmap.ptr + locrec->record[cnt].offset;
316             results[cnt].len = locrec->record[cnt].len;
317           }
318     }
319   else
320     {
321       /* Get the offsets of the data files and sort them.  */
322       for (cnt = nranges = 0; cnt < __LC_LAST; ++cnt)
323         if (cnt != LC_ALL)
324           {
325             ranges[nranges].from = locrec->record[cnt].offset;
326             ranges[nranges].len = locrec->record[cnt].len;
327             ranges[nranges].category = cnt;
328             ranges[nranges].result = NULL;
329
330             ++nranges;
331           }
332
333       qsort (ranges, nranges, sizeof (ranges[0]), rangecmp);
334
335       /* The information about mmap'd blocks is kept in a list.
336          Skip over the blocks which are before the data we need.  */
337       last = mapped = archmapped;
338       for (cnt = 0; cnt < nranges; ++cnt)
339         {
340           int upper;
341           size_t from;
342           size_t to;
343           void *addr;
344           struct archmapped *newp;
345
346           /* Determine whether the appropriate page is already mapped.  */
347           while (mapped != NULL
348                  && (mapped->from + mapped->len
349                      <= ranges[cnt].from + ranges[cnt].len))
350             {
351               last = mapped;
352               mapped = mapped->next;
353             }
354
355           /* Do we have a match?  */
356           if (mapped != NULL
357               && mapped->from <= ranges[cnt].from
358               && (ranges[cnt].from + ranges[cnt].len
359                   <= mapped->from + mapped->len))
360             {
361               /* Yep, already loaded.  */
362               results[ranges[cnt].category].addr = ((char *) mapped->ptr
363                                                     + ranges[cnt].from
364                                                     - mapped->from);
365               results[ranges[cnt].category].len = ranges[cnt].len;
366               continue;
367             }
368
369           /* Map the range with the locale data from the file.  We will
370              try to cover as much of the locale as possible.  I.e., if the
371              next category (next as in "next offset") is on the current or
372              immediately following page we use it as well.  */
373           assert (powerof2 (ps));
374           from = ranges[cnt].from & ~(ps - 1);
375           upper = cnt;
376           do
377             {
378               to = ranges[upper].from + ranges[upper].len;
379               if (to > (size_t) archive_stat.st_size)
380                 /* The archive locrectab contains bogus offsets.  */
381                 goto close_and_out;
382               to = (to + ps - 1) & ~(ps - 1);
383
384               /* If a range is already mmaped in, stop.  */
385               if (mapped != NULL && ranges[upper].from >= mapped->from)
386                 break;
387
388               ++upper;
389             }
390           /* Loop while still in contiguous pages. */
391           while (upper < nranges && ranges[upper].from < to + ps);
392
393           /* Open the file if it hasn't happened yet.  */
394           if (fd == -1)
395             {
396               struct stat64 st;
397               fd = open_not_cancel_2 (archfname, O_RDONLY|O_LARGEFILE);
398               if (fd == -1)
399                 /* Cannot open the archive, for whatever reason.  */
400                 return NULL;
401               /* Now verify we think this is really the same archive file
402                  we opened before.  If it has been changed we cannot trust
403                  the header we read previously.  */
404               if (__fxstat64 (_STAT_VER, fd, &st) < 0
405                   || st.st_size != archive_stat.st_size
406                   || st.st_mtime != archive_stat.st_mtime
407                   || st.st_dev != archive_stat.st_dev
408                   || st.st_ino != archive_stat.st_ino)
409                 goto close_and_out;
410             }
411
412           /* Map the range from the archive.  */
413           addr = __mmap64 (NULL, to - from, PROT_READ, MAP_FILE|MAP_COPY,
414                            fd, from);
415           if (addr == MAP_FAILED)
416             goto close_and_out;
417
418           /* Allocate a record for this mapping.  */
419           newp = (struct archmapped *) malloc (sizeof (struct archmapped));
420           if (newp == NULL)
421             {
422               (void) __munmap (addr, to - from);
423               goto close_and_out;
424             }
425
426           /* And queue it.  */
427           newp->ptr = addr;
428           newp->from = from;
429           newp->len = to - from;
430           assert (last->next == mapped);
431           newp->next = mapped;
432           last->next = newp;
433           last = newp;
434
435           /* Determine the load addresses for the category data.  */
436           do
437             {
438               assert (ranges[cnt].from >= from);
439               results[ranges[cnt].category].addr = ((char *) addr
440                                                     + ranges[cnt].from - from);
441               results[ranges[cnt].category].len = ranges[cnt].len;
442             }
443           while (++cnt < upper);
444           --cnt;                /* The 'for' will increase 'cnt' again.  */
445         }
446     }
447
448   /* We don't need the file descriptor any longer.  */
449   if (fd >= 0)
450     close_not_cancel_no_status (fd);
451   fd = -1;
452
453   /* We succeeded in mapping all the necessary regions of the archive.
454      Now we need the expected data structures to point into the data.  */
455
456   lia = malloc (sizeof *lia);
457   if (__builtin_expect (lia == NULL, 0))
458     return NULL;
459
460   lia->name = strdup (*namep);
461   if (__builtin_expect (lia->name == NULL, 0))
462     {
463       free (lia);
464       return NULL;
465     }
466
467   lia->next = archloaded;
468   archloaded = lia;
469
470   for (cnt = 0; cnt < __LC_LAST; ++cnt)
471     if (cnt != LC_ALL)
472       {
473         lia->data[cnt] = _nl_intern_locale_data (cnt,
474                                                  results[cnt].addr,
475                                                  results[cnt].len);
476         if (__builtin_expect (lia->data[cnt] != NULL, 1))
477           {
478             /* _nl_intern_locale_data leaves us these fields to initialize.  */
479             lia->data[cnt]->alloc = ld_archive;
480             lia->data[cnt]->name = lia->name;
481
482             /* We do this instead of bumping the count each time we return
483                this data because the mappings stay around forever anyway
484                and we might as well hold on to a little more memory and not
485                have to rebuild it on the next lookup of the same thing.
486                If we were to maintain the usage_count normally and let the
487                structures be freed, we would have to remove the elements
488                from archloaded too.  */
489             lia->data[cnt]->usage_count = UNDELETABLE;
490           }
491       }
492
493   *namep = lia->name;
494   return lia->data[category];
495 }
496
497 void __libc_freeres_fn_section
498 _nl_archive_subfreeres (void)
499 {
500   struct locale_in_archive *lia;
501   struct archmapped *am;
502
503   /* Toss out our cached locales.  */
504   lia = archloaded;
505   while (lia != NULL)
506     {
507       int category;
508       struct locale_in_archive *dead = lia;
509       lia = lia->next;
510
511       free (dead->name);
512       for (category = 0; category < __LC_LAST; ++category)
513         if (category != LC_ALL)
514           {
515             /* _nl_unload_locale just does this free for the archive case.  */
516             if (dead->data[category]->private.cleanup)
517               (*dead->data[category]->private.cleanup) (dead->data[category]);
518
519             free (dead->data[category]);
520           }
521       free (dead);
522     }
523   archloaded = NULL;
524
525   if (archmapped != NULL)
526     {
527       /* Now toss all the mapping windows, which we know nothing is using any
528          more because we just tossed all the locales that point into them.  */
529
530       assert (archmapped == &headmap);
531       archmapped = NULL;
532       (void) __munmap (headmap.ptr, headmap.len);
533       am = headmap.next;
534       while (am != NULL)
535         {
536           struct archmapped *dead = am;
537           am = am->next;
538           (void) __munmap (dead->ptr, dead->len);
539           free (dead);
540         }
541     }
542 }