xref: /titanic_44/usr/src/cmd/sgs/libld/common/ldlibs.c (revision b533f56bf95137d3de6666bd923e15ec373ea611)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55aefb655Srie  * Common Development and Distribution License (the "License").
65aefb655Srie  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
215aefb655Srie 
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  *	Copyright (c) 1988 AT&T
247c478bd9Sstevel@tonic-gate  *	  All Rights Reserved
257c478bd9Sstevel@tonic-gate  *
26dc0f59e5SAli Bahrami  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
277c478bd9Sstevel@tonic-gate  */
28*b533f56bSRobert Mustacchi /*
29*b533f56bSRobert Mustacchi  * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
30*b533f56bSRobert Mustacchi  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate  * Library processing
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate #include	<stdio.h>
367c478bd9Sstevel@tonic-gate #include	<unistd.h>
377c478bd9Sstevel@tonic-gate #include	<fcntl.h>
387c478bd9Sstevel@tonic-gate #include	<string.h>
397c478bd9Sstevel@tonic-gate #include	<limits.h>
407c478bd9Sstevel@tonic-gate #include	<errno.h>
415aefb655Srie #include	<debug.h>
42*b533f56bSRobert Mustacchi #include	<sys/sysmacros.h>
437c478bd9Sstevel@tonic-gate #include	"msg.h"
447c478bd9Sstevel@tonic-gate #include	"_libld.h"
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate /*
4757ef7aa9SRod Evans  * Define a list index for "-L" processing.  By default, "-L" search paths are
4857ef7aa9SRod Evans  * inserted at the beginning of the associated search list.  However, should a
4957ef7aa9SRod Evans  * ";" be discovered in a LD_LIBRARY_PATH listing, then any new "-L" search
5057ef7aa9SRod Evans  * paths are inserted following the ";".
517c478bd9Sstevel@tonic-gate  */
5257ef7aa9SRod Evans static Aliste	Lidx = 0;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /*
557c478bd9Sstevel@tonic-gate  * Function to handle -YL and -YU substitutions in LIBPATH.  It's probably
567c478bd9Sstevel@tonic-gate  * very unlikely that the link-editor will ever see this, as any use of these
577c478bd9Sstevel@tonic-gate  * options is normally processed by the compiler driver first and the finished
587c478bd9Sstevel@tonic-gate  * -YP string is sent to us.  The fact that these two options are not even
597c478bd9Sstevel@tonic-gate  * documented anymore makes it even more unlikely this processing will occur.
607c478bd9Sstevel@tonic-gate  */
617c478bd9Sstevel@tonic-gate static char *
compat_YL_YU(Ofl_desc * ofl,char * path,int index)625aefb655Srie compat_YL_YU(Ofl_desc *ofl, char *path, int index)
637c478bd9Sstevel@tonic-gate {
647c478bd9Sstevel@tonic-gate 	if (index == YLDIR) {
657c478bd9Sstevel@tonic-gate 		if (Llibdir) {
667c478bd9Sstevel@tonic-gate 			/*
677c478bd9Sstevel@tonic-gate 			 * User supplied "-YL,libdir", this is the pathname that
687c478bd9Sstevel@tonic-gate 			 * corresponds for compatibility to -YL (as defined in
697c478bd9Sstevel@tonic-gate 			 * sgs/include/paths.h)
707c478bd9Sstevel@tonic-gate 			 */
715aefb655Srie 			DBG_CALL(Dbg_libs_ylu(ofl->ofl_lml, Llibdir,
725aefb655Srie 			    path, index));
737c478bd9Sstevel@tonic-gate 			return (Llibdir);
747c478bd9Sstevel@tonic-gate 		}
757c478bd9Sstevel@tonic-gate 	} else if (index == YUDIR) {
767c478bd9Sstevel@tonic-gate 		if (Ulibdir) {
777c478bd9Sstevel@tonic-gate 			/*
787c478bd9Sstevel@tonic-gate 			 * User supplied "-YU,libdir", this is the pathname that
797c478bd9Sstevel@tonic-gate 			 * corresponds for compatibility to -YU (as defined in
807c478bd9Sstevel@tonic-gate 			 * sgs/include/paths.h)
817c478bd9Sstevel@tonic-gate 			 */
825aefb655Srie 			DBG_CALL(Dbg_libs_ylu(ofl->ofl_lml, Ulibdir,
835aefb655Srie 			    path, index));
847c478bd9Sstevel@tonic-gate 			return (Ulibdir);
857c478bd9Sstevel@tonic-gate 		}
867c478bd9Sstevel@tonic-gate 	}
877c478bd9Sstevel@tonic-gate 	return (path);
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate static char *
process_lib_path(Ofl_desc * ofl,APlist ** apl,char * path,Boolean subsflag)9157ef7aa9SRod Evans process_lib_path(Ofl_desc *ofl, APlist **apl, char *path, Boolean subsflag)
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate 	int	i;
947c478bd9Sstevel@tonic-gate 	char	*cp;
957c478bd9Sstevel@tonic-gate 	Boolean	seenflg = FALSE;
967c478bd9Sstevel@tonic-gate 	char	*dot = (char *)MSG_ORIG(MSG_STR_DOT);
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	for (i = YLDIR; i; i++) {
997c478bd9Sstevel@tonic-gate 		cp = strpbrk(path, MSG_ORIG(MSG_STR_PATHTOK));
1007c478bd9Sstevel@tonic-gate 		if (cp == NULL) {
1017c478bd9Sstevel@tonic-gate 			if (*path == '\0') {
1027c478bd9Sstevel@tonic-gate 				if (seenflg)
10357ef7aa9SRod Evans 					if (aplist_append(apl, (subsflag ?
10457ef7aa9SRod Evans 					    compat_YL_YU(ofl, dot, i) : dot),
10557ef7aa9SRod Evans 					    AL_CNT_OFL_LIBDIRS) == NULL)
1067c478bd9Sstevel@tonic-gate 						return ((char *)S_ERROR);
10757ef7aa9SRod Evans 
10857ef7aa9SRod Evans 			} else if (aplist_append(apl, (subsflag ?
10957ef7aa9SRod Evans 			    compat_YL_YU(ofl, path, i) : path),
11057ef7aa9SRod Evans 			    AL_CNT_OFL_LIBDIRS) == NULL) {
1117c478bd9Sstevel@tonic-gate 				return ((char *)S_ERROR);
11257ef7aa9SRod Evans 			}
1137c478bd9Sstevel@tonic-gate 			return (cp);
1147c478bd9Sstevel@tonic-gate 		}
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 		if (*cp == ':') {
1177c478bd9Sstevel@tonic-gate 			*cp = '\0';
1187c478bd9Sstevel@tonic-gate 			if (cp == path) {
11957ef7aa9SRod Evans 				if (aplist_append(apl, (subsflag ?
12057ef7aa9SRod Evans 				    compat_YL_YU(ofl, dot, i) : dot),
12157ef7aa9SRod Evans 				    AL_CNT_OFL_LIBDIRS) == NULL)
1227c478bd9Sstevel@tonic-gate 					return ((char *)S_ERROR);
12357ef7aa9SRod Evans 
12457ef7aa9SRod Evans 			} else if (aplist_append(apl, (subsflag ?
12557ef7aa9SRod Evans 			    compat_YL_YU(ofl, path, i) : path),
12657ef7aa9SRod Evans 			    AL_CNT_OFL_LIBDIRS) == NULL) {
1277c478bd9Sstevel@tonic-gate 				return ((char *)S_ERROR);
1287c478bd9Sstevel@tonic-gate 			}
1297c478bd9Sstevel@tonic-gate 			path = cp + 1;
1307c478bd9Sstevel@tonic-gate 			seenflg = TRUE;
1317c478bd9Sstevel@tonic-gate 			continue;
1327c478bd9Sstevel@tonic-gate 		}
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 		/* case ";" */
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 		if (cp != path) {
13757ef7aa9SRod Evans 			if (aplist_append(apl, (subsflag ?
13857ef7aa9SRod Evans 			    compat_YL_YU(ofl, path, i) : path),
13957ef7aa9SRod Evans 			    AL_CNT_OFL_LIBDIRS) == NULL)
1407c478bd9Sstevel@tonic-gate 				return ((char *)S_ERROR);
1417c478bd9Sstevel@tonic-gate 		} else {
1427c478bd9Sstevel@tonic-gate 			if (seenflg)
14357ef7aa9SRod Evans 				if (aplist_append(apl, (subsflag ?
14457ef7aa9SRod Evans 				    compat_YL_YU(ofl, dot, i) : dot),
14557ef7aa9SRod Evans 				    AL_CNT_OFL_LIBDIRS) == NULL)
1467c478bd9Sstevel@tonic-gate 					return ((char *)S_ERROR);
1477c478bd9Sstevel@tonic-gate 		}
1487c478bd9Sstevel@tonic-gate 		return (cp);
1497c478bd9Sstevel@tonic-gate 	}
1507c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
1517c478bd9Sstevel@tonic-gate 	return (NULL);	/* keep gcc happy */
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate /*
1557c478bd9Sstevel@tonic-gate  * adds the indicated path to those to be searched for libraries.
1567c478bd9Sstevel@tonic-gate  */
1577c478bd9Sstevel@tonic-gate uintptr_t
ld_add_libdir(Ofl_desc * ofl,const char * path)1585aefb655Srie ld_add_libdir(Ofl_desc *ofl, const char *path)
1597c478bd9Sstevel@tonic-gate {
16057ef7aa9SRod Evans 	if (aplist_insert(&ofl->ofl_ulibdirs, path,
16157ef7aa9SRod Evans 	    AL_CNT_OFL_LIBDIRS, Lidx++) == NULL)
1627c478bd9Sstevel@tonic-gate 		return (S_ERROR);
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	/*
1657c478bd9Sstevel@tonic-gate 	 * As -l and -L options can be interspersed, print the library
1667c478bd9Sstevel@tonic-gate 	 * search paths each time a new path is added.
1677c478bd9Sstevel@tonic-gate 	 */
16857ef7aa9SRod Evans 	DBG_CALL(Dbg_libs_update(ofl->ofl_lml, ofl->ofl_ulibdirs,
16957ef7aa9SRod Evans 	    ofl->ofl_dlibdirs));
1707c478bd9Sstevel@tonic-gate 	return (1);
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate /*
1747c478bd9Sstevel@tonic-gate  * Process a required library.  Combine the directory and filename, and then
1757c478bd9Sstevel@tonic-gate  * append either a `.so' or `.a' suffix and try opening the associated pathname.
1767c478bd9Sstevel@tonic-gate  */
177dc0f59e5SAli Bahrami static uintptr_t
find_lib_name(const char * dir,const char * file,Ofl_desc * ofl,Rej_desc * rej,ofl_flag_t flags)178*b533f56bSRobert Mustacchi find_lib_name(const char *dir, const char *file, Ofl_desc *ofl, Rej_desc *rej,
179*b533f56bSRobert Mustacchi     ofl_flag_t flags)
1807c478bd9Sstevel@tonic-gate {
1817c478bd9Sstevel@tonic-gate 	int		fd;
1827c478bd9Sstevel@tonic-gate 	size_t		dlen;
1837c478bd9Sstevel@tonic-gate 	char		*_path, path[PATH_MAX + 2];
1847c478bd9Sstevel@tonic-gate 	const char	*_dir = dir;
185dc0f59e5SAli Bahrami 	uintptr_t	open_ret;
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	/*
1887c478bd9Sstevel@tonic-gate 	 * Determine the size of the directory.  The directory and filename are
1897c478bd9Sstevel@tonic-gate 	 * concatenated into the local buffer which is purposely larger than
1907c478bd9Sstevel@tonic-gate 	 * PATH_MAX.  Should a pathname be created that exceeds the system
1917c478bd9Sstevel@tonic-gate 	 * limit, the open() will catch it, and a suitable rejection message is
1927c478bd9Sstevel@tonic-gate 	 * saved.
1937c478bd9Sstevel@tonic-gate 	 */
1947c478bd9Sstevel@tonic-gate 	if ((dlen = strlen(dir)) == 0) {
1957c478bd9Sstevel@tonic-gate 		_dir = (char *)MSG_ORIG(MSG_STR_DOT);
1967c478bd9Sstevel@tonic-gate 		dlen = 1;
1977c478bd9Sstevel@tonic-gate 	}
1987c478bd9Sstevel@tonic-gate 	dlen++;
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	/*
2017c478bd9Sstevel@tonic-gate 	 * If we are in dynamic mode try and open the associated shared object.
2027c478bd9Sstevel@tonic-gate 	 */
2037c478bd9Sstevel@tonic-gate 	if (ofl->ofl_flags & FLG_OF_DYNLIBS) {
2047c478bd9Sstevel@tonic-gate 		(void) snprintf(path, (PATH_MAX + 2), MSG_ORIG(MSG_STR_LIB_SO),
2057c478bd9Sstevel@tonic-gate 		    _dir, file);
2065aefb655Srie 		DBG_CALL(Dbg_libs_l(ofl->ofl_lml, file, path));
2077c478bd9Sstevel@tonic-gate 		if ((fd = open(path, O_RDONLY)) != -1) {
2087c478bd9Sstevel@tonic-gate 
20957ef7aa9SRod Evans 			if ((_path = libld_malloc(strlen(path) + 1)) == NULL)
210dc0f59e5SAli Bahrami 				return (S_ERROR);
2117c478bd9Sstevel@tonic-gate 			(void) strcpy(_path, path);
2127c478bd9Sstevel@tonic-gate 
213dc0f59e5SAli Bahrami 			open_ret = ld_process_open(_path, &_path[dlen], &fd,
214dc0f59e5SAli Bahrami 			    ofl, FLG_IF_NEEDED, rej, NULL);
2153906e0c2Srie 			if (fd != -1)
2167c478bd9Sstevel@tonic-gate 				(void) close(fd);
217*b533f56bSRobert Mustacchi 			if (open_ret != 0 && (flags & FLG_OF_ADEFLIB))
218*b533f56bSRobert Mustacchi 				ld_eprintf(ofl, ERR_WARNING,
219*b533f56bSRobert Mustacchi 				    MSG_INTL(MSG_ARG_ASSDEFLIB_FOUND), dir,
220*b533f56bSRobert Mustacchi 				    file);
221dc0f59e5SAli Bahrami 			return (open_ret);
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 		} else if (errno != ENOENT) {
2247c478bd9Sstevel@tonic-gate 			/*
2257c478bd9Sstevel@tonic-gate 			 * If the open() failed for anything other than the
2267c478bd9Sstevel@tonic-gate 			 * file not existing, record the error condition.
2277c478bd9Sstevel@tonic-gate 			 */
2287c478bd9Sstevel@tonic-gate 			rej->rej_type = SGS_REJ_STR;
2297c478bd9Sstevel@tonic-gate 			rej->rej_str = strerror(errno);
2307c478bd9Sstevel@tonic-gate 			rej->rej_name = strdup(path);
2317c478bd9Sstevel@tonic-gate 		}
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	/*
2357c478bd9Sstevel@tonic-gate 	 * If we are not in dynamic mode, or a shared object could not be
2367c478bd9Sstevel@tonic-gate 	 * located, try and open the associated archive.
2377c478bd9Sstevel@tonic-gate 	 */
2387c478bd9Sstevel@tonic-gate 	(void) snprintf(path, (PATH_MAX + 2), MSG_ORIG(MSG_STR_LIB_A),
2397c478bd9Sstevel@tonic-gate 	    _dir, file);
2405aefb655Srie 	DBG_CALL(Dbg_libs_l(ofl->ofl_lml, file, path));
2417c478bd9Sstevel@tonic-gate 	if ((fd = open(path, O_RDONLY)) != -1) {
2427c478bd9Sstevel@tonic-gate 
24357ef7aa9SRod Evans 		if ((_path = libld_malloc(strlen(path) + 1)) == NULL)
244dc0f59e5SAli Bahrami 			return (S_ERROR);
2457c478bd9Sstevel@tonic-gate 		(void) strcpy(_path, path);
2467c478bd9Sstevel@tonic-gate 
247dc0f59e5SAli Bahrami 		open_ret = ld_process_open(_path, &_path[dlen], &fd, ofl,
248dc0f59e5SAli Bahrami 		    FLG_IF_NEEDED, rej, NULL);
2493906e0c2Srie 		if (fd != -1)
2507c478bd9Sstevel@tonic-gate 			(void) close(fd);
251dc0f59e5SAli Bahrami 		return (open_ret);
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	} else if (errno != ENOENT) {
2547c478bd9Sstevel@tonic-gate 		/*
2557c478bd9Sstevel@tonic-gate 		 * If the open() failed for anything other than the
2567c478bd9Sstevel@tonic-gate 		 * file not existing, record the error condition.
2577c478bd9Sstevel@tonic-gate 		 */
2587c478bd9Sstevel@tonic-gate 		rej->rej_type = SGS_REJ_STR;
2597c478bd9Sstevel@tonic-gate 		rej->rej_str = strerror(errno);
2607c478bd9Sstevel@tonic-gate 		rej->rej_name = strdup(path);
2617c478bd9Sstevel@tonic-gate 	}
2627c478bd9Sstevel@tonic-gate 
263dc0f59e5SAli Bahrami 	return (0);
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate /*
2677c478bd9Sstevel@tonic-gate  * Take the abbreviated name of a library file (from -lfoo) and searches for the
2687c478bd9Sstevel@tonic-gate  * library.  The search path rules are:
2697c478bd9Sstevel@tonic-gate  *
2707c478bd9Sstevel@tonic-gate  *	o	use any user supplied paths, i.e. LD_LIBRARY_PATH and -L, then
2717c478bd9Sstevel@tonic-gate  *
2727c478bd9Sstevel@tonic-gate  *	o	use the default directories, i.e. LIBPATH or -YP.
2737c478bd9Sstevel@tonic-gate  *
2747c478bd9Sstevel@tonic-gate  * If we are in dynamic mode and -Bstatic is not in effect, first look for a
2757c478bd9Sstevel@tonic-gate  * shared object with full name: path/libfoo.so; then [or else] look for an
2767c478bd9Sstevel@tonic-gate  * archive with name: path/libfoo.a.  If no file is found, it's a fatal error,
2777c478bd9Sstevel@tonic-gate  * otherwise process the file appropriately depending on its type.
278*b533f56bSRobert Mustacchi  *
279*b533f56bSRobert Mustacchi  * If we end up using the default directories and -z assert-deflib has been
280*b533f56bSRobert Mustacchi  * turned on, then we pass that information down into find_lib_name which will
281*b533f56bSRobert Mustacchi  * warn appropriately if we find a shared object.
2827c478bd9Sstevel@tonic-gate  */
2837c478bd9Sstevel@tonic-gate uintptr_t
ld_find_library(const char * name,Ofl_desc * ofl)2845aefb655Srie ld_find_library(const char *name, Ofl_desc *ofl)
2857c478bd9Sstevel@tonic-gate {
28657ef7aa9SRod Evans 	Aliste		idx;
2877c478bd9Sstevel@tonic-gate 	char		*path;
288dc0f59e5SAli Bahrami 	uintptr_t	open_ret;
2897c478bd9Sstevel@tonic-gate 	Rej_desc	rej = { 0 };
290*b533f56bSRobert Mustacchi 	ofl_flag_t	flags = 0;
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	/*
2937c478bd9Sstevel@tonic-gate 	 * Search for this file in any user defined directories.
2947c478bd9Sstevel@tonic-gate 	 */
29557ef7aa9SRod Evans 	for (APLIST_TRAVERSE(ofl->ofl_ulibdirs, idx, path)) {
2967c478bd9Sstevel@tonic-gate 		Rej_desc	_rej = { 0 };
2977c478bd9Sstevel@tonic-gate 
298*b533f56bSRobert Mustacchi 		if ((open_ret = find_lib_name(path, name, ofl, &_rej,
299*b533f56bSRobert Mustacchi 		    flags)) == 0) {
3007c478bd9Sstevel@tonic-gate 			if (_rej.rej_type && (rej.rej_type == 0))
3017c478bd9Sstevel@tonic-gate 				rej = _rej;
3027c478bd9Sstevel@tonic-gate 			continue;
3037c478bd9Sstevel@tonic-gate 		}
304dc0f59e5SAli Bahrami 		return (open_ret);
3057c478bd9Sstevel@tonic-gate 	}
3067c478bd9Sstevel@tonic-gate 
307*b533f56bSRobert Mustacchi 	if (ofl->ofl_flags & FLG_OF_ADEFLIB) {
308*b533f56bSRobert Mustacchi 		flags |= FLG_OF_ADEFLIB;
309*b533f56bSRobert Mustacchi 		for (APLIST_TRAVERSE(ofl->ofl_assdeflib, idx, path)) {
310*b533f56bSRobert Mustacchi 			if (strncmp(name, path + MSG_STR_LIB_SIZE,
311*b533f56bSRobert Mustacchi 			    MAX(strlen(path + MSG_STR_LIB_SIZE) -
312*b533f56bSRobert Mustacchi 			    MSG_STR_SOEXT_SIZE, strlen(name))) == 0) {
313*b533f56bSRobert Mustacchi 				flags &= ~FLG_OF_ADEFLIB;
314*b533f56bSRobert Mustacchi 				break;
315*b533f56bSRobert Mustacchi 			}
316*b533f56bSRobert Mustacchi 		}
317*b533f56bSRobert Mustacchi 	}
318*b533f56bSRobert Mustacchi 
3197c478bd9Sstevel@tonic-gate 	/*
3207c478bd9Sstevel@tonic-gate 	 * Finally try the default library search directories.
3217c478bd9Sstevel@tonic-gate 	 */
32257ef7aa9SRod Evans 	for (APLIST_TRAVERSE(ofl->ofl_dlibdirs, idx, path)) {
3237c478bd9Sstevel@tonic-gate 		Rej_desc	_rej = { 0 };
3247c478bd9Sstevel@tonic-gate 
325*b533f56bSRobert Mustacchi 		if ((open_ret = find_lib_name(path, name, ofl, &_rej,
326*b533f56bSRobert Mustacchi 		    flags)) == 0) {
3277c478bd9Sstevel@tonic-gate 			if (_rej.rej_type && (rej.rej_type == 0))
3287c478bd9Sstevel@tonic-gate 				rej = _rej;
3297c478bd9Sstevel@tonic-gate 			continue;
3307c478bd9Sstevel@tonic-gate 		}
331*b533f56bSRobert Mustacchi 
332dc0f59e5SAli Bahrami 		return (open_ret);
3337c478bd9Sstevel@tonic-gate 	}
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	/*
3367c478bd9Sstevel@tonic-gate 	 * If we've got this far we haven't found a shared object or archive.
3377c478bd9Sstevel@tonic-gate 	 * If an object was found, but was rejected for some reason, print a
3387c478bd9Sstevel@tonic-gate 	 * diagnostic to that effect, otherwise generate a generic "not found"
3397c478bd9Sstevel@tonic-gate 	 * diagnostic.
3407c478bd9Sstevel@tonic-gate 	 */
341de777a60Sab196087 	if (rej.rej_type) {
342de777a60Sab196087 		Conv_reject_desc_buf_t rej_buf;
343de777a60Sab196087 
3441007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(reject[rej.rej_type]),
3457c478bd9Sstevel@tonic-gate 		    rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN),
346ba2be530Sab196087 		    conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach));
347de777a60Sab196087 	} else {
3481007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_LIB_NOTFOUND), name);
349de777a60Sab196087 	}
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	return (0);
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate /*
3557c478bd9Sstevel@tonic-gate  * Inspect the LD_LIBRARY_PATH variable (if the -i options has not been
3567c478bd9Sstevel@tonic-gate  * specified), and set up the directory list from which to search for
3577c478bd9Sstevel@tonic-gate  * libraries.  From the man page:
3587c478bd9Sstevel@tonic-gate  *
3597c478bd9Sstevel@tonic-gate  *	LD_LIBRARY_PATH=dirlist1;dirlist2
3607c478bd9Sstevel@tonic-gate  * and
3617c478bd9Sstevel@tonic-gate  *	ld ... -Lpath1 ... -Lpathn ...
3627c478bd9Sstevel@tonic-gate  *
3637c478bd9Sstevel@tonic-gate  * results in a search order of:
3647c478bd9Sstevel@tonic-gate  *
3657c478bd9Sstevel@tonic-gate  *	dirlist1 path1 ... pathn dirlist2 LIBPATH
3667c478bd9Sstevel@tonic-gate  *
3677c478bd9Sstevel@tonic-gate  * If LD_LIBRARY_PATH has no `;' specified, the pathname(s) supplied are
3687c478bd9Sstevel@tonic-gate  * all taken as dirlist2.
3697c478bd9Sstevel@tonic-gate  */
3707c478bd9Sstevel@tonic-gate uintptr_t
ld_lib_setup(Ofl_desc * ofl)3715aefb655Srie ld_lib_setup(Ofl_desc *ofl)
3727c478bd9Sstevel@tonic-gate {
3737c478bd9Sstevel@tonic-gate 	char	*path, *cp = NULL;
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 	/*
3767c478bd9Sstevel@tonic-gate 	 * Determine whether an LD_LIBRARY_PATH setting is in effect.
3777c478bd9Sstevel@tonic-gate 	 */
3787c478bd9Sstevel@tonic-gate 	if (!(ofl->ofl_flags & FLG_OF_IGNENV)) {
3797c478bd9Sstevel@tonic-gate #if	defined(_ELF64)
3807c478bd9Sstevel@tonic-gate 		if ((cp = getenv(MSG_ORIG(MSG_LD_LIBPATH_64))) == NULL)
3817c478bd9Sstevel@tonic-gate #else
3827c478bd9Sstevel@tonic-gate 		if ((cp = getenv(MSG_ORIG(MSG_LD_LIBPATH_32))) == NULL)
3837c478bd9Sstevel@tonic-gate #endif
3847c478bd9Sstevel@tonic-gate 			cp  = getenv(MSG_ORIG(MSG_LD_LIBPATH));
3857c478bd9Sstevel@tonic-gate 	}
3867c478bd9Sstevel@tonic-gate 
38798c080d5SRod Evans 	if (cp && cp[0]) {
38857ef7aa9SRod Evans 		if ((path = libld_malloc(strlen(cp) + 1)) == NULL)
3897c478bd9Sstevel@tonic-gate 			return (S_ERROR);
3907c478bd9Sstevel@tonic-gate 		(void) strcpy(path, cp);
3915aefb655Srie 		DBG_CALL(Dbg_libs_path(ofl->ofl_lml, path, LA_SER_DEFAULT, 0));
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 		/*
3947c478bd9Sstevel@tonic-gate 		 * Process the first path string (anything up to a null or
3957c478bd9Sstevel@tonic-gate 		 * a `;');
3967c478bd9Sstevel@tonic-gate 		 */
3975aefb655Srie 		path = process_lib_path(ofl, &ofl->ofl_ulibdirs, path, FALSE);
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 		/*
40157ef7aa9SRod Evans 		 * By default, -L paths are prepended to the library search
40257ef7aa9SRod Evans 		 * path list, because Lidx == 0.  If a ';' is seen within an
40357ef7aa9SRod Evans 		 * LD_LIBRARY_PATH string, change the insert index so that -L
40457ef7aa9SRod Evans 		 * paths are added following the ';'.
4057c478bd9Sstevel@tonic-gate 		 */
4067c478bd9Sstevel@tonic-gate 		if (path) {
40757ef7aa9SRod Evans 			Lidx = aplist_nitems(ofl->ofl_ulibdirs);
4087c478bd9Sstevel@tonic-gate 			*path = '\0';
4097c478bd9Sstevel@tonic-gate 			++path;
4105aefb655Srie 			cp = process_lib_path(ofl, &ofl->ofl_ulibdirs, path,
4115aefb655Srie 			    FALSE);
4127c478bd9Sstevel@tonic-gate 			if (cp == (char *)S_ERROR)
4137c478bd9Sstevel@tonic-gate 				return (S_ERROR);
4147c478bd9Sstevel@tonic-gate 			else if (cp)
4151007fd6fSAli Bahrami 				ld_eprintf(ofl, ERR_WARNING,
4165aefb655Srie 				    MSG_INTL(MSG_LIB_MALFORM));
4177c478bd9Sstevel@tonic-gate 		}
4187c478bd9Sstevel@tonic-gate 	}
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	/*
4217c478bd9Sstevel@tonic-gate 	 * Add the default LIBPATH or any -YP supplied path.
4227c478bd9Sstevel@tonic-gate 	 */
4235aefb655Srie 	DBG_CALL(Dbg_libs_yp(ofl->ofl_lml, Plibpath));
4245aefb655Srie 	cp = process_lib_path(ofl, &ofl->ofl_dlibdirs, Plibpath, TRUE);
4257c478bd9Sstevel@tonic-gate 	if (cp == (char *)S_ERROR)
4267c478bd9Sstevel@tonic-gate 		return (S_ERROR);
4277c478bd9Sstevel@tonic-gate 	else if (cp) {
4281007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_LIB_BADYP));
4297c478bd9Sstevel@tonic-gate 		return (S_ERROR);
4307c478bd9Sstevel@tonic-gate 	}
43157ef7aa9SRod Evans 	DBG_CALL(Dbg_libs_init(ofl->ofl_lml, ofl->ofl_ulibdirs,
43257ef7aa9SRod Evans 	    ofl->ofl_dlibdirs));
4337c478bd9Sstevel@tonic-gate 	return (1);
4347c478bd9Sstevel@tonic-gate }
435