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