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.
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
44 _dl_sysdep_read_whole_file (const char *file
, size_t *sizep
, int prot
)
46 void *result
= MAP_FAILED
;
48 int fd
= __open (file
, O_RDONLY
| O_CLOEXEC
);
51 if (__fxstat64 (_STAT_VER
, fd
, &st
) >= 0)
55 /* No need to map the file if it is empty. */
57 /* Map a copy of the file contents. */
58 result
= __mmap (NULL
, *sizep
, prot
,
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
79 _dl_debug_vdprintf (int fd
, int tag_p
, const char *fmt
, va_list arg
)
82 struct iovec iov
[NIOVMAX
];
89 const char *startp
= fmt
;
93 /* Generate the tag line once. It consists of the PID and a
94 colon followed by a tab. */
99 assert (pid
>= 0 && sizeof (pid_t
) <= 4);
100 p
= _itoa (pid
, &pidbuf
[10], 10, 0);
107 /* Append to the output. */
108 assert (niov
< NIOVMAX
);
109 iov
[niov
].iov_len
= 12;
110 iov
[niov
++].iov_base
= pidbuf
;
112 /* No more tags until we see the next newline. */
116 /* Skip everything except % and \n (if tags are needed). */
117 while (*fmt
!= '\0' && *fmt
!= '%' && (! tag_p
|| *fmt
!= '\n'))
120 /* Append constant string. */
121 assert (niov
< NIOVMAX
);
122 if ((iov
[niov
].iov_len
= fmt
- startp
) != 0)
123 iov
[niov
++].iov_base
= (char *) startp
;
127 /* It is a format specifier. */
131 #if LONG_MAX != INT_MAX
135 /* Recognize zero-digit fill flag. */
142 /* See whether with comes from a parameter. Note that no other
143 way to specify the width is implemented. */
146 width
= va_arg (arg
, int);
150 /* Handle precision. */
151 if (*fmt
== '.' && fmt
[1] == '*')
153 prec
= va_arg (arg
, int);
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')
162 #if LONG_MAX != INT_MAX
170 /* Integer formatting. */
174 /* We have to make a difference if long and int have a
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));
181 unsigned long int num
= va_arg (arg
, unsigned int);
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);
190 /* Pad to the width the user specified. */
192 while (endp
- cp
< width
)
195 iov
[niov
].iov_base
= cp
;
196 iov
[niov
].iov_len
= endp
- cp
;
202 /* Get the string argument. */
203 iov
[niov
].iov_base
= va_arg (arg
, char *);
204 iov
[niov
].iov_len
= strlen (iov
[niov
].iov_base
);
206 iov
[niov
].iov_len
= MIN ((size_t) prec
, iov
[niov
].iov_len
);
211 iov
[niov
].iov_base
= (void *) fmt
;
212 iov
[niov
].iov_len
= 1;
217 assert (! "invalid format specifier");
221 else if (*fmt
== '\n')
223 /* See whether we have to print a single newline character. */
226 iov
[niov
].iov_base
= (char *) startp
;
227 iov
[niov
++].iov_len
= 1;
230 /* No, just add it to the rest of the string. */
231 ++iov
[niov
- 1].iov_len
;
233 /* Next line, print a tag again. */
239 /* Finally write the result. */
240 _dl_writev (fd
, iov
, niov
);
244 /* Write to debug file. */
246 _dl_debug_printf (const char *fmt
, ...)
251 _dl_debug_vdprintf (GLRO(dl_debug_fd
), 1, fmt
, arg
);
256 /* Write to debug file but don't start with a tag. */
258 _dl_debug_printf_c (const char *fmt
, ...)
263 _dl_debug_vdprintf (GLRO(dl_debug_fd
), -1, fmt
, arg
);
268 /* Write the given file descriptor. */
270 _dl_dprintf (int fd
, const char *fmt
, ...)
275 _dl_debug_vdprintf (fd
, 0, fmt
, arg
);
280 /* Test whether given NAME matches any of the names of the given object. */
283 _dl_name_match_p (const char *name
, const struct link_map
*map
)
285 if (strcmp (name
, map
->l_name
) == 0)
288 struct libname_list
*runp
= map
->l_libname
;
291 if (strcmp (name
, runp
->name
) == 0)
302 _dl_higher_prime_number (unsigned long int n
)
304 /* These are primes that are near, but slightly smaller than, a
306 static const uint32_t primes
[] = {
331 UINT32_C (134217689),
332 UINT32_C (268435399),
333 UINT32_C (536870909),
334 UINT32_C (1073741789),
335 UINT32_C (2147483647),
337 UINT32_C (2147483647) + UINT32_C (2147483644)
340 const uint32_t *low
= &primes
[0];
341 const uint32_t *high
= &primes
[sizeof (primes
) / sizeof (primes
[0])];
345 const uint32_t *mid
= low
+ (high
- low
) / 2;
353 /* If we've run out of primes, abort. */
356 fprintf (stderr
, "Cannot find prime bigger than %lu\n", n
);
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. */
370 _dl_strtoul (const char *nptr
, char **endptr
)
373 bool positive
= true;
376 while (*nptr
== ' ' || *nptr
== '\t')
384 else if (*nptr
== '+')
387 if (*nptr
< '0' || *nptr
> '9')
390 *endptr
= (char *) nptr
;
398 if (nptr
[1] == 'x' || nptr
[1] == 'X')
413 if (*nptr
>= '0' && *nptr
<= '0' + max_digit
)
414 digval
= *nptr
- '0';
417 if (*nptr
>= 'a' && *nptr
<= 'f')
418 digval
= *nptr
- 'a' + 10;
419 else if (*nptr
>= 'A' && *nptr
<= 'F')
420 digval
= *nptr
- 'A' + 10;
427 if (result
>= (UINT64_MAX
- digval
) / base
)
430 *endptr
= (char *) nptr
;
439 *endptr
= (char *) nptr
;
441 /* Avoid 64-bit multiplication. */