setup.c revision d29b2c4438482eb00488be49a1f5d6835f455546
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 1988 AT&T 2N/A * All Rights Reserved 2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A * Run time linker common setup. 2N/A * Called from _setup to get the process going at startup. 2N/A/* needed for _brk_unlocked() */ 2N/A * Define for the executable's interpreter. 2N/A * Usually it is ld.so.1, but for the first release of ICL binaries 2N/A * it is libc.so.1. We keep this information so that we don't end 2N/A * up mapping libc twice if it is the interpreter. 2N/A * Establish the flags for loading each object. If we're called via 2N/A * lddstub, then the first shared object is the object being inspected 2N/A * by ldd(1). This object should not be marked as an interposer, as 2N/A * it is intended to act like the first object of the process. 2N/A * If this a secure application, then preload errors are 2N/A * reduced to warnings, as the errors are non-fatal. 2N/A * Establish state for the next preloadable object. If no 2N/A * error occurred with loading this object, indicate that this 2N/A * link-map list contains an interposer. 2N/A * If we're tracing shared objects via lddstub, establish a 2N/A * binding between the initial shared object and lddstub so that 2N/A * the shared object isn't called out from unused() processing. 2N/A * After the first object is loaded increment the caller to the 2N/A * initial preloaded object to provide intuitive ldd -v and -s * Now that ld.so has relocated itself, initialize our own 'environ' so * as to establish an address suitable for libc's hardware mul/div * Far the most common application execution revolves around appending * the application name to the users PATH definition, thus a full name * is passed to exec() which will in turn be returned via * AT_SUN_EXECNAME. Applications may also be invoked from the current * working directory, or via a relative name. * Determine whether the kernel has supplied a AT_SUN_EXECNAME aux * vector. This vector points to the full pathname, on the stack, of * the object that started the process. If this is null, then * AT_SUN_EXECNAME isn't supported (if the pathname exceeded the system * limit (PATH_MAX) the exec would have failed). This flag is used to * determine whether we can call resolvepath(). * Determine how ld.so.1 has been executed. if ((
fd == -
1) && (
phdr == 0)) {
* If we received neither the AT_EXECFD nor the AT_PHDR aux * vector, ld.so.1 must have been invoked directly from the * AT_SUN_EXECNAME provides the most precise name, if it is * available, otherwise fall back to argv[0]. At this time, * there is no process name. * Otherwise, we have a standard process. AT_SUN_EXECNAME * provides the most precise name, if it is available, * otherwise fall back to argv[0]. Provided the application * is already mapped, the process is the application, so * simplify the application name for use in any diagnostics. * At this point, we don't know the runtime linkers full path * name. The _rtldname passed to us is the SONAME of the * runtime linker, which is typically /lib/ld.so.1 no matter * what the full path is. Use this for now, we'll reset the * runtime linkers name once the application is analyzed. * Initialize any global variables. * If pagesize is unspecified find its value. * Add the unused portion of the last data page to the free space list. * The page size must be set before doing this. Here, _end refers to * the end of the runtime linkers bss. Note that we do not use the * unused data pages from any included .so's to supplement this free * space as badly behaved .os's may corrupt this data space, and in so * Establish initial link-map list flags, and link-map list alists. * Determine whether we have a secure executable. * Initialize a hardware capability descriptor for use in comparing * Look for environment strings (allows things like LD_NOAUDIT to be * established, although debugging isn't enabled until later). * Create a mapping descriptor for ld.so.1. We can determine our * two segments information from known symbols. * Create a link map structure for ld.so.1. * Initialize the runtime linkers information. * If ld.so.1 has been invoked directly, process its arguments. * Process any arguments that are specific to ld.so.1, and * reorganize the process stack to effectively remove ld.so.1 * from it. Reinitialize the environment pointer, as this may * have been shifted after skipping ld.so.1's arguments. * Open the object that ld.so.1 is to execute. * Map in the file, if exec has not already done so. If it has, * simply create a new link map structure for the executable. * Find out what type of object we have. * We now have a process name for error diagnostics. * Since ld.so.1 was the primary executed object - the * brk() base has not yet been initialized, we need to * initialize it. For an executable, initialize it to * the end of the object. For a shared object (ET_DYN) * initialize it to the first page in memory. * We scan the program headers to find the tail * of the memory image. We can't use MSIZE() * since that's already been page aligned. * The object has now been mmaped, we no longer need the file * Set up function ptr and arguments according to the type * of file class the executable is. (Currently only supported * types are ELF and a.out format.) Then create a link map * Set the memory size. Note, we only know the end of * text, and although we could find the _end by looking * up the symbol, this may not be present. We should * set ADDR to MAIN_BASE, but presently all the a.out * relocation code assumes ADDR is 0 for the dynamic * executable. (these data items are only used for * dladdr(3x), and there aren't many a.out dladdr(3x) * users to warrant spending much time on this :-). * Disable any object configuration cache (BCP apps * bring in sbcp which can benefit from any object * cache, but both the app and sbcp can't use the same * Make sure no-direct bindings are in effect. * Using the executables phdr address determine the base * address of the input file. NOTE, this assumes the * program headers and elf header are part of the same * mapped segment. Although this has held for many * years now, it might be more flexible if the kernel * gave use the ELF headers start address, rather than * Determine from the ELF header if we're been called * from a shared object or dynamic executable. If the * latter, then any addresses within the object are used * as is. Addresses within shared objects must be added * to the process's base address. * Allocate a mapping array to retain mapped segment * Extract the needed information from the segment * Retain segments mapping info. Round * each segment to a page boundary, as * this insures addresses are suitable * for mprotect() if required. * Establish the interpretors name as that defined within the initial * object (executable). This provides for ORIGIN processing of ld.so.1 * Having established the true runtime linkers name, simplify the name * Expand the fullpath name of the application. This typically occurs * as a part of loading an object, but as the kernel probably mapped * it in, complete this processing now. * Some troublesome programs will change the value of argv[0]. Dupping * the process string protects us, and insures the string is left in * If the kernel has provided hardware capabilities information, and * the executable contains hardware capabilities information, make * sure it's a valid object. * It's the responsibility of MAIN(crt0) to call it's _init and _fini * section, therefore null out any INIT/FINI so that this object isn't * collected during tsort processing. And, if the application has no * initarray or finiarray we can economize on establishing bindings. * Identify lddstub if necessary. * Retain our argument information for use in dlinfo. * Add our two main link-maps to the dynlm_list * Reset the link-map counts for both lists. The init count is used to * track how many objects have pending init sections, this gets incre- * mented each time an object is relocated. Since ld.so.1 relocates * itself, it's init count will remain zero. * The object count is used to track how many objects have pending fini * sections, as ld.so.1 handles its own fini we can zero its count. * Initialize debugger information structure. Some parts of this * structure were initialized statically. * Determine the dev/inode information for the executable to complete * load_so() checking for those who might dlopen(a.out). * Initialize any configuration information. * Establish the modes of the initial object. These modes are * propagated to any preloaded objects and explicit shared library * dependencies. Note, RTLD_NOW may have been established during * analysis of the application had it been built -z now. * If debugging was requested initialize things now that any cache has * been established. A user can specify LD_DEBUG=help to discover the * list of debugging tokens available without running the application. * However, don't allow this setting from a configuration file. * Note, to prevent recursion issues caused by loading and binding the * debugging libraries themselves, a local debugging descriptor is * initialized. Once the debugging setup has completed, this local * descriptor is copied to the global descriptor which effectively * enables diagnostic output. * Now that debugging is enabled generate any diagnostics from any * Any global auditing (set using LD_AUDIT or LD_PROFILE) that * can't be established is non-fatal. * Any object required auditing (set with a DT_DEPAUDIT dynamic * entry) that can't be established is fatal. * If this object requires global auditing, use the * local auditing information to set the global * auditing descriptor. The effect is that a * DT_DEPAUDIT act as an LD_AUDIT. * Clear the local auditor information. * Establish any local auditing. * Explicitly add the initial object and ld.so.1 to those objects being * audited. Note, although the ld.so.1 link-map isn't auditable, * establish a cookie for ld.so.1 as this may be bound to via the * Map in any preloadable shared objects. Note, it is valid to preload * a 4.x shared object with a 5.0 executable (or visa-versa), as this * functionality is required by ldd(1). * Load all dependent (needed) objects. * Relocate all the dependencies we've just added. * If this process has been established via crle(1), the environment * variable LD_CONFGEN will have been set. crle(1) may create this * process twice. The first time crle only needs to gather dependency * information. The second time, is to dldump() the images. * If we're only gathering dependencies, relocation is unnecessary. * As crle(1) may be building an arbitrary family of objects, they may * not fully relocate either. Hence the relocation phase is not carried * out now, but will be called by crle(1) once all objects have been * Inform the debuggers we're here and stable. Newer debuggers * can indicate their presence by setting the DT_DEBUG entry in * the dynamic executable (see elf_new_lm()). In this case call * getpid() so the debugger can catch the system call. This * handshake allows the debugger to initialize, and consequently * allows the user to set break points in .init code. * Indicate preinit activity, and call any auditing routines. These * routines are called before initializing any threads via libc, or * before collecting the complete set of .inits on the primary link-map. * Although most libc interfaces are encapsulated in local routines * within libc, they have been known to escape (ie. call a .plt). As * the appcert auditor uses preinit as a trigger to establish some * external interfaces to the main link-maps libc, we need to activate * this trigger before exercising any code within libc. Additionally, * I wouldn't put it past an auditor to add additional objects to the * primary link-map. Hence, we collect .inits after the audit call. * If we're creating initial configuration information, we're done * now that the auditing step has been called. * Sort the .init sections of all objects we've added. If we're * tracing we only need to execute this under ldd(1) with the -i or -u * If we are tracing we're done. This is the one legitimate use of a * direct call to rtldexit() rather than return, as we don't want to * return and jump to the application. * Establish any static TLS for this primary link-map. Note, regardless * of whether TLS is available, an initial handshake occurs with libc to * indicate we're processing the primary link-map. Having identified * the primary link-map, initialize threads. * Fire all dependencies .init sections. Identify any unused * dependencies, and leave the runtime linker - effectively calling * the dynamic executables entry point.