1 /* Map in a shared object's segments from the file.
2 Copyright (C) 1995-2022 Free Software Foundation, Inc.
3 Copyright The GNU Toolchain Authors.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
27 /* On some systems, no flag bits are given to specify file mapping. */
32 /* The right way to map in the shared library files is MAP_COPY, which
33 makes a virtual copy of the data at the time of the mmap call; this
34 guarantees the mapped pages will be consistent even if the file is
35 overwritten. Some losing VM systems like Linux's lack MAP_COPY. All we
36 get is MAP_PRIVATE, which copies each page when it is modified; this
37 means if the file is overwritten, we may at some point get some pages
38 from the new version after starting with pages from the old version.
40 To make up for the lack and avoid the overwriting problem,
41 what Linux does have is MAP_DENYWRITE. This prevents anyone
42 from modifying the file while we have it mapped. */
45 # define MAP_COPY (MAP_PRIVATE | MAP_DENYWRITE)
47 # define MAP_COPY MAP_PRIVATE
51 /* Some systems link their relocatable objects for another base address
52 than 0. We want to know the base address for these such that we can
53 subtract this address from the segment addresses during mapping.
54 This results in a more efficient address space usage. Defaults to
55 zero for almost all systems. */
57 # define MAP_BASE_ADDR(l) 0
61 /* Handle situations where we have a preferred location in memory for
62 the shared objects. */
63 #ifdef ELF_PREFERRED_ADDRESS_DATA
64 ELF_PREFERRED_ADDRESS_DATA
;
66 #ifndef ELF_PREFERRED_ADDRESS
67 # define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref)
69 #ifndef ELF_FIXED_ADDRESS
70 # define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0)
74 /* This structure describes one PT_LOAD command.
75 Its details have been expanded out and converted. */
78 ElfW(Addr
) mapstart
, mapend
, dataend
, allocend
, mapalign
;
80 int prot
; /* PROT_* bits. */
84 /* This is a subroutine of _dl_map_segments. It should be called for each
85 load command, some time after L->l_addr has been set correctly. It is
86 responsible for setting up the l_text_end and l_phdr fields. */
87 static __always_inline
void
88 _dl_postprocess_loadcmd (struct link_map
*l
, const ElfW(Ehdr
) *header
,
89 const struct loadcmd
*c
)
91 if (c
->prot
& PROT_EXEC
)
92 l
->l_text_end
= l
->l_addr
+ c
->mapend
;
95 && c
->mapoff
<= header
->e_phoff
96 && ((size_t) (c
->mapend
- c
->mapstart
+ c
->mapoff
)
97 >= header
->e_phoff
+ header
->e_phnum
* sizeof (ElfW(Phdr
))))
98 /* Found the program header in this segment. */
99 l
->l_phdr
= (void *) (uintptr_t) (c
->mapstart
+ header
->e_phoff
104 /* This is a subroutine of _dl_map_object_from_fd. It is responsible
105 for filling in several fields in *L: l_map_start, l_map_end, l_addr,
106 l_contiguous, l_text_end, l_phdr. On successful return, all the
107 segments are mapped (or copied, or whatever) from the file into their
108 final places in the address space, with the correct page permissions,
109 and any bss-like regions already zeroed. It returns a null pointer
110 on success, or an error message string (to be translated) on error
111 (having also set errno).
113 The file <dl-map-segments.h> defines this function. The canonical
114 implementation in elf/dl-map-segments.h might be replaced by a sysdeps
116 static const char *_dl_map_segments (struct link_map
*l
, int fd
,
117 const ElfW(Ehdr
) *header
, int type
,
118 const struct loadcmd loadcmds
[],
120 const size_t maplength
,
122 struct link_map
*loader
);
124 /* All the error message strings _dl_map_segments might return are
125 listed here so that different implementations in different sysdeps
126 dl-map-segments.h files all use consistent strings that are
127 guaranteed to have translations. */
128 #define DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT \
129 N_("failed to map segment from shared object")
130 #define DL_MAP_SEGMENTS_ERROR_MPROTECT \
131 N_("cannot change memory protections")
132 #define DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL \
133 N_("cannot map zero-fill pages")
136 #endif /* dl-load.h */