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 * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
30 */
31#ifndef	__RTLD_H
32#define	__RTLD_H
33
34/*
35 * Common header for run-time linker.
36 */
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <sys/avl.h>
40#include <sys/mman.h>
41#include <stdarg.h>
42#include <synch.h>
43#include <signal.h>
44#include <errno.h>
45#include <unistd.h>
46#include <link.h>
47#include <rtld.h>
48#include <sgs.h>
49#include <machdep.h>
50#include <rtc.h>
51#include <debug.h>
52#include <msg.h>
53#include <libc_int.h>
54
55#ifdef	__cplusplus
56extern "C" {
57#endif
58
59/*
60 * Dependency search rule order.
61 */
62#define	RPLENV		1		/* replaceable LD_LIBRARY_PATH */
63#define	PRMENV		2		/* permanent LD_LIBRARY_PATH */
64#define	RUNPATH		3		/* callers runpath */
65#define	DEFAULT		4		/* default library path */
66
67typedef struct fdesc	Fdesc;
68typedef struct fct	Fct;
69typedef	struct pdesc	Pdesc;
70
71/*
72 * Data structure for file class specific functions and data.
73 */
74struct fct {
75	/* Verify that the object is of this class. */
76	Fct	*(*fct_verify_file)(caddr_t, size_t, Fdesc *, const char *,
77	    Rej_desc *);
78
79	/* Generate a link-map to describe the loaded object. */
80	Rt_map	*(*fct_new_lmp)(Lm_list *, Aliste, Fdesc *, Addr, size_t,
81	    void *, Rt_map *, int *);
82
83	/* Retrieve the entry point of the object. */
84	Addr	(*fct_entry_pt)(void);
85
86	/* Determine the objects dependencies (needed entries). */
87	int	(*fct_needed)(Lm_list *, Aliste, Rt_map *, int *);
88
89	/* Look up a symbol for the object. */
90	int	(*fct_lookup_sym)(Slookup *, Sresult *, uint_t *, int *);
91
92	/* Relocate the object. */
93	int	(*fct_reloc)(Rt_map *, uint_t, int *, APlist **);
94
95	/* List of default directories to search for dependencies. */
96	Alist	**(*fct_get_def_dirs)(void);
97
98	/* List of secure directories to search for dependencies. */
99	Alist	**(*fct_get_sec_dirs)(void);
100
101	/* Transpose the name of the object. */
102	int	(*fct_fix_name)(const char *, Rt_map *, Alist **, Aliste,
103	    uint_t);
104
105	/* Get a shared object name */
106	char	*(*fct_get_so)(const char *, const char *, size_t, size_t);
107
108	/* Retrieve a symbolic address from the object. */
109	void	(*fct_dladdr)(ulong_t, Rt_map *, Dl_info *, void **, int);
110
111	/* Process a dlsym(3c) request within the object. */
112	int	(*fct_dlsym)(Grp_hdl *, Slookup *, Sresult *, uint_t *, int *);
113};
114
115/*
116 * Macros for getting to the file class table.
117 */
118#define	LM_ENTRY_PT(X)		((X)->rt_fct->fct_entry_pt)
119#define	LM_NEEDED(X)		((X)->rt_fct->fct_needed)
120#define	LM_LOOKUP_SYM(X)	((X)->rt_fct->fct_lookup_sym)
121#define	LM_RELOC(X)		((X)->rt_fct->fct_reloc)
122#define	LM_DEFAULT_DIRS(X)	((X)->rt_fct->fct_get_def_dirs)
123#define	LM_SECURE_DIRS(X)	((X)->rt_fct->fct_get_sec_dirs)
124#define	LM_FIX_NAME(X)		((X)->rt_fct->fct_fix_name)
125#define	LM_GET_SO(X)		((X)->rt_fct->fct_get_so)
126#define	LM_DLADDR(X)		((X)->rt_fct->fct_dladdr)
127#define	LM_DLSYM(X)		((X)->rt_fct->fct_dlsym)
128
129/*
130 * Initial memory map allocation.  Typical ELF objects contain a text and data
131 * segment, which can be augmented with a bss mapping.  Add a bunch more for
132 * luck.
133 */
134#define	MMAPFD_NUM	10
135
136/*
137 * Define Alist initialization counts.
138 */
139#define	AL_CNT_ALIAS	2		/* ALIAS() */
140#define	AL_CNT_DEPENDS	20		/* DEPENDS() */
141#define	AL_CNT_CALLERS	20		/* CALLERS() */
142#define	AL_CNT_GROUPS	20		/* GROUPS() */
143#define	AL_CNT_COPYREL	10		/* COPY() */
144#define	AL_CNT_LAZYFIND	10		/* elf_lazy_find_sym() */
145#define	AL_CNT_GRPCLCT	10		/* gdp_collect() */
146#define	AL_CNT_DEPCLCT	10		/* load_finish() */
147#define	AL_CNT_RTLDINFO	1		/* RTLDINFO() */
148#define	AL_CNT_FPNODE	4		/* FPNODE() */
149#define	AL_CNT_LMLISTS	20		/* lm_lists */
150#define	AL_CNT_LMNOW	8		/* lm_now */
151#define	AL_CNT_RELBIND	20		/* relocation binding */
152#define	AL_CNT_ACTAUDIT	2		/* lm_actaudit */
153#define	AL_CNT_MOVES	10		/* move_data */
154#define	AL_CNT_MPOBJS	4		/* elf_obj_file() */
155#define	AL_CNT_TEXTREL	2		/* text relocation segment */
156#define	AL_CNT_NEEDED	1		/* dependency path */
157#define	AL_CNT_SEARCH	4		/* search path */
158#define	AL_CNT_FILTEES	2		/* filtee path */
159#define	AL_CNT_HANDLES	1		/* hdl_list[] */
160#define	AL_CNT_FREELIST	80		/* free_alp */
161#define	AL_CNT_CAP	10		/* capabilities candidate */
162#define	AL_CNT_SPATH	4		/* search path */
163#define	AL_CNT_DYNLIST	2		/* dynlm_list */
164#define	AL_CNT_PENDING	2		/* pending tsort list (INITFIRST) */
165#define	AL_CNT_PLTPAD	10		/* plt padding */
166#define	AL_CNT_AUDITORS	2		/* auditing list */
167#define	AL_CNT_ENVIRON	20		/* environment list (enough for ldd) */
168#define	AL_CNT_COOKIES	2		/* head link-map list cookies */
169
170/*
171 * Size of buffer for building error messages.
172 */
173#define	ERRSIZE		2048		/* MAXPATHLEN * 2 */
174
175/*
176 * Configuration file information.
177 */
178typedef struct config {
179	const char	*c_name;
180	Addr		c_bgn;
181	Addr		c_end;
182	Word		*c_hashtbl;
183	Word		*c_hashchain;
184	const char	*c_strtbl;
185	Rtc_obj		*c_objtbl;
186	Rtc_fltr	*c_fltr;
187	Rtc_flte	*c_flte;
188} Config;
189
190/*
191 * Register symbol list.
192 */
193typedef struct reglist {
194	Rt_map		*rl_lmp;	/* defining object */
195	Sym		*rl_sym;	/* regsym */
196	struct reglist	*rl_next;	/* next entry */
197} Reglist;
198
199/*
200 * Data structure to hold interpreter information.
201 */
202typedef struct interp {
203	char		*i_name;	/* interpreter name */
204	caddr_t		i_faddr;	/* address interpreter is mapped at */
205} Interp;
206
207/*
208 * Data structure used to keep track of copy relocations.  These relocations
209 * are collected during initial relocation processing and maintained on the
210 * COPY(lmp) list of the defining object.  Each copy list is also added to the
211 * COPY(lmp) of the head object (normally the application dynamic executable)
212 * from which they will be processed after all relocations are done.
213 *
214 * The use of RTLD_GROUP will also reference individual objects COPY(lmp) lists
215 * in case a bound symbol must be assigned to it actual copy relocation.
216 */
217typedef struct {
218	const char	*r_name;	/* symbol name */
219	Sym		*r_rsym;	/* reference symbol table entry */
220	Rt_map		*r_rlmp;	/* reference link map */
221	Rt_map		*r_dlmp;	/* definition link map */
222	Sym		*r_dsym;	/* definition symbol table entry */
223	void		*r_radd;	/* copy to address */
224	const void	*r_dadd;	/* copy from address */
225	ulong_t		r_size;		/* copy size bytes */
226} Rel_copy;
227
228/*
229 * Define a file descriptor, which maintains information regarding a pathname
230 * that has been opened and minimally inspected.
231 */
232struct fdesc {
233	Rt_map		*fd_lmp;	/* existing link-map pointer */
234	Lm_list		*fd_lml;	/* callers link-map list */
235	Fct		*fd_ftp;	/* file functions pointer */
236	const char	*fd_oname;	/* original file name */
237	const char	*fd_odir;	/* original directory name */
238	const char	*fd_nname;	/* new file (expanded) name */
239	const char	*fd_pname;	/* new path (resolved) name */
240	dev_t		fd_dev;		/* file device number */
241	rtld_ino_t	fd_ino;		/* file inode number */
242	avl_index_t	fd_avlwhere;	/* avl tree insertion index */
243	Syscapset	fd_scapset;	/* capabilities */
244	mmapobj_result_t *fd_mapp;	/* mapping pointer */
245	uint_t		fd_mapn;	/* mapping number */
246	uint_t		fd_flags;
247};
248
249#define	FLG_FD_ALTER	0x0001		/* file is an alternate */
250#define	FLG_FD_SLASH	0x0002		/* file contains a "/" */
251#define	FLG_FD_RESOLVED	0x0004		/* fd_nname has been resolved */
252#define	FLG_FD_ALTCHECK	0x0008		/* alternative system capabilities */
253					/*	checked */
254#define	FLG_FD_ALTCAP	0x0010		/* alternative system capabilities */
255					/*	should be used */
256#define	FLG_FD_IGNORE	0x0020		/* descriptor should be ignored */
257
258/*
259 * File descriptor availability flag.
260 */
261#define	FD_UNAVAIL	-1
262
263/*
264 * Disabled filter flag.  Filter objects are referenced using their .dynamic
265 * index (DT_FILTER or DT_AUXILIARY).  This index is saved and used to lookup
266 * the required filter.  Note that 0 is a valid .dynamic index.  The caller's
267 * OBJFLTRNDX() element is initialized using the following flag, and should
268 * the filter's initialization fail, is reset to this value to indicate the
269 * filter is disabled.  UINT_MAX provides a convenient invalid .dynamic index.
270 */
271#define	FLTR_DISABLED	UINT_MAX
272
273/*
274 * Status flags for rtld_flags
275 */
276#define	RT_FL_THREADS	0x00000001	/* threads are enabled */
277#define	RT_FL_WARNFLTR	0x00000002	/* warn of missing filtees (ldd) */
278#define	RT_FL_DBNOTIF	0x00000004	/* binding activity going on */
279#define	RT_FL_DEFERRED	0x00000008	/* load deferred dependencies (ldd) */
280#define	RT_FL_NOBIND	0x00000010	/* don't carry out plt binding */
281#define	RT_FL_NOVERSION	0x00000020	/* disable version checking */
282#define	RT_FL_SECURE	0x00000040	/* setuid/segid flag */
283#define	RT_FL_APPLIC	0x00000080	/* executing application code */
284#define	RT_FL_NOENVIRON	0x00000100	/* don't process environment */
285					/*	variables (ld.so.1 -e) */
286#define	RT_FL_CONFGEN	0x00000200	/* don't relocate initiating object */
287					/*	set by crle(1) */
288#define	RT_FL_CONFAPP	0x00000400	/* application specific configuration */
289					/*	cache required */
290#define	RT_FL_DEBUGGER	0x00000800	/* a debugger is monitoring us */
291#define	RT_FL_OPERATION	0x00001000	/* start recording operations */
292#define	RT_FL_NEWLOCALE	0x00002000	/* message locale has changed */
293#define	RT_FL_NOBAPLT	0x00004000	/* sparc: don't use ba plt's */
294#define	RT_FL_NOAUXFLTR	0x00008000	/* disable auxiliary filters */
295
296#define	RT_FL_NOAUDIT	0x00020000	/* disable auditing */
297#define	RT_FL_ATEXIT	0x00040000	/* we're shutting down */
298#define	RT_FL_SILENCERR	0x00080000	/* silence error messages */
299
300#define	RT_FL_INITFIRST	0x00200000	/* processing a DT_INITFIRST object */
301
302#define	RT_FL_DEMANGLE	0x01000000	/* demangle C++ symbol names */
303#define	RT_FL_NOCFG	0x02000000	/* disable config file use */
304#define	RT_FL_NODIRCFG	0x04000000	/* disable directory config use */
305#define	RT_FL_NOOBJALT	0x08000000	/* disable object alternative use */
306#define	RT_FL_NOENVCFG	0x10000000	/* disable config envars use */
307#define	RT_FL_DIRCFG	0x20000000	/* directory config info available */
308#define	RT_FL_OBJALT	0x40000000	/* object alternatives are available */
309#define	RT_FL_MEMRESV	0x80000000	/* memory reservation established */
310
311/*
312 * Status flags for rtld_flags2
313 */
314#define	RT_FL2_HASAUDIT	0x00000001	/* auditing lm_list is present */
315#define	RT_FL2_RTLDSEEN	0x00000002	/* rtldinfo has been set */
316#define	RT_FL2_UNIFPROC	0x00000004	/* libc/libthread unified environment */
317
318#define	RT_FL2_NOFLTCFG	0x00000010	/* disable config filter use */
319#define	RT_FL2_FLTCFG	0x00000020	/* filter config info available */
320#define	RT_FL2_HWCAP	0x00000040	/* hardware capabilities available */
321#define	RT_FL2_FTL2WARN	0x00000080	/* convert fatal to warning messages */
322#define	RT_FL2_BINDNOW	0x00000100	/* LD_BIND_NOW in effect */
323#define	RT_FL2_BINDLAZY	0x00000200	/* disable RTLD_NOW (and LD_BIND_NOW) */
324#define	RT_FL2_PLMSETUP	0x00000400	/* primary link-map set up complete */
325#define	RT_FL2_BRANDED	0x00000800	/* process is branded */
326#define	RT_FL2_NOPLM	0x00001000	/* process has no primary link map */
327#define	RT_FL2_SETUID	0x00002000	/* ld.so.1 is setuid root */
328#define	RT_FL2_ADDR32	0x00004000	/* 32-bit address space requirement */
329
330/*
331 * Information flags for env_info.
332 */
333#define	ENV_INF_PATHCFG	0x00000001	/* replaceable LD_LIBRARY_PATH */
334					/*	originates from configuration */
335					/*	file */
336#define	ENV_INF_FLAGCFG	0x00000002	/* replaceable LD_FLAGS originates */
337					/*	from configuration file */
338
339/*
340 * RTLDINFO descriptor.
341 */
342typedef struct {
343	Rt_map		*rti_lmp;	/* RTLDINFO provider */
344	Lc_interface	*rti_info;	/* RTLDINFO data */
345} Rti_desc;
346
347/*
348 * Binding flags for the rt_bind_guard()/rt_bind_clear() routines.
349 * These are defined in usr/src/lib/libc/inc/libc_int.h in the
350 * latest version of the libc/rtld runtime interface (CI_V_FIVE).
351 */
352#if !defined(CI_V_FIVE)
353#define	THR_FLG_RTLD	0x00000001	/* rtldlock bind guard flag */
354#define	THR_FLG_NOLOCK	0x00000000	/* no-op before CI_V_FIVE */
355#define	THR_FLG_REENTER	0x00000000	/* no-op before CI_V_FIVE */
356#endif
357
358#define	ROUND(x, a)	(((int)(x) + ((int)(a) - 1)) & ~((int)(a) - 1))
359
360/*
361 * Print buffer.
362 */
363typedef struct {
364	char	*pr_buf;	/* pointer to beginning of buffer */
365	char	*pr_cur;	/* pointer to next free char in buffer */
366	size_t	pr_len;		/* buffer size */
367	int	pr_fd;		/* output fd */
368} Prfbuf;
369
370/*
371 * Path name descriptor.  Used to construct various path names such as search
372 * paths, dependency paths, filter paths etc.  The pd_info element can be used
373 * to hold various pointers, like Grp_hdl, Rtc_obj, etc.
374 */
375struct pdesc {
376	const char	*pd_pname;	/* path name - may be expanded */
377	const char	*pd_oname;	/* original name - unexpanded */
378	void		*pd_info;	/* possible auxiliary information */
379	size_t		pd_plen;	/* path name length */
380	uint_t		pd_flags;	/* descriptor specific flags */
381};
382
383/*
384 * Path name descriptors are passed to expand_path() and expand().  These
385 * routines break down possible multiple path strings (separated with ":"),
386 * and perform any reserved token expansion.  These routines are passed
387 * information that indicates the use of the path, for example, search paths,
388 * i.e., LD_LIBRARY_PATH, RPATHS, etc. are defined using la_objsearch()
389 * information (see LA_SER flags in link.h).  This information is recorded in
390 * the pd_flags field for later use.
391 *
392 * Define expansion path tokens.  These are used to prevent various expansions
393 * from occurring, and record those expansions that do.  Any expansion
394 * information is also recorded in the pd_flags field, and thus is or'd
395 * together with any LA_SER flags.
396 */
397#define	PD_TKN_ORIGIN	0x00001000	/* $ORIGIN expansion has occurred */
398#define	PD_TKN_PLATFORM	0x00002000	/* $PLATFORM expansion has occurred */
399#define	PD_TKN_OSNAME	0x00004000	/* $OSNAME expansion has occurred */
400#define	PD_TKN_OSREL	0x00008000	/* $OSREL expansion has occurred */
401#define	PD_TKN_ISALIST	0x00010000	/* $ISALIST expansion has occurred */
402#define	PD_TKN_CAP	0x00020000	/* $CAPABILITY/$HWCAP expansion has */
403					/*	occurred */
404#define	PD_TKN_MACHINE	0x00040000	/* $MACHINE expansion has occurred */
405#define	PD_TKN_RESOLVED	0x00080000	/* resolvepath() expansion has */
406					/*	occurred */
407#define	PD_MSK_EXPAND	0x000ff000	/* mask for all expansions */
408
409/*
410 * Define additional path information.  These definitions extend the path
411 * information, and may be passed into expand_path(), or set internally, or
412 * inherited from expand().  These definitions are or'd together with any
413 * LA_SER_ flags and PD_TKN_ flags.
414 */
415#define	PD_FLG_PNSLASH	0x00100000	/* pd_pname contains a slash */
416#define	PD_FLG_DUPLICAT	0x00200000	/* path is a duplicate */
417#define	PD_FLG_EXTLOAD	0x00400000	/* path defines extra loaded objects */
418					/*	(preload, audit etc.) */
419#define	PD_FLG_UNIQUE	0x00800000	/* ensure path is unique */
420#define	PD_FLG_USED	0x01000000	/* indicate that path is used */
421#define	PD_FLG_FULLPATH	0x02000000	/* ensure path is a full path */
422
423#define	PD_MSK_INHERIT	0x0ffff000	/* mask for pd_flags incorporation */
424
425/*
426 * Additional token expansion information.  Although these flags may be set
427 * within a token data item return from expand(), they are masked off with
428 * PD_MSK_INHERIT prior to any expansion information being recorded in a path
429 * name descriptor for later diagnostics.
430 */
431#define	TKN_NONE	0x00000001	/* no token expansion has occurred */
432#define	TKN_DOTSLASH	0x00000002	/* path contains a "./" */
433
434/*
435 * dlopen() handle list size.
436 */
437#define	HDLIST_SZ	101	/* prime no. for hashing */
438#define	HDLIST_ORP	102	/* orphan handle list */
439
440/*
441 * Define a path name search descriptor.  This "cookie" maintains state as
442 * search paths are processed with get_next_dir().  Note, the path list is an
443 * indirect pointer, as search paths can be reevaluated for secure applications
444 * to provide better error diagnostics.
445 */
446typedef struct {
447	uchar_t		*sp_rule;	/* present search rule */
448	Alist		**sp_dalpp;	/* present path list within rule */
449	Aliste		sp_idx;		/* present index within path list */
450} Spath_desc;
451
452/*
453 * Define a path name definition descriptor.  Used to maintain initial ELF and
454 * AOUT path name definitions.
455 */
456typedef struct {
457	const char	*sd_name;	/* path name */
458	size_t		sd_len;		/* path name size */
459} Spath_defn;
460
461/*
462 * Define _caller flags.
463 */
464#define	CL_NONE		0
465#define	CL_EXECDEF	1		/* supply the executable as a default */
466					/* if the caller can't be determined */
467
468/*
469 * Binding information flags.  These flags are passed up from low level binding
470 * routines to indicate "additional" information, such as why a binding has been
471 * rejected.  These flags use the same data element as is used to record any
472 * DBG_BINFO flags.  The DBG_BINFO flags are used to define the final bindings
473 * information and are used to provide better binding diagnostics.
474 */
475#define	BINFO_REJDIRECT		0x010000	/* reject a direct binding */
476#define	BINFO_REJSINGLE		0x100000	/* reject a singleton binding */
477#define	BINFO_REJGROUP		0x200000	/* reject a group binding */
478
479#define	BINFO_MSK_TRYAGAIN	0xf00000	/* a mask of bindings that */
480						/*    should be retried */
481#define	BINFO_MSK_REJECTED	0xff0000	/* a mask of bindings that */
482						/*    have been rejected */
483
484/*
485 * The 32-bit version of rtld uses special stat() wrapper functions
486 * that preserve the non-largefile semantics of stat()/fstat() while
487 * allowing for large inode values. The 64-bit rtld uses stat() directly.
488 */
489#ifdef _LP64
490#define	rtld_fstat	fstat
491#define	rtld_stat	stat
492typedef	struct stat	rtld_stat_t;
493#else
494typedef struct {
495	dev_t		st_dev;
496	rtld_ino_t	st_ino;
497	mode_t		st_mode;
498	uid_t		st_uid;
499	off_t		st_size;
500	timestruc_t	st_mtim;
501#ifdef sparc
502	blksize_t	st_blksize;
503#endif
504} rtld_stat_t;
505#endif
506
507/*
508 * Some capabilities aux vector definitions have been removed over time.
509 * However, existing objects may define these capabilities.  Establish
510 * capability masks that provide for deleting any removed capabilities, so
511 * that these capabilities are not used to validate the associated object.
512 *
513 * These masks are tightly coupled to the aux vector definitions in auxv_386.h
514 * and auxv_SPARC.h, however they are maintained here, as only ld.so.1 needs
515 * to remove these capabilities.  These definitions also describe where the
516 * flags are associated and allow for providing multi-architecture definitions
517 * should they become necessary, without having to pollute global header files.
518 */
519#if	defined(__x86)
520#define	AV_HW1_IGNORE	(0x8000 | 0x2000)	/* withdrawn MON and PAUSE */
521#else						/*    auxv_386.h flags */
522#define	AV_HW1_IGNORE	0
523#endif
524
525/*
526 * Error messages generated by ld.so.1 can be written to two different places.
527 * During initial startup, messages are flushed to the stderr.  Once ld.so.1
528 * has jumped to the application, messages are stored in an internal buffer for
529 * retrieval by dlerror().  Between these two conditions, events such as libc's
530 * callbacks, and calls to auditors, are effectively jumping to application
531 * code.  These transitions from application code to ld.so.1 code are guarded by
532 * the following macros to ensure any error messages are directed to the
533 * appropriate output.  The single argument, "f", is a local variable that
534 * can retain, and reinstate, the RT_FL_APPLIC flag of the global rtld_flags
535 * variable.
536 */
537#define	APPLICATION_ENTER(f) \
538	f = (rtld_flags & RT_FL_APPLIC) ? 0 : RT_FL_APPLIC; \
539	rtld_flags |= f;
540#define	APPLICATION_RETURN(f) \
541	rtld_flags &= ~f;
542
543/*
544 * Data declarations.
545 */
546extern Lc_desc		glcs[];		/* global external interfaces */
547
548extern	Rt_lock		rtldlock;	/* rtld lock */
549extern	int		thr_flg_nolock;
550extern	int		thr_flg_reenter;
551
552extern APlist		*dynlm_list;	/* dynamic list of link-maps */
553extern char		**environ;	/* environ pointer */
554
555extern int		dyn_plt_ent_size; /* Size of dynamic plt's */
556extern ulong_t		at_flags;	/* machine specific file flags */
557extern const char	*procname;	/* file name of executing process */
558extern Rtld_db_priv	r_debug;	/* debugging information */
559extern char		*lasterr;	/* string describing last error */
560extern Interp		*interp;	/* ELF executable interpreter info */
561extern const char	*rtldname;	/* name of the dynamic linker */
562extern APlist		*hdl_alp[];	/* dlopen() handle list */
563extern size_t		syspagsz;	/* system page size */
564extern Isa_desc		*isa;		/* isalist descriptor */
565extern Uts_desc		*uts;		/* utsname descriptor */
566extern uint_t		rtld_flags;	/* status flags for RTLD */
567extern uint_t		rtld_flags2;	/* additional status flags for RTLD */
568extern uint32_t		pltcnt21d;	/* cnt of 21d PLTs */
569extern uint32_t		pltcnt24d;	/* cnt of 24d PLTs */
570extern uint32_t		pltcntu32;	/* cnt of u32 PLTs */
571extern uint32_t		pltcntu44;	/* cnt of u44 PLTs */
572extern uint32_t		pltcntfull;	/* cnt of full PLTs */
573extern uint32_t		pltcntfar;	/* cnt of far PLTs */
574extern uchar_t		search_rules[];	/* dependency search rules */
575
576extern Fct		elf_fct;	/* ELF file class dependent data */
577
578#if	defined(__sparc) && !defined(__sparcv9)
579extern Fct		aout_fct;	/* a.out (4.x) file class dependent */
580					/*	data */
581#endif
582
583extern Config		*config;		/* configuration structure */
584extern const char	*locale;		/* locale environment setting */
585
586extern const char	*rpl_audit;	/* replaceable LD_AUDIT string */
587extern const char	*rpl_debug;	/* replaceable LD_DEBUG string */
588extern const char	*rpl_ldflags;	/* replaceable LD_FLAGS string */
589extern const char	*rpl_libpath;	/* replaceable LD_LIBRARY string */
590extern Alist		*rpl_libdirs;	/*	and its associated Pdesc list */
591extern const char	*rpl_preload;	/* replaceable LD_PRELOAD string */
592
593extern const char	*prm_audit;	/* permanent LD_AUDIT string */
594extern const char	*prm_debug;	/* permanent LD_DEBUG string */
595extern const char	*prm_ldflags;	/* permanent LD_FLAGS string */
596extern const char	*prm_libpath;	/* permanent LD_LIBRARY string */
597extern Alist		*prm_libdirs;	/*	and its associated Pdesc list */
598extern const char	*prm_preload;	/* permanent LD_PRELOAD string */
599
600extern Alist		*elf_def_dirs;	/* ELF default directory seach paths */
601extern Alist		*elf_sec_dirs;	/* ELF secure directory seach paths */
602extern Alist		*aout_def_dirs;	/* AOUT default directory seach paths */
603extern Alist		*aout_sec_dirs;	/* AOUT secure directory seach paths */
604
605extern uint_t		env_info;	/* information regarding environment */
606					/*	variables */
607extern int		killsig;	/* signal sent on fatal exit */
608extern APlist		*free_alp;	/* defragmentation list */
609
610extern uint_t		audit_argcnt;	/* no. of stack args to copy */
611extern Audit_desc	*auditors;	/* global auditors */
612extern APlist		*aud_preinit;	/* list of objects defining local */
613extern APlist		*aud_activity;	/*    preinit and activity auditors */
614
615extern char		**_environ;	/* environ reference for libc */
616
617extern const char	*dbg_file;	/* debugging directed to a file */
618
619extern Reglist		*reglist;	/* list of register symbols */
620
621extern const Msg	err_reject[];	/* rejection error message tables */
622extern const Msg	ldd_reject[];
623extern const Msg	ldd_warn[];
624
625extern const char	*profile_name;	/* object being profiled */
626extern const char	*profile_out;	/* profile output file */
627extern const char	*profile_lib;	/* audit library to perform profile */
628
629extern Dl_argsinfo	argsinfo;	/* process argument, environment and */
630					/*	auxv information */
631
632extern const char	*err_strs[ERR_NUM];
633					/* diagnostic error string headers */
634extern const char	*nosym_str;	/* MSG_GEN_NOSYM message cache */
635
636extern Syscapset	*org_scapset;	/* original system capabilities */
637extern Syscapset	*alt_scapset;	/* alternative system capabilities */
638
639extern const char	*rpl_hwcap;	/* replaceable hwcap str */
640extern const char	*rpl_sfcap;	/* replaceable sfcap str */
641extern const char	*rpl_machcap;	/* replaceable machcap str */
642extern const char	*rpl_platcap;	/* replaceable platcap str */
643extern const char	*rpl_cap_files;	/* associated files */
644
645extern const char	*prm_hwcap;	/* permanent hwcap str */
646extern const char	*prm_sfcap;	/* permanent sfcap str */
647extern const char	*prm_machcap;	/* permanent machcap str */
648extern const char	*prm_platcap;	/* permanent platcap str */
649extern const char	*prm_cap_files;	/* associated files */
650
651extern avl_tree_t	*capavl;	/* capabilities files */
652extern avl_tree_t	*nfavl;		/* not-found path names */
653extern avl_tree_t	*spavl;		/* secure path names */
654
655extern u_longlong_t	cnt_map;	/* Incr. for each object mapped */
656extern u_longlong_t	cnt_unmap;	/* Incr. for each object unmapped */
657
658/*
659 * Function declarations.
660 */
661extern void		addfree(void *, size_t);
662extern int		append_alias(Rt_map *, const char *, int *);
663extern Rt_map		*analyze_lmc(Lm_list *, Aliste, Rt_map *, Rt_map *,
664			    int *);
665extern void		atexit_fini(void);
666extern int		bind_one(Rt_map *, Rt_map *, uint_t);
667extern int		bufprint(Prfbuf *, const char *, ...);
668extern void		call_array(Addr *, uint_t, Rt_map *, Word);
669extern void		call_fini(Lm_list *, Rt_map **, Rt_map *);
670extern void		call_init(Rt_map **, int);
671extern int		callable(Rt_map *, Rt_map *, Grp_hdl *, uint_t);
672extern Rt_map		*_caller(caddr_t, int);
673extern caddr_t		caller(void);
674extern void		*calloc(size_t, size_t);
675extern int		cap_alternative(void);
676extern int		cap_check_fdesc(Fdesc *, Cap *, char *, Rej_desc *);
677extern int		cap_check_lmp(Rt_map *, Rej_desc *);
678extern int 		cap_filtees(Alist **, Aliste, const char *, Aliste,
679			    Rt_map *, Rt_map *, const char *, int, uint_t,
680			    int *);
681extern int		cap_match(Sresult *, uint_t, Sym *, char *);
682extern const char	*_conv_reloc_type(uint_t rel);
683extern Aliste		create_cntl(Lm_list *, int);
684extern void		defrag(void);
685extern int		dbg_setup(const char *, Dbg_desc *);
686extern const char	*demangle(const char *);
687extern int		dlclose_intn(Grp_hdl *, Rt_map *);
688extern int		dlclose_core(Grp_hdl *, Rt_map *, Lm_list *);
689extern int		dlsym_handle(Grp_hdl *, Slookup *, Sresult *, uint_t *,
690			    int *);
691extern void		*dlsym_intn(void *, const char *, Rt_map *, Rt_map **);
692extern Grp_hdl		*dlmopen_intn(Lm_list *, const char *, int, Rt_map *,
693			    uint_t, uint_t);
694extern size_t		doprf(const char *, va_list, Prfbuf *);
695extern int		dowrite(Prfbuf *);
696extern void		*dz_map(Lm_list *, caddr_t, size_t, int, int);
697extern int		enter(int);
698extern uint_t		expand(char **, size_t *, char **, uint_t, uint_t,
699			    Rt_map *);
700extern int		expand_paths(Rt_map *, const char *, Alist **, Aliste,
701			    uint_t, uint_t);
702extern void		free_hdl(Grp_hdl *);
703extern void		file_notfound(Lm_list *, const char *, Rt_map *,
704			    uint_t, Rej_desc *);
705extern int		find_path(Lm_list *, Rt_map *, uint_t, Fdesc *,
706			    Rej_desc *, int *);
707extern int		fpavl_insert(Lm_list *, Rt_map *, const char *,
708			    avl_index_t);
709extern Rt_map		*fpavl_recorded(Lm_list *, const char *, uint_t,
710			    avl_index_t *);
711extern void		fpavl_remove(Rt_map *);
712extern size_t		fullpath(Rt_map *, Fdesc *);
713extern Lmid_t		get_linkmap_id(Lm_list *);
714extern Pdesc		*get_next_dir(Spath_desc *, Rt_map *, uint_t);
715extern Grp_desc		*hdl_add(Grp_hdl *, Rt_map *, uint_t, int *);
716extern Grp_hdl		*hdl_create(Lm_list *, Rt_map *, Rt_map *, uint_t,
717			    uint_t, uint_t);
718extern int		hdl_initialize(Grp_hdl *, Rt_map *, int, int);
719extern int		hwcap1_check(Syscapset *, Xword, Rej_desc *);
720extern int		hwcap2_check(Syscapset *, Xword, Rej_desc *);
721extern void		is_dep_init(Rt_map *, Rt_map *);
722extern int		is_move_data(caddr_t);
723extern int		is_path_secure(char *, Rt_map *, uint_t, uint_t);
724extern int		is_rtld_setuid();
725extern int		is_sym_interposer(Rt_map *, Sym *);
726extern void		ldso_plt_init(Rt_map *);
727extern void		leave(Lm_list *, int);
728extern void		lm_append(Lm_list *, Aliste, Rt_map *);
729extern void		lm_delete(Lm_list *, Rt_map *, Rt_map *);
730extern void		lm_move(Lm_list *, Aliste, Aliste, Lm_cntl *,
731			    Lm_cntl *);
732extern Rt_map 		*load_cap(Lm_list *, Aliste, const char *, Rt_map *,
733			    uint_t, uint_t, Grp_hdl **, Rej_desc *, int *);
734extern void		load_completion(Rt_map *);
735extern Rt_map		*load_file(Lm_list *, Aliste, Rt_map *, Fdesc *, int *);
736extern Rt_map		*load_path(Lm_list *, Aliste, Rt_map *, int, uint_t,
737			    Grp_hdl **, Fdesc *, Rej_desc *, int *);
738extern Rt_map		*load_one(Lm_list *, Aliste, Alist *, Rt_map *, int,
739			    uint_t, Grp_hdl **, int *);
740extern const char	*load_trace(Lm_list *, Pdesc *, Rt_map *, Fdesc *);
741extern void		nfavl_insert(const char *, avl_index_t);
742extern void		*nu_map(Lm_list *, caddr_t, size_t, int, int);
743extern Fct		*map_obj(Lm_list *, Fdesc *, size_t, const char *, int,
744			    Rej_desc *);
745extern void		*malloc(size_t);
746extern int		machcap_check(Syscapset *, const char *, Rej_desc *);
747extern void		machine_name(Syscapset *);
748extern int		move_data(Rt_map *, APlist **);
749extern int		platcap_check(Syscapset *, const char *, Rej_desc *);
750extern void		platform_name(Syscapset *);
751extern int		pnavl_recorded(avl_tree_t **, const char *, uint_t,
752			    avl_index_t *);
753extern int		procenv_user(APlist *, Word *, Word *, int);
754extern void		rd_event(Lm_list *, rd_event_e, r_state_e);
755extern int		readenv_user(const char **, APlist **);
756extern int		readenv_config(Rtc_env *, Addr, int);
757extern void		rejection_inherit(Rej_desc *, Rej_desc *);
758extern int		relocate_lmc(Lm_list *, Aliste, Rt_map *, Rt_map *,
759			    int *);
760extern int		relocate_finish(Rt_map *, APlist *, int);
761extern void		remove_alist(Alist **, int);
762extern void		remove_cntl(Lm_list *, Aliste);
763extern int		remove_hdl(Grp_hdl *, Rt_map *, int *);
764extern void		remove_lmc(Lm_list *, Rt_map *, Aliste, const char *);
765extern void		remove_lml(Lm_list *);
766extern void		remove_so(Lm_list *, Rt_map *, Rt_map *);
767extern int		rt_critical(void);
768extern int		rt_bind_guard(int);
769extern int		rt_bind_clear(int);
770extern int		rt_get_extern(Lm_list *, Rt_map *);
771extern int		rt_mutex_lock(Rt_lock *);
772extern int		rt_mutex_unlock(Rt_lock *);
773extern void		rt_thr_init(Lm_list *);
774extern thread_t		rt_thr_self(void);
775extern void		rtld_db_dlactivity(Lm_list *);
776extern void		rtld_db_preinit(Lm_list *);
777extern void		rtld_db_postinit(Lm_list *);
778extern void		rtldexit(Lm_list *, int);
779#ifndef _LP64
780extern int		rtld_fstat(int, rtld_stat_t *restrict);
781extern int		rtld_stat(const char *restrict, rtld_stat_t *restrict);
782#endif
783extern int		rtld_getopt(char **, char ***, auxv_t **, Word *,
784			    Word *, int);
785extern void		security(uid_t, uid_t, gid_t, gid_t, int);
786extern void		set_environ(Lm_list *);
787extern void		set_dirs(Alist **, Spath_defn *, uint_t);
788extern int		set_prot(Rt_map *, mmapobj_result_t *, int);
789extern Rt_map		*setup(char **, auxv_t *, Word, char *, int, char *,
790			    ulong_t, ulong_t, int fd, Phdr *, char *, char **,
791			    uid_t, uid_t, gid_t, gid_t, void *, int, uint_t *);
792extern const char	*stravl_insert(const char *, uint_t, size_t, int);
793extern void		spavl_insert(const char *);
794extern int		sfcap1_check(Syscapset *, Xword, Rej_desc *);
795extern int		tls_assign(Lm_list *, Rt_map *, Phdr *);
796extern void		tls_modaddrem(Rt_map *, uint_t);
797extern int		tls_statmod(Lm_list *, Rt_map *);
798extern Rt_map		**tsort(Rt_map *, int, int);
799extern void		unused(Lm_list *);
800extern void		unmap_obj(mmapobj_result_t *, uint_t);
801extern int		update_mode(Rt_map *, int, int);
802extern void		zero(caddr_t, size_t);
803
804#if	defined(__sparc)
805/*
806 * SPARC Register symbol support.
807 */
808extern int		elf_regsyms(Rt_map *);
809extern void		set_sparc_g1(ulong_t);
810extern void		set_sparc_g2(ulong_t);
811extern void		set_sparc_g3(ulong_t);
812extern void		set_sparc_g4(ulong_t);
813extern void		set_sparc_g5(ulong_t);
814extern void		set_sparc_g6(ulong_t);
815extern void		set_sparc_g7(ulong_t);
816#endif
817
818extern long		_sysconfig(int);
819
820#ifdef	__cplusplus
821}
822#endif
823
824#endif /* __RTLD_H */
825