1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1988 AT&T 23 * All Rights Reserved 24 * 25 * 26 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #include <sys/types.h> 32 #include <sys/mman.h> 33 #include <signal.h> 34 #include <dlfcn.h> 35 #include <synch.h> 36 #include <debug.h> 37 #include "_rtld.h" 38 39 /* 40 * Declarations of global variables used in ld.so. 41 */ 42 Rt_lock rtldlock; 43 44 /* 45 * Major link-map lists. 46 */ 47 Lm_list lml_main = { 0 }; /* the `main's link map list */ 48 Lm_list lml_rtld = { 0 }; /* rtld's link map list */ 49 50 /* 51 * Entrance count. Each time ld.so.1 is entered this count is bumped. This 52 * value serves to identify the present ld.so.1 operation. Any ld.so.1 53 * operation can result in many symbol lookup requests (ie. loading objects and 54 * relocating all symbolic bindings). This count is used to protect against 55 * attempting to re-load a failed lazy load within a single call to ld.so.1, 56 * while allowing such attempts across calls. Should a lazy load fail, the 57 * present operation identifier is saved in the current symbol lookup data 58 * block (Slookup). Should a lazy load fall back operation be triggered, the 59 * identifier in the symbol lookup block is compared to the current ld.so.1 60 * entry count, and if the two are equal the fall back is skipped. 61 * 62 * With this count, there is a danger of wrap-around, although as an unsigned 63 * 32-bit value, it is highly unlikely that any application could usefully make 64 * 4.3 giga-calls into ld.so.1. The worst that can occur is that a fall back 65 * lazy load isn't triggered. However, most lazy loads that fail typically 66 * continue to fail unless the user takes corrective action (adds the necessary 67 * (fixed) dependencies to the system. 68 */ 69 ulong_t ld_entry_cnt = 0; 70 71 /* 72 * BEGIN: Exposed to rtld_db, don't change without a coordinated handshake with 73 * librtld_db (remembering that librtld_db must be able to read old as well as 74 * current core files). 75 */ 76 List dynlm_list = { 0, 0 }; /* dynamic list of link-maps */ 77 /* 78 * END: Exposed to rtld_db 79 */ 80 81 Reglist * reglist = 0; /* list of register symbols */ 82 83 ulong_t hwcap = 0; /* hardware capabilities */ 84 ulong_t sfcap = 0; /* software capabilities */ 85 86 /* 87 * Initialized fmap structure. 88 */ 89 static Fmap _fmap = { 0, 0, 0, 0, 0 }; 90 Fmap * fmap = &_fmap; /* initial file mapping info */ 91 92 /* 93 * Set of integers to track how many of what type of 94 * PLT's have been bound. This is only really interesting 95 * for SPARC since ia32 basically just has the one PLT. 96 */ 97 uint32_t pltcnt21d = 0; 98 uint32_t pltcnt24d = 0; 99 uint32_t pltcntu32 = 0; 100 uint32_t pltcntu44 = 0; 101 uint32_t pltcntfull = 0; 102 uint32_t pltcntfar = 0; 103 104 /* 105 * Enable technology (via status flags for RTLD) dependent upon whether we're 106 * in a patch or major release build environment. 107 */ 108 uint_t rtld_flags = 109 #ifdef EXPAND_RELATIVE 110 RT_FL_RELATIVE | 111 #endif 112 #ifdef SIEBEL_DISABLE 113 RT_FL_DISFIX_1 | 114 #endif 115 RT_FL_NOCONCUR; 116 uint_t rtld_flags2 = 0; 117 118 /* 119 * Various other global data. 120 */ 121 Lc_desc glcs[CI_MAX]; /* global external interfaces */ 122 123 const char *procname = (const char *)0; 124 const char *rtldname = MSG_ORIG(MSG_FIL_RTLD); 125 126 char *lasterr = (char *)0; /* string describing last error */ 127 /* cleared by each dlerror() */ 128 Interp *interp = 0; /* ELF interpreter info */ 129 List hdl_list[HDLIST_SZ+2]; /* dlopen() handle list */ 130 size_t syspagsz = 0; /* system page size */ 131 unsigned long at_flags = 0; /* machine specific file flags */ 132 char *platform = 0; /* platform name from AT_SUN_PLATFORM */ 133 size_t platform_sz = 0; /* platform string length */ 134 Uts_desc *uts; /* utsname descriptor */ 135 Isa_desc *isa; /* isalist descriptor */ 136 137 uint_t audit_argcnt = 64; /* no. of stack args to copy (default */ 138 /* is all) */ 139 Audit_desc *auditors = 0; /* global auditors (LD_AUDIT) */ 140 141 const char *rpl_audit = 0; /* replaceable LD_AUDIT string */ 142 const char *rpl_debug = 0; /* replaceable LD_DEBUG string */ 143 const char *rpl_ldflags = 0; /* replaceable LD_FLAGS string */ 144 const char *rpl_libpath = 0; /* replaceable LD_LIBRARY_PATH string */ 145 Pnode *rpl_libdirs = 0; /* and associated Pnode list */ 146 const char *rpl_preload = 0; /* replaceable LD_PRELOAD string */ 147 148 const char *prm_audit = 0; /* permanent LD_AUDIT string */ 149 const char *prm_debug = 0; /* permanent LD_DEBUG string */ 150 const char *prm_ldflags = 0; /* permanent LD_FLAGS string */ 151 const char *prm_libpath = 0; /* permanent LD_LIBRARY_PATH string */ 152 Pnode *prm_libdirs = 0; /* and associated Pnode list */ 153 const char *prm_preload = 0; /* permanent LD_PRELOAD string */ 154 155 uint_t env_info = 0; /* information regarding environment */ 156 /* variables */ 157 int killsig = SIGKILL; /* signal sent on fatal exit */ 158 159 /* 160 * Note, the debugging descriptor interposes on the default definition provided 161 * by liblddbg. This is required as ld.so.1 must only have outstanding relative 162 * relocations. 163 */ 164 static Dbg_desc _dbg_desc = {0, 0, 0}; 165 Dbg_desc *dbg_desc = &_dbg_desc; /* debugging descriptor */ 166 const char *dbg_file = 0; /* debugging directed to file */ 167 168 #pragma weak environ = _environ /* environ for PLT tracing - we */ 169 char **_environ = 0; /* supply the pair to satisfy any */ 170 /* libc requirements (hwmuldiv) */ 171 172 const char *profile_name; /* object being profiled */ 173 const char *profile_out; /* profile output file */ 174 const char *profile_lib; /* audit library to perform profile */ 175 176 unsigned char search_rules[] = { /* dependency search rules */ 177 RPLENV, /* replaceable LD_LIBRARY_PATH */ 178 PRMENV, /* permanent LD_LIBRARY_PATH */ 179 RUNPATH, /* callers runpath */ 180 DEFAULT, /* default library path */ 181 0 182 }; 183 184 Dl_argsinfo argsinfo = { 0 }; /* process argument, environment and */ 185 /* auxv information. */ 186 187 /* 188 * Frequently used messages are cached here to reduce _dgettext() overhead and 189 * also provide for resetting should the locale change (see _ld_libc()). 190 */ 191 const char *err_strs[ERR_NUM] = { 0 }; 192 const char *nosym_str = 0; 193 194 195 /* 196 * Rejection error message tables. 197 */ 198 const Msg 199 ldd_reject[] = { 200 MSG_STR_EMPTY, 201 MSG_LDD_REJ_MACH, /* MSG_INTL(MSG_LDD_REJ_MACH) */ 202 MSG_LDD_REJ_CLASS, /* MSG_INTL(MSG_LDD_REJ_CLASS) */ 203 MSG_LDD_REJ_DATA, /* MSG_INTL(MSG_LDD_REJ_DATA) */ 204 MSG_LDD_REJ_TYPE, /* MSG_INTL(MSG_LDD_REJ_TYPE) */ 205 MSG_LDD_REJ_BADFLAG, /* MSG_INTL(MSG_LDD_REJ_BADFLAG) */ 206 MSG_LDD_REJ_MISFLAG, /* MSG_INTL(MSG_LDD_REJ_MISFLAG) */ 207 MSG_LDD_REJ_VERSION, /* MSG_INTL(MSG_LDD_REJ_VERSION) */ 208 MSG_LDD_REJ_HAL, /* MSG_INTL(MSG_LDD_REJ_HAL) */ 209 MSG_LDD_REJ_US3, /* MSG_INTL(MSG_LDD_REJ_US3) */ 210 MSG_LDD_REJ_STR, /* MSG_INTL(MSG_LDD_REJ_STR) */ 211 MSG_LDD_REJ_UNKFILE, /* MSG_INTL(MSG_LDD_REJ_UNKFILE) */ 212 MSG_LDD_REJ_HWCAP_1, /* MSG_INTL(MSG_LDD_REJ_HWCAP_1) */ 213 }; 214 215 216 const Msg 217 err_reject[] = { 218 MSG_STR_EMPTY, 219 MSG_ERR_REJ_MACH, /* MSG_INTL(MSG_ERR_REJ_MACH) */ 220 MSG_ERR_REJ_CLASS, /* MSG_INTL(MSG_ERR_REJ_CLASS) */ 221 MSG_ERR_REJ_DATA, /* MSG_INTL(MSG_ERR_REJ_DATA) */ 222 MSG_ERR_REJ_TYPE, /* MSG_INTL(MSG_ERR_REJ_TYPE) */ 223 MSG_ERR_REJ_BADFLAG, /* MSG_INTL(MSG_ERR_REJ_BADFLAG) */ 224 MSG_ERR_REJ_MISFLAG, /* MSG_INTL(MSG_ERR_REJ_MISFLAG) */ 225 MSG_ERR_REJ_VERSION, /* MSG_INTL(MSG_ERR_REJ_VERSION) */ 226 MSG_ERR_REJ_HAL, /* MSG_INTL(MSG_ERR_REJ_HAL) */ 227 MSG_ERR_REJ_US3, /* MSG_INTL(MSG_ERR_REJ_US3) */ 228 MSG_ERR_REJ_STR, /* MSG_INTL(MSG_ERR_REJ_STR) */ 229 MSG_ERR_REJ_UNKFILE, /* MSG_INTL(MSG_ERR_REJ_UNKFILE) */ 230 MSG_ERR_REJ_HWCAP_1, /* MSG_INTL(MSG_ERR_REJ_HWCAP_1) */ 231 }; 232