1 /* Miscellaneous support functions for dynamic linker
2 Copyright (C) 1997-2018 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/>. */
30 #include <sys/param.h>
35 #include <dl-writev.h>
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
43 _dl_sysdep_read_whole_file (const char *file
, size_t *sizep
, int prot
)
45 void *result
= MAP_FAILED
;
47 int fd
= __open (file
, O_RDONLY
| O_CLOEXEC
);
50 if (__fxstat64 (_STAT_VER
, fd
, &st
) >= 0)
54 /* No need to map the file if it is empty. */
56 /* Map a copy of the file contents. */
57 result
= __mmap (NULL
, *sizep
, prot
,
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
78 _dl_debug_vdprintf (int fd
, int tag_p
, const char *fmt
, va_list arg
)
81 struct iovec iov
[NIOVMAX
];
88 const char *startp
= fmt
;
92 /* Generate the tag line once. It consists of the PID and a
93 colon followed by a tab. */
98 assert (pid
>= 0 && sizeof (pid_t
) <= 4);
99 p
= _itoa (pid
, &pidbuf
[10], 10, 0);
106 /* Append to the output. */
107 assert (niov
< NIOVMAX
);
108 iov
[niov
].iov_len
= 12;
109 iov
[niov
++].iov_base
= pidbuf
;
111 /* No more tags until we see the next newline. */
115 /* Skip everything except % and \n (if tags are needed). */
116 while (*fmt
!= '\0' && *fmt
!= '%' && (! tag_p
|| *fmt
!= '\n'))
119 /* Append constant string. */
120 assert (niov
< NIOVMAX
);
121 if ((iov
[niov
].iov_len
= fmt
- startp
) != 0)
122 iov
[niov
++].iov_base
= (char *) startp
;
126 /* It is a format specifier. */
130 #if LONG_MAX != INT_MAX
134 /* Recognize zero-digit fill flag. */
141 /* See whether with comes from a parameter. Note that no other
142 way to specify the width is implemented. */
145 width
= va_arg (arg
, int);
149 /* Handle precision. */
150 if (*fmt
== '.' && fmt
[1] == '*')
152 prec
= va_arg (arg
, int);
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')
161 #if LONG_MAX != INT_MAX
169 /* Integer formatting. */
173 /* We have to make a difference if long and int have a
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));
180 unsigned long int num
= va_arg (arg
, unsigned int);
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);
189 /* Pad to the width the user specified. */
191 while (endp
- cp
< width
)
194 iov
[niov
].iov_base
= cp
;
195 iov
[niov
].iov_len
= endp
- cp
;
201 /* Get the string argument. */
202 iov
[niov
].iov_base
= va_arg (arg
, char *);
203 iov
[niov
].iov_len
= strlen (iov
[niov
].iov_base
);
205 iov
[niov
].iov_len
= MIN ((size_t) prec
, iov
[niov
].iov_len
);
210 iov
[niov
].iov_base
= (void *) fmt
;
211 iov
[niov
].iov_len
= 1;
216 assert (! "invalid format specifier");
220 else if (*fmt
== '\n')
222 /* See whether we have to print a single newline character. */
225 iov
[niov
].iov_base
= (char *) startp
;
226 iov
[niov
++].iov_len
= 1;
229 /* No, just add it to the rest of the string. */
230 ++iov
[niov
- 1].iov_len
;
232 /* Next line, print a tag again. */
238 /* Finally write the result. */
239 _dl_writev (fd
, iov
, niov
);
243 /* Write to debug file. */
245 _dl_debug_printf (const char *fmt
, ...)
250 _dl_debug_vdprintf (GLRO(dl_debug_fd
), 1, fmt
, arg
);
255 /* Write to debug file but don't start with a tag. */
257 _dl_debug_printf_c (const char *fmt
, ...)
262 _dl_debug_vdprintf (GLRO(dl_debug_fd
), -1, fmt
, arg
);
267 /* Write the given file descriptor. */
269 _dl_dprintf (int fd
, const char *fmt
, ...)
274 _dl_debug_vdprintf (fd
, 0, fmt
, arg
);
279 /* Test whether given NAME matches any of the names of the given object. */
281 _dl_name_match_p (const char *name
, const struct link_map
*map
)
283 if (strcmp (name
, map
->l_name
) == 0)
286 struct libname_list
*runp
= map
->l_libname
;
289 if (strcmp (name
, runp
->name
) == 0)
299 _dl_higher_prime_number (unsigned long int n
)
301 /* These are primes that are near, but slightly smaller than, a
303 static const uint32_t primes
[] = {
328 UINT32_C (134217689),
329 UINT32_C (268435399),
330 UINT32_C (536870909),
331 UINT32_C (1073741789),
332 UINT32_C (2147483647),
334 UINT32_C (2147483647) + UINT32_C (2147483644)
337 const uint32_t *low
= &primes
[0];
338 const uint32_t *high
= &primes
[sizeof (primes
) / sizeof (primes
[0])];
342 const uint32_t *mid
= low
+ (high
- low
) / 2;
350 /* If we've run out of primes, abort. */
353 fprintf (stderr
, "Cannot find prime bigger than %lu\n", n
);
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. */
366 _dl_strtoul (const char *nptr
, char **endptr
)
369 bool positive
= true;
372 while (*nptr
== ' ' || *nptr
== '\t')
380 else if (*nptr
== '+')
383 if (*nptr
< '0' || *nptr
> '9')
386 *endptr
= (char *) nptr
;
394 if (nptr
[1] == 'x' || nptr
[1] == 'X')
409 if (*nptr
>= '0' && *nptr
<= '0' + max_digit
)
410 digval
= *nptr
- '0';
413 if (*nptr
>= 'a' && *nptr
<= 'f')
414 digval
= *nptr
- 'a' + 10;
415 else if (*nptr
>= 'A' && *nptr
<= 'F')
416 digval
= *nptr
- 'A' + 10;
423 if (result
>= (UINT64_MAX
- digval
) / base
)
426 *endptr
= (char *) nptr
;
435 *endptr
= (char *) nptr
;
437 /* Avoid 64-bit multiplication. */