(root)/
glibc-2.38/
elf/
dl-load.h
       1  /* Map in a shared object's segments from the file.
       2     Copyright (C) 1995-2023 Free Software Foundation, Inc.
       3     Copyright The GNU Toolchain Authors.
       4     This file is part of the GNU C Library.
       5  
       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.
      10  
      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.
      15  
      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/>.  */
      19  
      20  #ifndef _DL_LOAD_H
      21  #define _DL_LOAD_H	1
      22  
      23  #include <link.h>
      24  #include <sys/mman.h>
      25  
      26  
      27  /* On some systems, no flag bits are given to specify file mapping.  */
      28  #ifndef MAP_FILE
      29  # define MAP_FILE       0
      30  #endif
      31  
      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.
      39  
      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.  */
      43  #ifndef MAP_COPY
      44  # ifdef MAP_DENYWRITE
      45  #  define MAP_COPY      (MAP_PRIVATE | MAP_DENYWRITE)
      46  # else
      47  #  define MAP_COPY      MAP_PRIVATE
      48  # endif
      49  #endif
      50  
      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.  */
      56  #ifndef MAP_BASE_ADDR
      57  # define MAP_BASE_ADDR(l)       0
      58  #endif
      59  
      60  
      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;
      65  #endif
      66  #ifndef ELF_PREFERRED_ADDRESS
      67  # define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref)
      68  #endif
      69  #ifndef ELF_FIXED_ADDRESS
      70  # define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0)
      71  #endif
      72  
      73  
      74  /* This structure describes one PT_LOAD command.
      75     Its details have been expanded out and converted.  */
      76  struct loadcmd
      77  {
      78    ElfW(Addr) mapstart, mapend, dataend, allocend, mapalign;
      79    ElfW(Off) mapoff;
      80    int prot;                             /* PROT_* bits.  */
      81  };
      82  
      83  
      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)
      90  {
      91    if (c->prot & PROT_EXEC)
      92      l->l_text_end = l->l_addr + c->mapend;
      93  
      94    if (l->l_phdr == 0
      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
     100                                        - c->mapoff);
     101  }
     102  
     103  
     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).
     112  
     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
     115     version.  */
     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[],
     119                                       size_t nloadcmds,
     120                                       const size_t maplength,
     121                                       bool has_holes,
     122                                       struct link_map *loader);
     123  
     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")
     134  
     135  
     136  #endif	/* dl-load.h */