(root)/
glibc-2.38/
elf/
dl-support.c
       1  /* Support for dynamic linking code in static libc.
       2     Copyright (C) 1996-2023 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 Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the 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     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  /* This file defines some things that for the dynamic linker are defined in
      20     rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking.  */
      21  
      22  #include <string.h>
      23  /* Mark symbols hidden in static PIE for early self relocation to work.
      24     Note: string.h may have ifuncs which cannot be hidden on i686.  */
      25  #if BUILD_PIE_DEFAULT
      26  # pragma GCC visibility push(hidden)
      27  #endif
      28  #include <errno.h>
      29  #include <libintl.h>
      30  #include <stdlib.h>
      31  #include <unistd.h>
      32  #include <sys/param.h>
      33  #include <stdint.h>
      34  #include <ldsodefs.h>
      35  #include <dl-machine.h>
      36  #include <libc-lock.h>
      37  #include <dl-cache.h>
      38  #include <dl-procinfo.h>
      39  #include <unsecvars.h>
      40  #include <hp-timing.h>
      41  #include <stackinfo.h>
      42  #include <dl-vdso.h>
      43  #include <dl-vdso-setup.h>
      44  #include <dl-auxv.h>
      45  #include <dl-find_object.h>
      46  #include <array_length.h>
      47  #include <dl-symbol-redir-ifunc.h>
      48  
      49  extern char *__progname;
      50  char **_dl_argv = &__progname;	/* This is checked for some error messages.  */
      51  
      52  /* Name of the architecture.  */
      53  const char *_dl_platform;
      54  size_t _dl_platformlen;
      55  
      56  int _dl_debug_mask;
      57  int _dl_lazy;
      58  int _dl_dynamic_weak;
      59  
      60  /* If nonzero print warnings about problematic situations.  */
      61  int _dl_verbose;
      62  
      63  /* We never do profiling.  */
      64  const char *_dl_profile;
      65  const char *_dl_profile_output;
      66  
      67  /* Names of shared object for which the RUNPATHs and RPATHs should be
      68     ignored.  */
      69  const char *_dl_inhibit_rpath;
      70  
      71  /* The map for the object we will profile.  */
      72  struct link_map *_dl_profile_map;
      73  
      74  /* This is the address of the last stack address ever used.  */
      75  void *__libc_stack_end;
      76  
      77  /* Path where the binary is found.  */
      78  const char *_dl_origin_path;
      79  
      80  /* Nonzero if runtime lookup should not update the .got/.plt.  */
      81  int _dl_bind_not;
      82  
      83  /* A dummy link map for the executable, used by dlopen to access the global
      84     scope.  We don't export any symbols ourselves, so this can be minimal.  */
      85  static struct link_map _dl_main_map =
      86    {
      87      .l_name = (char *) "",
      88      .l_real = &_dl_main_map,
      89      .l_ns = LM_ID_BASE,
      90      .l_libname = &(struct libname_list) { .name = "", .dont_free = 1 },
      91      .l_searchlist =
      92        {
      93  	.r_list = &(struct link_map *) { &_dl_main_map },
      94  	.r_nlist = 1,
      95        },
      96      .l_symbolic_searchlist = { .r_list = &(struct link_map *) { NULL } },
      97      .l_type = lt_executable,
      98      .l_scope_mem = { &_dl_main_map.l_searchlist },
      99      .l_scope_max = (sizeof (_dl_main_map.l_scope_mem)
     100  		    / sizeof (_dl_main_map.l_scope_mem[0])),
     101      .l_scope = _dl_main_map.l_scope_mem,
     102      .l_local_scope = { &_dl_main_map.l_searchlist },
     103      .l_used = 1,
     104      .l_tls_offset = NO_TLS_OFFSET,
     105      .l_serial = 1,
     106    };
     107  
     108  /* Namespace information.  */
     109  struct link_namespaces _dl_ns[DL_NNS] =
     110    {
     111      [LM_ID_BASE] =
     112        {
     113  	._ns_loaded = &_dl_main_map,
     114  	._ns_nloaded = 1,
     115  	._ns_main_searchlist = &_dl_main_map.l_searchlist,
     116        }
     117    };
     118  size_t _dl_nns = 1;
     119  
     120  /* Incremented whenever something may have been added to dl_loaded. */
     121  unsigned long long _dl_load_adds = 1;
     122  
     123  /* Fake scope of the main application.  */
     124  struct r_scope_elem _dl_initial_searchlist =
     125    {
     126      .r_list = &(struct link_map *) { &_dl_main_map },
     127      .r_nlist = 1,
     128    };
     129  
     130  #ifndef HAVE_INLINED_SYSCALLS
     131  /* Nonzero during startup.  */
     132  int _dl_starting_up = 1;
     133  #endif
     134  
     135  /* Random data provided by the kernel.  */
     136  void *_dl_random;
     137  
     138  /* Get architecture specific initializer.  */
     139  #include <dl-procruntime.c>
     140  #include <dl-procinfo.c>
     141  
     142  size_t _dl_pagesize = EXEC_PAGESIZE;
     143  
     144  size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
     145  
     146  int _dl_inhibit_cache;
     147  
     148  /* All known directories in sorted order.  */
     149  struct r_search_path_elem *_dl_all_dirs;
     150  
     151  /* All directories after startup.  */
     152  struct r_search_path_elem *_dl_init_all_dirs;
     153  
     154  /* The object to be initialized first.  */
     155  struct link_map *_dl_initfirst;
     156  
     157  /* Descriptor to write debug messages to.  */
     158  int _dl_debug_fd = STDERR_FILENO;
     159  
     160  ElfW(auxv_t) *_dl_auxv;
     161  const ElfW(Phdr) *_dl_phdr;
     162  size_t _dl_phnum;
     163  uint64_t _dl_hwcap;
     164  uint64_t _dl_hwcap2;
     165  
     166  enum dso_sort_algorithm _dl_dso_sort_algo;
     167  
     168  /* The value of the FPU control word the kernel will preset in hardware.  */
     169  fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
     170  
     171  /* Prevailing state of the stack.  Generally this includes PF_X, indicating it's
     172   * executable but this isn't true for all platforms.  */
     173  ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
     174  
     175  #if PTHREAD_IN_LIBC
     176  list_t _dl_stack_used;
     177  list_t _dl_stack_user;
     178  list_t _dl_stack_cache;
     179  size_t _dl_stack_cache_actsize;
     180  uintptr_t _dl_in_flight_stack;
     181  int _dl_stack_cache_lock;
     182  #else
     183  /* If loading a shared object requires that we make the stack executable
     184     when it was not, we do it by calling this function.
     185     It returns an errno code or zero on success.  */
     186  int (*_dl_make_stack_executable_hook) (void **) = _dl_make_stack_executable;
     187  void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
     188  #endif
     189  struct dl_scope_free_list *_dl_scope_free_list;
     190  
     191  #ifdef NEED_DL_SYSINFO
     192  /* Needed for improved syscall handling on at least x86/Linux.  NB: Don't
     193     initialize it here to avoid RELATIVE relocation in static PIE.  */
     194  uintptr_t _dl_sysinfo;
     195  #endif
     196  #ifdef NEED_DL_SYSINFO_DSO
     197  /* Address of the ELF headers in the vsyscall page.  */
     198  const ElfW(Ehdr) *_dl_sysinfo_dso;
     199  
     200  struct link_map *_dl_sysinfo_map;
     201  
     202  # include "get-dynamic-info.h"
     203  #endif
     204  #include "setup-vdso.h"
     205  /* Define the vDSO function pointers.  */
     206  #include <dl-vdso-setup.c>
     207  
     208  /* During the program run we must not modify the global data of
     209     loaded shared object simultaneously in two threads.  Therefore we
     210     protect `_dl_open' and `_dl_close' in dl-close.c.
     211  
     212     This must be a recursive lock since the initializer function of
     213     the loaded object might as well require a call to this function.
     214     At this time it is not anymore a problem to modify the tables.  */
     215  __rtld_lock_define_initialized_recursive (, _dl_load_lock)
     216  /* This lock is used to keep __dl_iterate_phdr from inspecting the
     217     list of loaded objects while an object is added to or removed from
     218     that list.  */
     219  __rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
     220    /* This lock protects global and module specific TLS related data.
     221       E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
     222       GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
     223       accessed and when TLS related relocations are processed for a
     224       module.  It was introduced to keep pthread_create accessing TLS
     225       state that is being set up.  */
     226  __rtld_lock_define_initialized_recursive (, _dl_load_tls_lock)
     227  
     228  
     229  #ifdef HAVE_AUX_VECTOR
     230  #include <dl-parse_auxv.h>
     231  
     232  int _dl_clktck;
     233  
     234  void
     235  _dl_aux_init (ElfW(auxv_t) *av)
     236  {
     237  #ifdef NEED_DL_SYSINFO
     238    /* NB: Avoid RELATIVE relocation in static PIE.  */
     239    GL(dl_sysinfo) = DL_SYSINFO_DEFAULT;
     240  #endif
     241  
     242    _dl_auxv = av;
     243    dl_parse_auxv_t auxv_values;
     244    /* Use an explicit initialization loop here because memset may not
     245       be available yet.  */
     246    for (int i = 0; i < array_length (auxv_values); ++i)
     247      auxv_values[i] = 0;
     248    _dl_parse_auxv (av, auxv_values);
     249  
     250    _dl_phdr = (void*) auxv_values[AT_PHDR];
     251    _dl_phnum = auxv_values[AT_PHNUM];
     252  
     253    if (_dl_phdr == NULL)
     254      {
     255        /* Starting from binutils-2.23, the linker will define the
     256           magic symbol __ehdr_start to point to our own ELF header
     257           if it is visible in a segment that also includes the phdrs.
     258           So we can set up _dl_phdr and _dl_phnum even without any
     259           information from auxv.  */
     260  
     261        extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
     262        assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr));
     263        _dl_phdr = (const void *) &__ehdr_start + __ehdr_start.e_phoff;
     264        _dl_phnum = __ehdr_start.e_phnum;
     265      }
     266  
     267    assert (_dl_phdr != NULL);
     268  }
     269  #endif
     270  
     271  
     272  void
     273  _dl_non_dynamic_init (void)
     274  {
     275    _dl_main_map.l_origin = _dl_get_origin ();
     276    _dl_main_map.l_phdr = GL(dl_phdr);
     277    _dl_main_map.l_phnum = GL(dl_phnum);
     278  
     279    _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
     280  
     281    /* Set up the data structures for the system-supplied DSO early,
     282       so they can influence _dl_init_paths.  */
     283    setup_vdso (NULL, NULL);
     284  
     285    /* With vDSO setup we can initialize the function pointers.  */
     286    setup_vdso_pointers ();
     287  
     288    /* Initialize the data structures for the search paths for shared
     289       objects.  */
     290    _dl_init_paths (getenv ("LD_LIBRARY_PATH"), "LD_LIBRARY_PATH",
     291  		  /* No glibc-hwcaps selection support in statically
     292  		     linked binaries.  */
     293  		  NULL, NULL);
     294  
     295    /* Remember the last search directory added at startup.  */
     296    _dl_init_all_dirs = GL(dl_all_dirs);
     297  
     298    _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
     299  
     300    _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
     301  
     302    _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
     303  
     304    _dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
     305    if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
     306      _dl_profile_output
     307        = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
     308  
     309    if (__libc_enable_secure)
     310      {
     311        static const char unsecure_envvars[] =
     312  	UNSECURE_ENVVARS
     313  	;
     314        const char *cp = unsecure_envvars;
     315  
     316        while (cp < unsecure_envvars + sizeof (unsecure_envvars))
     317  	{
     318  	  __unsetenv (cp);
     319  	  cp = strchr (cp, '\0') + 1;
     320  	}
     321      }
     322  
     323  #ifdef DL_PLATFORM_INIT
     324    DL_PLATFORM_INIT;
     325  #endif
     326  
     327    /* Now determine the length of the platform string.  */
     328    if (_dl_platform != NULL)
     329      _dl_platformlen = strlen (_dl_platform);
     330  
     331    for (const ElfW(Phdr) *ph = _dl_phdr; ph < &_dl_phdr[_dl_phnum]; ++ph)
     332      switch (ph->p_type)
     333        {
     334        /* Check if the stack is nonexecutable.  */
     335        case PT_GNU_STACK:
     336  	_dl_stack_flags = ph->p_flags;
     337  	break;
     338  
     339        case PT_GNU_RELRO:
     340  	_dl_main_map.l_relro_addr = ph->p_vaddr;
     341  	_dl_main_map.l_relro_size = ph->p_memsz;
     342  	break;
     343        }
     344  
     345    call_function_static_weak (_dl_find_object_init);
     346  
     347    /* Setup relro on the binary itself.  */
     348    if (_dl_main_map.l_relro_size != 0)
     349      _dl_protect_relro (&_dl_main_map);
     350  }
     351  
     352  #ifdef DL_SYSINFO_IMPLEMENTATION
     353  DL_SYSINFO_IMPLEMENTATION
     354  #endif
     355  
     356  #if ENABLE_STATIC_PIE
     357  /* Since relocation to hidden _dl_main_map causes relocation overflow on
     358     aarch64, a function is used to get the address of _dl_main_map.  */
     359  
     360  struct link_map *
     361  _dl_get_dl_main_map (void)
     362  {
     363    return &_dl_main_map;
     364  }
     365  #endif
     366  
     367  /* This is used by _dl_runtime_profile, not used on static code.  */
     368  void
     369  DL_ARCH_FIXUP_ATTRIBUTE
     370  _dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
     371  		   const void *inregs, void *outregs)
     372  {
     373  }