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 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. 27 */ 28 29 #include <sys/types.h> 30 #include <sys/mman.h> 31 #include <signal.h> 32 #include <dlfcn.h> 33 #include <synch.h> 34 #include <debug.h> 35 #include "_rtld.h" 36 37 /* 38 * Declarations of global variables used in ld.so. 39 */ 40 Rt_lock rtldlock; 41 int thr_flg_nolock = 0; 42 int thr_flg_reenter = 0; 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 following initial process 52 * setup, this count is bumped. This value serves to identify the present 53 * ld.so.1 operation. 54 * 55 * An ld.so.1 operation can result in many symbol lookup requests (i.e., loading 56 * objects and relocating all symbolic bindings). This count is used to protect 57 * against attempting to re-load a failed lazy load within a single call to 58 * ld.so.1, while allowing such attempts across calls. Should a lazy load fail, 59 * the present operation identifier is saved in the current symbol lookup data 60 * block (Slookup). Should a lazy load fall back operation be triggered, the 61 * identifier in the symbol lookup block is compared to the current ld.so.1 62 * entry count, and if the two are equal the fall back is skipped. 63 * 64 * With this count, there is a danger of wrap-around, although as an unsigned 65 * 32-bit value, it is highly unlikely that any application could usefully make 66 * 4.3 giga-calls into ld.so.1. The worst that can occur is that a fall back 67 * lazy load isn't triggered. However, most lazy loads that fail typically 68 * continue to fail unless the user takes corrective action (adds the necessary 69 * (fixed) dependencies to the system). 70 */ 71 ulong_t ld_entry_cnt = 1; 72 73 /* 74 * BEGIN: Exposed to rtld_db, don't change without a coordinated handshake with 75 * librtld_db (remembering that librtld_db must be able to read old as well as 76 * current core files). 77 */ 78 APlist *dynlm_list = NULL; /* dynamic list of link-maps */ 79 /* 80 * END: Exposed to rtld_db 81 */ 82 83 Reglist *reglist = NULL; /* list of register symbols */ 84 85 /* 86 * Set of integers to track how many of what type of PLT's have been bound. 87 * This is only really interesting for SPARC since ia32 has only one PLT. 88 */ 89 uint32_t pltcnt21d = 0; 90 uint32_t pltcnt24d = 0; 91 uint32_t pltcntu32 = 0; 92 uint32_t pltcntu44 = 0; 93 uint32_t pltcntfull = 0; 94 uint32_t pltcntfar = 0; 95 96 /* 97 * AVL tree pointers. 98 */ 99 avl_tree_t *capavl = NULL; /* capabilities files */ 100 avl_tree_t *nfavl = NULL; /* not-found path names */ 101 avl_tree_t *spavl = NULL; /* secure path names */ 102 103 /* 104 * Various other global data. 105 */ 106 uint_t rtld_flags = 0; 107 uint_t rtld_flags2 = 0; 108 109 Lc_desc glcs[CI_MAX]; /* global external interfaces */ 110 111 const char *procname = NULL; 112 const char *rtldname = MSG_ORIG(MSG_FIL_RTLD); 113 114 char *lasterr = NULL; /* string describing last error */ 115 /* cleared by each dlerror() */ 116 Interp *interp = NULL; /* ELF interpreter info */ 117 APlist *hdl_alp[HDLIST_SZ+2]; /* dlopen() handle list */ 118 size_t syspagsz = 0; /* system page size */ 119 ulong_t at_flags = 0; /* machine specific file flags */ 120 Uts_desc *uts = NULL; /* utsname descriptor */ 121 Isa_desc *isa = NULL; /* isalist descriptor */ 122 123 uint_t audit_argcnt = 64; /* no. of stack args to copy (default */ 124 /* is all) */ 125 Audit_desc *auditors = NULL; /* global auditors (LD_AUDIT) */ 126 APlist *aud_preinit = NULL; /* list of objects defining local */ 127 APlist *aud_activity = NULL; /* preinit and activity auditors */ 128 129 const char *rpl_audit = NULL; /* replaceable LD_AUDIT string */ 130 const char *rpl_debug = NULL; /* replaceable LD_DEBUG string */ 131 const char *rpl_ldflags = NULL; /* replaceable LD_FLAGS string */ 132 const char *rpl_libpath = NULL; /* replaceable LD_LIBRARY_PATH string */ 133 Alist *rpl_libdirs = NULL; /* and associated Pdesc list */ 134 const char *rpl_preload = NULL; /* replaceable LD_PRELOAD string */ 135 136 const char *prm_audit = NULL; /* permanent LD_AUDIT string */ 137 const char *prm_debug = NULL; /* permanent LD_DEBUG string */ 138 const char *prm_ldflags = NULL; /* permanent LD_FLAGS string */ 139 const char *prm_libpath = NULL; /* permanent LD_LIBRARY_PATH string */ 140 Alist *prm_libdirs = NULL; /* and associated Pdesc list */ 141 const char *prm_preload = NULL; /* permanent LD_PRELOAD string */ 142 143 uint_t env_info = 0; /* information regarding environment */ 144 /* variables */ 145 int killsig = SIGKILL; /* signal sent on fatal exit */ 146 APlist *free_alp = NULL; /* defragmentation list */ 147 148 /* 149 * Capabilities are provided by the system. However, users can define an 150 * alternative set of system capabilities, where they can add, subtract, or 151 * override the system capabilities for testing purposes. Furthermore, these 152 * alternative capabilities can be specified such that they only apply to 153 * specified files rather than to all objects. 154 * 155 * The org_scapset is relied upon by the amd64 version of elf_rtbndr to 156 * determine whether or not AVX registers are present in the system. 157 */ 158 static Syscapset scapset = { 0 }; 159 Syscapset *org_scapset = &scapset; /* original system and */ 160 Syscapset *alt_scapset = &scapset; /* alternative system */ 161 /* capabilities */ 162 163 const char *rpl_hwcap = NULL; /* replaceable hwcap str */ 164 const char *rpl_sfcap = NULL; /* replaceable sfcap str */ 165 const char *rpl_machcap = NULL; /* replaceable machcap str */ 166 const char *rpl_platcap = NULL; /* replaceable platcap str */ 167 const char *rpl_cap_files = NULL; /* associated files */ 168 169 const char *prm_hwcap = NULL; /* permanent hwcap str */ 170 const char *prm_sfcap = NULL; /* permanent sfcap str */ 171 const char *prm_machcap = NULL; /* permanent machcap str */ 172 const char *prm_platcap = NULL; /* permanent platcap str */ 173 const char *prm_cap_files = NULL; /* associated files */ 174 175 /* 176 * Note, the debugging descriptor interposes on the default definition provided 177 * by liblddbg. This is required as ld.so.1 must only have outstanding relative 178 * relocations. 179 */ 180 static Dbg_desc _dbg_desc = {0, 0, 0}; 181 Dbg_desc *dbg_desc = &_dbg_desc; /* debugging descriptor */ 182 const char *dbg_file = NULL; /* debugging directed to file */ 183 184 #pragma weak environ = _environ /* environ for PLT tracing - we */ 185 char **_environ = NULL; /* supply the pair to satisfy any */ 186 /* libc requirements (hwmuldiv) */ 187 188 const char *profile_name = NULL; /* object being profiled */ 189 const char *profile_out = NULL; /* profile output file */ 190 const char *profile_lib = NULL; /* audit library to perform profile */ 191 192 uchar_t search_rules[] = { /* dependency search rules */ 193 RPLENV, /* replaceable LD_LIBRARY_PATH */ 194 PRMENV, /* permanent LD_LIBRARY_PATH */ 195 RUNPATH, /* callers runpath */ 196 DEFAULT, /* default library path */ 197 0 198 }; 199 200 Dl_argsinfo argsinfo = { 0 }; /* process argument, environment and */ 201 /* auxv information. */ 202 203 /* 204 * Frequently used messages are cached here to reduce _dgettext() overhead and 205 * also provide for resetting should the locale change (see _ld_libc()). 206 */ 207 const char *err_strs[ERR_NUM] = { NULL }; 208 const char *nosym_str = NULL; 209 210 211 /* 212 * Rejection error message tables. 213 */ 214 const Msg 215 ldd_reject[SGS_REJ_NUM] = { 216 MSG_STR_EMPTY, 217 MSG_LDD_REJ_MACH, /* MSG_INTL(MSG_LDD_REJ_MACH) */ 218 MSG_LDD_REJ_CLASS, /* MSG_INTL(MSG_LDD_REJ_CLASS) */ 219 MSG_LDD_REJ_DATA, /* MSG_INTL(MSG_LDD_REJ_DATA) */ 220 MSG_LDD_REJ_TYPE, /* MSG_INTL(MSG_LDD_REJ_TYPE) */ 221 MSG_LDD_REJ_BADFLAG, /* MSG_INTL(MSG_LDD_REJ_BADFLAG) */ 222 MSG_LDD_REJ_MISFLAG, /* MSG_INTL(MSG_LDD_REJ_MISFLAG) */ 223 MSG_LDD_REJ_VERSION, /* MSG_INTL(MSG_LDD_REJ_VERSION) */ 224 MSG_LDD_REJ_HAL, /* MSG_INTL(MSG_LDD_REJ_HAL) */ 225 MSG_LDD_REJ_US3, /* MSG_INTL(MSG_LDD_REJ_US3) */ 226 MSG_LDD_REJ_STR, /* MSG_INTL(MSG_LDD_REJ_STR) */ 227 MSG_LDD_REJ_UNKFILE, /* MSG_INTL(MSG_LDD_REJ_UNKFILE) */ 228 MSG_LDD_REJ_UNKCAP, /* MSG_INTL(MSG_LDD_REJ_UNKCAP) */ 229 MSG_LDD_REJ_HWCAP_1, /* MSG_INTL(MSG_LDD_REJ_HWCAP_1) */ 230 MSG_LDD_REJ_SFCAP_1, /* MSG_INTL(MSG_LDD_REJ_SFCAP_1) */ 231 MSG_LDD_REJ_MACHCAP, /* MSG_INTL(MSG_LDD_REJ_MACHCAP) */ 232 MSG_LDD_REJ_PLATCAP, /* MSG_INTL(MSG_LDD_REJ_PLATCAP) */ 233 MSG_LDD_REJ_HWCAP_2, /* MSG_INTL(MSG_LDD_REJ_HWCAP_2) */ 234 MSG_LDD_REJ_ARCHIVE /* MSG_INTL(MSG_LDD_REJ_ARCHIVE) */ 235 }; 236 #if SGS_REJ_NUM != (SGS_REJ_ARCHIVE + 1) 237 #error SGS_REJ_NUM has changed 238 #endif 239 240 const Msg 241 err_reject[SGS_REJ_NUM] = { 242 MSG_STR_EMPTY, 243 MSG_ERR_REJ_MACH, /* MSG_INTL(MSG_ERR_REJ_MACH) */ 244 MSG_ERR_REJ_CLASS, /* MSG_INTL(MSG_ERR_REJ_CLASS) */ 245 MSG_ERR_REJ_DATA, /* MSG_INTL(MSG_ERR_REJ_DATA) */ 246 MSG_ERR_REJ_TYPE, /* MSG_INTL(MSG_ERR_REJ_TYPE) */ 247 MSG_ERR_REJ_BADFLAG, /* MSG_INTL(MSG_ERR_REJ_BADFLAG) */ 248 MSG_ERR_REJ_MISFLAG, /* MSG_INTL(MSG_ERR_REJ_MISFLAG) */ 249 MSG_ERR_REJ_VERSION, /* MSG_INTL(MSG_ERR_REJ_VERSION) */ 250 MSG_ERR_REJ_HAL, /* MSG_INTL(MSG_ERR_REJ_HAL) */ 251 MSG_ERR_REJ_US3, /* MSG_INTL(MSG_ERR_REJ_US3) */ 252 MSG_ERR_REJ_STR, /* MSG_INTL(MSG_ERR_REJ_STR) */ 253 MSG_ERR_REJ_UNKFILE, /* MSG_INTL(MSG_ERR_REJ_UNKFILE) */ 254 MSG_ERR_REJ_UNKCAP, /* MSG_INTL(MSG_ERR_REJ_UNKCAP) */ 255 MSG_ERR_REJ_HWCAP_1, /* MSG_INTL(MSG_ERR_REJ_HWCAP_1) */ 256 MSG_ERR_REJ_SFCAP_1, /* MSG_INTL(MSG_ERR_REJ_SFCAP_1) */ 257 MSG_ERR_REJ_MACHCAP, /* MSG_INTL(MSG_ERR_REJ_MACHCAP) */ 258 MSG_ERR_REJ_PLATCAP, /* MSG_INTL(MSG_ERR_REJ_PLATCAP) */ 259 MSG_ERR_REJ_HWCAP_2, /* MSG_INTL(MSG_ERR_REJ_HWCAP_2) */ 260 MSG_ERR_REJ_ARCHIVE, /* MSG_INTL(MSG_ERR_REJ_ARCHIVE) */ 261 }; 262 #if SGS_REJ_NUM != (SGS_REJ_ARCHIVE + 1) 263 #error SGS_REJ_NUM has changed 264 #endif 265 266 const Msg 267 ldd_warn[SGS_REJ_NUM] = { 268 MSG_STR_EMPTY, 269 MSG_STR_EMPTY, 270 MSG_STR_EMPTY, 271 MSG_STR_EMPTY, 272 MSG_STR_EMPTY, 273 MSG_STR_EMPTY, 274 MSG_STR_EMPTY, 275 MSG_STR_EMPTY, 276 MSG_STR_EMPTY, 277 MSG_STR_EMPTY, 278 MSG_STR_EMPTY, 279 MSG_STR_EMPTY, 280 MSG_LDD_WARN_UNKCAP, /* MSG_INTL(MSG_LDD_WARN_UNKCAP) */ 281 MSG_LDD_WARN_HWCAP_1, /* MSG_INTL(MSG_LDD_WARN_HWCAP_1) */ 282 MSG_LDD_WARN_SFCAP_1, /* MSG_INTL(MSG_LDD_WARN_SFCAP_1) */ 283 MSG_LDD_WARN_MACHCAP, /* MSG_INTL(MSG_LDD_WARN_MACHCAP) */ 284 MSG_LDD_WARN_PLATCAP, /* MSG_INTL(MSG_LDD_WARN_PLATCAP) */ 285 MSG_LDD_WARN_HWCAP_2, /* MSG_INTL(MSG_LDD_WARN_HWCAP_2) */ 286 MSG_STR_EMPTY 287 }; 288 #if SGS_REJ_NUM != (SGS_REJ_ARCHIVE + 1) 289 #error SGS_REJ_NUM has changed 290 #endif