87859219f18f12daba6b2e6ffa68c1952eb95ab0
[platform/upstream/glibc.git] / elf / dl-load.c
1 /* _dl_map_object -- Map in a shared object's segments from the file.
2    Copyright (C) 1995, 1996, 1997 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 Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    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    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include <link.h>
21 #include <sys/types.h>
22 #include <sys/mman.h>
23 #include <string.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 #include "dynamic-link.h"
29
30
31 /* On some systems, no flag bits are given to specify file mapping.  */
32 #ifndef MAP_FILE
33 #define MAP_FILE        0
34 #endif
35
36 /* The right way to map in the shared library files is MAP_COPY, which
37    makes a virtual copy of the data at the time of the mmap call; this
38    guarantees the mapped pages will be consistent even if the file is
39    overwritten.  Some losing VM systems like Linux's lack MAP_COPY.  All we
40    get is MAP_PRIVATE, which copies each page when it is modified; this
41    means if the file is overwritten, we may at some point get some pages
42    from the new version after starting with pages from the old version.  */
43 #ifndef MAP_COPY
44 #define MAP_COPY        MAP_PRIVATE
45 #endif
46
47 /* Some systems link their relocatable objects for another base address
48    than 0.  We want to know the base address for these such that we can
49    subtract this address from the segment addresses during mapping.
50    This results in a more efficient address space usage.  Defaults to
51    zero for almost all systems.  */
52 #ifndef MAP_BASE_ADDR
53 #define MAP_BASE_ADDR(l)        0
54 #endif
55
56
57 #include <endian.h>
58 #if BYTE_ORDER == BIG_ENDIAN
59 #define byteorder ELFDATA2MSB
60 #define byteorder_name "big-endian"
61 #elif BYTE_ORDER == LITTLE_ENDIAN
62 #define byteorder ELFDATA2LSB
63 #define byteorder_name "little-endian"
64 #else
65 #error "Unknown BYTE_ORDER " BYTE_ORDER
66 #define byteorder ELFDATANONE
67 #endif
68
69 #define STRING(x) #x
70
71 #ifdef MAP_ANON
72 /* The fd is not examined when using MAP_ANON.  */
73 #define ANONFD -1
74 #else
75 int _dl_zerofd = -1;
76 #define ANONFD _dl_zerofd
77 #endif
78
79 /* Handle situations where we have a preferred location in memory for
80    the shared objects.  */
81 #ifdef ELF_PREFERRED_ADDRESS_DATA
82 ELF_PREFERRED_ADDRESS_DATA;
83 #endif
84 #ifndef ELF_PREFERRED_ADDRESS
85 #define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref)
86 #endif
87 #ifndef ELF_FIXED_ADDRESS
88 #define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0)
89 #endif
90
91 size_t _dl_pagesize;
92
93
94 /* Local version of `strdup' function.  */
95 static inline char *
96 local_strdup (const char *s)
97 {
98   size_t len = strlen (s) + 1;
99   void *new = malloc (len);
100
101   if (new == NULL)
102     return NULL;
103
104   return (char *) memcpy (new, s, len);
105 }
106
107
108 /* Map in the shared object NAME, actually located in REALNAME, and already
109    opened on FD.  */
110
111 struct link_map *
112 _dl_map_object_from_fd (char *name, int fd, char *realname,
113                         struct link_map *loader, int l_type)
114 {
115   struct link_map *l = NULL;
116   void *file_mapping = NULL;
117   size_t mapping_size = 0;
118
119 #define LOSE(s) lose (0, (s))
120   void lose (int code, const char *msg)
121     {
122       (void) __close (fd);
123       if (file_mapping)
124         __munmap (file_mapping, mapping_size);
125       if (l)
126         {
127           /* Remove the stillborn object from the list and free it.  */
128           if (l->l_prev)
129             l->l_prev->l_next = l->l_next;
130           if (l->l_next)
131             l->l_next->l_prev = l->l_prev;
132           free (l);
133         }
134       free (name);
135       free (realname);
136       _dl_signal_error (code, name, msg);
137     }
138
139   inline caddr_t map_segment (ElfW(Addr) mapstart, size_t len,
140                               int prot, int fixed, off_t offset)
141     {
142       caddr_t mapat = __mmap ((caddr_t) mapstart, len, prot,
143                               fixed|MAP_COPY|MAP_FILE,
144                               fd, offset);
145       if (mapat == (caddr_t) -1)
146         lose (errno, "failed to map segment from shared object");
147       return mapat;
148     }
149
150   /* Make sure LOCATION is mapped in.  */
151   void *map (off_t location, size_t size)
152     {
153       if ((off_t) mapping_size <= location + (off_t) size)
154         {
155           void *result;
156           if (file_mapping)
157             __munmap (file_mapping, mapping_size);
158           mapping_size = (location + size + 1 + _dl_pagesize - 1);
159           mapping_size &= ~(_dl_pagesize - 1);
160           result = __mmap (file_mapping, mapping_size, PROT_READ,
161                            MAP_COPY|MAP_FILE, fd, 0);
162           if (result == (void *) -1)
163             lose (errno, "cannot map file data");
164           file_mapping = result;
165         }
166       return file_mapping + location;
167     }
168
169   const ElfW(Ehdr) *header;
170   const ElfW(Phdr) *phdr;
171   const ElfW(Phdr) *ph;
172   int type;
173
174   /* Look again to see if the real name matched another already loaded.  */
175   for (l = _dl_loaded; l; l = l->l_next)
176     if (! strcmp (realname, l->l_name))
177       {
178         struct libname_list *lnp, *lastp;
179         /* The object is already loaded.
180            Just bump its reference count and return it.  */
181         __close (fd);
182
183         /* If the name is not in the list of names for this object add
184            it.  */
185         free (realname);
186         lastp = NULL;
187         for (lnp = l->l_libname; lnp != NULL; lastp = lnp, lnp = lnp->next)
188           if (strcmp (name, lnp->name) == 0)
189             {
190               free (name);
191               break;
192             }
193         if (lnp == NULL)
194           {
195             struct libname_list *newname = malloc (sizeof *newname);
196             if (newname == NULL)
197               /* No more memory.  */
198               lose (ENOMEM, "cannot allocate name record");
199             /* The object should have a libname set.  */
200             assert (lastp != NULL);
201
202             newname->name = name;
203             newname->next = NULL;
204             lastp->next = newname;
205           }
206         ++l->l_opencount;
207         return l;
208       }
209
210   if (_dl_pagesize == 0)
211     _dl_pagesize = __getpagesize ();
212
213   /* Map in the first page to read the header.  */
214   header = map (0, sizeof *header);
215
216   /* Check the header for basic validity.  */
217   if (*(Elf32_Word *) &header->e_ident !=
218 #if BYTE_ORDER == LITTLE_ENDIAN
219       ((ELFMAG0 << (EI_MAG0 * 8)) |
220        (ELFMAG1 << (EI_MAG1 * 8)) |
221        (ELFMAG2 << (EI_MAG2 * 8)) |
222        (ELFMAG3 << (EI_MAG3 * 8)))
223 #else
224       ((ELFMAG0 << (EI_MAG3 * 8)) |
225        (ELFMAG1 << (EI_MAG2 * 8)) |
226        (ELFMAG2 << (EI_MAG1 * 8)) |
227        (ELFMAG3 << (EI_MAG0 * 8)))
228 #endif
229       )
230     LOSE ("invalid ELF header");
231 #define ELF32_CLASS ELFCLASS32
232 #define ELF64_CLASS ELFCLASS64
233   if (header->e_ident[EI_CLASS] != ELFW(CLASS))
234     LOSE ("ELF file class not " STRING(__ELF_WORDSIZE) "-bit");
235   if (header->e_ident[EI_DATA] != byteorder)
236     LOSE ("ELF file data encoding not " byteorder_name);
237   if (header->e_ident[EI_VERSION] != EV_CURRENT)
238     LOSE ("ELF file version ident not " STRING(EV_CURRENT));
239   if (header->e_version != EV_CURRENT)
240     LOSE ("ELF file version not " STRING(EV_CURRENT));
241   if (! elf_machine_matches_host (header->e_machine))
242     LOSE ("ELF file machine architecture not " ELF_MACHINE_NAME);
243   if (header->e_phentsize != sizeof (ElfW(Phdr)))
244     LOSE ("ELF file's phentsize not the expected size");
245
246 #ifndef MAP_ANON
247 #define MAP_ANON 0
248   if (_dl_zerofd == -1)
249     {
250       _dl_zerofd = _dl_sysdep_open_zero_fill ();
251       if (_dl_zerofd == -1)
252         {
253           __close (fd);
254           _dl_signal_error (errno, NULL, "cannot open zero fill device");
255         }
256     }
257 #endif
258
259   /* Enter the new object in the list of loaded objects.  */
260   l = _dl_new_object (realname, name, l_type);
261   if (! l)
262     lose (ENOMEM, "cannot create shared object descriptor");
263   l->l_opencount = 1;
264   l->l_loader = loader;
265
266   /* Extract the remaining details we need from the ELF header
267      and then map in the program header table.  */
268   l->l_entry = header->e_entry;
269   type = header->e_type;
270   l->l_phnum = header->e_phnum;
271   phdr = map (header->e_phoff, l->l_phnum * sizeof (ElfW(Phdr)));
272
273   {
274     /* Scan the program header table, collecting its load commands.  */
275     struct loadcmd
276       {
277         ElfW(Addr) mapstart, mapend, dataend, allocend;
278         off_t mapoff;
279         int prot;
280       } loadcmds[l->l_phnum], *c;
281     size_t nloadcmds = 0;
282
283     l->l_ld = 0;
284     l->l_phdr = 0;
285     l->l_addr = 0;
286     for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)
287       switch (ph->p_type)
288         {
289           /* These entries tell us where to find things once the file's
290              segments are mapped in.  We record the addresses it says
291              verbatim, and later correct for the run-time load address.  */
292         case PT_DYNAMIC:
293           l->l_ld = (void *) ph->p_vaddr;
294           break;
295         case PT_PHDR:
296           l->l_phdr = (void *) ph->p_vaddr;
297           break;
298
299         case PT_LOAD:
300           /* A load command tells us to map in part of the file.
301              We record the load commands and process them all later.  */
302           if (ph->p_align % _dl_pagesize != 0)
303             LOSE ("ELF load command alignment not page-aligned");
304           if ((ph->p_vaddr - ph->p_offset) % ph->p_align)
305             LOSE ("ELF load command address/offset not properly aligned");
306           {
307             struct loadcmd *c = &loadcmds[nloadcmds++];
308             c->mapstart = ph->p_vaddr & ~(ph->p_align - 1);
309             c->mapend = ((ph->p_vaddr + ph->p_filesz + _dl_pagesize - 1)
310                          & ~(_dl_pagesize - 1));
311             c->dataend = ph->p_vaddr + ph->p_filesz;
312             c->allocend = ph->p_vaddr + ph->p_memsz;
313             c->mapoff = ph->p_offset & ~(ph->p_align - 1);
314             c->prot = 0;
315             if (ph->p_flags & PF_R)
316               c->prot |= PROT_READ;
317             if (ph->p_flags & PF_W)
318               c->prot |= PROT_WRITE;
319             if (ph->p_flags & PF_X)
320               c->prot |= PROT_EXEC;
321             break;
322           }
323         }
324
325     /* We are done reading the file's headers now.  Unmap them.  */
326     __munmap (file_mapping, mapping_size);
327
328     /* Now process the load commands and map segments into memory.  */
329     c = loadcmds;
330
331     if (type == ET_DYN || type == ET_REL)
332       {
333         /* This is a position-independent shared object.  We can let the
334            kernel map it anywhere it likes, but we must have space for all
335            the segments in their specified positions relative to the first.
336            So we map the first segment without MAP_FIXED, but with its
337            extent increased to cover all the segments.  Then we remove
338            access from excess portion, and there is known sufficient space
339            there to remap from the later segments.
340
341            As a refinement, sometimes we have an address that we would
342            prefer to map such objects at; but this is only a preference,
343            the OS can do whatever it likes. */
344         caddr_t mapat;
345         ElfW(Addr) mappref;
346         size_t maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart;
347         mappref = (ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart)
348                    - MAP_BASE_ADDR (l));
349         mapat = map_segment (mappref, maplength, c->prot, 0, c->mapoff);
350         l->l_addr = (ElfW(Addr)) mapat - c->mapstart;
351
352         /* Change protection on the excess portion to disallow all access;
353            the portions we do not remap later will be inaccessible as if
354            unallocated.  Then jump into the normal segment-mapping loop to
355            handle the portion of the segment past the end of the file
356            mapping.  */
357         __mprotect ((caddr_t) (l->l_addr + c->mapend),
358                     loadcmds[nloadcmds - 1].allocend - c->mapend,
359                     0);
360         goto postmap;
361       }
362     else
363       {
364         /* Notify ELF_PREFERRED_ADDRESS that we have to load this one
365            fixed.  */
366         ELF_FIXED_ADDRESS (loader, c->mapstart);
367       }
368
369     while (c < &loadcmds[nloadcmds])
370       {
371         if (c->mapend > c->mapstart)
372           /* Map the segment contents from the file.  */
373           map_segment (l->l_addr + c->mapstart, c->mapend - c->mapstart,
374                        c->prot, MAP_FIXED, c->mapoff);
375
376       postmap:
377         if (c->allocend > c->dataend)
378           {
379             /* Extra zero pages should appear at the end of this segment,
380                after the data mapped from the file.   */
381             ElfW(Addr) zero, zeroend, zeropage;
382
383             zero = l->l_addr + c->dataend;
384             zeroend = l->l_addr + c->allocend;
385             zeropage = (zero + _dl_pagesize - 1) & ~(_dl_pagesize - 1);
386
387             if (zeroend < zeropage)
388               /* All the extra data is in the last page of the segment.
389                  We can just zero it.  */
390               zeropage = zeroend;
391
392             if (zeropage > zero)
393               {
394                 /* Zero the final part of the last page of the segment.  */
395                 if ((c->prot & PROT_WRITE) == 0)
396                   {
397                     /* Dag nab it.  */
398                     if (__mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)),
399                                     _dl_pagesize, c->prot|PROT_WRITE) < 0)
400                       lose (errno, "cannot change memory protections");
401                   }
402                 memset ((void *) zero, 0, zeropage - zero);
403                 if ((c->prot & PROT_WRITE) == 0)
404                   __mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)),
405                               _dl_pagesize, c->prot);
406               }
407
408             if (zeroend > zeropage)
409               {
410                 /* Map the remaining zero pages in from the zero fill FD.  */
411                 caddr_t mapat;
412                 mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage,
413                                 c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,
414                                 ANONFD, 0);
415                 if (mapat == (caddr_t) -1)
416                   lose (errno, "cannot map zero-fill pages");
417               }
418           }
419
420         ++c;
421       }
422
423     if (l->l_phdr == 0)
424       {
425         /* There was no PT_PHDR specified.  We need to find the phdr in the
426            load image ourselves.  We assume it is in fact in the load image
427            somewhere, and that the first load command starts at the
428            beginning of the file and thus contains the ELF file header.  */
429         ElfW(Addr) bof = l->l_addr + loadcmds[0].mapstart;
430         assert (loadcmds[0].mapoff == 0);
431         l->l_phdr = (void *) (bof + ((const ElfW(Ehdr) *) bof)->e_phoff);
432       }
433     else
434       /* Adjust the PT_PHDR value by the runtime load address.  */
435       (ElfW(Addr)) l->l_phdr += l->l_addr;
436   }
437
438   /* We are done mapping in the file.  We no longer need the descriptor.  */
439   __close (fd);
440
441   if (l->l_type == lt_library && type == ET_EXEC)
442     l->l_type = lt_executable;
443
444   if (l->l_ld == 0)
445     {
446       if (type == ET_DYN)
447         LOSE ("object file has no dynamic section");
448     }
449   else
450     (ElfW(Addr)) l->l_ld += l->l_addr;
451
452   l->l_entry += l->l_addr;
453
454   elf_get_dynamic_info (l->l_ld, l->l_info);
455   if (l->l_info[DT_HASH])
456     _dl_setup_hash (l);
457
458   return l;
459 }
460 \f
461 /* Try to open NAME in one of the directories in DIRPATH.
462    Return the fd, or -1.  If successful, fill in *REALNAME
463    with the malloc'd full directory name.  */
464
465 static int
466 open_path (const char *name, size_t namelen,
467            const char *dirpath,
468            char **realname,
469            const char *trusted_dirs[])
470 {
471   char *buf;
472   const char *p;
473   int fd;
474
475   p = dirpath;
476   if (p == NULL || *p == '\0')
477     {
478       __set_errno (ENOENT);
479       return -1;
480     }
481
482   buf = __alloca (strlen (dirpath) + 1 + namelen);
483   do
484     {
485       size_t buflen;
486       size_t this_len;
487
488       dirpath = p;
489       p = strpbrk (dirpath, ":;");
490       if (p == NULL)
491         p = strchr (dirpath, '\0');
492
493       this_len = p - dirpath;
494
495       /* When we run a setuid program we do not accept any directory.  */
496       if (__libc_enable_secure)
497         {
498           /* All trusted directory must be complete name.  */
499           if (dirpath[0] != '/')
500             continue;
501
502           /* If we got a list of trusted directories only accept one
503              of these.  */
504           if (trusted_dirs != NULL)
505             {
506               const char **trust = trusted_dirs;
507
508               while (*trust !=  NULL)
509                 if (memcmp (dirpath, *trust, this_len) == 0
510                     && (*trust)[this_len] == '\0')
511                   break;
512                 else
513                   ++trust;
514
515               /* If directory is not trusted, ignore this directory.  */
516               if (*trust == NULL)
517                 continue;
518             }
519         }
520
521       if (this_len == 0)
522         {
523           /* Two adjacent colons, or a colon at the beginning or the end of
524              the path means to search the current directory.  */
525           (void) memcpy (buf, name, namelen);
526           buflen = namelen;
527         }
528       else
529         {
530           /* Construct the pathname to try.  */
531           (void) memcpy (buf, dirpath, this_len);
532           buf[this_len] = '/';
533           (void) memcpy (&buf[this_len + 1], name, namelen);
534           buflen = this_len + 1 + namelen;
535         }
536
537       fd = __open (buf, O_RDONLY);
538       if (fd != -1)
539         {
540           *realname = malloc (buflen);
541           if (*realname)
542             {
543               memcpy (*realname, buf, buflen);
544               return fd;
545             }
546           else
547             {
548               /* No memory for the name, we certainly won't be able
549                  to load and link it.  */
550               __close (fd);
551               return -1;
552             }
553         }
554       if (errno != ENOENT && errno != EACCES)
555         /* The file exists and is readable, but something went wrong.  */
556         return -1;
557     }
558   while (*p++ != '\0');
559
560   return -1;
561 }
562
563 /* Map in the shared object file NAME.  */
564
565 struct link_map *
566 _dl_map_object (struct link_map *loader, const char *name, int type,
567                 int trace_mode)
568 {
569   int fd;
570   char *realname;
571   char *name_copy;
572   struct link_map *l;
573
574   /* Look for this name among those already loaded.  */
575   for (l = _dl_loaded; l; l = l->l_next)
576     if (_dl_name_match_p (name, l) ||
577         /* If the requested name matches the soname of a loaded object,
578            use that object.  */
579         (l->l_info[DT_SONAME] &&
580          ! strcmp (name, (const char *) (l->l_addr +
581                                          l->l_info[DT_STRTAB]->d_un.d_ptr +
582                                          l->l_info[DT_SONAME]->d_un.d_val))))
583       {
584         /* The object is already loaded.
585            Just bump its reference count and return it.  */
586         ++l->l_opencount;
587         return l;
588       }
589
590   if (strchr (name, '/') == NULL)
591     {
592       /* Search for NAME in several places.  */
593
594       size_t namelen = strlen (name) + 1;
595
596       inline void trypath (const char *dirpath, const char *trusted[])
597         {
598           fd = open_path (name, namelen, dirpath, &realname, trusted);
599         }
600
601       fd = -1;
602
603       /* First try the DT_RPATH of the dependent object that caused NAME
604          to be loaded.  Then that object's dependent, and on up.  */
605       for (l = loader; fd == -1 && l; l = l->l_loader)
606         if (l && l->l_info[DT_RPATH])
607           trypath ((const char *) (l->l_addr +
608                                    l->l_info[DT_STRTAB]->d_un.d_ptr +
609                                    l->l_info[DT_RPATH]->d_un.d_val), NULL);
610       /* If dynamically linked, try the DT_RPATH of the executable itself.  */
611       l = _dl_loaded;
612       if (fd == -1 && l && l->l_type != lt_loaded && l->l_info[DT_RPATH])
613         trypath ((const char *) (l->l_addr +
614                                  l->l_info[DT_STRTAB]->d_un.d_ptr +
615                                  l->l_info[DT_RPATH]->d_un.d_val), NULL);
616       /* Try an environment variable (unless setuid).  */
617       if (fd == -1)
618         {
619           static const char *trusted_dirs[] =
620           {
621 #include "trusted-dirs.h"
622             NULL
623           };
624           const char *ld_library_path = getenv ("LD_LIBRARY_PATH");
625
626           if (ld_library_path != NULL && *ld_library_path != '\0')
627             trypath (ld_library_path, trusted_dirs);
628         }
629       if (fd == -1)
630         {
631           /* Check the list of libraries in the file /etc/ld.so.cache,
632              for compatibility with Linux's ldconfig program.  */
633           extern const char *_dl_load_cache_lookup (const char *name);
634           const char *cached = _dl_load_cache_lookup (name);
635           if (cached)
636             {
637               fd = __open (cached, O_RDONLY);
638               if (fd != -1)
639                 {
640                   realname = local_strdup (cached);
641                   if (realname == NULL)
642                     {
643                       __close (fd);
644                       fd = -1;
645                     }
646                 }
647             }
648         }
649       /* Finally, try the default path.  */
650       if (fd == -1)
651         {
652           extern const char *_dl_rpath; /* Set in rtld.c. */
653           trypath (_dl_rpath, NULL);
654         }
655     }
656   else
657     {
658       fd = __open (name, O_RDONLY);
659       if (fd != -1)
660         {
661           realname = local_strdup (name);
662           if (realname == NULL)
663             {
664               __close (fd);
665               fd = -1;
666             }
667         }
668     }
669
670   if (fd != -1)
671     {
672       name_copy = local_strdup (name);
673       if (name_copy == NULL)
674         {
675           __close (fd);
676           fd = -1;
677         }
678     }
679
680   if (fd == -1)
681     {
682       if (trace_mode)
683         {
684           /* We haven't found an appropriate library.  But since we
685              are only interested in the list of libraries this isn't
686              so severe.  Fake an entry with all the information we
687              have.  */
688           static const ElfW(Symndx) dummy_bucket = STN_UNDEF;
689
690           /* Enter the new object in the list of loaded objects.  */
691           if ((name_copy = local_strdup (name)) == NULL
692               || (l = _dl_new_object (name_copy, name, type)) == NULL)
693             _dl_signal_error (ENOMEM, name,
694                               "cannot create shared object descriptor");
695           /* We use an opencount of 0 as a sign for the faked entry.  */
696           l->l_opencount = 0;
697           l->l_reserved = 0;
698           l->l_buckets = &dummy_bucket;
699           l->l_nbuckets = 1;
700           l->l_relocated = 1;
701
702           return l;
703         }
704       else
705         _dl_signal_error (errno, name, "cannot open shared object file");
706     }
707
708   return _dl_map_object_from_fd (name_copy, fd, realname, loader, type);
709 }