Override elf_nacl.xr linker script so that libc_pic.os links correctly
[glibc/nacl-glibc.git] / elf / dl-misc.c
blob9f11e750927e0b7ed9c5de0d3b2d37852799a6a2
1 /* Miscellaneous support functions for dynamic linker
2 Copyright (C) 1997-2002, 2003, 2004, 2006 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
18 02111-1307 USA. */
20 #include <assert.h>
21 #include <fcntl.h>
22 #include <ldsodefs.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 <sys/mman.h>
30 #include <sys/param.h>
31 #include <sys/stat.h>
32 #include <sys/uio.h>
33 #include <sysdep.h>
34 #include <stdio-common/_itoa.h>
35 #include <bits/libc-lock.h>
37 #ifndef MAP_ANON
38 /* This is the only dl-sysdep.c function that is actually needed at run-time
39 by _dl_map_object. */
41 int
42 _dl_sysdep_open_zero_fill (void)
44 return __open ("/dev/zero", O_RDONLY);
46 #endif
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
50 is returned. */
52 void *
53 internal_function
54 _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
56 void *result = MAP_FAILED;
57 struct stat64 st;
58 int fd = __open (file, O_RDONLY);
59 if (fd >= 0)
61 if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
63 *sizep = st.st_size;
65 /* No need to map the file if it is empty. */
66 if (*sizep != 0)
67 /* Map a copy of the file contents. */
68 result = __mmap (NULL, *sizep, prot,
69 #ifdef MAP_COPY
70 MAP_COPY
71 #else
72 MAP_PRIVATE
73 #endif
74 #ifdef MAP_FILE
75 | MAP_FILE
76 #endif
77 , fd, 0);
79 __close (fd);
81 return result;
85 /* Bare-bones printf implementation. This function only knows about
86 the formats and flags needed and can handle only up to 64 stripes in
87 the output. */
88 static void
89 _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
91 # define NIOVMAX 64
92 struct iovec iov[NIOVMAX];
93 int niov = 0;
94 pid_t pid = 0;
95 char pidbuf[12];
97 while (*fmt != '\0')
99 const char *startp = fmt;
101 if (tag_p > 0)
103 /* Generate the tag line once. It consists of the PID and a
104 colon followed by a tab. */
105 if (pid == 0)
107 char *p;
108 #if 0
109 pid = __getpid ();
110 assert (pid >= 0 && sizeof (pid_t) <= 4);
111 #endif
112 pid = 1;
113 p = _itoa (pid, &pidbuf[10], 10, 0);
114 while (p > pidbuf)
115 *--p = ' ';
116 pidbuf[10] = ':';
117 pidbuf[11] = '\t';
120 /* Append to the output. */
121 assert (niov < NIOVMAX);
122 iov[niov].iov_len = 12;
123 iov[niov++].iov_base = pidbuf;
125 /* No more tags until we see the next newline. */
126 tag_p = -1;
129 /* Skip everything except % and \n (if tags are needed). */
130 while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
131 ++fmt;
133 /* Append constant string. */
134 assert (niov < NIOVMAX);
135 if ((iov[niov].iov_len = fmt - startp) != 0)
136 iov[niov++].iov_base = (char *) startp;
138 if (*fmt == '%')
140 /* It is a format specifier. */
141 char fill = ' ';
142 int width = -1;
143 int prec = -1;
144 #if LONG_MAX != INT_MAX
145 int long_mod = 0;
146 #endif
148 /* Recognize zero-digit fill flag. */
149 if (*++fmt == '0')
151 fill = '0';
152 ++fmt;
155 /* See whether with comes from a parameter. Note that no other
156 way to specify the width is implemented. */
157 if (*fmt == '*')
159 width = va_arg (arg, int);
160 ++fmt;
163 /* Handle precision. */
164 if (*fmt == '.' && fmt[1] == '*')
166 prec = va_arg (arg, int);
167 fmt += 2;
170 /* Recognize the l modifier. It is only important on some
171 platforms where long and int have a different size. We
172 can use the same code for size_t. */
173 if (*fmt == 'l' || *fmt == 'Z')
175 #if LONG_MAX != INT_MAX
176 long_mod = 1;
177 #endif
178 ++fmt;
181 switch (*fmt)
183 /* Integer formatting. */
184 case 'u':
185 case 'x':
187 /* We have to make a difference if long and int have a
188 different size. */
189 #if LONG_MAX != INT_MAX
190 unsigned long int num = (long_mod
191 ? va_arg (arg, unsigned long int)
192 : va_arg (arg, unsigned int));
193 #else
194 unsigned long int num = va_arg (arg, unsigned int);
195 #endif
196 /* We use alloca() to allocate the buffer with the most
197 pessimistic guess for the size. Using alloca() allows
198 having more than one integer formatting in a call. */
199 char *buf = (char *) alloca (3 * sizeof (unsigned long int));
200 char *endp = &buf[3 * sizeof (unsigned long int)];
201 char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
203 /* Pad to the width the user specified. */
204 if (width != -1)
205 while (endp - cp < width)
206 *--cp = fill;
208 iov[niov].iov_base = cp;
209 iov[niov].iov_len = endp - cp;
210 ++niov;
212 break;
214 case 's':
215 /* Get the string argument. */
216 iov[niov].iov_base = va_arg (arg, char *);
217 iov[niov].iov_len = strlen (iov[niov].iov_base);
218 if (prec != -1)
219 iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
220 ++niov;
221 break;
223 case '%':
224 iov[niov].iov_base = (void *) fmt;
225 iov[niov].iov_len = 1;
226 ++niov;
227 break;
229 default:
230 assert (! "invalid format specifier");
232 ++fmt;
234 else if (*fmt == '\n')
236 /* See whether we have to print a single newline character. */
237 if (fmt == startp)
239 iov[niov].iov_base = (char *) startp;
240 iov[niov++].iov_len = 1;
242 else
243 /* No, just add it to the rest of the string. */
244 ++iov[niov - 1].iov_len;
246 /* Next line, print a tag again. */
247 tag_p = 1;
248 ++fmt;
252 /* Finally write the result. */
253 #if defined(HAVE_INLINED_SYSCALLS) && 0
254 INTERNAL_SYSCALL_DECL (err);
255 INTERNAL_SYSCALL (writev, err, 3, fd, &iov, niov);
256 #elif defined(RTLD_PRIVATE_ERRNO) && 0
257 /* We have to take this lock just to be sure we don't clobber the private
258 errno when it's being used by another thread that cares about it.
259 Yet we must be sure not to try calling the lock functions before
260 the thread library is fully initialized. */
261 if (__builtin_expect (INTUSE (_dl_starting_up), 0))
262 __writev (fd, iov, niov);
263 else
265 __rtld_lock_lock_recursive (GL(dl_load_lock));
266 __writev (fd, iov, niov);
267 __rtld_lock_unlock_recursive (GL(dl_load_lock));
269 #else
270 __writev (fd, iov, niov);
271 #endif
275 /* Write to debug file. */
276 void
277 _dl_debug_printf (const char *fmt, ...)
279 va_list arg;
281 va_start (arg, fmt);
282 _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
283 va_end (arg);
287 /* Write to debug file but don't start with a tag. */
288 void
289 _dl_debug_printf_c (const char *fmt, ...)
291 va_list arg;
293 va_start (arg, fmt);
294 _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
295 va_end (arg);
299 /* Write the given file descriptor. */
300 void
301 _dl_dprintf (int fd, const char *fmt, ...)
303 va_list arg;
305 va_start (arg, fmt);
306 _dl_debug_vdprintf (fd, 0, fmt, arg);
307 va_end (arg);
311 /* Test whether given NAME matches any of the names of the given object. */
313 internal_function
314 _dl_name_match_p (const char *name, const struct link_map *map)
316 if (strcmp (name, map->l_name) == 0)
317 return 1;
319 struct libname_list *runp = map->l_libname;
321 while (runp != NULL)
322 if (strcmp (name, runp->name) == 0)
323 return 1;
324 else
325 runp = runp->next;
327 return 0;