(linenum→info "unix/slp.c:2238")

glibc/2.7/elf/dl-support.c

    1: /* Support for dynamic linking code in static libc.
    2:    Copyright (C) 1996-2005, 2006, 2007 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, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: /* This file defines some things that for the dynamic linker are defined in
   21:    rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking.  */
   22: 
   23: #include <errno.h>
   24: #include <libintl.h>
   25: #include <stdlib.h>
   26: #include <unistd.h>
   27: #include <ldsodefs.h>
   28: #include <dl-machine.h>
   29: #include <bits/libc-lock.h>
   30: #include <dl-cache.h>
   31: #include <dl-librecon.h>
   32: #include <dl-procinfo.h>
   33: #include <unsecvars.h>
   34: #include <hp-timing.h>
   35: 
   36: extern char *__progname;
   37: char **_dl_argv = &__progname;  /* This is checked for some error messages.  */
   38: 
   39: /* Name of the architecture.  */
   40: const char *_dl_platform;
   41: size_t _dl_platformlen;
   42: 
   43: int _dl_debug_mask;
   44: int _dl_lazy;
   45: ElfW(Addr) _dl_use_load_bias = -2;
   46: int _dl_dynamic_weak;
   47: 
   48: /* If nonzero print warnings about problematic situations.  */
   49: int _dl_verbose;
   50: 
   51: /* We never do profiling.  */
   52: const char *_dl_profile;
   53: const char *_dl_profile_output;
   54: 
   55: /* Names of shared object for which the RUNPATHs and RPATHs should be
   56:    ignored.  */
   57: const char *_dl_inhibit_rpath;
   58: 
   59: /* The map for the object we will profile.  */
   60: struct link_map *_dl_profile_map;
   61: 
   62: /* This is the address of the last stack address ever used.  */
   63: void *__libc_stack_end;
   64: 
   65: /* Path where the binary is found.  */
   66: const char *_dl_origin_path;
   67: 
   68: /* Nonzero if runtime lookup should not update the .got/.plt.  */
   69: int _dl_bind_not;
   70: 
   71: /* Namespace information.  */
   72: struct link_namespaces _dl_ns[DL_NNS];
   73: 
   74: /* Incremented whenever something may have been added to dl_loaded. */
   75: unsigned long long _dl_load_adds;
   76: 
   77: /* Fake scope.  In dynamically linked binaries this is the scope of the
   78:    main application but here we don't have something like this.  So
   79:    create a fake scope containing nothing.  */
   80: struct r_scope_elem _dl_initial_searchlist;
   81: 
   82: #ifndef HAVE_INLINED_SYSCALLS
   83: /* Nonzero during startup.  */
   84: int _dl_starting_up = 1;
   85: #endif
   86: 
   87: /* Get architecture specific initializer.  */
   88: #include <dl-procinfo.c>
   89: 
   90: /* We expect less than a second for relocation.  */
   91: #ifdef HP_SMALL_TIMING_AVAIL
   92: # undef HP_TIMING_AVAIL
   93: # define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL
   94: #endif
   95: 
   96: /* Initial value of the CPU clock.  */
   97: #ifndef HP_TIMING_NONAVAIL
   98: hp_timing_t _dl_cpuclock_offset;
   99: #endif
  100: 
  101: void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
  102: 
  103: size_t _dl_pagesize;
  104: 
  105: unsigned int _dl_osversion;
  106: 
  107: /* All known directories in sorted order.  */
  108: struct r_search_path_elem *_dl_all_dirs;
  109: 
  110: /* All directories after startup.  */
  111: struct r_search_path_elem *_dl_init_all_dirs;
  112: 
  113: /* The object to be initialized first.  */
  114: struct link_map *_dl_initfirst;
  115: 
  116: /* Descriptor to write debug messages to.  */
  117: int _dl_debug_fd = STDERR_FILENO;
  118: 
  119: int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
  120: 
  121: ElfW(Phdr) *_dl_phdr;
  122: size_t _dl_phnum;
  123: uint64_t _dl_hwcap __attribute__ ((nocommon));
  124: 
  125: /* Prevailing state of the stack, PF_X indicating it's executable.  */
  126: ElfW(Word) _dl_stack_flags = PF_R|PF_W|PF_X;
  127: 
  128: /* If loading a shared object requires that we make the stack executable
  129:    when it was not, we do it by calling this function.
  130:    It returns an errno code or zero on success.  */
  131: int (*_dl_make_stack_executable_hook) (void **) internal_function
  132:   = _dl_make_stack_executable;
  133: 
  134: 
  135: /* Function in libpthread to wait for termination of lookups.  */
  136: void (*_dl_wait_lookup_done) (void);
  137: 
  138: struct dl_scope_free_list *_dl_scope_free_list;
  139: 
  140: #ifdef NEED_DL_SYSINFO
  141: /* Needed for improved syscall handling on at least x86/Linux.  */
  142: uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
  143: #endif
  144: #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
  145: /* Address of the ELF headers in the vsyscall page.  */
  146: const ElfW(Ehdr) *_dl_sysinfo_dso;
  147: #endif
  148: 
  149: /* During the program run we must not modify the global data of
  150:    loaded shared object simultanously in two threads.  Therefore we
  151:    protect `_dl_open' and `_dl_close' in dl-close.c.
  152: 
  153:    This must be a recursive lock since the initializer function of
  154:    the loaded object might as well require a call to this function.
  155:    At this time it is not anymore a problem to modify the tables.  */
  156: __rtld_lock_define_initialized_recursive (, _dl_load_lock)
  157: 
  158: 
  159: #ifdef HAVE_AUX_VECTOR
  160: int _dl_clktck;
  161: 
  162: void
  163: internal_function
  164: _dl_aux_init (ElfW(auxv_t) *av)
  165: {
  166:   int seen = 0;
  167:   uid_t uid = 0;
  168:   gid_t gid = 0;
  169: 
  170:   for (; av->a_type != AT_NULL; ++av)
  171:     switch (av->a_type)
  172:       {
  173:       case AT_PAGESZ:
  174:         GLRO(dl_pagesize) = av->a_un.a_val;
  175:         break;
  176:       case AT_CLKTCK:
  177:         GLRO(dl_clktck) = av->a_un.a_val;
  178:         break;
  179:       case AT_PHDR:
  180:         GL(dl_phdr) = (void *) av->a_un.a_val;
  181:         break;
  182:       case AT_PHNUM:
  183:         GL(dl_phnum) = av->a_un.a_val;
  184:         break;
  185:       case AT_HWCAP:
  186:         GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
  187:         break;
  188: #ifdef NEED_DL_SYSINFO
  189:       case AT_SYSINFO:
  190:         GL(dl_sysinfo) = av->a_un.a_val;
  191:         break;
  192: #endif
  193: #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
  194:       case AT_SYSINFO_EHDR:
  195:         GL(dl_sysinfo_dso) = (void *) av->a_un.a_val;
  196:         break;
  197: #endif
  198:       case AT_UID:
  199:         uid ^= av->a_un.a_val;
  200:         seen |= 1;
  201:         break;
  202:       case AT_EUID:
  203:         uid ^= av->a_un.a_val;
  204:         seen |= 2;
  205:         break;
  206:       case AT_GID:
  207:         gid ^= av->a_un.a_val;
  208:         seen |= 4;
  209:         break;
  210:       case AT_EGID:
  211:         gid ^= av->a_un.a_val;
  212:         seen |= 8;
  213:         break;
  214:       case AT_SECURE:
  215:         seen = -1;
  216:         __libc_enable_secure = av->a_un.a_val;
  217:         __libc_enable_secure_decided = 1;
  218:         break;
  219: # ifdef DL_PLATFORM_AUXV
  220:       DL_PLATFORM_AUXV
  221: # endif
  222:       }
  223:   if (seen == 0xf)
  224:     {
  225:       __libc_enable_secure = uid != 0 || gid != 0;
  226:       __libc_enable_secure_decided = 1;
  227:     }
  228: }
  229: #endif
  230: 
  231: 
  232: void
  233: internal_function
  234: _dl_non_dynamic_init (void)
  235: {
  236:   if (HP_TIMING_AVAIL)
  237:     HP_TIMING_NOW (_dl_cpuclock_offset);
  238: 
  239:   if (!_dl_pagesize)
  240:     _dl_pagesize = __getpagesize ();
  241: 
  242:   _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
  243: 
  244:   /* Initialize the data structures for the search paths for shared
  245:      objects.  */
  246:   _dl_init_paths (getenv ("LD_LIBRARY_PATH"));
  247: 
  248:   _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
  249: 
  250:   _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
  251: 
  252:   _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
  253: 
  254:   _dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
  255:   if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
  256:     _dl_profile_output
  257:       = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
  258: 
  259:   if (__libc_enable_secure)
  260:     {
  261:       static const char unsecure_envvars[] =
  262:         UNSECURE_ENVVARS
  263: #ifdef EXTRA_UNSECURE_ENVVARS
  264:         EXTRA_UNSECURE_ENVVARS
  265: #endif
  266:         ;
  267:       const char *cp = unsecure_envvars;
  268: 
  269:       while (cp < unsecure_envvars + sizeof (unsecure_envvars))
  270:         {
  271:           __unsetenv (cp);
  272:           cp = (const char *) __rawmemchr (cp, '\0') + 1;
  273:         }
  274: 
  275:       if (__access ("/etc/suid-debug", F_OK) != 0)
  276:         __unsetenv ("MALLOC_CHECK_");
  277:     }
  278: 
  279: #ifdef DL_PLATFORM_INIT
  280:   DL_PLATFORM_INIT;
  281: #endif
  282: 
  283: #ifdef DL_OSVERSION_INIT
  284:   DL_OSVERSION_INIT;
  285: #endif
  286: 
  287:   /* Now determine the length of the platform string.  */
  288:   if (_dl_platform != NULL)
  289:     _dl_platformlen = strlen (_dl_platform);
  290: 
  291:   /* Scan for a program header telling us the stack is nonexecutable.  */
  292:   if (_dl_phdr != NULL)
  293:     for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
  294:       if (_dl_phdr[i].p_type == PT_GNU_STACK)
  295:         {
  296:           _dl_stack_flags = _dl_phdr[i].p_flags;
  297:           break;
  298:         }
  299: }
  300: 
  301: 
  302: const struct r_strlenpair *
  303: internal_function
  304: _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
  305:                       size_t *max_capstrlen)
  306: {
  307:   static struct r_strlenpair result;
  308:   static char buf[1];
  309: 
  310:   result.str = buf;     /* Does not really matter.  */
  311:   result.len = 0;
  312: 
  313:   *sz = 1;
  314:   return &result;
  315: }
  316: 
  317: 
  318: #ifdef DL_SYSINFO_IMPLEMENTATION
  319: DL_SYSINFO_IMPLEMENTATION
  320: #endif
Syntax (Markdown)