]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-misc.c
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / elf / dl-misc.c
CommitLineData
0501d603 1/* Miscellaneous support functions for dynamic linker
d4697bc9 2 Copyright (C) 1997-2014 Free Software Foundation, Inc.
9498096c
UD
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
41bdb6e2
AJ
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.
9498096c
UD
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
41bdb6e2 13 Lesser General Public License for more details.
9498096c 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
9498096c 18
0501d603
UD
19#include <assert.h>
20#include <fcntl.h>
48896b9d 21#include <ldsodefs.h>
1f33d36a 22#include <libc-symbols.h>
b5ba0659 23#include <limits.h>
fc7f617d 24#include <link.h>
9498096c 25#include <stdarg.h>
b5ba0659 26#include <stdlib.h>
9498096c 27#include <string.h>
8193034b 28#include <unistd.h>
e054f494 29#include <stdint.h>
0501d603 30#include <sys/mman.h>
b5ba0659 31#include <sys/param.h>
0501d603 32#include <sys/stat.h>
b5ba0659 33#include <sys/uio.h>
5bbcba0d 34#include <sysdep.h>
eb96ffb0 35#include <_itoa.h>
d5e82754
RM
36#include <dl-writev.h>
37
0501d603 38
0501d603 39/* Read the whole contents of FILE into new mmap'd space with given
40b07f5b
UD
40 protections. *SIZEP gets the size of the file. On error MAP_FAILED
41 is returned. */
0501d603
UD
42
43void *
48896b9d 44internal_function
0501d603
UD
45_dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
46{
40b07f5b 47 void *result = MAP_FAILED;
5763742f 48 struct stat64 st;
554881ef
UD
49 int flags = O_RDONLY;
50#ifdef O_CLOEXEC
51 flags |= O_CLOEXEC;
52#endif
53 int fd = __open (file, flags);
40b07f5b 54 if (fd >= 0)
0501d603 55 {
40b07f5b
UD
56 if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
57 {
58 *sizep = st.st_size;
59
60 /* No need to map the file if it is empty. */
61 if (*sizep != 0)
62 /* Map a copy of the file contents. */
63 result = __mmap (NULL, *sizep, prot,
0501d603 64#ifdef MAP_COPY
40b07f5b 65 MAP_COPY
0501d603 66#else
40b07f5b 67 MAP_PRIVATE
0501d603
UD
68#endif
69#ifdef MAP_FILE
40b07f5b 70 | MAP_FILE
0501d603 71#endif
40b07f5b
UD
72 , fd, 0);
73 }
74 __close (fd);
0501d603 75 }
0501d603
UD
76 return result;
77}
9498096c
UD
78
79
5bbcba0d 80/* Bare-bones printf implementation. This function only knows about
b5ba0659
UD
81 the formats and flags needed and can handle only up to 64 stripes in
82 the output. */
83static void
84_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
9498096c 85{
db2f05ba
RM
86# define NIOVMAX 64
87 struct iovec iov[NIOVMAX];
b5ba0659
UD
88 int niov = 0;
89 pid_t pid = 0;
d94e16c4 90 char pidbuf[12];
9498096c 91
b5ba0659 92 while (*fmt != '\0')
9498096c 93 {
b5ba0659
UD
94 const char *startp = fmt;
95
96 if (tag_p > 0)
97 {
98 /* Generate the tag line once. It consists of the PID and a
99 colon followed by a tab. */
100 if (pid == 0)
101 {
102 char *p;
103 pid = __getpid ();
d94e16c4
UD
104 assert (pid >= 0 && sizeof (pid_t) <= 4);
105 p = _itoa (pid, &pidbuf[10], 10, 0);
b5ba0659 106 while (p > pidbuf)
d94e16c4
UD
107 *--p = ' ';
108 pidbuf[10] = ':';
109 pidbuf[11] = '\t';
b5ba0659
UD
110 }
111
112 /* Append to the output. */
db2f05ba 113 assert (niov < NIOVMAX);
d94e16c4 114 iov[niov].iov_len = 12;
b5ba0659
UD
115 iov[niov++].iov_base = pidbuf;
116
117 /* No more tags until we see the next newline. */
118 tag_p = -1;
119 }
120
121 /* Skip everything except % and \n (if tags are needed). */
122 while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
123 ++fmt;
124
125 /* Append constant string. */
db2f05ba 126 assert (niov < NIOVMAX);
b5ba0659
UD
127 if ((iov[niov].iov_len = fmt - startp) != 0)
128 iov[niov++].iov_base = (char *) startp;
129
130 if (*fmt == '%')
131 {
132 /* It is a format specifier. */
133 char fill = ' ';
134 int width = -1;
37d8b778 135 int prec = -1;
b5ba0659
UD
136#if LONG_MAX != INT_MAX
137 int long_mod = 0;
138#endif
139
140 /* Recognize zero-digit fill flag. */
141 if (*++fmt == '0')
142 {
143 fill = '0';
144 ++fmt;
145 }
146
147 /* See whether with comes from a parameter. Note that no other
148 way to specify the width is implemented. */
149 if (*fmt == '*')
150 {
151 width = va_arg (arg, int);
152 ++fmt;
153 }
154
37d8b778
UD
155 /* Handle precision. */
156 if (*fmt == '.' && fmt[1] == '*')
157 {
158 prec = va_arg (arg, int);
159 fmt += 2;
160 }
161
b5ba0659
UD
162 /* Recognize the l modifier. It is only important on some
163 platforms where long and int have a different size. We
164 can use the same code for size_t. */
165 if (*fmt == 'l' || *fmt == 'Z')
166 {
167#if LONG_MAX != INT_MAX
168 long_mod = 1;
169#endif
170 ++fmt;
171 }
172
173 switch (*fmt)
174 {
175 /* Integer formatting. */
176 case 'u':
177 case 'x':
178 {
179 /* We have to make a difference if long and int have a
180 different size. */
181#if LONG_MAX != INT_MAX
182 unsigned long int num = (long_mod
7b97934b 183 ? va_arg (arg, unsigned long int)
b5ba0659
UD
184 : va_arg (arg, unsigned int));
185#else
186 unsigned long int num = va_arg (arg, unsigned int);
187#endif
188 /* We use alloca() to allocate the buffer with the most
189 pessimistic guess for the size. Using alloca() allows
190 having more than one integer formatting in a call. */
191 char *buf = (char *) alloca (3 * sizeof (unsigned long int));
192 char *endp = &buf[3 * sizeof (unsigned long int)];
9710f75d 193 char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
b5ba0659
UD
194
195 /* Pad to the width the user specified. */
196 if (width != -1)
197 while (endp - cp < width)
198 *--cp = fill;
199
200 iov[niov].iov_base = cp;
201 iov[niov].iov_len = endp - cp;
202 ++niov;
203 }
204 break;
205
206 case 's':
207 /* Get the string argument. */
208 iov[niov].iov_base = va_arg (arg, char *);
209 iov[niov].iov_len = strlen (iov[niov].iov_base);
37d8b778 210 if (prec != -1)
6dd67bd5 211 iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
b5ba0659
UD
212 ++niov;
213 break;
214
cf44e2dd
UD
215 case '%':
216 iov[niov].iov_base = (void *) fmt;
217 iov[niov].iov_len = 1;
218 ++niov;
219 break;
220
b5ba0659
UD
221 default:
222 assert (! "invalid format specifier");
223 }
224 ++fmt;
225 }
226 else if (*fmt == '\n')
227 {
228 /* See whether we have to print a single newline character. */
229 if (fmt == startp)
230 {
231 iov[niov].iov_base = (char *) startp;
232 iov[niov++].iov_len = 1;
233 }
234 else
235 /* No, just add it to the rest of the string. */
236 ++iov[niov - 1].iov_len;
237
238 /* Next line, print a tag again. */
239 tag_p = 1;
240 ++fmt;
241 }
8193034b 242 }
b5ba0659
UD
243
244 /* Finally write the result. */
d5e82754 245 _dl_writev (fd, iov, niov);
8193034b
UD
246}
247
248
b5ba0659 249/* Write to debug file. */
8193034b 250void
b5ba0659 251_dl_debug_printf (const char *fmt, ...)
8193034b 252{
b5ba0659
UD
253 va_list arg;
254
255 va_start (arg, fmt);
dd70526e 256 _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
b5ba0659
UD
257 va_end (arg);
258}
259
260
261/* Write to debug file but don't start with a tag. */
262void
263_dl_debug_printf_c (const char *fmt, ...)
264{
265 va_list arg;
266
267 va_start (arg, fmt);
dd70526e 268 _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
b5ba0659
UD
269 va_end (arg);
270}
271
272
273/* Write the given file descriptor. */
274void
275_dl_dprintf (int fd, const char *fmt, ...)
276{
277 va_list arg;
278
279 va_start (arg, fmt);
280 _dl_debug_vdprintf (fd, 0, fmt, arg);
281 va_end (arg);
9498096c 282}
dd272e57
UD
283
284
285/* Test whether given NAME matches any of the names of the given object. */
286int
287internal_function
871b9158 288_dl_name_match_p (const char *name, const struct link_map *map)
dd272e57
UD
289{
290 if (strcmp (name, map->l_name) == 0)
291 return 1;
292
293 struct libname_list *runp = map->l_libname;
294
295 while (runp != NULL)
296 if (strcmp (name, runp->name) == 0)
297 return 1;
298 else
299 runp = runp->next;
300
301 return 0;
302}
eba0994e
UD
303
304
305unsigned long int
55c4ce68 306internal_function
eba0994e
UD
307_dl_higher_prime_number (unsigned long int n)
308{
309 /* These are primes that are near, but slightly smaller than, a
310 power of two. */
311 static const uint32_t primes[] = {
312 UINT32_C (7),
313 UINT32_C (13),
314 UINT32_C (31),
315 UINT32_C (61),
316 UINT32_C (127),
317 UINT32_C (251),
318 UINT32_C (509),
319 UINT32_C (1021),
320 UINT32_C (2039),
321 UINT32_C (4093),
322 UINT32_C (8191),
323 UINT32_C (16381),
324 UINT32_C (32749),
325 UINT32_C (65521),
326 UINT32_C (131071),
327 UINT32_C (262139),
328 UINT32_C (524287),
329 UINT32_C (1048573),
330 UINT32_C (2097143),
331 UINT32_C (4194301),
332 UINT32_C (8388593),
333 UINT32_C (16777213),
334 UINT32_C (33554393),
335 UINT32_C (67108859),
336 UINT32_C (134217689),
337 UINT32_C (268435399),
338 UINT32_C (536870909),
339 UINT32_C (1073741789),
340 UINT32_C (2147483647),
554881ef 341 /* 4294967291L */
eba0994e
UD
342 UINT32_C (2147483647) + UINT32_C (2147483644)
343 };
344
345 const uint32_t *low = &primes[0];
346 const uint32_t *high = &primes[sizeof (primes) / sizeof (primes[0])];
347
348 while (low != high)
349 {
350 const uint32_t *mid = low + (high - low) / 2;
351 if (n > *mid)
352 low = mid + 1;
353 else
354 high = mid;
355 }
356
357#if 0
358 /* If we've run out of primes, abort. */
359 if (n > *low)
360 {
361 fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
362 abort ();
363 }
364#endif
365
366 return *low;
367}
1f33d36a
PP
368
369/* To support accessing TLS variables from signal handlers, we need an
370 async signal safe memory allocator. These routines are never
371 themselves invoked reentrantly (all calls to them are surrounded by
372 signal masks) but may be invoked concurrently from many threads.
373 The current implementation is not particularly performant nor space
374 efficient, but it will be used rarely (and only in binaries that use
375 dlopen.) The API matches that of malloc() and friends. */
376
377struct __signal_safe_allocator_header
378{
379 size_t size;
380 void *start;
381};
382
063b2acb
PP
383static inline struct __signal_safe_allocator_header *
384ptr_to_signal_safe_allocator_header (void *ptr)
385{
386 return (struct __signal_safe_allocator_header *)
387 ((char *) (ptr) - sizeof (struct __signal_safe_allocator_header));
388}
389
1f33d36a
PP
390void *weak_function
391__signal_safe_memalign (size_t boundary, size_t size)
392{
393 struct __signal_safe_allocator_header *header;
063b2acb 394
1f33d36a
PP
395 if (boundary < sizeof (*header))
396 boundary = sizeof (*header);
397
398 /* Boundary must be a power of two. */
e81c64bb 399 if (!powerof2 (boundary))
1f33d36a
PP
400 return NULL;
401
402 size_t pg = GLRO (dl_pagesize);
403 size_t padded_size;
404 if (boundary <= pg)
405 {
406 /* We'll get a pointer certainly aligned to boundary, so just
407 add one more boundary-sized chunk to hold the header. */
408 padded_size = roundup (size, boundary) + boundary;
409 }
410 else
411 {
412 /* If we want K pages aligned to a J-page boundary, K+J+1 pages
413 contains at least one such region that isn't directly at the start
414 (so we can place the header.) This is wasteful, but you're the one
415 who wanted 64K-aligned TLS. */
416 padded_size = roundup (size, pg) + boundary + pg;
417 }
418
419
420 size_t actual_size = roundup (padded_size, pg);
421 void *actual = mmap (NULL, actual_size, PROT_READ | PROT_WRITE,
422 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
423 if (actual == MAP_FAILED)
424 return NULL;
425
426 if (boundary <= pg)
427 {
428 header = actual + boundary - sizeof (*header);
429 }
430 else
431 {
432 intptr_t actual_pg = ((intptr_t) actual) / pg;
433 intptr_t boundary_pg = boundary / pg;
434 intptr_t start_pg = actual_pg + boundary_pg;
435 start_pg -= start_pg % boundary_pg;
436 if (start_pg > (actual_pg + 1))
437 {
438 int ret = munmap (actual, (start_pg - actual_pg - 1) * pg);
439 assert (ret == 0);
440 actual = (void *) ((start_pg - 1) * pg);
441 }
442 char *start = (void *) (start_pg * pg);
063b2acb 443 header = ptr_to_signal_safe_allocator_header (start);
1f33d36a 444 }
063b2acb 445
1f33d36a
PP
446 header->size = actual_size;
447 header->start = actual;
448 void *ptr = header;
449 ptr += sizeof (*header);
450 if (((intptr_t) ptr) % boundary != 0)
451 _dl_fatal_printf ("__signal_safe_memalign produced incorrect alignment\n");
452 return ptr;
453}
454
455void * weak_function
456__signal_safe_malloc (size_t size)
457{
458 return __signal_safe_memalign (1, size);
459}
460
461void weak_function
462__signal_safe_free (void *ptr)
463{
464 if (ptr == NULL)
465 return;
466
063b2acb
PP
467 struct __signal_safe_allocator_header *header
468 = ptr_to_signal_safe_allocator_header (ptr);
1f33d36a
PP
469 int ret = munmap (header->start, header->size);
470
471 assert (ret == 0);
472}
473
474void * weak_function
475__signal_safe_realloc (void *ptr, size_t size)
476{
477 if (size == 0)
478 {
479 __signal_safe_free (ptr);
480 return NULL;
481 }
482 if (ptr == NULL)
483 return __signal_safe_malloc (size);
484
063b2acb
PP
485 struct __signal_safe_allocator_header *header
486 = ptr_to_signal_safe_allocator_header (ptr);
1f33d36a
PP
487 size_t old_size = header->size;
488 if (old_size - sizeof (*header) >= size)
489 return ptr;
490
491 void *new_ptr = __signal_safe_malloc (size);
492 if (new_ptr == NULL)
493 return NULL;
494
495 memcpy (new_ptr, ptr, old_size);
496 __signal_safe_free (ptr);
497
498 return new_ptr;
499}
500
501void * weak_function
502__signal_safe_calloc (size_t nmemb, size_t size)
503{
504 void *ptr = __signal_safe_malloc (nmemb * size);
505 if (ptr == NULL)
506 return NULL;
507 return memset (ptr, 0, nmemb * size);
508}