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