(_dl_relocate_object): Call elf_machine_runtime_setup unconditionally,
[kopensolaris-gnu/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 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
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, 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
48 #include <endian.h>
49 #if BYTE_ORDER == BIG_ENDIAN
50 #define byteorder ELFDATA2MSB
51 #define byteorder_name "big-endian"
52 #elif BYTE_ORDER == LITTLE_ENDIAN
53 #define byteorder ELFDATA2LSB
54 #define byteorder_name "little-endian"
55 #else
56 #error "Unknown BYTE_ORDER " BYTE_ORDER
57 #define byteorder ELFDATANONE
58 #endif
59
60 #define STRING(x) #x
61
62 int _dl_zerofd = -1;
63
64
65 /* Try to open NAME in one of the directories in DIRPATH.
66    Return the fd, or -1.  If successful, fill in *REALNAME
67    with the malloc'd full directory name.  */
68
69 static int
70 open_path (const char *name, size_t namelen,
71            const char *dirpath,
72            char **realname)
73 {
74   char *buf;
75   const char *p;
76   int fd;
77
78   p = dirpath;
79   if (p == NULL || *p == '\0')
80     {
81       errno = ENOENT;
82       return -1;
83     }
84
85   buf = alloca (strlen (dirpath) + 1 + namelen);
86   do
87     {
88       dirpath = p;
89       p = strpbrk (dirpath, ":;");
90       if (p == NULL)
91         p = strchr (dirpath, '\0');
92
93       if (p == dirpath)
94         /* Two adjacent colons, or a colon at the beginning or the end of
95            the path means to search the current directory.  */
96         (void) memcpy (buf, name, namelen);
97       else
98         {
99           /* Construct the pathname to try.  */
100           (void) memcpy (buf, dirpath, p - dirpath);
101           buf[p - dirpath] = '/';
102           (void) memcpy (&buf[(p - dirpath) + 1], name, namelen);
103         }
104
105       fd = open (buf, O_RDONLY);
106       if (fd != -1)
107         {
108           *realname = strdup (buf);
109           return fd;
110         }
111       if (errno != ENOENT && errno != EACCES)
112         /* The file exists and is readable, but something went wrong.  */
113         return -1;
114     }
115   while (*p++ != '\0');
116
117   return -1;
118 }
119
120
121 /* Map in the shared object file NAME.  */
122
123 struct link_map *
124 _dl_map_object (struct link_map *loader, const char *name)
125 {
126   int fd;
127   char *realname;
128   struct link_map *l;
129
130   /* Look for this name among those already loaded.  */
131   for (l = _dl_loaded; l; l = l->l_next)
132     if (! strcmp (name, l->l_libname))
133       {
134         /* The object is already loaded.
135            Just bump its reference count and return it.  */
136         ++l->l_opencount;
137         return l;
138       }
139
140   if (strchr (name, '/') == NULL)
141     {
142       /* Search for NAME in several places.  */
143
144       size_t namelen = strlen (name) + 1;
145
146       inline void trypath (const char *dirpath)
147         {
148           fd = open_path (name, namelen, dirpath, &realname);
149         }
150
151       fd = -1;
152       if (loader && loader->l_info[DT_RPATH])
153         trypath ((const char *) (loader->l_addr +
154                                  loader->l_info[DT_STRTAB]->d_un.d_ptr +
155                                  loader->l_info[DT_RPATH]->d_un.d_val));
156       if (fd == -1 && ! _dl_secure)
157         trypath (getenv ("LD_LIBRARY_PATH"));
158       if (fd == -1)
159         {
160           extern const char *_dl_rpath; /* Set in rtld.c. */
161           trypath (_dl_rpath);
162         }
163     }
164   else
165     {
166       fd = open (name, O_RDONLY);
167       if (fd != -1)
168         realname = strdup (name);
169     }
170
171   if (fd == -1)
172     _dl_signal_error (errno, name, "cannot open shared object file");
173
174   return _dl_map_object_from_fd (name, fd, realname);
175 }
176
177
178 /* Map in the shared object NAME, actually located in REALNAME, and already
179    opened on FD.  */
180
181 struct link_map *
182 _dl_map_object_from_fd (const char *name, int fd, char *realname)
183 {
184   struct link_map *l = NULL;
185   const size_t pagesize = getpagesize ();
186   void *file_mapping = NULL;
187   size_t mapping_size = 0;
188
189 #define LOSE(s) lose (0, (s))
190   void lose (int code, const char *msg)
191     {
192       (void) close (fd);
193       if (file_mapping)
194         munmap (file_mapping, mapping_size);
195       _dl_signal_error (code, l ? l->l_name : name, msg);
196     }
197
198   inline caddr_t map_segment (Elf32_Addr mapstart, size_t len,
199                               int prot, int fixed, off_t offset)
200     {
201       caddr_t mapat = mmap ((caddr_t) mapstart, len, prot,
202                             fixed|MAP_COPY|MAP_FILE,
203                             fd, offset);
204       if (mapat == (caddr_t) -1)
205         lose (errno, "failed to map segment from shared object");
206       return mapat;
207     }
208
209   /* Make sure LOCATION is mapped in.  */
210   void *map (off_t location, size_t size)
211     {
212       if ((off_t) mapping_size <= location + (off_t) size)
213         {
214           void *result;
215           if (file_mapping)
216             munmap (file_mapping, mapping_size);
217           mapping_size = (location + size + 1 + pagesize - 1);
218           mapping_size &= ~(pagesize - 1);
219           result = mmap (file_mapping, mapping_size, PROT_READ,
220                          MAP_COPY|MAP_FILE, fd, 0);
221           if (result == (void *) -1)
222             lose (errno, "cannot map file data");
223           file_mapping = result;
224         }
225       return file_mapping + location;
226     }
227
228   const Elf32_Ehdr *header;
229   const Elf32_Phdr *phdr;
230   const Elf32_Phdr *ph;
231   int type;
232
233   /* Look again to see if the real name matched another already loaded.  */
234   for (l = _dl_loaded; l; l = l->l_next)
235     if (! strcmp (realname, l->l_name))
236       {
237         /* The object is already loaded.
238            Just bump its reference count and return it.  */
239         close (fd);
240         free (realname);
241         ++l->l_opencount;
242         return l;
243       }
244
245   /* Map in the first page to read the header.  */
246   header = map (0, sizeof *header);
247
248   /* Check the header for basic validity.  */
249   if (*(Elf32_Word *) &header->e_ident !=
250 #if BYTE_ORDER == LITTLE_ENDIAN
251       ((ELFMAG0 << (EI_MAG0 * 8)) |
252        (ELFMAG1 << (EI_MAG1 * 8)) |
253        (ELFMAG2 << (EI_MAG2 * 8)) |
254        (ELFMAG3 << (EI_MAG3 * 8)))
255 #else
256       ((ELFMAG0 << (EI_MAG3 * 8)) |
257        (ELFMAG1 << (EI_MAG2 * 8)) |
258        (ELFMAG2 << (EI_MAG1 * 8)) |
259        (ELFMAG3 << (EI_MAG0 * 8)))
260 #endif
261       )
262     LOSE ("invalid ELF header");
263   if (header->e_ident[EI_CLASS] != ELFCLASS32)
264     LOSE ("ELF file class not 32-bit");
265   if (header->e_ident[EI_DATA] != byteorder)
266     LOSE ("ELF file data encoding not " byteorder_name);
267   if (header->e_ident[EI_VERSION] != EV_CURRENT)
268     LOSE ("ELF file version ident not " STRING(EV_CURRENT));
269   if (header->e_version != EV_CURRENT)
270     LOSE ("ELF file version not " STRING(EV_CURRENT));
271   if (! elf_machine_matches_host (header->e_machine))
272     LOSE ("ELF file machine architecture not " ELF_MACHINE_NAME);
273   if (header->e_phentsize != sizeof (Elf32_Phdr))
274     LOSE ("ELF file's phentsize not the expected size");
275
276   /* Enter the new object in the list of loaded objects.  */
277   l = _dl_new_object (realname, name, lt_loaded);
278   l->l_opencount = 1;
279
280   if (_dl_zerofd == -1)
281     {
282       _dl_zerofd = _dl_sysdep_open_zero_fill ();
283       if (_dl_zerofd == -1)
284         _dl_signal_error (errno, NULL, "cannot open zero fill device");
285     }
286
287   /* Extract the remaining details we need from the ELF header
288      and then map in the program header table.  */
289   l->l_entry = header->e_entry;
290   type = header->e_type;
291   l->l_phnum = header->e_phnum;
292   phdr = map (header->e_phoff, l->l_phnum * sizeof (Elf32_Phdr));
293
294   {
295     /* Scan the program header table, collecting its load commands.  */
296     struct loadcmd
297       {
298         Elf32_Addr mapstart, mapend, dataend, allocend;
299         off_t mapoff;
300         int prot;
301       } loadcmds[l->l_phnum], *c;
302     size_t nloadcmds = 0;
303
304     l->l_ld = 0;
305     l->l_phdr = 0;
306     l->l_addr = 0;
307     for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph)
308       switch (ph->p_type)
309         {
310           /* These entries tell us where to find things once the file's
311              segments are mapped in.  We record the addresses it says
312              verbatim, and later correct for the run-time load address.  */
313         case PT_DYNAMIC:
314           l->l_ld = (void *) ph->p_vaddr;
315           break;
316         case PT_PHDR:
317           l->l_phdr = (void *) ph->p_vaddr;
318           break;
319
320         case PT_LOAD:
321           /* A load command tells us to map in part of the file.
322              We record the load commands and process them all later.  */
323           if (ph->p_align % pagesize != 0)
324             LOSE ("ELF load command alignment not page-aligned");
325           if ((ph->p_vaddr - ph->p_offset) % ph->p_align)
326             LOSE ("ELF load command address/offset not properly aligned");
327           {
328             struct loadcmd *c = &loadcmds[nloadcmds++];
329             c->mapstart = ph->p_vaddr & ~(ph->p_align - 1);
330             c->mapend = ((ph->p_vaddr + ph->p_filesz + pagesize - 1)
331                          & ~(pagesize - 1));
332             c->dataend = ph->p_vaddr + ph->p_filesz;
333             c->allocend = ph->p_vaddr + ph->p_memsz;
334             c->mapoff = ph->p_offset & ~(ph->p_align - 1);
335             c->prot = 0;
336             if (ph->p_flags & PF_R)
337               c->prot |= PROT_READ;
338             if (ph->p_flags & PF_W)
339               c->prot |= PROT_WRITE;
340             if (ph->p_flags & PF_X)
341               c->prot |= PROT_EXEC;
342             break;
343           }
344         }
345
346     /* We are done reading the file's headers now.  Unmap them.  */
347     munmap (file_mapping, mapping_size);
348
349     /* Now process the load commands and map segments into memory.  */
350     c = loadcmds;
351
352     if (type == ET_DYN || type == ET_REL)
353       {
354         /* This is a position-independent shared object.  We can let the
355            kernel map it anywhere it likes, but we must have space for all
356            the segments in their specified positions relative to the first.
357            So we map the first segment without MAP_FIXED, but with its
358            extent increased to cover all the segments.  Then we unmap the
359            excess portion, and there is known sufficient space there to map
360            the later segments.  */
361         caddr_t mapat;
362         mapat = map_segment (c->mapstart,
363                              loadcmds[nloadcmds - 1].allocend - c->mapstart,
364                              c->prot, 0, c->mapoff);
365         l->l_addr = (Elf32_Addr) mapat - c->mapstart;
366
367         /* Unmap the excess portion, and then jump into the normal
368            segment-mapping loop to handle the portion of the segment past
369            the end of the file mapping.  */
370         munmap (mapat + c->mapend,
371                 loadcmds[nloadcmds - 1].allocend - c->mapend);
372         goto postmap;
373       }
374
375     while (c < &loadcmds[nloadcmds])
376       {
377         if (c->mapend > c->mapstart)
378           /* Map the segment contents from the file.  */
379           map_segment (l->l_addr + c->mapstart, c->mapend - c->mapstart,
380                        c->prot, MAP_FIXED, c->mapoff);
381
382       postmap:
383         if (c->allocend > c->dataend)
384           {
385             /* Extra zero pages should appear at the end of this segment,
386                after the data mapped from the file.   */
387             Elf32_Addr zero, zeroend, zeropage;
388
389             zero = l->l_addr + c->dataend;
390             zeroend = l->l_addr + c->allocend;
391             zeropage = (zero + pagesize - 1) & ~(pagesize - 1);
392
393             if (zeroend < zeropage)
394               /* All the extra data is in the last page of the segment.
395                  We can just zero it.  */
396               zeropage = zeroend;
397
398             if (zeropage > zero)
399               {
400                 /* Zero the final part of the last page of the segment.  */
401                 if ((c->prot & PROT_WRITE) == 0)
402                   {
403                     /* Dag nab it.  */
404                     if (mprotect ((caddr_t) (zero & ~(pagesize - 1)),
405                                   pagesize, c->prot|PROT_WRITE) < 0)
406                       lose (errno, "cannot change memory protections");
407                   }
408                 memset ((void *) zero, 0, zeropage - zero);
409                 if ((c->prot & PROT_WRITE) == 0)
410                   mprotect ((caddr_t) (zero & ~(pagesize - 1)),
411                             pagesize, c->prot);
412               }
413
414             if (zeroend > zeropage)
415               {
416                 /* Map the remaining zero pages in from the zero fill FD.  */
417                 caddr_t mapat;
418                 mapat = mmap ((caddr_t) zeropage, zeroend - zeropage, c->prot,
419                               MAP_ANON|MAP_PRIVATE|MAP_FIXED,
420                               _dl_zerofd, 0);
421                 if (mapat == (caddr_t) -1)
422                   lose (errno, "cannot map zero-fill pages");
423               }
424           }
425
426         ++c;
427       }
428   }
429
430   if (type == ET_EXEC)
431     l->l_type = lt_executable;
432
433   if (l->l_ld == 0)
434     {
435       if (type == ET_DYN)
436         LOSE ("object file has no dynamic section");
437     }
438   else
439     (Elf32_Addr) l->l_ld += l->l_addr;
440
441   if (l->l_phdr == 0)
442     l->l_phdr = (void *) ((const Elf32_Ehdr *) l->l_addr)->e_phoff;
443   (Elf32_Addr) l->l_phdr += l->l_addr;
444
445   elf_get_dynamic_info (l->l_ld, l->l_info);
446   if (l->l_info[DT_HASH])
447     _dl_setup_hash (l);
448
449   return l;
450 }