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.
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.
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]
23 * Copyright (c) 1988 AT&T
26 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
29 #include <sys/types.h>
38 * Declarations of global variables used in ld.so.
41 int thr_flg_nolock
= 0;
42 int thr_flg_reenter
= 0;
45 * Major link-map lists.
47 Lm_list lml_main
= { 0 }; /* the `main's link map list */
48 Lm_list lml_rtld
= { 0 }; /* rtld's link map list */
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
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.
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).
71 ulong_t ld_entry_cnt
= 1;
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).
78 APlist
*dynlm_list
= NULL
; /* dynamic list of link-maps */
80 * END: Exposed to rtld_db
83 Reglist
*reglist
= NULL
; /* list of register symbols */
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.
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;
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 */
104 * Various other global data.
106 uint_t rtld_flags
= 0;
107 uint_t rtld_flags2
= 0;
109 Lc_desc glcs
[CI_MAX
]; /* global external interfaces */
111 const char *procname
= NULL
;
112 const char *rtldname
= MSG_ORIG(MSG_FIL_RTLD
);
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 */
123 uint_t audit_argcnt
= 64; /* no. of stack args to copy (default */
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 */
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 */
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 */
143 uint_t env_info
= 0; /* information regarding environment */
145 int killsig
= SIGKILL
; /* signal sent on fatal exit */
146 APlist
*free_alp
= NULL
; /* defragmentation list */
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.
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.
158 static Syscapset scapset
= { 0 };
159 Syscapset
*org_scapset
= &scapset
; /* original system and */
160 Syscapset
*alt_scapset
= &scapset
; /* alternative system */
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 */
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 */
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
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 */
184 #pragma weak environ = _environ /* environ for PLT tracing - we */
185 char **_environ
= NULL
; /* supply the pair to satisfy any */
186 /* libc requirements (hwmuldiv) */
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 */
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 */
200 Dl_argsinfo argsinfo
= { 0 }; /* process argument, environment and */
201 /* auxv information. */
204 * Frequently used messages are cached here to reduce _dgettext() overhead and
205 * also provide for resetting should the locale change (see _ld_libc()).
207 const char *err_strs
[ERR_NUM
] = { NULL
};
208 const char *nosym_str
= NULL
;
212 * Rejection error message tables.
215 ldd_reject
[SGS_REJ_NUM
] = {
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) */
236 #if SGS_REJ_NUM != (SGS_REJ_ARCHIVE + 1)
237 #error SGS_REJ_NUM has changed
241 err_reject
[SGS_REJ_NUM
] = {
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) */
262 #if SGS_REJ_NUM != (SGS_REJ_ARCHIVE + 1)
263 #error SGS_REJ_NUM has changed
267 ldd_warn
[SGS_REJ_NUM
] = {
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) */
288 #if SGS_REJ_NUM != (SGS_REJ_ARCHIVE + 1)
289 #error SGS_REJ_NUM has changed