aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-map-segments.h
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-map-segments.h')
-rw-r--r--elf/dl-map-segments.h157
1 files changed, 0 insertions, 157 deletions
diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h
deleted file mode 100644
index d36f9bd2f6..0000000000
--- a/elf/dl-map-segments.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Map in a shared object's segments. Generic version.
- Copyright (C) 1995-2017 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <dl-load.h>
-
-/* This implementation assumes (as does the corresponding implementation
- of _dl_unmap_segments, in dl-unmap-segments.h) that shared objects
- are always laid out with all segments contiguous (or with gaps
- between them small enough that it's preferable to reserve all whole
- pages inside the gaps with PROT_NONE mappings rather than permitting
- other use of those parts of the address space). */
-
-static __always_inline const char *
-_dl_map_segments (struct link_map *l, int fd,
- const ElfW(Ehdr) *header, int type,
- const struct loadcmd loadcmds[], size_t nloadcmds,
- const size_t maplength, bool has_holes,
- struct link_map *loader)
-{
- const struct loadcmd *c = loadcmds;
-
- if (__glibc_likely (type == ET_DYN))
- {
- /* This is a position-independent shared object. We can let the
- kernel map it anywhere it likes, but we must have space for all
- the segments in their specified positions relative to the first.
- So we map the first segment without MAP_FIXED, but with its
- extent increased to cover all the segments. Then we remove
- access from excess portion, and there is known sufficient space
- there to remap from the later segments.
-
- As a refinement, sometimes we have an address that we would
- prefer to map such objects at; but this is only a preference,
- the OS can do whatever it likes. */
- ElfW(Addr) mappref
- = (ELF_PREFERRED_ADDRESS (loader, maplength,
- c->mapstart & GLRO(dl_use_load_bias))
- - MAP_BASE_ADDR (l));
-
- /* Remember which part of the address space this object uses. */
- l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength,
- c->prot,
- MAP_COPY|MAP_FILE,
- fd, c->mapoff);
- if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED))
- return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
-
- l->l_map_end = l->l_map_start + maplength;
- l->l_addr = l->l_map_start - c->mapstart;
-
- if (has_holes)
- {
- /* Change protection on the excess portion to disallow all access;
- the portions we do not remap later will be inaccessible as if
- unallocated. Then jump into the normal segment-mapping loop to
- handle the portion of the segment past the end of the file
- mapping. */
- if (__glibc_unlikely
- (__mprotect ((caddr_t) (l->l_addr + c->mapend),
- loadcmds[nloadcmds - 1].mapstart - c->mapend,
- PROT_NONE) < 0))
- return DL_MAP_SEGMENTS_ERROR_MPROTECT;
- }
-
- l->l_contiguous = 1;
-
- goto postmap;
- }
-
- /* Remember which part of the address space this object uses. */
- l->l_map_start = c->mapstart + l->l_addr;
- l->l_map_end = l->l_map_start + maplength;
- l->l_contiguous = !has_holes;
-
- while (c < &loadcmds[nloadcmds])
- {
- if (c->mapend > c->mapstart
- /* Map the segment contents from the file. */
- && (__mmap ((void *) (l->l_addr + c->mapstart),
- c->mapend - c->mapstart, c->prot,
- MAP_FIXED|MAP_COPY|MAP_FILE,
- fd, c->mapoff)
- == MAP_FAILED))
- return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
-
- postmap:
- _dl_postprocess_loadcmd (l, header, c);
-
- if (c->allocend > c->dataend)
- {
- /* Extra zero pages should appear at the end of this segment,
- after the data mapped from the file. */
- ElfW(Addr) zero, zeroend, zeropage;
-
- zero = l->l_addr + c->dataend;
- zeroend = l->l_addr + c->allocend;
- zeropage = ((zero + GLRO(dl_pagesize) - 1)
- & ~(GLRO(dl_pagesize) - 1));
-
- if (zeroend < zeropage)
- /* All the extra data is in the last page of the segment.
- We can just zero it. */
- zeropage = zeroend;
-
- if (zeropage > zero)
- {
- /* Zero the final part of the last page of the segment. */
- if (__glibc_unlikely ((c->prot & PROT_WRITE) == 0))
- {
- /* Dag nab it. */
- if (__mprotect ((caddr_t) (zero
- & ~(GLRO(dl_pagesize) - 1)),
- GLRO(dl_pagesize), c->prot|PROT_WRITE) < 0)
- return DL_MAP_SEGMENTS_ERROR_MPROTECT;
- }
- memset ((void *) zero, '\0', zeropage - zero);
- if (__glibc_unlikely ((c->prot & PROT_WRITE) == 0))
- __mprotect ((caddr_t) (zero & ~(GLRO(dl_pagesize) - 1)),
- GLRO(dl_pagesize), c->prot);
- }
-
- if (zeroend > zeropage)
- {
- /* Map the remaining zero pages in from the zero fill FD. */
- caddr_t mapat;
- mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage,
- c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,
- -1, 0);
- if (__glibc_unlikely (mapat == MAP_FAILED))
- return DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL;
- }
- }
-
- ++c;
- }
-
- /* Notify ELF_PREFERRED_ADDRESS that we have to load this one
- fixed. */
- ELF_FIXED_ADDRESS (loader, c->mapstart);
-
- return NULL;
-}