Back to index

glibc  2.9
dl-support.c
Go to the documentation of this file.
00001 /* Support for dynamic linking code in static libc.
00002    Copyright (C) 1996-2005, 2006, 2007, 2008 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 /* This file defines some things that for the dynamic linker are defined in
00021    rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking.  */
00022 
00023 #include <errno.h>
00024 #include <libintl.h>
00025 #include <stdlib.h>
00026 #include <unistd.h>
00027 #include <ldsodefs.h>
00028 #include <dl-machine.h>
00029 #include <bits/libc-lock.h>
00030 #include <dl-cache.h>
00031 #include <dl-librecon.h>
00032 #include <dl-procinfo.h>
00033 #include <unsecvars.h>
00034 #include <hp-timing.h>
00035 
00036 extern char *__progname;
00037 char **_dl_argv = &__progname;     /* This is checked for some error messages.  */
00038 
00039 /* Name of the architecture.  */
00040 const char *_dl_platform;
00041 size_t _dl_platformlen;
00042 
00043 int _dl_debug_mask;
00044 int _dl_lazy;
00045 ElfW(Addr) _dl_use_load_bias = -2;
00046 int _dl_dynamic_weak;
00047 
00048 /* If nonzero print warnings about problematic situations.  */
00049 int _dl_verbose;
00050 
00051 /* We never do profiling.  */
00052 const char *_dl_profile;
00053 const char *_dl_profile_output;
00054 
00055 /* Names of shared object for which the RUNPATHs and RPATHs should be
00056    ignored.  */
00057 const char *_dl_inhibit_rpath;
00058 
00059 /* The map for the object we will profile.  */
00060 struct link_map *_dl_profile_map;
00061 
00062 /* This is the address of the last stack address ever used.  */
00063 void *__libc_stack_end;
00064 
00065 /* Path where the binary is found.  */
00066 const char *_dl_origin_path;
00067 
00068 /* Nonzero if runtime lookup should not update the .got/.plt.  */
00069 int _dl_bind_not;
00070 
00071 /* Namespace information.  */
00072 struct link_namespaces _dl_ns[DL_NNS];
00073 
00074 /* Incremented whenever something may have been added to dl_loaded. */
00075 unsigned long long _dl_load_adds;
00076 
00077 /* Fake scope.  In dynamically linked binaries this is the scope of the
00078    main application but here we don't have something like this.  So
00079    create a fake scope containing nothing.  */
00080 struct r_scope_elem _dl_initial_searchlist;
00081 
00082 #ifndef HAVE_INLINED_SYSCALLS
00083 /* Nonzero during startup.  */
00084 int _dl_starting_up = 1;
00085 #endif
00086 
00087 /* Get architecture specific initializer.  */
00088 #include <dl-procinfo.c>
00089 
00090 /* We expect less than a second for relocation.  */
00091 #ifdef HP_SMALL_TIMING_AVAIL
00092 # undef HP_TIMING_AVAIL
00093 # define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL
00094 #endif
00095 
00096 /* Initial value of the CPU clock.  */
00097 #ifndef HP_TIMING_NONAVAIL
00098 hp_timing_t _dl_cpuclock_offset;
00099 #endif
00100 
00101 void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
00102 
00103 size_t _dl_pagesize;
00104 
00105 unsigned int _dl_osversion;
00106 
00107 /* All known directories in sorted order.  */
00108 struct r_search_path_elem *_dl_all_dirs;
00109 
00110 /* All directories after startup.  */
00111 struct r_search_path_elem *_dl_init_all_dirs;
00112 
00113 /* The object to be initialized first.  */
00114 struct link_map *_dl_initfirst;
00115 
00116 /* Descriptor to write debug messages to.  */
00117 int _dl_debug_fd = STDERR_FILENO;
00118 
00119 int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
00120 
00121 ElfW(Phdr) *_dl_phdr;
00122 size_t _dl_phnum;
00123 uint64_t _dl_hwcap __attribute__ ((nocommon));
00124 
00125 /* Prevailing state of the stack, PF_X indicating it's executable.  */
00126 ElfW(Word) _dl_stack_flags = PF_R|PF_W|PF_X;
00127 
00128 /* If loading a shared object requires that we make the stack executable
00129    when it was not, we do it by calling this function.
00130    It returns an errno code or zero on success.  */
00131 int (*_dl_make_stack_executable_hook) (void **) internal_function
00132   = _dl_make_stack_executable;
00133 
00134 
00135 /* Function in libpthread to wait for termination of lookups.  */
00136 void (*_dl_wait_lookup_done) (void);
00137 
00138 struct dl_scope_free_list *_dl_scope_free_list;
00139 
00140 #ifdef NEED_DL_SYSINFO
00141 /* Needed for improved syscall handling on at least x86/Linux.  */
00142 uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
00143 #endif
00144 #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
00145 /* Address of the ELF headers in the vsyscall page.  */
00146 const ElfW(Ehdr) *_dl_sysinfo_dso;
00147 #endif
00148 
00149 /* During the program run we must not modify the global data of
00150    loaded shared object simultanously in two threads.  Therefore we
00151    protect `_dl_open' and `_dl_close' in dl-close.c.
00152 
00153    This must be a recursive lock since the initializer function of
00154    the loaded object might as well require a call to this function.
00155    At this time it is not anymore a problem to modify the tables.  */
00156 __rtld_lock_define_initialized_recursive (, _dl_load_lock)
00157 
00158 
00159 #ifdef HAVE_AUX_VECTOR
00160 int _dl_clktck;
00161 
00162 void
00163 internal_function
00164 _dl_aux_init (ElfW(auxv_t) *av)
00165 {
00166   int seen = 0;
00167   uid_t uid = 0;
00168   gid_t gid = 0;
00169 
00170   for (; av->a_type != AT_NULL; ++av)
00171     switch (av->a_type)
00172       {
00173       case AT_PAGESZ:
00174        GLRO(dl_pagesize) = av->a_un.a_val;
00175        break;
00176       case AT_CLKTCK:
00177        GLRO(dl_clktck) = av->a_un.a_val;
00178        break;
00179       case AT_PHDR:
00180        GL(dl_phdr) = (void *) av->a_un.a_val;
00181        break;
00182       case AT_PHNUM:
00183        GL(dl_phnum) = av->a_un.a_val;
00184        break;
00185       case AT_HWCAP:
00186        GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
00187        break;
00188 #ifdef NEED_DL_SYSINFO
00189       case AT_SYSINFO:
00190        GL(dl_sysinfo) = av->a_un.a_val;
00191        break;
00192 #endif
00193 #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
00194       case AT_SYSINFO_EHDR:
00195        GL(dl_sysinfo_dso) = (void *) av->a_un.a_val;
00196        break;
00197 #endif
00198       case AT_UID:
00199        uid ^= av->a_un.a_val;
00200        seen |= 1;
00201        break;
00202       case AT_EUID:
00203        uid ^= av->a_un.a_val;
00204        seen |= 2;
00205        break;
00206       case AT_GID:
00207        gid ^= av->a_un.a_val;
00208        seen |= 4;
00209        break;
00210       case AT_EGID:
00211        gid ^= av->a_un.a_val;
00212        seen |= 8;
00213        break;
00214       case AT_SECURE:
00215        seen = -1;
00216        __libc_enable_secure = av->a_un.a_val;
00217        __libc_enable_secure_decided = 1;
00218        break;
00219 # ifdef DL_PLATFORM_AUXV
00220       DL_PLATFORM_AUXV
00221 # endif
00222       }
00223   if (seen == 0xf)
00224     {
00225       __libc_enable_secure = uid != 0 || gid != 0;
00226       __libc_enable_secure_decided = 1;
00227     }
00228 }
00229 #endif
00230 
00231 
00232 void
00233 internal_function
00234 _dl_non_dynamic_init (void)
00235 {
00236   if (HP_TIMING_AVAIL)
00237     HP_TIMING_NOW (_dl_cpuclock_offset);
00238 
00239   if (!_dl_pagesize)
00240     _dl_pagesize = __getpagesize ();
00241 
00242   _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
00243 
00244   /* Initialize the data structures for the search paths for shared
00245      objects.  */
00246   _dl_init_paths (getenv ("LD_LIBRARY_PATH"));
00247 
00248   _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
00249 
00250   _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
00251 
00252   _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
00253 
00254   _dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
00255   if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
00256     _dl_profile_output
00257       = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
00258 
00259   if (__libc_enable_secure)
00260     {
00261       static const char unsecure_envvars[] =
00262        UNSECURE_ENVVARS
00263 #ifdef EXTRA_UNSECURE_ENVVARS
00264        EXTRA_UNSECURE_ENVVARS
00265 #endif
00266        ;
00267       const char *cp = unsecure_envvars;
00268 
00269       while (cp < unsecure_envvars + sizeof (unsecure_envvars))
00270        {
00271          __unsetenv (cp);
00272          cp = (const char *) __rawmemchr (cp, '\0') + 1;
00273        }
00274 
00275       if (__access ("/etc/suid-debug", F_OK) != 0)
00276        __unsetenv ("MALLOC_CHECK_");
00277     }
00278 
00279 #ifdef DL_PLATFORM_INIT
00280   DL_PLATFORM_INIT;
00281 #endif
00282 
00283 #ifdef DL_OSVERSION_INIT
00284   DL_OSVERSION_INIT;
00285 #endif
00286 
00287   /* Now determine the length of the platform string.  */
00288   if (_dl_platform != NULL)
00289     _dl_platformlen = strlen (_dl_platform);
00290 
00291   /* Scan for a program header telling us the stack is nonexecutable.  */
00292   if (_dl_phdr != NULL)
00293     for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
00294       if (_dl_phdr[i].p_type == PT_GNU_STACK)
00295        {
00296          _dl_stack_flags = _dl_phdr[i].p_flags;
00297          break;
00298        }
00299 }
00300 
00301 
00302 const struct r_strlenpair *
00303 internal_function
00304 _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
00305                     size_t *max_capstrlen)
00306 {
00307   static struct r_strlenpair result;
00308   static char buf[1];
00309 
00310   result.str = buf;  /* Does not really matter.  */
00311   result.len = 0;
00312 
00313   *sz = 1;
00314   return &result;
00315 }
00316 
00317 
00318 #ifdef DL_SYSINFO_IMPLEMENTATION
00319 DL_SYSINFO_IMPLEMENTATION
00320 #endif