Cleanup compile warnings.
[glibc.git] / elf / dl-misc.c
blobe5c76a75a0b33f939af62c60a5df12c6d7d91951
1 /* Miscellaneous support functions for dynamic linker
2 Copyright (C) 1997-2013 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 #include <assert.h>
20 #include <fcntl.h>
21 #include <ldsodefs.h>
22 #include <libc-symbols.h>
23 #include <limits.h>
24 #include <link.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <stdint.h>
30 #include <sys/mman.h>
31 #include <sys/param.h>
32 #include <sys/stat.h>
33 #include <sys/uio.h>
34 #include <sysdep.h>
35 #include <_itoa.h>
36 #include <dl-writev.h>
39 /* Read the whole contents of FILE into new mmap'd space with given
40 protections. *SIZEP gets the size of the file. On error MAP_FAILED
41 is returned. */
43 void *
44 internal_function
45 _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
47 void *result = MAP_FAILED;
48 struct stat64 st;
49 int flags = O_RDONLY;
50 #ifdef O_CLOEXEC
51 flags |= O_CLOEXEC;
52 #endif
53 int fd = __open (file, flags);
54 if (fd >= 0)
56 if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
58 *sizep = st.st_size;
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,
64 #ifdef MAP_COPY
65 MAP_COPY
66 #else
67 MAP_PRIVATE
68 #endif
69 #ifdef MAP_FILE
70 | MAP_FILE
71 #endif
72 , fd, 0);
74 __close (fd);
76 return result;
80 /* Bare-bones printf implementation. This function only knows about
81 the formats and flags needed and can handle only up to 64 stripes in
82 the output. */
83 static void
84 _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
86 # define NIOVMAX 64
87 struct iovec iov[NIOVMAX];
88 int niov = 0;
89 pid_t pid = 0;
90 char pidbuf[12];
92 while (*fmt != '\0')
94 const char *startp = fmt;
96 if (tag_p > 0)
98 /* Generate the tag line once. It consists of the PID and a
99 colon followed by a tab. */
100 if (pid == 0)
102 char *p;
103 pid = __getpid ();
104 assert (pid >= 0 && sizeof (pid_t) <= 4);
105 p = _itoa (pid, &pidbuf[10], 10, 0);
106 while (p > pidbuf)
107 *--p = ' ';
108 pidbuf[10] = ':';
109 pidbuf[11] = '\t';
112 /* Append to the output. */
113 assert (niov < NIOVMAX);
114 iov[niov].iov_len = 12;
115 iov[niov++].iov_base = pidbuf;
117 /* No more tags until we see the next newline. */
118 tag_p = -1;
121 /* Skip everything except % and \n (if tags are needed). */
122 while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
123 ++fmt;
125 /* Append constant string. */
126 assert (niov < NIOVMAX);
127 if ((iov[niov].iov_len = fmt - startp) != 0)
128 iov[niov++].iov_base = (char *) startp;
130 if (*fmt == '%')
132 /* It is a format specifier. */
133 char fill = ' ';
134 int width = -1;
135 int prec = -1;
136 #if LONG_MAX != INT_MAX
137 int long_mod = 0;
138 #endif
140 /* Recognize zero-digit fill flag. */
141 if (*++fmt == '0')
143 fill = '0';
144 ++fmt;
147 /* See whether with comes from a parameter. Note that no other
148 way to specify the width is implemented. */
149 if (*fmt == '*')
151 width = va_arg (arg, int);
152 ++fmt;
155 /* Handle precision. */
156 if (*fmt == '.' && fmt[1] == '*')
158 prec = va_arg (arg, int);
159 fmt += 2;
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')
167 #if LONG_MAX != INT_MAX
168 long_mod = 1;
169 #endif
170 ++fmt;
173 switch (*fmt)
175 /* Integer formatting. */
176 case 'u':
177 case 'x':
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
183 ? va_arg (arg, unsigned long int)
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)];
193 char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
195 /* Pad to the width the user specified. */
196 if (width != -1)
197 while (endp - cp < width)
198 *--cp = fill;
200 iov[niov].iov_base = cp;
201 iov[niov].iov_len = endp - cp;
202 ++niov;
204 break;
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);
210 if (prec != -1)
211 iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
212 ++niov;
213 break;
215 case '%':
216 iov[niov].iov_base = (void *) fmt;
217 iov[niov].iov_len = 1;
218 ++niov;
219 break;
221 default:
222 assert (! "invalid format specifier");
224 ++fmt;
226 else if (*fmt == '\n')
228 /* See whether we have to print a single newline character. */
229 if (fmt == startp)
231 iov[niov].iov_base = (char *) startp;
232 iov[niov++].iov_len = 1;
234 else
235 /* No, just add it to the rest of the string. */
236 ++iov[niov - 1].iov_len;
238 /* Next line, print a tag again. */
239 tag_p = 1;
240 ++fmt;
244 /* Finally write the result. */
245 _dl_writev (fd, iov, niov);
249 /* Write to debug file. */
250 void
251 _dl_debug_printf (const char *fmt, ...)
253 va_list arg;
255 va_start (arg, fmt);
256 _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
257 va_end (arg);
261 /* Write to debug file but don't start with a tag. */
262 void
263 _dl_debug_printf_c (const char *fmt, ...)
265 va_list arg;
267 va_start (arg, fmt);
268 _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
269 va_end (arg);
273 /* Write the given file descriptor. */
274 void
275 _dl_dprintf (int fd, const char *fmt, ...)
277 va_list arg;
279 va_start (arg, fmt);
280 _dl_debug_vdprintf (fd, 0, fmt, arg);
281 va_end (arg);
285 /* Test whether given NAME matches any of the names of the given object. */
287 internal_function
288 _dl_name_match_p (const char *name, const struct link_map *map)
290 if (strcmp (name, map->l_name) == 0)
291 return 1;
293 struct libname_list *runp = map->l_libname;
295 while (runp != NULL)
296 if (strcmp (name, runp->name) == 0)
297 return 1;
298 else
299 runp = runp->next;
301 return 0;
305 unsigned long int
306 internal_function
307 _dl_higher_prime_number (unsigned long int n)
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),
341 /* 4294967291L */
342 UINT32_C (2147483647) + UINT32_C (2147483644)
345 const uint32_t *low = &primes[0];
346 const uint32_t *high = &primes[sizeof (primes) / sizeof (primes[0])];
348 while (low != high)
350 const uint32_t *mid = low + (high - low) / 2;
351 if (n > *mid)
352 low = mid + 1;
353 else
354 high = mid;
357 #if 0
358 /* If we've run out of primes, abort. */
359 if (n > *low)
361 fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
362 abort ();
364 #endif
366 return *low;
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. */
377 struct __signal_safe_allocator_header
379 size_t size;
380 void *start;
383 static inline struct __signal_safe_allocator_header *
384 ptr_to_signal_safe_allocator_header (void *ptr)
386 return (struct __signal_safe_allocator_header *)
387 ((char *) (ptr) - sizeof (struct __signal_safe_allocator_header));
390 void *weak_function
391 __signal_safe_memalign (size_t boundary, size_t size)
393 struct __signal_safe_allocator_header *header;
395 if (boundary < sizeof (*header))
396 boundary = sizeof (*header);
398 /* Boundary must be a power of two. */
399 if ((boundary & (boundary - 1)) == 0)
400 return NULL;
402 size_t pg = GLRO (dl_pagesize);
403 size_t padded_size;
404 if (boundary <= pg)
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;
410 else
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;
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;
426 if (boundary <= pg)
428 header = actual + boundary - sizeof (*header);
430 else
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))
438 int ret = munmap (actual, (start_pg - actual_pg - 1) * pg);
439 assert (ret == 0);
440 actual = (void *) ((start_pg - 1) * pg);
442 char *start = (void *) (start_pg * pg);
443 header = ptr_to_signal_safe_allocator_header (start);
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;
455 void * weak_function
456 __signal_safe_malloc (size_t size)
458 return __signal_safe_memalign (1, size);
461 void weak_function
462 __signal_safe_free (void *ptr)
464 if (ptr == NULL)
465 return;
467 struct __signal_safe_allocator_header *header
468 = ptr_to_signal_safe_allocator_header (ptr);
469 int ret = munmap (header->start, header->size);
471 assert (ret == 0);
474 void * weak_function
475 __signal_safe_realloc (void *ptr, size_t size)
477 if (size == 0)
479 __signal_safe_free (ptr);
480 return NULL;
482 if (ptr == NULL)
483 return __signal_safe_malloc (size);
485 struct __signal_safe_allocator_header *header
486 = ptr_to_signal_safe_allocator_header (ptr);
487 size_t old_size = header->size;
488 if (old_size - sizeof (*header) >= size)
489 return ptr;
491 void *new_ptr = __signal_safe_malloc (size);
492 if (new_ptr == NULL)
493 return NULL;
495 memcpy (new_ptr, ptr, old_size);
496 __signal_safe_free (ptr);
498 return new_ptr;
501 void * weak_function
502 __signal_safe_calloc (size_t nmemb, size_t size)
504 void *ptr = __signal_safe_malloc (nmemb * size);
505 if (ptr == NULL)
506 return NULL;
507 return memset (ptr, 0, nmemb * size);