1 | /* Map in a shared object's segments from the file. |
---|
2 | Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. |
---|
3 | This file is part of the GNU C Library. |
---|
4 | |
---|
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. |
---|
9 | |
---|
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. |
---|
14 | |
---|
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. */ |
---|
19 | |
---|
20 | #include <elf.h> |
---|
21 | #include <errno.h> |
---|
22 | #include <fcntl.h> |
---|
23 | #include <libintl.h> |
---|
24 | #include <stdlib.h> |
---|
25 | #include <stdio.h> |
---|
26 | #include <string.h> |
---|
27 | #include <unistd.h> |
---|
28 | #include <ldsodefs.h> |
---|
29 | #include <sys/mman.h> |
---|
30 | #include <sys/param.h> |
---|
31 | #include <sys/stat.h> |
---|
32 | #include <sys/types.h> |
---|
33 | #include "dynamic-link.h" |
---|
34 | #include <abi-tag.h> |
---|
35 | #include <dl-osinfo.h> |
---|
36 | |
---|
37 | #include <dl-dst.h> |
---|
38 | |
---|
39 | /* On some systems, no flag bits are given to specify file mapping. */ |
---|
40 | #ifndef MAP_FILE |
---|
41 | # define MAP_FILE 0 |
---|
42 | #endif |
---|
43 | |
---|
44 | /* The right way to map in the shared library files is MAP_COPY, which |
---|
45 | makes a virtual copy of the data at the time of the mmap call; this |
---|
46 | guarantees the mapped pages will be consistent even if the file is |
---|
47 | overwritten. Some losing VM systems like Linux's lack MAP_COPY. All we |
---|
48 | get is MAP_PRIVATE, which copies each page when it is modified; this |
---|
49 | means if the file is overwritten, we may at some point get some pages |
---|
50 | from the new version after starting with pages from the old version. */ |
---|
51 | #ifndef MAP_COPY |
---|
52 | # define MAP_COPY MAP_PRIVATE |
---|
53 | #endif |
---|
54 | |
---|
55 | /* Some systems link their relocatable objects for another base address |
---|
56 | than 0. We want to know the base address for these such that we can |
---|
57 | subtract this address from the segment addresses during mapping. |
---|
58 | This results in a more efficient address space usage. Defaults to |
---|
59 | zero for almost all systems. */ |
---|
60 | #ifndef MAP_BASE_ADDR |
---|
61 | # define MAP_BASE_ADDR(l) 0 |
---|
62 | #endif |
---|
63 | |
---|
64 | |
---|
65 | #include <endian.h> |
---|
66 | #if BYTE_ORDER == BIG_ENDIAN |
---|
67 | # define byteorder ELFDATA2MSB |
---|
68 | #elif BYTE_ORDER == LITTLE_ENDIAN |
---|
69 | # define byteorder ELFDATA2LSB |
---|
70 | #else |
---|
71 | # error "Unknown BYTE_ORDER " BYTE_ORDER |
---|
72 | # define byteorder ELFDATANONE |
---|
73 | #endif |
---|
74 | |
---|
75 | #define STRING(x) __STRING (x) |
---|
76 | |
---|
77 | #ifdef MAP_ANON |
---|
78 | /* The fd is not examined when using MAP_ANON. */ |
---|
79 | # define ANONFD -1 |
---|
80 | #else |
---|
81 | int _dl_zerofd = -1; |
---|
82 | # define ANONFD _dl_zerofd |
---|
83 | #endif |
---|
84 | |
---|
85 | /* Handle situations where we have a preferred location in memory for |
---|
86 | the shared objects. */ |
---|
87 | #ifdef ELF_PREFERRED_ADDRESS_DATA |
---|
88 | ELF_PREFERRED_ADDRESS_DATA; |
---|
89 | #endif |
---|
90 | #ifndef ELF_PREFERRED_ADDRESS |
---|
91 | # define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref) |
---|
92 | #endif |
---|
93 | #ifndef ELF_FIXED_ADDRESS |
---|
94 | # define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0) |
---|
95 | #endif |
---|
96 | |
---|
97 | /* Type for the buffer we put the ELF header and hopefully the program |
---|
98 | header. This buffer does not really have to be too large. In most |
---|
99 | cases the program header follows the ELF header directly. If this |
---|
100 | is not the case all bets are off and we can make the header arbitrarily |
---|
101 | large and still won't get it read. This means the only question is |
---|
102 | how large are the ELF and program header combined. The ELF header |
---|
103 | in 64-bit files is 56 bytes long. Each program header entry is again |
---|
104 | 56 bytes long. I.e., even with a file which has 17 program header |
---|
105 | entries we only have to read 1kB. And 17 program header entries is |
---|
106 | plenty, normal files have < 10. If this heuristic should really fail |
---|
107 | for some file the code in `_dl_map_object_from_fd' knows how to |
---|
108 | recover. */ |
---|
109 | struct filebuf |
---|
110 | { |
---|
111 | ssize_t len; |
---|
112 | char buf[1024]; |
---|
113 | }; |
---|
114 | |
---|
115 | size_t _dl_pagesize; |
---|
116 | |
---|
117 | unsigned int _dl_osversion; |
---|
118 | |
---|
119 | int _dl_clktck; |
---|
120 | |
---|
121 | extern const char *_dl_platform; |
---|
122 | extern size_t _dl_platformlen; |
---|
123 | |
---|
124 | /* The object to be initialized first. */ |
---|
125 | struct link_map *_dl_initfirst; |
---|
126 | |
---|
127 | /* This is the decomposed LD_LIBRARY_PATH search path. */ |
---|
128 | static struct r_search_path_struct env_path_list; |
---|
129 | |
---|
130 | /* List of the hardware capabilities we might end up using. */ |
---|
131 | static const struct r_strlenpair *capstr; |
---|
132 | static size_t ncapstr; |
---|
133 | static size_t max_capstrlen; |
---|
134 | |
---|
135 | |
---|
136 | /* Get the generated information about the trusted directories. */ |
---|
137 | #include "trusted-dirs.h" |
---|
138 | |
---|
139 | static const char system_dirs[] = SYSTEM_DIRS; |
---|
140 | static const size_t system_dirs_len[] = |
---|
141 | { |
---|
142 | SYSTEM_DIRS_LEN |
---|
143 | }; |
---|
144 | #define nsystem_dirs_len \ |
---|
145 | (sizeof (system_dirs_len) / sizeof (system_dirs_len[0])) |
---|
146 | |
---|
147 | |
---|
148 | /* Local version of `strdup' function. */ |
---|
149 | static inline char * |
---|
150 | local_strdup (const char *s) |
---|
151 | { |
---|
152 | size_t len = strlen (s) + 1; |
---|
153 | void *new = malloc (len); |
---|
154 | |
---|
155 | if (new == NULL) |
---|
156 | return NULL; |
---|
157 | |
---|
158 | return (char *) memcpy (new, s, len); |
---|
159 | } |
---|
160 | |
---|
161 | |
---|
162 | static size_t |
---|
163 | is_dst (const char *start, const char *name, const char *str, size_t cmplen, |
---|
164 | int is_path, int secure) |
---|
165 | { |
---|
166 | size_t len; |
---|
167 | |
---|
168 | if (strncmp (name, str, cmplen) == 0) |
---|
169 | len = cmplen + 1; |
---|
170 | else if (strncmp (name, str + 1, cmplen - 2) == 0 |
---|
171 | && (name[cmplen - 2] == '\0' || name[cmplen - 2] == '/' |
---|
172 | || (is_path && name[cmplen - 2] == ':'))) |
---|
173 | len = cmplen - 1; |
---|
174 | else |
---|
175 | return 0; |
---|
176 | |
---|
177 | if (__builtin_expect (secure, 0) |
---|
178 | && ((name[len - 1] != '\0' && (!is_path || name[len - 1] != ':')) |
---|
179 | || (name != start + 1 && (!is_path || name[-2] != ':')))) |
---|
180 | return 0; |
---|
181 | |
---|
182 | return len; |
---|
183 | } |
---|
184 | |
---|
185 | |
---|
186 | size_t |
---|
187 | _dl_dst_count (const char *name, int is_path) |
---|
188 | { |
---|
189 | const char *const start = name; |
---|
190 | size_t cnt = 0; |
---|
191 | |
---|
192 | do |
---|
193 | { |
---|
194 | size_t len = 1; |
---|
195 | |
---|
196 | /* $ORIGIN is not expanded for SUID/GUID programs (except if it |
---|
197 | is $ORIGIN alone) and it must always appear first in path. |
---|
198 | |
---|
199 | Note that it is no bug that the string in the second and |
---|
200 | fourth `strncmp' call is longer than the sequence which is |
---|
201 | actually tested. */ |
---|
202 | if ((len = is_dst (start, name + 1, "{ORIGIN}", 8, is_path, |
---|
203 | 0)) != 0 |
---|
204 | || ((len = is_dst (start, name + 1, "{PLATFORM}", 10, is_path, 0)) |
---|
205 | != 0)) |
---|
206 | ++cnt; |
---|
207 | |
---|
208 | name = strchr (name + len, '$'); |
---|
209 | } |
---|
210 | while (name != NULL); |
---|
211 | |
---|
212 | return cnt; |
---|
213 | } |
---|
214 | |
---|
215 | |
---|
216 | char * |
---|
217 | _dl_dst_substitute (struct link_map *l, const char *name, char *result, |
---|
218 | int is_path) |
---|
219 | { |
---|
220 | const char *const start = name; |
---|
221 | char *last_elem, *wp; |
---|
222 | |
---|
223 | /* Now fill the result path. While copying over the string we keep |
---|
224 | track of the start of the last path element. When we come accross |
---|
225 | a DST we copy over the value or (if the value is not available) |
---|
226 | leave the entire path element out. */ |
---|
227 | last_elem = wp = result; |
---|
228 | |
---|
229 | do |
---|
230 | { |
---|
231 | if (__builtin_expect (*name == '$', 0)) |
---|
232 | { |
---|
233 | const char *repl = NULL; |
---|
234 | size_t len = 1; |
---|
235 | |
---|
236 | /* Note that it is no bug that the string in the second and |
---|
237 | fourth `strncmp' call is longer than the sequence which |
---|
238 | is actually tested. */ |
---|
239 | if ((len = is_dst (start, name + 1, "{ORIGIN}", 8, is_path, |
---|
240 | 0)) != 0) |
---|
241 | repl = l->l_origin; |
---|
242 | else if ((len = is_dst (start, name + 1, "{PLATFORM}", 10, is_path, |
---|
243 | 0)) != 0) |
---|
244 | repl = _dl_platform; |
---|
245 | |
---|
246 | if (repl != NULL && repl != (const char *) -1) |
---|
247 | { |
---|
248 | wp = strcpy (wp, repl); |
---|
249 | wp += strlen (repl); |
---|
250 | name += len; |
---|
251 | } |
---|
252 | else if (len > 1) |
---|
253 | { |
---|
254 | /* We cannot use this path element, the value of the |
---|
255 | replacement is unknown. */ |
---|
256 | wp = last_elem; |
---|
257 | name += len; |
---|
258 | while (*name != '\0' && (!is_path || *name != ':')) |
---|
259 | ++name; |
---|
260 | } |
---|
261 | else |
---|
262 | /* No DST we recognize. */ |
---|
263 | *wp++ = *name++; |
---|
264 | } |
---|
265 | else |
---|
266 | { |
---|
267 | *wp++ = *name++; |
---|
268 | if (is_path && *name == ':') |
---|
269 | last_elem = wp; |
---|
270 | } |
---|
271 | } |
---|
272 | while (*name != '\0'); |
---|
273 | |
---|
274 | *wp = '\0'; |
---|
275 | |
---|
276 | return result; |
---|
277 | } |
---|
278 | |
---|
279 | |
---|
280 | /* Return copy of argument with all recognized dynamic string tokens |
---|
281 | ($ORIGIN and $PLATFORM for now) replaced. On some platforms it |
---|
282 | might not be possible to determine the path from which the object |
---|
283 | belonging to the map is loaded. In this case the path element |
---|
284 | containing $ORIGIN is left out. */ |
---|
285 | static char * |
---|
286 | expand_dynamic_string_token (struct link_map *l, const char *s) |
---|
287 | { |
---|
288 | /* We make two runs over the string. First we determine how large the |
---|
289 | resulting string is and then we copy it over. Since this is now |
---|
290 | frequently executed operation we are looking here not for performance |
---|
291 | but rather for code size. */ |
---|
292 | size_t cnt; |
---|
293 | size_t total; |
---|
294 | char *result; |
---|
295 | |
---|
296 | /* Determine the number of DST elements. */ |
---|
297 | cnt = DL_DST_COUNT (s, 1); |
---|
298 | |
---|
299 | /* If we do not have to replace anything simply copy the string. */ |
---|
300 | if (__builtin_expect (cnt, 0) == 0) |
---|
301 | return local_strdup (s); |
---|
302 | |
---|
303 | /* Determine the length of the substituted string. */ |
---|
304 | total = DL_DST_REQUIRED (l, s, strlen (s), cnt); |
---|
305 | |
---|
306 | /* Allocate the necessary memory. */ |
---|
307 | result = (char *) malloc (total + 1); |
---|
308 | if (result == NULL) |
---|
309 | return NULL; |
---|
310 | |
---|
311 | return DL_DST_SUBSTITUTE (l, s, result, 1); |
---|
312 | } |
---|
313 | |
---|
314 | |
---|
315 | /* Add `name' to the list of names for a particular shared object. |
---|
316 | `name' is expected to have been allocated with malloc and will |
---|
317 | be freed if the shared object already has this name. |
---|
318 | Returns false if the object already had this name. */ |
---|
319 | static void |
---|
320 | internal_function |
---|
321 | add_name_to_object (struct link_map *l, const char *name) |
---|
322 | { |
---|
323 | struct libname_list *lnp, *lastp; |
---|
324 | struct libname_list *newname; |
---|
325 | size_t name_len; |
---|
326 | |
---|
327 | lastp = NULL; |
---|
328 | for (lnp = l->l_libname; lnp != NULL; lastp = lnp, lnp = lnp->next) |
---|
329 | if (strcmp (name, lnp->name) == 0) |
---|
330 | return; |
---|
331 | |
---|
332 | name_len = strlen (name) + 1; |
---|
333 | newname = (struct libname_list *) malloc (sizeof *newname + name_len); |
---|
334 | if (newname == NULL) |
---|
335 | { |
---|
336 | /* No more memory. */ |
---|
337 | _dl_signal_error (ENOMEM, name, NULL, N_("cannot allocate name record")); |
---|
338 | return; |
---|
339 | } |
---|
340 | /* The object should have a libname set from _dl_new_object. */ |
---|
341 | assert (lastp != NULL); |
---|
342 | |
---|
343 | newname->name = memcpy (newname + 1, name, name_len); |
---|
344 | newname->next = NULL; |
---|
345 | newname->dont_free = 0; |
---|
346 | lastp->next = newname; |
---|
347 | } |
---|
348 | |
---|
349 | /* All known directories in sorted order. */ |
---|
350 | struct r_search_path_elem *_dl_all_dirs; |
---|
351 | |
---|
352 | /* All directories after startup. */ |
---|
353 | struct r_search_path_elem *_dl_init_all_dirs; |
---|
354 | |
---|
355 | /* Standard search directories. */ |
---|
356 | static struct r_search_path_struct rtld_search_dirs; |
---|
357 | |
---|
358 | static size_t max_dirnamelen; |
---|
359 | |
---|
360 | static inline struct r_search_path_elem ** |
---|
361 | fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep, |
---|
362 | int check_trusted, const char *what, const char *where) |
---|
363 | { |
---|
364 | char *cp; |
---|
365 | size_t nelems = 0; |
---|
366 | |
---|
367 | printf("In fillin_rpath\n"); |
---|
368 | while ((cp = strsep (&rpath, sep)) != NULL) |
---|
369 | { |
---|
370 | struct r_search_path_elem *dirp; |
---|
371 | size_t len = strlen (cp); |
---|
372 | |
---|
373 | /* `strsep' can pass an empty string. This has to be |
---|
374 | interpreted as `use the current directory'. */ |
---|
375 | if (len == 0) |
---|
376 | { |
---|
377 | static const char curwd[] = "./"; |
---|
378 | cp = (char *) curwd; |
---|
379 | } |
---|
380 | |
---|
381 | /* Remove trailing slashes (except for "/"). */ |
---|
382 | while (len > 1 && cp[len - 1] == '/') |
---|
383 | --len; |
---|
384 | |
---|
385 | /* Now add one if there is none so far. */ |
---|
386 | if (len > 0 && cp[len - 1] != '/') |
---|
387 | cp[len++] = '/'; |
---|
388 | |
---|
389 | /* Make sure we don't use untrusted directories if we run SUID. */ |
---|
390 | if (__builtin_expect (check_trusted, 0)) |
---|
391 | { |
---|
392 | const char *trun = system_dirs; |
---|
393 | size_t idx; |
---|
394 | int unsecure = 1; |
---|
395 | |
---|
396 | /* All trusted directories must be complete names. */ |
---|
397 | if (cp[0] == '/') |
---|
398 | { |
---|
399 | for (idx = 0; idx < nsystem_dirs_len; ++idx) |
---|
400 | { |
---|
401 | if (len == system_dirs_len[idx] |
---|
402 | && memcmp (trun, cp, len) == 0) |
---|
403 | { |
---|
404 | /* Found it. */ |
---|
405 | unsecure = 0; |
---|
406 | break; |
---|
407 | } |
---|
408 | |
---|
409 | trun += system_dirs_len[idx] + 1; |
---|
410 | } |
---|
411 | } |
---|
412 | |
---|
413 | if (unsecure) |
---|
414 | /* Simply drop this directory. */ |
---|
415 | continue; |
---|
416 | } |
---|
417 | |
---|
418 | /* See if this directory is already known. */ |
---|
419 | for (dirp = _dl_all_dirs; dirp != NULL; dirp = dirp->next) |
---|
420 | if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0) |
---|
421 | break; |
---|
422 | |
---|
423 | if (dirp != NULL) |
---|
424 | { |
---|
425 | /* It is available, see whether it's on our own list. */ |
---|
426 | size_t cnt; |
---|
427 | for (cnt = 0; cnt < nelems; ++cnt) |
---|
428 | if (result[cnt] == dirp) |
---|
429 | break; |
---|
430 | |
---|
431 | if (cnt == nelems) |
---|
432 | result[nelems++] = dirp; |
---|
433 | } |
---|
434 | else |
---|
435 | { |
---|
436 | size_t cnt; |
---|
437 | enum r_dir_status init_val; |
---|
438 | size_t where_len = where ? strlen (where) + 1 : 0; |
---|
439 | |
---|
440 | /* It's a new directory. Create an entry and add it. */ |
---|
441 | dirp = (struct r_search_path_elem *) |
---|
442 | malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status) |
---|
443 | + where_len + len + 1); |
---|
444 | if (dirp == NULL) |
---|
445 | _dl_signal_error (ENOMEM, NULL, NULL, |
---|
446 | N_("cannot create cache for search path")); |
---|
447 | |
---|
448 | dirp->dirname = ((char *) dirp + sizeof (*dirp) |
---|
449 | + ncapstr * sizeof (enum r_dir_status)); |
---|
450 | *((char *) (memcpy ((char *) dirp->dirname, cp, len) + len)) = '\0'; |
---|
451 | dirp->dirnamelen = len; |
---|
452 | |
---|
453 | if (len > max_dirnamelen) |
---|
454 | max_dirnamelen = len; |
---|
455 | |
---|
456 | /* We have to make sure all the relative directories are |
---|
457 | never ignored. The current directory might change and |
---|
458 | all our saved information would be void. */ |
---|
459 | init_val = cp[0] != '/' ? existing : unknown; |
---|
460 | for (cnt = 0; cnt < ncapstr; ++cnt) |
---|
461 | dirp->status[cnt] = init_val; |
---|
462 | |
---|
463 | dirp->what = what; |
---|
464 | if (__builtin_expect (where != NULL, 1)) |
---|
465 | dirp->where = memcpy ((char *) dirp + sizeof (*dirp) + len + 1 |
---|
466 | + ncapstr * sizeof (enum r_dir_status), |
---|
467 | where, where_len); |
---|
468 | else |
---|
469 | dirp->where = NULL; |
---|
470 | |
---|
471 | dirp->next = _dl_all_dirs; |
---|
472 | _dl_all_dirs = dirp; |
---|
473 | |
---|
474 | /* Put it in the result array. */ |
---|
475 | result[nelems++] = dirp; |
---|
476 | } |
---|
477 | } |
---|
478 | |
---|
479 | /* Terminate the array. */ |
---|
480 | result[nelems] = NULL; |
---|
481 | |
---|
482 | return result; |
---|
483 | } |
---|
484 | |
---|
485 | |
---|
486 | static void |
---|
487 | internal_function |
---|
488 | decompose_rpath (struct r_search_path_struct *sps, |
---|
489 | const char *rpath, struct link_map *l, const char *what) |
---|
490 | { |
---|
491 | /* Make a copy we can work with. */ |
---|
492 | const char *where = l->l_name; |
---|
493 | char *copy; |
---|
494 | char *cp; |
---|
495 | struct r_search_path_elem **result; |
---|
496 | size_t nelems; |
---|
497 | /* Initialize to please the compiler. */ |
---|
498 | const char *errstring = NULL; |
---|
499 | |
---|
500 | /* First see whether we must forget the RUNPATH and RPATH from this |
---|
501 | object. */ |
---|
502 | if (__builtin_expect (_dl_inhibit_rpath != NULL, 0)) |
---|
503 | { |
---|
504 | const char *found = strstr (_dl_inhibit_rpath, where); |
---|
505 | if (found != NULL) |
---|
506 | { |
---|
507 | size_t len = strlen (where); |
---|
508 | if ((found == _dl_inhibit_rpath || found[-1] == ':') |
---|
509 | && (found[len] == '\0' || found[len] == ':')) |
---|
510 | { |
---|
511 | /* This object is on the list of objects for which the |
---|
512 | RUNPATH and RPATH must not be used. */ |
---|
513 | result = (struct r_search_path_elem **) |
---|
514 | malloc (sizeof (*result)); |
---|
515 | if (result == NULL) |
---|
516 | { |
---|
517 | signal_error_cache: |
---|
518 | errstring = N_("cannot create cache for search path"); |
---|
519 | signal_error: |
---|
520 | _dl_signal_error (ENOMEM, NULL, NULL, errstring); |
---|
521 | } |
---|
522 | |
---|
523 | result[0] = NULL; |
---|
524 | |
---|
525 | sps->dirs = result; |
---|
526 | sps->malloced = 1; |
---|
527 | |
---|
528 | return; |
---|
529 | } |
---|
530 | } |
---|
531 | } |
---|
532 | |
---|
533 | /* Make a writable copy. At the same time expand possible dynamic |
---|
534 | string tokens. */ |
---|
535 | copy = expand_dynamic_string_token (l, rpath); |
---|
536 | if (copy == NULL) |
---|
537 | { |
---|
538 | errstring = N_("cannot create RUNPATH/RPATH copy"); |
---|
539 | goto signal_error; |
---|
540 | } |
---|
541 | |
---|
542 | /* Count the number of necessary elements in the result array. */ |
---|
543 | nelems = 0; |
---|
544 | for (cp = copy; *cp != '\0'; ++cp) |
---|
545 | if (*cp == ':') |
---|
546 | ++nelems; |
---|
547 | |
---|
548 | /* Allocate room for the result. NELEMS + 1 is an upper limit for the |
---|
549 | number of necessary entries. */ |
---|
550 | result = (struct r_search_path_elem **) malloc ((nelems + 1 + 1) |
---|
551 | * sizeof (*result)); |
---|
552 | if (result == NULL) |
---|
553 | goto signal_error_cache; |
---|
554 | |
---|
555 | fillin_rpath (copy, result, ":", 0, what, where); |
---|
556 | |
---|
557 | /* Free the copied RPATH string. `fillin_rpath' make own copies if |
---|
558 | necessary. */ |
---|
559 | free (copy); |
---|
560 | |
---|
561 | sps->dirs = result; |
---|
562 | /* The caller will change this value if we haven't used a real malloc. */ |
---|
563 | sps->malloced = 1; |
---|
564 | } |
---|
565 | |
---|
566 | |
---|
567 | void |
---|
568 | internal_function |
---|
569 | _dl_init_paths (const char *llp) |
---|
570 | { |
---|
571 | size_t idx; |
---|
572 | const char *strp; |
---|
573 | struct r_search_path_elem *pelem, **aelem; |
---|
574 | size_t round_size; |
---|
575 | #ifdef SHARED |
---|
576 | struct link_map *l; |
---|
577 | #endif |
---|
578 | /* Initialize to please the compiler. */ |
---|
579 | const char *errstring = NULL; |
---|
580 | |
---|
581 | /* Fill in the information about the application's RPATH and the |
---|
582 | directories addressed by the LD_LIBRARY_PATH environment variable. */ |
---|
583 | |
---|
584 | /* Get the capabilities. */ |
---|
585 | capstr = _dl_important_hwcaps (_dl_platform, _dl_platformlen, |
---|
586 | &ncapstr, &max_capstrlen); |
---|
587 | |
---|
588 | /* First set up the rest of the default search directory entries. */ |
---|
589 | aelem = rtld_search_dirs.dirs = (struct r_search_path_elem **) |
---|
590 | malloc ((nsystem_dirs_len + 1) * sizeof (struct r_search_path_elem *)); |
---|
591 | if (rtld_search_dirs.dirs == NULL) |
---|
592 | { |
---|
593 | errstring = N_("cannot create search path array"); |
---|
594 | signal_error: |
---|
595 | _dl_signal_error (ENOMEM, NULL, NULL, errstring); |
---|
596 | } |
---|
597 | |
---|
598 | round_size = ((2 * sizeof (struct r_search_path_elem) - 1 |
---|
599 | + ncapstr * sizeof (enum r_dir_status)) |
---|
600 | / sizeof (struct r_search_path_elem)); |
---|
601 | |
---|
602 | rtld_search_dirs.dirs[0] = (struct r_search_path_elem *) |
---|
603 | malloc ((sizeof (system_dirs) / sizeof (system_dirs[0])) |
---|
604 | * round_size * sizeof (struct r_search_path_elem)); |
---|
605 | if (rtld_search_dirs.dirs[0] == NULL) |
---|
606 | { |
---|
607 | errstring = N_("cannot create cache for search path"); |
---|
608 | goto signal_error; |
---|
609 | } |
---|
610 | |
---|
611 | rtld_search_dirs.malloced = 0; |
---|
612 | pelem = _dl_all_dirs = rtld_search_dirs.dirs[0]; |
---|
613 | strp = system_dirs; |
---|
614 | idx = 0; |
---|
615 | |
---|
616 | do |
---|
617 | { |
---|
618 | size_t cnt; |
---|
619 | |
---|
620 | *aelem++ = pelem; |
---|
621 | |
---|
622 | pelem->what = "system search path"; |
---|
623 | pelem->where = NULL; |
---|
624 | |
---|
625 | pelem->dirname = strp; |
---|
626 | pelem->dirnamelen = system_dirs_len[idx]; |
---|
627 | strp += system_dirs_len[idx] + 1; |
---|
628 | |
---|
629 | /* System paths must be absolute. */ |
---|
630 | assert (pelem->dirname[0] == '/'); |
---|
631 | for (cnt = 0; cnt < ncapstr; ++cnt) |
---|
632 | pelem->status[cnt] = unknown; |
---|
633 | |
---|
634 | pelem->next = (++idx == nsystem_dirs_len ? NULL : (pelem + round_size)); |
---|
635 | |
---|
636 | pelem += round_size; |
---|
637 | } |
---|
638 | while (idx < nsystem_dirs_len); |
---|
639 | |
---|
640 | max_dirnamelen = SYSTEM_DIRS_MAX_LEN; |
---|
641 | *aelem = NULL; |
---|
642 | |
---|
643 | #ifdef SHARED |
---|
644 | /* This points to the map of the main object. */ |
---|
645 | l = _dl_loaded; |
---|
646 | if (l != NULL) |
---|
647 | { |
---|
648 | assert (l->l_type != lt_loaded); |
---|
649 | |
---|
650 | if (l->l_info[DT_RUNPATH]) |
---|
651 | { |
---|
652 | /* Allocate room for the search path and fill in information |
---|
653 | from RUNPATH. */ |
---|
654 | decompose_rpath (&l->l_runpath_dirs, |
---|
655 | (const void *) (D_PTR (l, l_info[DT_STRTAB]) |
---|
656 | + l->l_info[DT_RUNPATH]->d_un.d_val), |
---|
657 | l, "RUNPATH"); |
---|
658 | |
---|
659 | /* The RPATH is ignored. */ |
---|
660 | l->l_rpath_dirs.dirs = (void *) -1; |
---|
661 | } |
---|
662 | else |
---|
663 | { |
---|
664 | l->l_runpath_dirs.dirs = (void *) -1; |
---|
665 | |
---|
666 | if (l->l_info[DT_RPATH]) |
---|
667 | { |
---|
668 | /* Allocate room for the search path and fill in information |
---|
669 | from RPATH. */ |
---|
670 | decompose_rpath (&l->l_rpath_dirs, |
---|
671 | (const void *) (D_PTR (l, l_info[DT_STRTAB]) |
---|
672 | + l->l_info[DT_RPATH]->d_un.d_val), |
---|
673 | l, "RPATH"); |
---|
674 | l->l_rpath_dirs.malloced = 0; |
---|
675 | } |
---|
676 | else |
---|
677 | l->l_rpath_dirs.dirs = (void *) -1; |
---|
678 | } |
---|
679 | } |
---|
680 | #endif /* SHARED */ |
---|
681 | |
---|
682 | if (llp != NULL && *llp != '\0') |
---|
683 | { |
---|
684 | size_t nllp; |
---|
685 | const char *cp = llp; |
---|
686 | const char *old = llp; |
---|
687 | size_t len = strlen (old) + 1; |
---|
688 | char *new = alloca(len); |
---|
689 | char *llp_tmp; |
---|
690 | |
---|
691 | llp_tmp = memcpy (new, old, len); |
---|
692 | |
---|
693 | /* Decompose the LD_LIBRARY_PATH contents. First determine how many |
---|
694 | elements it has. */ |
---|
695 | nllp = 1; |
---|
696 | while (*cp) |
---|
697 | { |
---|
698 | if (*cp == ':' || *cp == ';') |
---|
699 | ++nllp; |
---|
700 | ++cp; |
---|
701 | } |
---|
702 | |
---|
703 | env_path_list.dirs = (struct r_search_path_elem **) |
---|
704 | malloc ((nllp + 1) * sizeof (struct r_search_path_elem *)); |
---|
705 | if (env_path_list.dirs == NULL) |
---|
706 | { |
---|
707 | errstring = N_("cannot create cache for search path"); |
---|
708 | goto signal_error; |
---|
709 | } |
---|
710 | |
---|
711 | (void) fillin_rpath (llp_tmp, env_path_list.dirs, ":;", |
---|
712 | 0, "LD_LIBRARY_PATH", NULL); |
---|
713 | |
---|
714 | if (env_path_list.dirs[0] == NULL) |
---|
715 | { |
---|
716 | free (env_path_list.dirs); |
---|
717 | env_path_list.dirs = (void *) -1; |
---|
718 | } |
---|
719 | |
---|
720 | env_path_list.malloced = 0; |
---|
721 | } |
---|
722 | else |
---|
723 | env_path_list.dirs = (void *) -1; |
---|
724 | |
---|
725 | /* Remember the last search directory added at startup. */ |
---|
726 | _dl_init_all_dirs = _dl_all_dirs; |
---|
727 | } |
---|
728 | |
---|
729 | |
---|
730 | /* Think twice before changing anything in this function. It is placed |
---|
731 | here and prepared using the `alloca' magic to prevent it from being |
---|
732 | inlined. The function is only called in case of an error. But then |
---|
733 | performance does not count. The function used to be "inlinable" and |
---|
734 | the compiled did so all the time. This increased the code size for |
---|
735 | absolutely no good reason. */ |
---|
736 | static void |
---|
737 | __attribute__ ((noreturn)) |
---|
738 | lose (int code, int fd, const char *name, char *realname, struct link_map *l, |
---|
739 | const char *msg) |
---|
740 | { |
---|
741 | /* The use of `alloca' here looks ridiculous but it helps. The goal |
---|
742 | is to avoid the function from being inlined. There is no official |
---|
743 | way to do this so we use this trick. gcc never inlines functions |
---|
744 | which use `alloca'. */ |
---|
745 | int *a = (int *) alloca (sizeof (int)); |
---|
746 | a[0] = fd; |
---|
747 | /* The file might already be closed. */ |
---|
748 | if (a[0] != -1) |
---|
749 | (void) close (a[0]); |
---|
750 | if (l != NULL) |
---|
751 | { |
---|
752 | /* Remove the stillborn object from the list and free it. */ |
---|
753 | assert (l->l_next == NULL); |
---|
754 | #ifndef SHARED |
---|
755 | if (l->l_prev == NULL) |
---|
756 | /* No other module loaded. */ |
---|
757 | _dl_loaded = NULL; |
---|
758 | else |
---|
759 | #endif |
---|
760 | l->l_prev->l_next = NULL; |
---|
761 | --_dl_nloaded; |
---|
762 | free (l); |
---|
763 | } |
---|
764 | free (realname); |
---|
765 | _dl_signal_error (code, name, NULL, msg); |
---|
766 | } |
---|
767 | |
---|
768 | |
---|
769 | /* Map in the shared object NAME, actually located in REALNAME, and already |
---|
770 | opened on FD. */ |
---|
771 | |
---|
772 | #ifndef EXTERNAL_MAP_FROM_FD |
---|
773 | static |
---|
774 | #endif |
---|
775 | struct link_map * |
---|
776 | _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, |
---|
777 | char *realname, struct link_map *loader, int l_type, |
---|
778 | int mode) |
---|
779 | { |
---|
780 | struct link_map *l = NULL; |
---|
781 | const ElfW(Ehdr) *header; |
---|
782 | const ElfW(Phdr) *phdr; |
---|
783 | const ElfW(Phdr) *ph; |
---|
784 | size_t maplength; |
---|
785 | int type; |
---|
786 | struct stat64 st; |
---|
787 | /* Initialize to keep the compiler happy. */ |
---|
788 | const char *errstring = NULL; |
---|
789 | int errval = 0; |
---|
790 | |
---|
791 | /* Get file information. */ |
---|
792 | if (__builtin_expect (fstat64 (fd, &st) < 0, 0)) |
---|
793 | { |
---|
794 | errstring = N_("cannot stat shared object"); |
---|
795 | call_lose_errno: |
---|
796 | errval = errno; |
---|
797 | call_lose: |
---|
798 | fprintf (stderr, "%s\n", errstring); |
---|
799 | lose (errval, fd, name, realname, l, errstring); |
---|
800 | } |
---|
801 | |
---|
802 | /* Look again to see if the real name matched another already loaded. */ |
---|
803 | for (l = _dl_loaded; l; l = l->l_next) |
---|
804 | if (l->l_ino == st.st_ino && l->l_dev == st.st_dev) |
---|
805 | { |
---|
806 | /* The object is already loaded. |
---|
807 | Just bump its reference count and return it. */ |
---|
808 | close (fd); |
---|
809 | |
---|
810 | /* If the name is not in the list of names for this object add |
---|
811 | it. */ |
---|
812 | free (realname); |
---|
813 | add_name_to_object (l, name); |
---|
814 | |
---|
815 | return l; |
---|
816 | } |
---|
817 | |
---|
818 | if (mode & RTLD_NOLOAD) |
---|
819 | /* We are not supposed to load the object unless it is already |
---|
820 | loaded. So return now. */ |
---|
821 | return NULL; |
---|
822 | |
---|
823 | /* Print debugging message. */ |
---|
824 | if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) |
---|
825 | _dl_debug_printf ("file=%s; generating link map\n", name); |
---|
826 | |
---|
827 | /* This is the ELF header. We read it in `open_verify'. */ |
---|
828 | header = (void *) fbp->buf; |
---|
829 | |
---|
830 | #ifndef MAP_ANON |
---|
831 | # define MAP_ANON 0 |
---|
832 | if (_dl_zerofd == -1) |
---|
833 | { |
---|
834 | _dl_zerofd = _dl_sysdep_open_zero_fill (); |
---|
835 | if (_dl_zerofd == -1) |
---|
836 | { |
---|
837 | close (fd); |
---|
838 | _dl_signal_error (errno, NULL, NULL, |
---|
839 | N_("cannot open zero fill device")); |
---|
840 | } |
---|
841 | } |
---|
842 | #endif |
---|
843 | |
---|
844 | /* Enter the new object in the list of loaded objects. */ |
---|
845 | l = _dl_new_object (realname, name, l_type, loader); |
---|
846 | if (__builtin_expect (! l, 0)) |
---|
847 | { |
---|
848 | errstring = N_("cannot create shared object descriptor"); |
---|
849 | goto call_lose_errno; |
---|
850 | } |
---|
851 | |
---|
852 | /* Extract the remaining details we need from the ELF header |
---|
853 | and then read in the program header table. */ |
---|
854 | l->l_entry = header->e_entry; |
---|
855 | type = header->e_type; |
---|
856 | l->l_phnum = header->e_phnum; |
---|
857 | |
---|
858 | maplength = header->e_phnum * sizeof (ElfW(Phdr)); |
---|
859 | if (header->e_phoff + maplength <= fbp->len) |
---|
860 | phdr = (void *) (fbp->buf + header->e_phoff); |
---|
861 | else |
---|
862 | { |
---|
863 | phdr = alloca (maplength); |
---|
864 | lseek (fd, SEEK_SET, header->e_phoff); |
---|
865 | if (__libc_read (fd, (void *) phdr, maplength) != maplength) |
---|
866 | { |
---|
867 | errstring = N_("cannot read file data"); |
---|
868 | goto call_lose_errno; |
---|
869 | } |
---|
870 | } |
---|
871 | |
---|
872 | { |
---|
873 | /* Scan the program header table, collecting its load commands. */ |
---|
874 | struct loadcmd |
---|
875 | { |
---|
876 | ElfW(Addr) mapstart, mapend, dataend, allocend; |
---|
877 | off_t mapoff; |
---|
878 | int prot; |
---|
879 | } loadcmds[l->l_phnum], *c; |
---|
880 | size_t nloadcmds = 0; |
---|
881 | |
---|
882 | /* The struct is initialized to zero so this is not necessary: |
---|
883 | l->l_ld = 0; |
---|
884 | l->l_phdr = 0; |
---|
885 | l->l_addr = 0; */ |
---|
886 | for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph) |
---|
887 | switch (ph->p_type) |
---|
888 | { |
---|
889 | /* These entries tell us where to find things once the file's |
---|
890 | segments are mapped in. We record the addresses it says |
---|
891 | verbatim, and later correct for the run-time load address. */ |
---|
892 | case PT_DYNAMIC: |
---|
893 | l->l_ld = (void *) ph->p_vaddr; |
---|
894 | l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn)); |
---|
895 | break; |
---|
896 | |
---|
897 | case PT_PHDR: |
---|
898 | l->l_phdr = (void *) ph->p_vaddr; |
---|
899 | break; |
---|
900 | |
---|
901 | case PT_LOAD: |
---|
902 | /* A load command tells us to map in part of the file. |
---|
903 | We record the load commands and process them all later. */ |
---|
904 | if ((ph->p_align & (_dl_pagesize - 1)) != 0) |
---|
905 | { |
---|
906 | errstring = N_("ELF load command alignment not page-aligned"); |
---|
907 | goto call_lose; |
---|
908 | } |
---|
909 | if (((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1)) != 0) |
---|
910 | { |
---|
911 | errstring |
---|
912 | = N_("ELF load command address/offset not properly aligned"); |
---|
913 | goto call_lose; |
---|
914 | } |
---|
915 | |
---|
916 | { |
---|
917 | struct loadcmd *c = &loadcmds[nloadcmds++]; |
---|
918 | c->mapstart = ph->p_vaddr & ~(ph->p_align - 1); |
---|
919 | c->mapend = ((ph->p_vaddr + ph->p_filesz + _dl_pagesize - 1) |
---|
920 | & ~(_dl_pagesize - 1)); |
---|
921 | c->dataend = ph->p_vaddr + ph->p_filesz; |
---|
922 | c->allocend = ph->p_vaddr + ph->p_memsz; |
---|
923 | c->mapoff = ph->p_offset & ~(ph->p_align - 1); |
---|
924 | |
---|
925 | /* Optimize a common case. */ |
---|
926 | #if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7 |
---|
927 | c->prot = (PF_TO_PROT |
---|
928 | >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf; |
---|
929 | #else |
---|
930 | c->prot = 0; |
---|
931 | if (ph->p_flags & PF_R) |
---|
932 | c->prot |= PROT_READ; |
---|
933 | if (ph->p_flags & PF_W) |
---|
934 | c->prot |= PROT_WRITE; |
---|
935 | if (ph->p_flags & PF_X) |
---|
936 | c->prot |= PROT_EXEC; |
---|
937 | #endif |
---|
938 | } |
---|
939 | break; |
---|
940 | } |
---|
941 | |
---|
942 | /* Now process the load commands and map segments into memory. */ |
---|
943 | c = loadcmds; |
---|
944 | |
---|
945 | /* Length of the sections to be loaded. */ |
---|
946 | maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart; |
---|
947 | |
---|
948 | if (__builtin_expect (type, ET_DYN) == ET_DYN) |
---|
949 | { |
---|
950 | /* This is a position-independent shared object. We can let the |
---|
951 | kernel map it anywhere it likes, but we must have space for all |
---|
952 | the segments in their specified positions relative to the first. |
---|
953 | So we map the first segment without MAP_FIXED, but with its |
---|
954 | extent increased to cover all the segments. Then we remove |
---|
955 | access from excess portion, and there is known sufficient space |
---|
956 | there to remap from the later segments. |
---|
957 | |
---|
958 | As a refinement, sometimes we have an address that we would |
---|
959 | prefer to map such objects at; but this is only a preference, |
---|
960 | the OS can do whatever it likes. */ |
---|
961 | ElfW(Addr) mappref; |
---|
962 | mappref = (ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart) |
---|
963 | - MAP_BASE_ADDR (l)); |
---|
964 | |
---|
965 | /* Remember which part of the address space this object uses. */ |
---|
966 | l->l_map_start = (ElfW(Addr)) mmap ((void *) mappref, maplength, |
---|
967 | c->prot, MAP_COPY | MAP_FILE, |
---|
968 | fd, c->mapoff); |
---|
969 | if ((void *) l->l_map_start == MAP_FAILED) |
---|
970 | { |
---|
971 | map_error: |
---|
972 | errstring = N_("failed to map segment from shared object"); |
---|
973 | goto call_lose_errno; |
---|
974 | } |
---|
975 | |
---|
976 | l->l_map_end = l->l_map_start + maplength; |
---|
977 | l->l_addr = l->l_map_start - c->mapstart; |
---|
978 | |
---|
979 | /* Change protection on the excess portion to disallow all access; |
---|
980 | the portions we do not remap later will be inaccessible as if |
---|
981 | unallocated. Then jump into the normal segment-mapping loop to |
---|
982 | handle the portion of the segment past the end of the file |
---|
983 | mapping. */ |
---|
984 | mprotect ((caddr_t) (l->l_addr + c->mapend), |
---|
985 | loadcmds[nloadcmds - 1].allocend - c->mapend, |
---|
986 | PROT_NONE); |
---|
987 | |
---|
988 | goto postmap; |
---|
989 | } |
---|
990 | else |
---|
991 | { |
---|
992 | /* This object is loaded at a fixed address. This must never |
---|
993 | happen for objects loaded with dlopen(). */ |
---|
994 | if (__builtin_expect (mode & __RTLD_DLOPEN, 0)) |
---|
995 | { |
---|
996 | errstring = N_("cannot dynamically load executable"); |
---|
997 | goto call_lose; |
---|
998 | } |
---|
999 | |
---|
1000 | /* Notify ELF_PREFERRED_ADDRESS that we have to load this one |
---|
1001 | fixed. */ |
---|
1002 | ELF_FIXED_ADDRESS (loader, c->mapstart); |
---|
1003 | } |
---|
1004 | |
---|
1005 | /* Remember which part of the address space this object uses. */ |
---|
1006 | l->l_map_start = c->mapstart + l->l_addr; |
---|
1007 | l->l_map_end = l->l_map_start + maplength; |
---|
1008 | |
---|
1009 | while (c < &loadcmds[nloadcmds]) |
---|
1010 | { |
---|
1011 | if (c->mapend > c->mapstart |
---|
1012 | /* Map the segment contents from the file. */ |
---|
1013 | && (mmap ((void *) (l->l_addr + c->mapstart), |
---|
1014 | c->mapend - c->mapstart, c->prot, |
---|
1015 | MAP_FIXED | MAP_COPY | MAP_FILE, fd, c->mapoff) |
---|
1016 | == MAP_FAILED)) |
---|
1017 | goto map_error; |
---|
1018 | |
---|
1019 | postmap: |
---|
1020 | if (l->l_phdr == 0 |
---|
1021 | && c->mapoff <= header->e_phoff |
---|
1022 | && (c->mapend - c->mapstart + c->mapoff |
---|
1023 | >= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr)))) |
---|
1024 | /* Found the program header in this segment. */ |
---|
1025 | l->l_phdr = (void *) (c->mapstart + header->e_phoff - c->mapoff); |
---|
1026 | |
---|
1027 | if (c->allocend > c->dataend) |
---|
1028 | { |
---|
1029 | /* Extra zero pages should appear at the end of this segment, |
---|
1030 | after the data mapped from the file. */ |
---|
1031 | ElfW(Addr) zero, zeroend, zeropage; |
---|
1032 | |
---|
1033 | zero = l->l_addr + c->dataend; |
---|
1034 | zeroend = l->l_addr + c->allocend; |
---|
1035 | zeropage = (zero + _dl_pagesize - 1) & ~(_dl_pagesize - 1); |
---|
1036 | |
---|
1037 | if (zeroend < zeropage) |
---|
1038 | /* All the extra data is in the last page of the segment. |
---|
1039 | We can just zero it. */ |
---|
1040 | zeropage = zeroend; |
---|
1041 | |
---|
1042 | if (zeropage > zero) |
---|
1043 | { |
---|
1044 | /* Zero the final part of the last page of the segment. */ |
---|
1045 | if ((c->prot & PROT_WRITE) == 0) |
---|
1046 | { |
---|
1047 | /* Dag nab it. */ |
---|
1048 | if (mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), |
---|
1049 | _dl_pagesize, c->prot|PROT_WRITE) < 0) |
---|
1050 | { |
---|
1051 | errstring = N_("cannot change memory protections"); |
---|
1052 | goto call_lose_errno; |
---|
1053 | } |
---|
1054 | } |
---|
1055 | memset ((void *) zero, '\0', zeropage - zero); |
---|
1056 | if ((c->prot & PROT_WRITE) == 0) |
---|
1057 | mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), |
---|
1058 | _dl_pagesize, c->prot); |
---|
1059 | } |
---|
1060 | |
---|
1061 | if (zeroend > zeropage) |
---|
1062 | { |
---|
1063 | /* Map the remaining zero pages in from the zero fill FD. */ |
---|
1064 | caddr_t mapat; |
---|
1065 | mapat = mmap ((caddr_t) zeropage, zeroend - zeropage, |
---|
1066 | c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED, |
---|
1067 | ANONFD, 0); |
---|
1068 | if (mapat == MAP_FAILED) |
---|
1069 | { |
---|
1070 | errstring = N_("cannot map zero-fill pages"); |
---|
1071 | goto call_lose_errno; |
---|
1072 | } |
---|
1073 | } |
---|
1074 | } |
---|
1075 | |
---|
1076 | ++c; |
---|
1077 | } |
---|
1078 | |
---|
1079 | if (l->l_phdr == NULL) |
---|
1080 | { |
---|
1081 | /* The program header is not contained in any of the segments. |
---|
1082 | We have to allocate memory ourself and copy it over from |
---|
1083 | out temporary place. */ |
---|
1084 | ElfW(Phdr) *newp = (ElfW(Phdr) *) malloc (header->e_phnum |
---|
1085 | * sizeof (ElfW(Phdr))); |
---|
1086 | if (newp == NULL) |
---|
1087 | { |
---|
1088 | errstring = N_("cannot allocate memory for program header"); |
---|
1089 | goto call_lose_errno; |
---|
1090 | } |
---|
1091 | |
---|
1092 | l->l_phdr = memcpy (newp, phdr, |
---|
1093 | (header->e_phnum * sizeof (ElfW(Phdr)))); |
---|
1094 | l->l_phdr_allocated = 1; |
---|
1095 | } |
---|
1096 | else |
---|
1097 | /* Adjust the PT_PHDR value by the runtime load address. */ |
---|
1098 | l->l_phdr = (ElfW(Addr)) l->l_phdr + l->l_addr; |
---|
1099 | } |
---|
1100 | |
---|
1101 | /* We are done mapping in the file. We no longer need the descriptor. */ |
---|
1102 | close (fd); |
---|
1103 | /* Signal that we closed the file. */ |
---|
1104 | fd = -1; |
---|
1105 | |
---|
1106 | if (l->l_type == lt_library && type == ET_EXEC) |
---|
1107 | l->l_type = lt_executable; |
---|
1108 | |
---|
1109 | if (l->l_ld == 0) |
---|
1110 | { |
---|
1111 | if (type == ET_DYN) |
---|
1112 | { |
---|
1113 | errstring = N_("object file has no dynamic section"); |
---|
1114 | goto call_lose; |
---|
1115 | } |
---|
1116 | } |
---|
1117 | else |
---|
1118 | l->l_ld = (ElfW(Addr)) l->l_ld + l->l_addr; |
---|
1119 | |
---|
1120 | l->l_entry += l->l_addr; |
---|
1121 | |
---|
1122 | if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) |
---|
1123 | _dl_debug_printf (" dynamic: 0x%0*lx base: 0x%0*lx size: 0x%0*Zx\n" |
---|
1124 | " entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u\n\n", |
---|
1125 | (int) sizeof (void *) * 2, (unsigned long int) l->l_ld, |
---|
1126 | (int) sizeof (void *) * 2, (unsigned long int) l->l_addr, |
---|
1127 | (int) sizeof (void *) * 2, maplength, |
---|
1128 | (int) sizeof (void *) * 2, (unsigned long int) l->l_entry, |
---|
1129 | (int) sizeof (void *) * 2, (unsigned long int) l->l_phdr, |
---|
1130 | (int) sizeof (void *) * 2, l->l_phnum); |
---|
1131 | |
---|
1132 | elf_get_dynamic_info (l); |
---|
1133 | |
---|
1134 | /* Make sure we are dlopen()ing an object which has the DF_1_NOOPEN |
---|
1135 | flag set. */ |
---|
1136 | if (__builtin_expect (l->l_flags_1 & DF_1_NOOPEN, 0) |
---|
1137 | && (mode & __RTLD_DLOPEN)) |
---|
1138 | { |
---|
1139 | /* We are not supposed to load this object. Free all resources. */ |
---|
1140 | munmap ((void *) l->l_map_start, l->l_map_end - l->l_map_start); |
---|
1141 | |
---|
1142 | if (!l->l_libname->dont_free) |
---|
1143 | free (l->l_libname); |
---|
1144 | |
---|
1145 | if (l->l_phdr_allocated) |
---|
1146 | free ((void *) l->l_phdr); |
---|
1147 | |
---|
1148 | errstring = N_("shared object cannot be dlopen()ed"); |
---|
1149 | goto call_lose; |
---|
1150 | } |
---|
1151 | |
---|
1152 | if (l->l_info[DT_HASH]) |
---|
1153 | _dl_setup_hash (l); |
---|
1154 | |
---|
1155 | /* If this object has DT_SYMBOLIC set modify now its scope. We don't |
---|
1156 | have to do this for the main map. */ |
---|
1157 | if (__builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0) |
---|
1158 | && &l->l_searchlist != l->l_scope[0]) |
---|
1159 | { |
---|
1160 | /* Create an appropriate searchlist. It contains only this map. |
---|
1161 | |
---|
1162 | XXX This is the definition of DT_SYMBOLIC in SysVr4. The old |
---|
1163 | GNU ld.so implementation had a different interpretation which |
---|
1164 | is more reasonable. We are prepared to add this possibility |
---|
1165 | back as part of a GNU extension of the ELF format. */ |
---|
1166 | l->l_symbolic_searchlist.r_list = |
---|
1167 | (struct link_map **) malloc (sizeof (struct link_map *)); |
---|
1168 | |
---|
1169 | if (l->l_symbolic_searchlist.r_list == NULL) |
---|
1170 | { |
---|
1171 | errstring = N_("cannot create searchlist"); |
---|
1172 | goto call_lose_errno; |
---|
1173 | } |
---|
1174 | |
---|
1175 | l->l_symbolic_searchlist.r_list[0] = l; |
---|
1176 | l->l_symbolic_searchlist.r_nlist = 1; |
---|
1177 | |
---|
1178 | /* Now move the existing entries one back. */ |
---|
1179 | memmove (&l->l_scope[1], &l->l_scope[0], |
---|
1180 | (l->l_scope_max - 1) * sizeof (l->l_scope[0])); |
---|
1181 | |
---|
1182 | /* Now add the new entry. */ |
---|
1183 | l->l_scope[0] = &l->l_symbolic_searchlist; |
---|
1184 | } |
---|
1185 | |
---|
1186 | /* Remember whether this object must be initialized first. */ |
---|
1187 | if (l->l_flags_1 & DF_1_INITFIRST) |
---|
1188 | _dl_initfirst = l; |
---|
1189 | |
---|
1190 | /* Finally the file information. */ |
---|
1191 | l->l_dev = st.st_dev; |
---|
1192 | l->l_ino = st.st_ino; |
---|
1193 | |
---|
1194 | return l; |
---|
1195 | } |
---|
1196 | |
---|
1197 | /* Print search path. */ |
---|
1198 | static void |
---|
1199 | print_search_path (struct r_search_path_elem **list, |
---|
1200 | const char *what, const char *name) |
---|
1201 | { |
---|
1202 | char buf[max_dirnamelen + max_capstrlen]; |
---|
1203 | int first = 1; |
---|
1204 | |
---|
1205 | _dl_debug_printf (" search path="); |
---|
1206 | |
---|
1207 | while (*list != NULL && (*list)->what == what) /* Yes, ==. */ |
---|
1208 | { |
---|
1209 | char *endp = memcpy (buf, (*list)->dirname, (*list)->dirnamelen); |
---|
1210 | size_t cnt; |
---|
1211 | endp += (*list)->dirnamelen; |
---|
1212 | |
---|
1213 | |
---|
1214 | for (cnt = 0; cnt < ncapstr; ++cnt) |
---|
1215 | if ((*list)->status[cnt] != nonexisting) |
---|
1216 | { |
---|
1217 | char *cp = memcpy (endp, capstr[cnt].str, capstr[cnt].len); |
---|
1218 | cp += capstr[cnt].len; |
---|
1219 | |
---|
1220 | if (cp == buf || (cp == buf + 1 && buf[0] == '/')) |
---|
1221 | cp[0] = '\0'; |
---|
1222 | else |
---|
1223 | cp[-1] = '\0'; |
---|
1224 | |
---|
1225 | _dl_debug_printf_c (first ? "%s" : ":%s", buf); |
---|
1226 | first = 0; |
---|
1227 | } |
---|
1228 | |
---|
1229 | ++list; |
---|
1230 | } |
---|
1231 | |
---|
1232 | if (name != NULL) |
---|
1233 | _dl_debug_printf_c ("\t\t(%s from file %s)\n", what, |
---|
1234 | name[0] ? name : _dl_argv[0]); |
---|
1235 | else |
---|
1236 | _dl_debug_printf_c ("\t\t(%s)\n", what); |
---|
1237 | } |
---|
1238 | |
---|
1239 | /* Open a file and verify it is an ELF file for this architecture. We |
---|
1240 | ignore only ELF files for other architectures. Non-ELF files and |
---|
1241 | ELF files with different header information cause fatal errors since |
---|
1242 | this could mean there is something wrong in the installation and the |
---|
1243 | user might want to know about this. */ |
---|
1244 | static int |
---|
1245 | open_verify (const char *name, struct filebuf *fbp) |
---|
1246 | { |
---|
1247 | /* This is the expected ELF header. */ |
---|
1248 | #define ELF32_CLASS ELFCLASS32 |
---|
1249 | #define ELF64_CLASS ELFCLASS64 |
---|
1250 | #ifndef VALID_ELF_HEADER |
---|
1251 | # define VALID_ELF_HEADER(hdr,exp,size) (memcmp (hdr, exp, size) == 0) |
---|
1252 | # define VALID_ELF_OSABI(osabi) (osabi == ELFOSABI_SYSV) |
---|
1253 | # define VALID_ELF_ABIVERSION(ver) (ver == 0) |
---|
1254 | #endif |
---|
1255 | static const unsigned char expected[EI_PAD] = |
---|
1256 | { |
---|
1257 | [EI_MAG0] = ELFMAG0, |
---|
1258 | [EI_MAG1] = ELFMAG1, |
---|
1259 | [EI_MAG2] = ELFMAG2, |
---|
1260 | [EI_MAG3] = ELFMAG3, |
---|
1261 | [EI_CLASS] = ELFW(CLASS), |
---|
1262 | [EI_DATA] = byteorder, |
---|
1263 | [EI_VERSION] = EV_CURRENT, |
---|
1264 | [EI_OSABI] = ELFOSABI_SYSV, |
---|
1265 | [EI_ABIVERSION] = 0 |
---|
1266 | }; |
---|
1267 | static const struct |
---|
1268 | { |
---|
1269 | ElfW(Word) vendorlen; |
---|
1270 | ElfW(Word) datalen; |
---|
1271 | ElfW(Word) type; |
---|
1272 | char vendor[4]; |
---|
1273 | } expected_note = { 4, 16, 1, "GNU" }; |
---|
1274 | int fd; |
---|
1275 | /* Initialize it to make the compiler happy. */ |
---|
1276 | const char *errstring = NULL; |
---|
1277 | int errval = 0; |
---|
1278 | |
---|
1279 | /* Open the file. We always open files read-only. */ |
---|
1280 | fd = open (name, O_RDONLY); |
---|
1281 | if (fd != -1) |
---|
1282 | { |
---|
1283 | ElfW(Ehdr) *ehdr; |
---|
1284 | ElfW(Phdr) *phdr, *ph; |
---|
1285 | ElfW(Word) *abi_note, abi_note_buf[8]; |
---|
1286 | unsigned int osversion; |
---|
1287 | size_t maplength; |
---|
1288 | |
---|
1289 | /* We successfully openened the file. Now verify it is a file |
---|
1290 | we can use. */ |
---|
1291 | __set_errno (0); |
---|
1292 | fbp->len = __libc_read (fd, fbp->buf, sizeof (fbp->buf)); |
---|
1293 | |
---|
1294 | /* This is where the ELF header is loaded. */ |
---|
1295 | assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr))); |
---|
1296 | ehdr = (ElfW(Ehdr) *) fbp->buf; |
---|
1297 | |
---|
1298 | /* Now run the tests. */ |
---|
1299 | if (__builtin_expect (fbp->len < (ssize_t) sizeof (ElfW(Ehdr)), 0)) |
---|
1300 | { |
---|
1301 | errval = errno; |
---|
1302 | errstring = (errval == 0 |
---|
1303 | ? N_("file too short") : N_("cannot read file data")); |
---|
1304 | call_lose: |
---|
1305 | lose (errval, fd, name, NULL, NULL, errstring); |
---|
1306 | } |
---|
1307 | |
---|
1308 | /* See whether the ELF header is what we expect. */ |
---|
1309 | if (__builtin_expect (! VALID_ELF_HEADER (ehdr->e_ident, expected, |
---|
1310 | EI_PAD), 0)) |
---|
1311 | { |
---|
1312 | /* Something is wrong. */ |
---|
1313 | if (*(Elf32_Word *) &ehdr->e_ident != |
---|
1314 | #if BYTE_ORDER == LITTLE_ENDIAN |
---|
1315 | ((ELFMAG0 << (EI_MAG0 * 8)) | |
---|
1316 | (ELFMAG1 << (EI_MAG1 * 8)) | |
---|
1317 | (ELFMAG2 << (EI_MAG2 * 8)) | |
---|
1318 | (ELFMAG3 << (EI_MAG3 * 8))) |
---|
1319 | #else |
---|
1320 | ((ELFMAG0 << (EI_MAG3 * 8)) | |
---|
1321 | (ELFMAG1 << (EI_MAG2 * 8)) | |
---|
1322 | (ELFMAG2 << (EI_MAG1 * 8)) | |
---|
1323 | (ELFMAG3 << (EI_MAG0 * 8))) |
---|
1324 | #endif |
---|
1325 | ) |
---|
1326 | errstring = N_("invalid ELF header"); |
---|
1327 | else if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS)) |
---|
1328 | /* This is not a fatal error. On architectures where |
---|
1329 | 32-bit and 64-bit binaries can be run this might |
---|
1330 | happen. */ |
---|
1331 | goto close_and_out; |
---|
1332 | else if (ehdr->e_ident[EI_DATA] != byteorder) |
---|
1333 | { |
---|
1334 | if (BYTE_ORDER == BIG_ENDIAN) |
---|
1335 | errstring = N_("ELF file data encoding not big-endian"); |
---|
1336 | else |
---|
1337 | errstring = N_("ELF file data encoding not little-endian"); |
---|
1338 | } |
---|
1339 | else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) |
---|
1340 | errstring |
---|
1341 | = N_("ELF file version ident does not match current one"); |
---|
1342 | /* XXX We should be able so set system specific versions which are |
---|
1343 | allowed here. */ |
---|
1344 | else if (!VALID_ELF_OSABI (ehdr->e_ident[EI_OSABI])) |
---|
1345 | errstring = N_("ELF file OS ABI invalid"); |
---|
1346 | else if (!VALID_ELF_ABIVERSION (ehdr->e_ident[EI_ABIVERSION])) |
---|
1347 | errstring = N_("ELF file ABI version invalid"); |
---|
1348 | else |
---|
1349 | /* Otherwise we don't know what went wrong. */ |
---|
1350 | errstring = N_("internal error"); |
---|
1351 | |
---|
1352 | goto call_lose; |
---|
1353 | } |
---|
1354 | |
---|
1355 | if (__builtin_expect (ehdr->e_version, EV_CURRENT) != EV_CURRENT) |
---|
1356 | { |
---|
1357 | errstring = N_("ELF file version does not match current one"); |
---|
1358 | goto call_lose; |
---|
1359 | } |
---|
1360 | if (! __builtin_expect (elf_machine_matches_host (ehdr), 1)) |
---|
1361 | goto close_and_out; |
---|
1362 | else if (__builtin_expect (ehdr->e_phentsize, sizeof (ElfW(Phdr))) |
---|
1363 | != sizeof (ElfW(Phdr))) |
---|
1364 | { |
---|
1365 | errstring = N_("ELF file's phentsize not the expected size"); |
---|
1366 | goto call_lose; |
---|
1367 | } |
---|
1368 | else if (__builtin_expect (ehdr->e_type, ET_DYN) != ET_DYN |
---|
1369 | && __builtin_expect (ehdr->e_type, ET_EXEC) != ET_EXEC) |
---|
1370 | { |
---|
1371 | errstring = N_("only ET_DYN and ET_EXEC can be loaded"); |
---|
1372 | goto call_lose; |
---|
1373 | } |
---|
1374 | |
---|
1375 | maplength = ehdr->e_phnum * sizeof (ElfW(Phdr)); |
---|
1376 | if (ehdr->e_phoff + maplength <= fbp->len) |
---|
1377 | phdr = (void *) (fbp->buf + ehdr->e_phoff); |
---|
1378 | else |
---|
1379 | { |
---|
1380 | phdr = alloca (maplength); |
---|
1381 | lseek (fd, SEEK_SET, ehdr->e_phoff); |
---|
1382 | if (__libc_read (fd, (void *) phdr, maplength) != maplength) |
---|
1383 | { |
---|
1384 | read_error: |
---|
1385 | errval = errno; |
---|
1386 | errstring = N_("cannot read file data"); |
---|
1387 | goto call_lose; |
---|
1388 | } |
---|
1389 | } |
---|
1390 | |
---|
1391 | /* Check .note.ABI-tag if present. */ |
---|
1392 | for (ph = phdr; ph < &phdr[ehdr->e_phnum]; ++ph) |
---|
1393 | if (ph->p_type == PT_NOTE && ph->p_filesz == 32 && ph->p_align >= 4) |
---|
1394 | { |
---|
1395 | if (ph->p_offset + 32 <= fbp->len) |
---|
1396 | abi_note = (void *) (fbp->buf + ph->p_offset); |
---|
1397 | else |
---|
1398 | { |
---|
1399 | lseek (fd, SEEK_SET, ph->p_offset); |
---|
1400 | if (__libc_read (fd, (void *) abi_note_buf, 32) != 32) |
---|
1401 | goto read_error; |
---|
1402 | |
---|
1403 | abi_note = abi_note_buf; |
---|
1404 | } |
---|
1405 | |
---|
1406 | if (memcmp (abi_note, &expected_note, sizeof (expected_note))) |
---|
1407 | continue; |
---|
1408 | |
---|
1409 | osversion = (abi_note[5] & 0xff) * 65536 |
---|
1410 | + (abi_note[6] & 0xff) * 256 |
---|
1411 | + (abi_note[7] & 0xff); |
---|
1412 | if (abi_note[4] != __ABI_TAG_OS |
---|
1413 | || (_dl_osversion && _dl_osversion < osversion)) |
---|
1414 | { |
---|
1415 | close_and_out: |
---|
1416 | close (fd); |
---|
1417 | __set_errno (ENOENT); |
---|
1418 | fd = -1; |
---|
1419 | } |
---|
1420 | |
---|
1421 | break; |
---|
1422 | } |
---|
1423 | } |
---|
1424 | |
---|
1425 | return fd; |
---|
1426 | } |
---|
1427 | |
---|
1428 | /* Try to open NAME in one of the directories in *DIRSP. |
---|
1429 | Return the fd, or -1. If successful, fill in *REALNAME |
---|
1430 | with the malloc'd full directory name. If it turns out |
---|
1431 | that none of the directories in *DIRSP exists, *DIRSP is |
---|
1432 | replaced with (void *) -1, and the old value is free()d |
---|
1433 | if MAY_FREE_DIRS is true. */ |
---|
1434 | |
---|
1435 | static int |
---|
1436 | open_path (const char *name, size_t namelen, int preloaded, |
---|
1437 | struct r_search_path_struct *sps, char **realname, |
---|
1438 | struct filebuf *fbp) |
---|
1439 | { |
---|
1440 | struct r_search_path_elem **dirs = sps->dirs; |
---|
1441 | char *buf; |
---|
1442 | int fd = -1; |
---|
1443 | const char *current_what = NULL; |
---|
1444 | int any = 0; |
---|
1445 | |
---|
1446 | buf = alloca (max_dirnamelen + max_capstrlen + namelen); |
---|
1447 | do |
---|
1448 | { |
---|
1449 | struct r_search_path_elem *this_dir = *dirs; |
---|
1450 | size_t buflen = 0; |
---|
1451 | size_t cnt; |
---|
1452 | char *edp; |
---|
1453 | int here_any = 0; |
---|
1454 | int err; |
---|
1455 | |
---|
1456 | /* If we are debugging the search for libraries print the path |
---|
1457 | now if it hasn't happened now. */ |
---|
1458 | if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0) |
---|
1459 | && current_what != this_dir->what) |
---|
1460 | { |
---|
1461 | current_what = this_dir->what; |
---|
1462 | print_search_path (dirs, current_what, this_dir->where); |
---|
1463 | } |
---|
1464 | |
---|
1465 | edp = (char *) (memcpy (buf, this_dir->dirname, this_dir->dirnamelen) + this_dir->dirnamelen); |
---|
1466 | for (cnt = 0; fd == -1 && cnt < ncapstr; ++cnt) |
---|
1467 | { |
---|
1468 | char *tmp; |
---|
1469 | /* Skip this directory if we know it does not exist. */ |
---|
1470 | if (this_dir->status[cnt] == nonexisting) |
---|
1471 | continue; |
---|
1472 | |
---|
1473 | tmp = memcpy (edp, capstr[cnt].str, capstr[cnt].len); |
---|
1474 | tmp += capstr[cnt].len; |
---|
1475 | |
---|
1476 | tmp = memcpy (tmp, name, namelen); |
---|
1477 | tmp += namelen; |
---|
1478 | buflen = ((char *) (tmp - buf)); |
---|
1479 | |
---|
1480 | /* Print name we try if this is wanted. */ |
---|
1481 | if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) |
---|
1482 | _dl_debug_printf (" trying file=%s\n", buf); |
---|
1483 | |
---|
1484 | fd = open_verify (buf, fbp); |
---|
1485 | if (this_dir->status[cnt] == unknown) |
---|
1486 | { |
---|
1487 | if (fd != -1) |
---|
1488 | this_dir->status[cnt] = existing; |
---|
1489 | else |
---|
1490 | { |
---|
1491 | /* We failed to open machine dependent library. Let's |
---|
1492 | test whether there is any directory at all. */ |
---|
1493 | struct stat64 st; |
---|
1494 | |
---|
1495 | buf[buflen - namelen - 1] = '\0'; |
---|
1496 | |
---|
1497 | if (stat64 (buf, &st) != 0 |
---|
1498 | || ! S_ISDIR (st.st_mode)) |
---|
1499 | /* The directory does not exist or it is no directory. */ |
---|
1500 | this_dir->status[cnt] = nonexisting; |
---|
1501 | else |
---|
1502 | this_dir->status[cnt] = existing; |
---|
1503 | } |
---|
1504 | } |
---|
1505 | |
---|
1506 | /* Remember whether we found any existing directory. */ |
---|
1507 | here_any |= this_dir->status[cnt] == existing; |
---|
1508 | |
---|
1509 | if (fd != -1 && __builtin_expect (preloaded, 0) |
---|
1510 | && 0) |
---|
1511 | { |
---|
1512 | /* This is an extra security effort to make sure nobody can |
---|
1513 | preload broken shared objects which are in the trusted |
---|
1514 | directories and so exploit the bugs. */ |
---|
1515 | struct stat64 st; |
---|
1516 | |
---|
1517 | if (fstat64 (fd, &st) != 0 |
---|
1518 | || (st.st_mode & S_ISUID) == 0) |
---|
1519 | { |
---|
1520 | /* The shared object cannot be tested for being SUID |
---|
1521 | or this bit is not set. In this case we must not |
---|
1522 | use this object. */ |
---|
1523 | close (fd); |
---|
1524 | fd = -1; |
---|
1525 | /* We simply ignore the file, signal this by setting |
---|
1526 | the error value which would have been set by `open'. */ |
---|
1527 | errno = ENOENT; |
---|
1528 | } |
---|
1529 | } |
---|
1530 | } |
---|
1531 | |
---|
1532 | if (fd != -1) |
---|
1533 | { |
---|
1534 | *realname = (char *) malloc (buflen); |
---|
1535 | if (*realname != NULL) |
---|
1536 | { |
---|
1537 | memcpy (*realname, buf, buflen); |
---|
1538 | return fd; |
---|
1539 | } |
---|
1540 | else |
---|
1541 | { |
---|
1542 | /* No memory for the name, we certainly won't be able |
---|
1543 | to load and link it. */ |
---|
1544 | close (fd); |
---|
1545 | return -1; |
---|
1546 | } |
---|
1547 | } |
---|
1548 | if (here_any && (err = errno) != ENOENT && err != EACCES) |
---|
1549 | /* The file exists and is readable, but something went wrong. */ |
---|
1550 | return -1; |
---|
1551 | |
---|
1552 | /* Remember whether we found anything. */ |
---|
1553 | any |= here_any; |
---|
1554 | } |
---|
1555 | while (*++dirs != NULL); |
---|
1556 | |
---|
1557 | /* Remove the whole path if none of the directories exists. */ |
---|
1558 | if (__builtin_expect (! any, 0)) |
---|
1559 | { |
---|
1560 | /* Paths which were allocated using the minimal malloc() in ld.so |
---|
1561 | must not be freed using the general free() in libc. */ |
---|
1562 | if (sps->malloced) |
---|
1563 | free (sps->dirs); |
---|
1564 | sps->dirs = (void *) -1; |
---|
1565 | } |
---|
1566 | |
---|
1567 | return -1; |
---|
1568 | } |
---|
1569 | |
---|
1570 | /* Map in the shared object file NAME. */ |
---|
1571 | |
---|
1572 | struct link_map * |
---|
1573 | internal_function |
---|
1574 | _dl_map_object (struct link_map *loader, const char *name, int preloaded, |
---|
1575 | int type, int trace_mode, int mode) |
---|
1576 | { |
---|
1577 | int fd; |
---|
1578 | char *realname; |
---|
1579 | char *name_copy; |
---|
1580 | struct link_map *l; |
---|
1581 | struct filebuf fb; |
---|
1582 | |
---|
1583 | /* Look for this name among those already loaded. */ |
---|
1584 | for (l = _dl_loaded; l; l = l->l_next) |
---|
1585 | { |
---|
1586 | /* If the requested name matches the soname of a loaded object, |
---|
1587 | use that object. Elide this check for names that have not |
---|
1588 | yet been opened. */ |
---|
1589 | if (__builtin_expect (l->l_faked, 0) != 0) |
---|
1590 | continue; |
---|
1591 | if (!_dl_name_match_p (name, l)) |
---|
1592 | { |
---|
1593 | const char *soname; |
---|
1594 | |
---|
1595 | if (__builtin_expect (l->l_soname_added, 1) |
---|
1596 | || l->l_info[DT_SONAME] == NULL) |
---|
1597 | continue; |
---|
1598 | |
---|
1599 | soname = ((const char *) D_PTR (l, l_info[DT_STRTAB]) |
---|
1600 | + l->l_info[DT_SONAME]->d_un.d_val); |
---|
1601 | if (strcmp (name, soname) != 0) |
---|
1602 | continue; |
---|
1603 | |
---|
1604 | /* We have a match on a new name -- cache it. */ |
---|
1605 | add_name_to_object (l, soname); |
---|
1606 | l->l_soname_added = 1; |
---|
1607 | } |
---|
1608 | |
---|
1609 | /* We have a match. */ |
---|
1610 | return l; |
---|
1611 | } |
---|
1612 | |
---|
1613 | /* Display information if we are debugging. */ |
---|
1614 | if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0) && loader != NULL) |
---|
1615 | _dl_debug_printf ("\nfile=%s; needed by %s\n", name, |
---|
1616 | loader->l_name[0] ? loader->l_name : _dl_argv[0]); |
---|
1617 | |
---|
1618 | if (strchr (name, '/') == NULL) |
---|
1619 | { |
---|
1620 | /* Search for NAME in several places. */ |
---|
1621 | |
---|
1622 | size_t namelen = strlen (name) + 1; |
---|
1623 | |
---|
1624 | if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) |
---|
1625 | _dl_debug_printf ("find library=%s; searching\n", name); |
---|
1626 | |
---|
1627 | fd = -1; |
---|
1628 | |
---|
1629 | /* When the object has the RUNPATH information we don't use any |
---|
1630 | RPATHs. */ |
---|
1631 | if (loader == NULL || loader->l_info[DT_RUNPATH] == NULL) |
---|
1632 | { |
---|
1633 | /* First try the DT_RPATH of the dependent object that caused NAME |
---|
1634 | to be loaded. Then that object's dependent, and on up. */ |
---|
1635 | for (l = loader; fd == -1 && l; l = l->l_loader) |
---|
1636 | { |
---|
1637 | if (l->l_rpath_dirs.dirs == NULL) |
---|
1638 | { |
---|
1639 | if (l->l_info[DT_RPATH] == NULL) |
---|
1640 | { |
---|
1641 | /* There is no path. */ |
---|
1642 | l->l_rpath_dirs.dirs = (void *) -1; |
---|
1643 | continue; |
---|
1644 | } |
---|
1645 | else |
---|
1646 | { |
---|
1647 | /* Make sure the cache information is available. */ |
---|
1648 | size_t ptrval = (D_PTR (l, l_info[DT_STRTAB]) |
---|
1649 | + l->l_info[DT_RPATH]->d_un.d_val); |
---|
1650 | decompose_rpath (&l->l_rpath_dirs, |
---|
1651 | (const char *) ptrval, l, "RPATH"); |
---|
1652 | } |
---|
1653 | } |
---|
1654 | |
---|
1655 | if (l->l_rpath_dirs.dirs != (void *) -1) |
---|
1656 | fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, |
---|
1657 | &realname, &fb); |
---|
1658 | } |
---|
1659 | |
---|
1660 | /* If dynamically linked, try the DT_RPATH of the executable |
---|
1661 | itself. */ |
---|
1662 | l = _dl_loaded; |
---|
1663 | if (fd == -1 && l && l->l_type != lt_loaded && l != loader |
---|
1664 | && l->l_rpath_dirs.dirs != (void *) -1) |
---|
1665 | fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, |
---|
1666 | &realname, &fb); |
---|
1667 | } |
---|
1668 | |
---|
1669 | /* Try the LD_LIBRARY_PATH environment variable. */ |
---|
1670 | if (fd == -1 && env_path_list.dirs != (void *) -1) |
---|
1671 | fd = open_path (name, namelen, preloaded, &env_path_list, |
---|
1672 | &realname, &fb); |
---|
1673 | |
---|
1674 | /* Look at the RUNPATH information for this binary. |
---|
1675 | |
---|
1676 | Note that this is no real loop. 'while' is used only to enable |
---|
1677 | us to use 'break' instead of a 'goto' to jump to the end. The |
---|
1678 | loop is always left after the first round. */ |
---|
1679 | while (fd == -1 && loader != NULL |
---|
1680 | && loader->l_runpath_dirs.dirs != (void *) -1) |
---|
1681 | { |
---|
1682 | if (loader->l_runpath_dirs.dirs == NULL) |
---|
1683 | { |
---|
1684 | if (loader->l_info[DT_RUNPATH] == NULL) |
---|
1685 | { |
---|
1686 | /* No RUNPATH. */ |
---|
1687 | loader->l_runpath_dirs.dirs = (void *) -1; |
---|
1688 | break; |
---|
1689 | } |
---|
1690 | else |
---|
1691 | { |
---|
1692 | /* Make sure the cache information is available. */ |
---|
1693 | size_t ptrval = (D_PTR (loader, l_info[DT_STRTAB]) |
---|
1694 | + loader->l_info[DT_RUNPATH]->d_un.d_val); |
---|
1695 | decompose_rpath (&loader->l_runpath_dirs, |
---|
1696 | (const char *) ptrval, loader, "RUNPATH"); |
---|
1697 | } |
---|
1698 | } |
---|
1699 | |
---|
1700 | if (loader->l_runpath_dirs.dirs != (void *) -1) |
---|
1701 | fd = open_path (name, namelen, preloaded, |
---|
1702 | &loader->l_runpath_dirs, &realname, &fb); |
---|
1703 | break; |
---|
1704 | } |
---|
1705 | |
---|
1706 | if (fd == -1 |
---|
1707 | && (__builtin_expect (! preloaded, 1) || ! 0)) |
---|
1708 | { |
---|
1709 | /* Check the list of libraries in the file /etc/ld.so.cache, |
---|
1710 | for compatibility with Linux's ldconfig program. */ |
---|
1711 | const char *cached = _dl_load_cache_lookup (name); |
---|
1712 | |
---|
1713 | if (cached != NULL) |
---|
1714 | { |
---|
1715 | #ifdef SHARED |
---|
1716 | l = loader ?: _dl_loaded; |
---|
1717 | #else |
---|
1718 | l = loader; |
---|
1719 | #endif |
---|
1720 | |
---|
1721 | /* If the loader has the DF_1_NODEFLIB flag set we must not |
---|
1722 | use a cache entry from any of these directories. */ |
---|
1723 | if ( |
---|
1724 | #ifndef SHARED |
---|
1725 | /* 'l' is always != NULL for dynamically linked objects. */ |
---|
1726 | l != NULL && |
---|
1727 | #endif |
---|
1728 | __builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0)) |
---|
1729 | { |
---|
1730 | const char *dirp = system_dirs; |
---|
1731 | unsigned int cnt = 0; |
---|
1732 | |
---|
1733 | do |
---|
1734 | { |
---|
1735 | if (memcmp (cached, dirp, system_dirs_len[cnt]) == 0) |
---|
1736 | { |
---|
1737 | /* The prefix matches. Don't use the entry. */ |
---|
1738 | cached = NULL; |
---|
1739 | break; |
---|
1740 | } |
---|
1741 | |
---|
1742 | dirp += system_dirs_len[cnt] + 1; |
---|
1743 | ++cnt; |
---|
1744 | } |
---|
1745 | while (cnt < nsystem_dirs_len); |
---|
1746 | } |
---|
1747 | |
---|
1748 | if (cached != NULL) |
---|
1749 | { |
---|
1750 | fd = open_verify (cached, &fb); |
---|
1751 | if (__builtin_expect (fd != -1, 1)) |
---|
1752 | { |
---|
1753 | realname = local_strdup (cached); |
---|
1754 | if (realname == NULL) |
---|
1755 | { |
---|
1756 | close (fd); |
---|
1757 | fd = -1; |
---|
1758 | } |
---|
1759 | } |
---|
1760 | } |
---|
1761 | } |
---|
1762 | } |
---|
1763 | |
---|
1764 | /* Finally, try the default path. */ |
---|
1765 | if (fd == -1 |
---|
1766 | && ((l = loader ?: _dl_loaded) |
---|
1767 | /* 'l' is always != NULL for dynamically linked objects. */ |
---|
1768 | #ifdef SHARED |
---|
1769 | , |
---|
1770 | #else |
---|
1771 | == NULL || |
---|
1772 | #endif |
---|
1773 | __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)) |
---|
1774 | && rtld_search_dirs.dirs != (void *) -1) |
---|
1775 | fd = open_path (name, namelen, preloaded, &rtld_search_dirs, |
---|
1776 | &realname, &fb); |
---|
1777 | |
---|
1778 | /* Add another newline when we a tracing the library loading. */ |
---|
1779 | if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) |
---|
1780 | _dl_debug_printf ("\n"); |
---|
1781 | } |
---|
1782 | else |
---|
1783 | { |
---|
1784 | /* The path may contain dynamic string tokens. */ |
---|
1785 | realname = (loader |
---|
1786 | ? expand_dynamic_string_token (loader, name) |
---|
1787 | : local_strdup (name)); |
---|
1788 | if (realname == NULL) |
---|
1789 | fd = -1; |
---|
1790 | else |
---|
1791 | { |
---|
1792 | fd = open_verify (realname, &fb); |
---|
1793 | if (__builtin_expect (fd, 0) == -1) |
---|
1794 | free (realname); |
---|
1795 | } |
---|
1796 | } |
---|
1797 | |
---|
1798 | if (__builtin_expect (fd, 0) == -1) |
---|
1799 | { |
---|
1800 | if (trace_mode) |
---|
1801 | { |
---|
1802 | /* We haven't found an appropriate library. But since we |
---|
1803 | are only interested in the list of libraries this isn't |
---|
1804 | so severe. Fake an entry with all the information we |
---|
1805 | have. */ |
---|
1806 | static const Elf_Symndx dummy_bucket = STN_UNDEF; |
---|
1807 | |
---|
1808 | /* Enter the new object in the list of loaded objects. */ |
---|
1809 | if ((name_copy = local_strdup (name)) == NULL |
---|
1810 | || (l = _dl_new_object (name_copy, name, type, loader)) == NULL) |
---|
1811 | _dl_signal_error (ENOMEM, name, NULL, |
---|
1812 | N_("cannot create shared object descriptor")); |
---|
1813 | /* Signal that this is a faked entry. */ |
---|
1814 | l->l_faked = 1; |
---|
1815 | /* Since the descriptor is initialized with zero we do not |
---|
1816 | have do this here. |
---|
1817 | l->l_reserved = 0; */ |
---|
1818 | l->l_buckets = &dummy_bucket; |
---|
1819 | l->l_nbuckets = 1; |
---|
1820 | l->l_relocated = 1; |
---|
1821 | |
---|
1822 | return l; |
---|
1823 | } |
---|
1824 | else |
---|
1825 | _dl_signal_error (errno, name, NULL, |
---|
1826 | N_("cannot open shared object file")); |
---|
1827 | } |
---|
1828 | |
---|
1829 | return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode); |
---|
1830 | } |
---|