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