Blame elf/dl-load.h

Packit Service 82fcde
/* Map in a shared object's segments from the file.
Packit Service 82fcde
   Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef _DL_LOAD_H
Packit Service 82fcde
#define _DL_LOAD_H	1
Packit Service 82fcde
Packit Service 82fcde
#include <link.h>
Packit Service 82fcde
#include <sys/mman.h>
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* On some systems, no flag bits are given to specify file mapping.  */
Packit Service 82fcde
#ifndef MAP_FILE
Packit Service 82fcde
# define MAP_FILE       0
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* The right way to map in the shared library files is MAP_COPY, which
Packit Service 82fcde
   makes a virtual copy of the data at the time of the mmap call; this
Packit Service 82fcde
   guarantees the mapped pages will be consistent even if the file is
Packit Service 82fcde
   overwritten.  Some losing VM systems like Linux's lack MAP_COPY.  All we
Packit Service 82fcde
   get is MAP_PRIVATE, which copies each page when it is modified; this
Packit Service 82fcde
   means if the file is overwritten, we may at some point get some pages
Packit Service 82fcde
   from the new version after starting with pages from the old version.
Packit Service 82fcde
Packit Service 82fcde
   To make up for the lack and avoid the overwriting problem,
Packit Service 82fcde
   what Linux does have is MAP_DENYWRITE.  This prevents anyone
Packit Service 82fcde
   from modifying the file while we have it mapped.  */
Packit Service 82fcde
#ifndef MAP_COPY
Packit Service 82fcde
# ifdef MAP_DENYWRITE
Packit Service 82fcde
#  define MAP_COPY      (MAP_PRIVATE | MAP_DENYWRITE)
Packit Service 82fcde
# else
Packit Service 82fcde
#  define MAP_COPY      MAP_PRIVATE
Packit Service 82fcde
# endif
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Some systems link their relocatable objects for another base address
Packit Service 82fcde
   than 0.  We want to know the base address for these such that we can
Packit Service 82fcde
   subtract this address from the segment addresses during mapping.
Packit Service 82fcde
   This results in a more efficient address space usage.  Defaults to
Packit Service 82fcde
   zero for almost all systems.  */
Packit Service 82fcde
#ifndef MAP_BASE_ADDR
Packit Service 82fcde
# define MAP_BASE_ADDR(l)       0
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Handle situations where we have a preferred location in memory for
Packit Service 82fcde
   the shared objects.  */
Packit Service 82fcde
#ifdef ELF_PREFERRED_ADDRESS_DATA
Packit Service 82fcde
ELF_PREFERRED_ADDRESS_DATA;
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef ELF_PREFERRED_ADDRESS
Packit Service 82fcde
# define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref)
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef ELF_FIXED_ADDRESS
Packit Service 82fcde
# define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* This structure describes one PT_LOAD command.
Packit Service 82fcde
   Its details have been expanded out and converted.  */
Packit Service 82fcde
struct loadcmd
Packit Service 82fcde
{
Packit Service 82fcde
  ElfW(Addr) mapstart, mapend, dataend, allocend;
Packit Service 82fcde
  ElfW(Off) mapoff;
Packit Service 82fcde
  int prot;                             /* PROT_* bits.  */
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* This is a subroutine of _dl_map_segments.  It should be called for each
Packit Service 82fcde
   load command, some time after L->l_addr has been set correctly.  It is
Packit Service 82fcde
   responsible for setting up the l_text_end and l_phdr fields.  */
Packit Service 82fcde
static void __always_inline
Packit Service 82fcde
_dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
Packit Service 82fcde
                         const struct loadcmd *c)
Packit Service 82fcde
{
Packit Service 82fcde
  if (c->prot & PROT_EXEC)
Packit Service 82fcde
    l->l_text_end = l->l_addr + c->mapend;
Packit Service 82fcde
Packit Service 82fcde
  if (l->l_phdr == 0
Packit Service 82fcde
      && c->mapoff <= header->e_phoff
Packit Service 82fcde
      && ((size_t) (c->mapend - c->mapstart + c->mapoff)
Packit Service 82fcde
          >= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr))))
Packit Service 82fcde
    /* Found the program header in this segment.  */
Packit Service 82fcde
    l->l_phdr = (void *) (uintptr_t) (c->mapstart + header->e_phoff
Packit Service 82fcde
                                      - c->mapoff);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* This is a subroutine of _dl_map_object_from_fd.  It is responsible
Packit Service 82fcde
   for filling in several fields in *L: l_map_start, l_map_end, l_addr,
Packit Service 82fcde
   l_contiguous, l_text_end, l_phdr.  On successful return, all the
Packit Service 82fcde
   segments are mapped (or copied, or whatever) from the file into their
Packit Service 82fcde
   final places in the address space, with the correct page permissions,
Packit Service 82fcde
   and any bss-like regions already zeroed.  It returns a null pointer
Packit Service 82fcde
   on success, or an error message string (to be translated) on error
Packit Service 82fcde
   (having also set errno).
Packit Service 82fcde
Packit Service 82fcde
   The file <dl-map-segments.h> defines this function.  The canonical
Packit Service 82fcde
   implementation in elf/dl-map-segments.h might be replaced by a sysdeps
Packit Service 82fcde
   version.  */
Packit Service 82fcde
static const char *_dl_map_segments (struct link_map *l, int fd,
Packit Service 82fcde
                                     const ElfW(Ehdr) *header, int type,
Packit Service 82fcde
                                     const struct loadcmd loadcmds[],
Packit Service 82fcde
                                     size_t nloadcmds,
Packit Service 82fcde
                                     const size_t maplength,
Packit Service 82fcde
                                     bool has_holes,
Packit Service 82fcde
                                     struct link_map *loader);
Packit Service 82fcde
Packit Service 82fcde
/* All the error message strings _dl_map_segments might return are
Packit Service 82fcde
   listed here so that different implementations in different sysdeps
Packit Service 82fcde
   dl-map-segments.h files all use consistent strings that are
Packit Service 82fcde
   guaranteed to have translations.  */
Packit Service 82fcde
#define DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT \
Packit Service 82fcde
  N_("failed to map segment from shared object")
Packit Service 82fcde
#define DL_MAP_SEGMENTS_ERROR_MPROTECT \
Packit Service 82fcde
  N_("cannot change memory protections")
Packit Service 82fcde
#define DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL \
Packit Service 82fcde
  N_("cannot map zero-fill pages")
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#endif	/* dl-load.h */