xref: /illumos-gate/usr/src/cmd/sgs/rtld/common/globals.c (revision 241c90a06e8d1708235651863df515a2d522a03a)
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 		MSG_LDD_REJ_KMOD	/* MSG_INTL(MSG_LDD_REJ_KMOD) */
236 	};
237 #if SGS_REJ_NUM != (SGS_REJ_KMOD + 1)
238 #error SGS_REJ_NUM has changed
239 #endif
240 
241 const Msg
242 err_reject[SGS_REJ_NUM] = {
243 		MSG_STR_EMPTY,
244 		MSG_ERR_REJ_MACH,	/* MSG_INTL(MSG_ERR_REJ_MACH) */
245 		MSG_ERR_REJ_CLASS,	/* MSG_INTL(MSG_ERR_REJ_CLASS) */
246 		MSG_ERR_REJ_DATA,	/* MSG_INTL(MSG_ERR_REJ_DATA) */
247 		MSG_ERR_REJ_TYPE,	/* MSG_INTL(MSG_ERR_REJ_TYPE) */
248 		MSG_ERR_REJ_BADFLAG,	/* MSG_INTL(MSG_ERR_REJ_BADFLAG) */
249 		MSG_ERR_REJ_MISFLAG,	/* MSG_INTL(MSG_ERR_REJ_MISFLAG) */
250 		MSG_ERR_REJ_VERSION,	/* MSG_INTL(MSG_ERR_REJ_VERSION) */
251 		MSG_ERR_REJ_HAL,	/* MSG_INTL(MSG_ERR_REJ_HAL) */
252 		MSG_ERR_REJ_US3,	/* MSG_INTL(MSG_ERR_REJ_US3) */
253 		MSG_ERR_REJ_STR,	/* MSG_INTL(MSG_ERR_REJ_STR) */
254 		MSG_ERR_REJ_UNKFILE,	/* MSG_INTL(MSG_ERR_REJ_UNKFILE) */
255 		MSG_ERR_REJ_UNKCAP,	/* MSG_INTL(MSG_ERR_REJ_UNKCAP) */
256 		MSG_ERR_REJ_HWCAP_1,	/* MSG_INTL(MSG_ERR_REJ_HWCAP_1) */
257 		MSG_ERR_REJ_SFCAP_1,	/* MSG_INTL(MSG_ERR_REJ_SFCAP_1) */
258 		MSG_ERR_REJ_MACHCAP,	/* MSG_INTL(MSG_ERR_REJ_MACHCAP) */
259 		MSG_ERR_REJ_PLATCAP,	/* MSG_INTL(MSG_ERR_REJ_PLATCAP) */
260 		MSG_ERR_REJ_HWCAP_2,	/* MSG_INTL(MSG_ERR_REJ_HWCAP_2) */
261 		MSG_ERR_REJ_ARCHIVE,	/* MSG_INTL(MSG_ERR_REJ_ARCHIVE) */
262 		MSG_ERR_REJ_KMOD,	/* MSG_INTL(MSG_ERR_REJ_KMOD) */
263 	};
264 #if SGS_REJ_NUM != (SGS_REJ_KMOD + 1)
265 #error SGS_REJ_NUM has changed
266 #endif
267 
268 const Msg
269 ldd_warn[SGS_REJ_NUM] = {
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_STR_EMPTY,
281 		MSG_STR_EMPTY,
282 		MSG_LDD_WARN_UNKCAP,	/* MSG_INTL(MSG_LDD_WARN_UNKCAP) */
283 		MSG_LDD_WARN_HWCAP_1,	/* MSG_INTL(MSG_LDD_WARN_HWCAP_1) */
284 		MSG_LDD_WARN_SFCAP_1,	/* MSG_INTL(MSG_LDD_WARN_SFCAP_1) */
285 		MSG_LDD_WARN_MACHCAP,	/* MSG_INTL(MSG_LDD_WARN_MACHCAP) */
286 		MSG_LDD_WARN_PLATCAP,	/* MSG_INTL(MSG_LDD_WARN_PLATCAP) */
287 		MSG_LDD_WARN_HWCAP_2,	/* MSG_INTL(MSG_LDD_WARN_HWCAP_2) */
288 		MSG_STR_EMPTY,
289 		MSG_STR_EMPTY,
290 	};
291 #if SGS_REJ_NUM != (SGS_REJ_KMOD + 1)
292 #error SGS_REJ_NUM has changed
293 #endif
294