1 /* Miscellaneous support functions for dynamic linker
2 Copyright (C) 1997-2004, 2006, 2007 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
30 #include <sys/param.h>
34 #include <stdio-common/_itoa.h>
35 #include <bits/libc-lock.h>
38 /* This is the only dl-sysdep.c function that is actually needed at run-time
42 _dl_sysdep_open_zero_fill (void)
44 return __open ("/dev/zero", O_RDONLY);
48 /* Read the whole contents of FILE into new mmap'd space with given
49 protections. *SIZEP gets the size of the file. On error MAP_FAILED
54 _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
56 void *result = MAP_FAILED;
58 int oflags = O_RDONLY;
62 int fd = __open (file, oflags);
65 if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
69 /* No need to map the file if it is empty. */
71 /* Map a copy of the file contents. */
72 result = __mmap (NULL, *sizep, prot,
89 /* Bare-bones printf implementation. This function only knows about
90 the formats and flags needed and can handle only up to 64 stripes in
93 _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
96 struct iovec iov[NIOVMAX];
103 const char *startp = fmt;
107 /* Generate the tag line once. It consists of the PID and a
108 colon followed by a tab. */
113 assert (pid >= 0 && sizeof (pid_t) <= 4);
114 p = _itoa (pid, &pidbuf[10], 10, 0);
121 /* Append to the output. */
122 assert (niov < NIOVMAX);
123 iov[niov].iov_len = 12;
124 iov[niov++].iov_base = pidbuf;
126 /* No more tags until we see the next newline. */
130 /* Skip everything except % and \n (if tags are needed). */
131 while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
134 /* Append constant string. */
135 assert (niov < NIOVMAX);
136 if ((iov[niov].iov_len = fmt - startp) != 0)
137 iov[niov++].iov_base = (char *) startp;
141 /* It is a format specifier. */
145 #if LONG_MAX != INT_MAX
149 /* Recognize zero-digit fill flag. */
156 /* See whether with comes from a parameter. Note that no other
157 way to specify the width is implemented. */
160 width = va_arg (arg, int);
164 /* Handle precision. */
165 if (*fmt == '.' && fmt[1] == '*')
167 prec = va_arg (arg, int);
171 /* Recognize the l modifier. It is only important on some
172 platforms where long and int have a different size. We
173 can use the same code for size_t. */
174 if (*fmt == 'l' || *fmt == 'Z')
176 #if LONG_MAX != INT_MAX
184 /* Integer formatting. */
188 /* We have to make a difference if long and int have a
190 #if LONG_MAX != INT_MAX
191 unsigned long int num = (long_mod
192 ? va_arg (arg, unsigned long int)
193 : va_arg (arg, unsigned int));
195 unsigned long int num = va_arg (arg, unsigned int);
197 /* We use alloca() to allocate the buffer with the most
198 pessimistic guess for the size. Using alloca() allows
199 having more than one integer formatting in a call. */
200 char *buf = (char *) alloca (3 * sizeof (unsigned long int));
201 char *endp = &buf[3 * sizeof (unsigned long int)];
202 char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
204 /* Pad to the width the user specified. */
206 while (endp - cp < width)
209 iov[niov].iov_base = cp;
210 iov[niov].iov_len = endp - cp;
216 /* Get the string argument. */
217 iov[niov].iov_base = va_arg (arg, char *);
218 iov[niov].iov_len = strlen (iov[niov].iov_base);
220 iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
225 iov[niov].iov_base = (void *) fmt;
226 iov[niov].iov_len = 1;
231 assert (! "invalid format specifier");
235 else if (*fmt == '\n')
237 /* See whether we have to print a single newline character. */
240 iov[niov].iov_base = (char *) startp;
241 iov[niov++].iov_len = 1;
244 /* No, just add it to the rest of the string. */
245 ++iov[niov - 1].iov_len;
247 /* Next line, print a tag again. */
253 /* Finally write the result. */
254 #ifdef HAVE_INLINED_SYSCALLS
255 INTERNAL_SYSCALL_DECL (err);
256 INTERNAL_SYSCALL (writev, err, 3, fd, &iov, niov);
257 #elif RTLD_PRIVATE_ERRNO
258 /* We have to take this lock just to be sure we don't clobber the private
259 errno when it's being used by another thread that cares about it.
260 Yet we must be sure not to try calling the lock functions before
261 the thread library is fully initialized. */
262 if (__builtin_expect (INTUSE (_dl_starting_up), 0))
263 __writev (fd, iov, niov);
266 __rtld_lock_lock_recursive (GL(dl_load_lock));
267 __writev (fd, iov, niov);
268 __rtld_lock_unlock_recursive (GL(dl_load_lock));
271 __writev (fd, iov, niov);
276 /* Write to debug file. */
278 _dl_debug_printf (const char *fmt, ...)
283 _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
288 /* Write to debug file but don't start with a tag. */
290 _dl_debug_printf_c (const char *fmt, ...)
295 _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
300 /* Write the given file descriptor. */
302 _dl_dprintf (int fd, const char *fmt, ...)
307 _dl_debug_vdprintf (fd, 0, fmt, arg);
312 /* Test whether given NAME matches any of the names of the given object. */
315 _dl_name_match_p (const char *name, const struct link_map *map)
317 if (strcmp (name, map->l_name) == 0)
320 struct libname_list *runp = map->l_libname;
323 if (strcmp (name, runp->name) == 0)