xref: /illumos-gate/usr/src/cmd/sgs/rtld/common/globals.c (revision 3afe87ebb25691cb6d158edaa34a6fb9b703a691)
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] = { 0 };
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