Update copyright dates not handled by scripts/update-copyrights.
[platform/upstream/glibc.git] / elf / dl-misc.c
1 /* Miscellaneous support functions for dynamic linker
2    Copyright (C) 1997-2019 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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <assert.h>
20 #include <fcntl.h>
21 #include <ldsodefs.h>
22 #include <limits.h>
23 #include <link.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <stdint.h>
29 #include <sys/mman.h>
30 #include <sys/param.h>
31 #include <sys/stat.h>
32 #include <sys/uio.h>
33 #include <sysdep.h>
34 #include <_itoa.h>
35 #include <dl-writev.h>
36 #include <not-cancel.h>
37
38 /* Read the whole contents of FILE into new mmap'd space with given
39    protections.  *SIZEP gets the size of the file.  On error MAP_FAILED
40    is returned.  */
41
42 void *
43 _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
44 {
45   void *result = MAP_FAILED;
46   struct stat64 st;
47   int fd = __open64_nocancel (file, O_RDONLY | O_CLOEXEC);
48   if (fd >= 0)
49     {
50       if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
51         {
52           *sizep = st.st_size;
53
54           /* No need to map the file if it is empty.  */
55           if (*sizep != 0)
56             /* Map a copy of the file contents.  */
57             result = __mmap (NULL, *sizep, prot,
58 #ifdef MAP_COPY
59                              MAP_COPY
60 #else
61                              MAP_PRIVATE
62 #endif
63 #ifdef MAP_FILE
64                              | MAP_FILE
65 #endif
66                              , fd, 0);
67         }
68       __close_nocancel (fd);
69     }
70   return result;
71 }
72
73
74 /* Bare-bones printf implementation.  This function only knows about
75    the formats and flags needed and can handle only up to 64 stripes in
76    the output.  */
77 static void
78 _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
79 {
80 # define NIOVMAX 64
81   struct iovec iov[NIOVMAX];
82   int niov = 0;
83   pid_t pid = 0;
84   char pidbuf[12];
85
86   while (*fmt != '\0')
87     {
88       const char *startp = fmt;
89
90       if (tag_p > 0)
91         {
92           /* Generate the tag line once.  It consists of the PID and a
93              colon followed by a tab.  */
94           if (pid == 0)
95             {
96               char *p;
97               pid = __getpid ();
98               assert (pid >= 0 && sizeof (pid_t) <= 4);
99               p = _itoa (pid, &pidbuf[10], 10, 0);
100               while (p > pidbuf)
101                 *--p = ' ';
102               pidbuf[10] = ':';
103               pidbuf[11] = '\t';
104             }
105
106           /* Append to the output.  */
107           assert (niov < NIOVMAX);
108           iov[niov].iov_len = 12;
109           iov[niov++].iov_base = pidbuf;
110
111           /* No more tags until we see the next newline.  */
112           tag_p = -1;
113         }
114
115       /* Skip everything except % and \n (if tags are needed).  */
116       while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
117         ++fmt;
118
119       /* Append constant string.  */
120       assert (niov < NIOVMAX);
121       if ((iov[niov].iov_len = fmt - startp) != 0)
122         iov[niov++].iov_base = (char *) startp;
123
124       if (*fmt == '%')
125         {
126           /* It is a format specifier.  */
127           char fill = ' ';
128           int width = -1;
129           int prec = -1;
130 #if LONG_MAX != INT_MAX
131           int long_mod = 0;
132 #endif
133
134           /* Recognize zero-digit fill flag.  */
135           if (*++fmt == '0')
136             {
137               fill = '0';
138               ++fmt;
139             }
140
141           /* See whether with comes from a parameter.  Note that no other
142              way to specify the width is implemented.  */
143           if (*fmt == '*')
144             {
145               width = va_arg (arg, int);
146               ++fmt;
147             }
148
149           /* Handle precision.  */
150           if (*fmt == '.' && fmt[1] == '*')
151             {
152               prec = va_arg (arg, int);
153               fmt += 2;
154             }
155
156           /* Recognize the l modifier.  It is only important on some
157              platforms where long and int have a different size.  We
158              can use the same code for size_t.  */
159           if (*fmt == 'l' || *fmt == 'Z')
160             {
161 #if LONG_MAX != INT_MAX
162               long_mod = 1;
163 #endif
164               ++fmt;
165             }
166
167           switch (*fmt)
168             {
169               /* Integer formatting.  */
170             case 'u':
171             case 'x':
172               {
173                 /* We have to make a difference if long and int have a
174                    different size.  */
175 #if LONG_MAX != INT_MAX
176                 unsigned long int num = (long_mod
177                                          ? va_arg (arg, unsigned long int)
178                                          : va_arg (arg, unsigned int));
179 #else
180                 unsigned long int num = va_arg (arg, unsigned int);
181 #endif
182                 /* We use alloca() to allocate the buffer with the most
183                    pessimistic guess for the size.  Using alloca() allows
184                    having more than one integer formatting in a call.  */
185                 char *buf = (char *) alloca (3 * sizeof (unsigned long int));
186                 char *endp = &buf[3 * sizeof (unsigned long int)];
187                 char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
188
189                 /* Pad to the width the user specified.  */
190                 if (width != -1)
191                   while (endp - cp < width)
192                     *--cp = fill;
193
194                 iov[niov].iov_base = cp;
195                 iov[niov].iov_len = endp - cp;
196                 ++niov;
197               }
198               break;
199
200             case 's':
201               /* Get the string argument.  */
202               iov[niov].iov_base = va_arg (arg, char *);
203               iov[niov].iov_len = strlen (iov[niov].iov_base);
204               if (prec != -1)
205                 iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
206               ++niov;
207               break;
208
209             case '%':
210               iov[niov].iov_base = (void *) fmt;
211               iov[niov].iov_len = 1;
212               ++niov;
213               break;
214
215             default:
216               assert (! "invalid format specifier");
217             }
218           ++fmt;
219         }
220       else if (*fmt == '\n')
221         {
222           /* See whether we have to print a single newline character.  */
223           if (fmt == startp)
224             {
225               iov[niov].iov_base = (char *) startp;
226               iov[niov++].iov_len = 1;
227             }
228           else
229             /* No, just add it to the rest of the string.  */
230             ++iov[niov - 1].iov_len;
231
232           /* Next line, print a tag again.  */
233           tag_p = 1;
234           ++fmt;
235         }
236     }
237
238   /* Finally write the result.  */
239   _dl_writev (fd, iov, niov);
240 }
241
242
243 /* Write to debug file.  */
244 void
245 _dl_debug_printf (const char *fmt, ...)
246 {
247   va_list arg;
248
249   va_start (arg, fmt);
250   _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
251   va_end (arg);
252 }
253
254
255 /* Write to debug file but don't start with a tag.  */
256 void
257 _dl_debug_printf_c (const char *fmt, ...)
258 {
259   va_list arg;
260
261   va_start (arg, fmt);
262   _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
263   va_end (arg);
264 }
265
266
267 /* Write the given file descriptor.  */
268 void
269 _dl_dprintf (int fd, const char *fmt, ...)
270 {
271   va_list arg;
272
273   va_start (arg, fmt);
274   _dl_debug_vdprintf (fd, 0, fmt, arg);
275   va_end (arg);
276 }
277
278
279 /* Test whether given NAME matches any of the names of the given object.  */
280 int
281 _dl_name_match_p (const char *name, const struct link_map *map)
282 {
283   if (strcmp (name, map->l_name) == 0)
284     return 1;
285
286   struct libname_list *runp = map->l_libname;
287
288   while (runp != NULL)
289     if (strcmp (name, runp->name) == 0)
290       return 1;
291     else
292       runp = runp->next;
293
294   return 0;
295 }
296
297
298 unsigned long int
299 _dl_higher_prime_number (unsigned long int n)
300 {
301   /* These are primes that are near, but slightly smaller than, a
302      power of two.  */
303   static const uint32_t primes[] = {
304     UINT32_C (7),
305     UINT32_C (13),
306     UINT32_C (31),
307     UINT32_C (61),
308     UINT32_C (127),
309     UINT32_C (251),
310     UINT32_C (509),
311     UINT32_C (1021),
312     UINT32_C (2039),
313     UINT32_C (4093),
314     UINT32_C (8191),
315     UINT32_C (16381),
316     UINT32_C (32749),
317     UINT32_C (65521),
318     UINT32_C (131071),
319     UINT32_C (262139),
320     UINT32_C (524287),
321     UINT32_C (1048573),
322     UINT32_C (2097143),
323     UINT32_C (4194301),
324     UINT32_C (8388593),
325     UINT32_C (16777213),
326     UINT32_C (33554393),
327     UINT32_C (67108859),
328     UINT32_C (134217689),
329     UINT32_C (268435399),
330     UINT32_C (536870909),
331     UINT32_C (1073741789),
332     UINT32_C (2147483647),
333                                        /* 4294967291L */
334     UINT32_C (2147483647) + UINT32_C (2147483644)
335   };
336
337   const uint32_t *low = &primes[0];
338   const uint32_t *high = &primes[sizeof (primes) / sizeof (primes[0])];
339
340   while (low != high)
341     {
342       const uint32_t *mid = low + (high - low) / 2;
343       if (n > *mid)
344        low = mid + 1;
345       else
346        high = mid;
347     }
348
349 #if 0
350   /* If we've run out of primes, abort.  */
351   if (n > *low)
352     {
353       fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
354       abort ();
355     }
356 #endif
357
358   return *low;
359 }
360
361 /* A stripped down strtoul-like implementation for very early use.  It
362    does not set errno if the result is outside bounds because it may get
363    called before errno may have been set up.  */
364
365 uint64_t
366 _dl_strtoul (const char *nptr, char **endptr)
367 {
368   uint64_t result = 0;
369   bool positive = true;
370   unsigned max_digit;
371
372   while (*nptr == ' ' || *nptr == '\t')
373     ++nptr;
374
375   if (*nptr == '-')
376     {
377       positive = false;
378       ++nptr;
379     }
380   else if (*nptr == '+')
381     ++nptr;
382
383   if (*nptr < '0' || *nptr > '9')
384     {
385       if (endptr != NULL)
386         *endptr = (char *) nptr;
387       return 0UL;
388     }
389
390   int base = 10;
391   max_digit = 9;
392   if (*nptr == '0')
393     {
394       if (nptr[1] == 'x' || nptr[1] == 'X')
395         {
396           base = 16;
397           nptr += 2;
398         }
399       else
400         {
401           base = 8;
402           max_digit = 7;
403         }
404     }
405
406   while (1)
407     {
408       int digval;
409       if (*nptr >= '0' && *nptr <= '0' + max_digit)
410         digval = *nptr - '0';
411       else if (base == 16)
412         {
413           if (*nptr >= 'a' && *nptr <= 'f')
414             digval = *nptr - 'a' + 10;
415           else if (*nptr >= 'A' && *nptr <= 'F')
416             digval = *nptr - 'A' + 10;
417           else
418             break;
419         }
420       else
421         break;
422
423       if (result >= (UINT64_MAX - digval) / base)
424         {
425           if (endptr != NULL)
426             *endptr = (char *) nptr;
427           return UINT64_MAX;
428         }
429       result *= base;
430       result += digval;
431       ++nptr;
432     }
433
434   if (endptr != NULL)
435     *endptr = (char *) nptr;
436
437   /* Avoid 64-bit multiplication.  */
438   if (!positive)
439     result = -result;
440
441   return result;
442 }