xref: /onnv-gate/usr/src/cmd/sgs/libld/common/ldlibs.c (revision 13074:787bf65954d0)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51618Srie  * Common Development and Distribution License (the "License").
61618Srie  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211618Srie 
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  *	Copyright (c) 1988 AT&T
240Sstevel@tonic-gate  *	  All Rights Reserved
250Sstevel@tonic-gate  *
2612254SAli.Bahrami@Oracle.COM  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
270Sstevel@tonic-gate  */
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * Library processing
310Sstevel@tonic-gate  */
320Sstevel@tonic-gate #include	<stdio.h>
330Sstevel@tonic-gate #include	<unistd.h>
340Sstevel@tonic-gate #include	<fcntl.h>
350Sstevel@tonic-gate #include	<string.h>
360Sstevel@tonic-gate #include	<limits.h>
370Sstevel@tonic-gate #include	<errno.h>
381618Srie #include	<debug.h>
390Sstevel@tonic-gate #include	"msg.h"
400Sstevel@tonic-gate #include	"_libld.h"
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
439131SRod.Evans@Sun.COM  * Define a list index for "-L" processing.  By default, "-L" search paths are
449131SRod.Evans@Sun.COM  * inserted at the beginning of the associated search list.  However, should a
459131SRod.Evans@Sun.COM  * ";" be discovered in a LD_LIBRARY_PATH listing, then any new "-L" search
469131SRod.Evans@Sun.COM  * paths are inserted following the ";".
470Sstevel@tonic-gate  */
489131SRod.Evans@Sun.COM static Aliste	Lidx = 0;
490Sstevel@tonic-gate 
500Sstevel@tonic-gate /*
510Sstevel@tonic-gate  * Function to handle -YL and -YU substitutions in LIBPATH.  It's probably
520Sstevel@tonic-gate  * very unlikely that the link-editor will ever see this, as any use of these
530Sstevel@tonic-gate  * options is normally processed by the compiler driver first and the finished
540Sstevel@tonic-gate  * -YP string is sent to us.  The fact that these two options are not even
550Sstevel@tonic-gate  * documented anymore makes it even more unlikely this processing will occur.
560Sstevel@tonic-gate  */
570Sstevel@tonic-gate static char *
compat_YL_YU(Ofl_desc * ofl,char * path,int index)581618Srie compat_YL_YU(Ofl_desc *ofl, char *path, int index)
590Sstevel@tonic-gate {
600Sstevel@tonic-gate 	if (index == YLDIR) {
610Sstevel@tonic-gate 		if (Llibdir) {
620Sstevel@tonic-gate 			/*
630Sstevel@tonic-gate 			 * User supplied "-YL,libdir", this is the pathname that
640Sstevel@tonic-gate 			 * corresponds for compatibility to -YL (as defined in
650Sstevel@tonic-gate 			 * sgs/include/paths.h)
660Sstevel@tonic-gate 			 */
671618Srie 			DBG_CALL(Dbg_libs_ylu(ofl->ofl_lml, Llibdir,
681618Srie 			    path, index));
690Sstevel@tonic-gate 			return (Llibdir);
700Sstevel@tonic-gate 		}
710Sstevel@tonic-gate 	} else if (index == YUDIR) {
720Sstevel@tonic-gate 		if (Ulibdir) {
730Sstevel@tonic-gate 			/*
740Sstevel@tonic-gate 			 * User supplied "-YU,libdir", this is the pathname that
750Sstevel@tonic-gate 			 * corresponds for compatibility to -YU (as defined in
760Sstevel@tonic-gate 			 * sgs/include/paths.h)
770Sstevel@tonic-gate 			 */
781618Srie 			DBG_CALL(Dbg_libs_ylu(ofl->ofl_lml, Ulibdir,
791618Srie 			    path, index));
800Sstevel@tonic-gate 			return (Ulibdir);
810Sstevel@tonic-gate 		}
820Sstevel@tonic-gate 	}
830Sstevel@tonic-gate 	return (path);
840Sstevel@tonic-gate }
850Sstevel@tonic-gate 
860Sstevel@tonic-gate static char *
process_lib_path(Ofl_desc * ofl,APlist ** apl,char * path,Boolean subsflag)879131SRod.Evans@Sun.COM process_lib_path(Ofl_desc *ofl, APlist **apl, char *path, Boolean subsflag)
880Sstevel@tonic-gate {
890Sstevel@tonic-gate 	int	i;
900Sstevel@tonic-gate 	char	*cp;
910Sstevel@tonic-gate 	Boolean	seenflg = FALSE;
920Sstevel@tonic-gate 	char	*dot = (char *)MSG_ORIG(MSG_STR_DOT);
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	for (i = YLDIR; i; i++) {
950Sstevel@tonic-gate 		cp = strpbrk(path, MSG_ORIG(MSG_STR_PATHTOK));
960Sstevel@tonic-gate 		if (cp == NULL) {
970Sstevel@tonic-gate 			if (*path == '\0') {
980Sstevel@tonic-gate 				if (seenflg)
999131SRod.Evans@Sun.COM 					if (aplist_append(apl, (subsflag ?
1009131SRod.Evans@Sun.COM 					    compat_YL_YU(ofl, dot, i) : dot),
1019131SRod.Evans@Sun.COM 					    AL_CNT_OFL_LIBDIRS) == NULL)
1024734Sab196087 						return ((char *)S_ERROR);
1039131SRod.Evans@Sun.COM 
1049131SRod.Evans@Sun.COM 			} else if (aplist_append(apl, (subsflag ?
1059131SRod.Evans@Sun.COM 			    compat_YL_YU(ofl, path, i) : path),
1069131SRod.Evans@Sun.COM 			    AL_CNT_OFL_LIBDIRS) == NULL) {
1079131SRod.Evans@Sun.COM 				return ((char *)S_ERROR);
1089131SRod.Evans@Sun.COM 			}
1090Sstevel@tonic-gate 			return (cp);
1100Sstevel@tonic-gate 		}
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 		if (*cp == ':') {
1130Sstevel@tonic-gate 			*cp = '\0';
1140Sstevel@tonic-gate 			if (cp == path) {
1159131SRod.Evans@Sun.COM 				if (aplist_append(apl, (subsflag ?
1169131SRod.Evans@Sun.COM 				    compat_YL_YU(ofl, dot, i) : dot),
1179131SRod.Evans@Sun.COM 				    AL_CNT_OFL_LIBDIRS) == NULL)
1180Sstevel@tonic-gate 					return ((char *)S_ERROR);
1199131SRod.Evans@Sun.COM 
1209131SRod.Evans@Sun.COM 			} else if (aplist_append(apl, (subsflag ?
1219131SRod.Evans@Sun.COM 			    compat_YL_YU(ofl, path, i) : path),
1229131SRod.Evans@Sun.COM 			    AL_CNT_OFL_LIBDIRS) == NULL) {
1239131SRod.Evans@Sun.COM 				return ((char *)S_ERROR);
1240Sstevel@tonic-gate 			}
1250Sstevel@tonic-gate 			path = cp + 1;
1260Sstevel@tonic-gate 			seenflg = TRUE;
1270Sstevel@tonic-gate 			continue;
1280Sstevel@tonic-gate 		}
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 		/* case ";" */
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 		if (cp != path) {
1339131SRod.Evans@Sun.COM 			if (aplist_append(apl, (subsflag ?
1349131SRod.Evans@Sun.COM 			    compat_YL_YU(ofl, path, i) : path),
1359131SRod.Evans@Sun.COM 			    AL_CNT_OFL_LIBDIRS) == NULL)
1360Sstevel@tonic-gate 				return ((char *)S_ERROR);
1370Sstevel@tonic-gate 		} else {
1380Sstevel@tonic-gate 			if (seenflg)
1399131SRod.Evans@Sun.COM 				if (aplist_append(apl, (subsflag ?
1409131SRod.Evans@Sun.COM 				    compat_YL_YU(ofl, dot, i) : dot),
1419131SRod.Evans@Sun.COM 				    AL_CNT_OFL_LIBDIRS) == NULL)
1420Sstevel@tonic-gate 					return ((char *)S_ERROR);
1430Sstevel@tonic-gate 		}
1440Sstevel@tonic-gate 		return (cp);
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate 	/* NOTREACHED */
1470Sstevel@tonic-gate 	return (NULL);	/* keep gcc happy */
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate /*
1510Sstevel@tonic-gate  * adds the indicated path to those to be searched for libraries.
1520Sstevel@tonic-gate  */
1530Sstevel@tonic-gate uintptr_t
ld_add_libdir(Ofl_desc * ofl,const char * path)1541618Srie ld_add_libdir(Ofl_desc *ofl, const char *path)
1550Sstevel@tonic-gate {
1569131SRod.Evans@Sun.COM 	if (aplist_insert(&ofl->ofl_ulibdirs, path,
1579131SRod.Evans@Sun.COM 	    AL_CNT_OFL_LIBDIRS, Lidx++) == NULL)
1589131SRod.Evans@Sun.COM 		return (S_ERROR);
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	/*
1610Sstevel@tonic-gate 	 * As -l and -L options can be interspersed, print the library
1620Sstevel@tonic-gate 	 * search paths each time a new path is added.
1630Sstevel@tonic-gate 	 */
1649131SRod.Evans@Sun.COM 	DBG_CALL(Dbg_libs_update(ofl->ofl_lml, ofl->ofl_ulibdirs,
1659131SRod.Evans@Sun.COM 	    ofl->ofl_dlibdirs));
1660Sstevel@tonic-gate 	return (1);
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate /*
1700Sstevel@tonic-gate  * Process a required library.  Combine the directory and filename, and then
1710Sstevel@tonic-gate  * append either a `.so' or `.a' suffix and try opening the associated pathname.
1720Sstevel@tonic-gate  */
17312254SAli.Bahrami@Oracle.COM static uintptr_t
find_lib_name(const char * dir,const char * file,Ofl_desc * ofl,Rej_desc * rej)1740Sstevel@tonic-gate find_lib_name(const char *dir, const char *file, Ofl_desc *ofl, Rej_desc *rej)
1750Sstevel@tonic-gate {
1760Sstevel@tonic-gate 	int		fd;
1770Sstevel@tonic-gate 	size_t		dlen;
1780Sstevel@tonic-gate 	char		*_path, path[PATH_MAX + 2];
1790Sstevel@tonic-gate 	const char	*_dir = dir;
18012254SAli.Bahrami@Oracle.COM 	uintptr_t	open_ret;
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate 	/*
1830Sstevel@tonic-gate 	 * Determine the size of the directory.  The directory and filename are
1840Sstevel@tonic-gate 	 * concatenated into the local buffer which is purposely larger than
1850Sstevel@tonic-gate 	 * PATH_MAX.  Should a pathname be created that exceeds the system
1860Sstevel@tonic-gate 	 * limit, the open() will catch it, and a suitable rejection message is
1870Sstevel@tonic-gate 	 * saved.
1880Sstevel@tonic-gate 	 */
1890Sstevel@tonic-gate 	if ((dlen = strlen(dir)) == 0) {
1900Sstevel@tonic-gate 		_dir = (char *)MSG_ORIG(MSG_STR_DOT);
1910Sstevel@tonic-gate 		dlen = 1;
1920Sstevel@tonic-gate 	}
1930Sstevel@tonic-gate 	dlen++;
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	/*
1960Sstevel@tonic-gate 	 * If we are in dynamic mode try and open the associated shared object.
1970Sstevel@tonic-gate 	 */
1980Sstevel@tonic-gate 	if (ofl->ofl_flags & FLG_OF_DYNLIBS) {
1990Sstevel@tonic-gate 		(void) snprintf(path, (PATH_MAX + 2), MSG_ORIG(MSG_STR_LIB_SO),
2000Sstevel@tonic-gate 		    _dir, file);
2011618Srie 		DBG_CALL(Dbg_libs_l(ofl->ofl_lml, file, path));
2020Sstevel@tonic-gate 		if ((fd = open(path, O_RDONLY)) != -1) {
2030Sstevel@tonic-gate 
2049131SRod.Evans@Sun.COM 			if ((_path = libld_malloc(strlen(path) + 1)) == NULL)
20512254SAli.Bahrami@Oracle.COM 				return (S_ERROR);
2060Sstevel@tonic-gate 			(void) strcpy(_path, path);
2070Sstevel@tonic-gate 
20812254SAli.Bahrami@Oracle.COM 			open_ret = ld_process_open(_path, &_path[dlen], &fd,
20912254SAli.Bahrami@Oracle.COM 			    ofl, FLG_IF_NEEDED, rej, NULL);
2102978Srie 			if (fd != -1)
2112978Srie 				(void) close(fd);
21212254SAli.Bahrami@Oracle.COM 			return (open_ret);
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 		} else if (errno != ENOENT) {
2150Sstevel@tonic-gate 			/*
2160Sstevel@tonic-gate 			 * If the open() failed for anything other than the
2170Sstevel@tonic-gate 			 * file not existing, record the error condition.
2180Sstevel@tonic-gate 			 */
2190Sstevel@tonic-gate 			rej->rej_type = SGS_REJ_STR;
2200Sstevel@tonic-gate 			rej->rej_str = strerror(errno);
2210Sstevel@tonic-gate 			rej->rej_name = strdup(path);
2220Sstevel@tonic-gate 		}
2230Sstevel@tonic-gate 	}
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	/*
2260Sstevel@tonic-gate 	 * If we are not in dynamic mode, or a shared object could not be
2270Sstevel@tonic-gate 	 * located, try and open the associated archive.
2280Sstevel@tonic-gate 	 */
2290Sstevel@tonic-gate 	(void) snprintf(path, (PATH_MAX + 2), MSG_ORIG(MSG_STR_LIB_A),
2300Sstevel@tonic-gate 	    _dir, file);
2311618Srie 	DBG_CALL(Dbg_libs_l(ofl->ofl_lml, file, path));
2320Sstevel@tonic-gate 	if ((fd = open(path, O_RDONLY)) != -1) {
2330Sstevel@tonic-gate 
2349131SRod.Evans@Sun.COM 		if ((_path = libld_malloc(strlen(path) + 1)) == NULL)
23512254SAli.Bahrami@Oracle.COM 			return (S_ERROR);
2360Sstevel@tonic-gate 		(void) strcpy(_path, path);
2370Sstevel@tonic-gate 
23812254SAli.Bahrami@Oracle.COM 		open_ret = ld_process_open(_path, &_path[dlen], &fd, ofl,
23912254SAli.Bahrami@Oracle.COM 		    FLG_IF_NEEDED, rej, NULL);
2402978Srie 		if (fd != -1)
2412978Srie 			(void) close(fd);
24212254SAli.Bahrami@Oracle.COM 		return (open_ret);
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate 	} else if (errno != ENOENT) {
2450Sstevel@tonic-gate 		/*
2460Sstevel@tonic-gate 		 * If the open() failed for anything other than the
2470Sstevel@tonic-gate 		 * file not existing, record the error condition.
2480Sstevel@tonic-gate 		 */
2490Sstevel@tonic-gate 		rej->rej_type = SGS_REJ_STR;
2500Sstevel@tonic-gate 		rej->rej_str = strerror(errno);
2510Sstevel@tonic-gate 		rej->rej_name = strdup(path);
2520Sstevel@tonic-gate 	}
2530Sstevel@tonic-gate 
25412254SAli.Bahrami@Oracle.COM 	return (0);
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate /*
2580Sstevel@tonic-gate  * Take the abbreviated name of a library file (from -lfoo) and searches for the
2590Sstevel@tonic-gate  * library.  The search path rules are:
2600Sstevel@tonic-gate  *
2610Sstevel@tonic-gate  *	o	use any user supplied paths, i.e. LD_LIBRARY_PATH and -L, then
2620Sstevel@tonic-gate  *
2630Sstevel@tonic-gate  *	o	use the default directories, i.e. LIBPATH or -YP.
2640Sstevel@tonic-gate  *
2650Sstevel@tonic-gate  * If we are in dynamic mode and -Bstatic is not in effect, first look for a
2660Sstevel@tonic-gate  * shared object with full name: path/libfoo.so; then [or else] look for an
2670Sstevel@tonic-gate  * archive with name: path/libfoo.a.  If no file is found, it's a fatal error,
2680Sstevel@tonic-gate  * otherwise process the file appropriately depending on its type.
2690Sstevel@tonic-gate  */
2700Sstevel@tonic-gate uintptr_t
ld_find_library(const char * name,Ofl_desc * ofl)2711618Srie ld_find_library(const char *name, Ofl_desc *ofl)
2720Sstevel@tonic-gate {
2739131SRod.Evans@Sun.COM 	Aliste		idx;
2740Sstevel@tonic-gate 	char		*path;
27512254SAli.Bahrami@Oracle.COM 	uintptr_t	open_ret;
2760Sstevel@tonic-gate 	Rej_desc	rej = { 0 };
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate 	/*
2790Sstevel@tonic-gate 	 * Search for this file in any user defined directories.
2800Sstevel@tonic-gate 	 */
2819131SRod.Evans@Sun.COM 	for (APLIST_TRAVERSE(ofl->ofl_ulibdirs, idx, path)) {
2820Sstevel@tonic-gate 		Rej_desc	_rej = { 0 };
2830Sstevel@tonic-gate 
28412254SAli.Bahrami@Oracle.COM 		if ((open_ret = find_lib_name(path, name, ofl, &_rej)) == 0) {
2850Sstevel@tonic-gate 			if (_rej.rej_type && (rej.rej_type == 0))
2860Sstevel@tonic-gate 				rej = _rej;
2870Sstevel@tonic-gate 			continue;
2880Sstevel@tonic-gate 		}
28912254SAli.Bahrami@Oracle.COM 		return (open_ret);
2900Sstevel@tonic-gate 	}
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate 	/*
2930Sstevel@tonic-gate 	 * Finally try the default library search directories.
2940Sstevel@tonic-gate 	 */
2959131SRod.Evans@Sun.COM 	for (APLIST_TRAVERSE(ofl->ofl_dlibdirs, idx, path)) {
2960Sstevel@tonic-gate 		Rej_desc	_rej = { 0 };
2970Sstevel@tonic-gate 
29812254SAli.Bahrami@Oracle.COM 		if ((open_ret = find_lib_name(path, name, ofl, &_rej)) == 0) {
2990Sstevel@tonic-gate 			if (_rej.rej_type && (rej.rej_type == 0))
3000Sstevel@tonic-gate 				rej = _rej;
3010Sstevel@tonic-gate 			continue;
3020Sstevel@tonic-gate 		}
30312254SAli.Bahrami@Oracle.COM 		return (open_ret);
3040Sstevel@tonic-gate 	}
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	/*
3070Sstevel@tonic-gate 	 * If we've got this far we haven't found a shared object or archive.
3080Sstevel@tonic-gate 	 * If an object was found, but was rejected for some reason, print a
3090Sstevel@tonic-gate 	 * diagnostic to that effect, otherwise generate a generic "not found"
3100Sstevel@tonic-gate 	 * diagnostic.
3110Sstevel@tonic-gate 	 */
3124734Sab196087 	if (rej.rej_type) {
3134734Sab196087 		Conv_reject_desc_buf_t rej_buf;
3144734Sab196087 
315*13074SAli.Bahrami@Oracle.COM 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(reject[rej.rej_type]),
3160Sstevel@tonic-gate 		    rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN),
3176206Sab196087 		    conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach));
3184734Sab196087 	} else {
319*13074SAli.Bahrami@Oracle.COM 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_LIB_NOTFOUND), name);
3204734Sab196087 	}
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate 	return (0);
3230Sstevel@tonic-gate }
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate /*
3260Sstevel@tonic-gate  * Inspect the LD_LIBRARY_PATH variable (if the -i options has not been
3270Sstevel@tonic-gate  * specified), and set up the directory list from which to search for
3280Sstevel@tonic-gate  * libraries.  From the man page:
3290Sstevel@tonic-gate  *
3300Sstevel@tonic-gate  *	LD_LIBRARY_PATH=dirlist1;dirlist2
3310Sstevel@tonic-gate  * and
3320Sstevel@tonic-gate  *	ld ... -Lpath1 ... -Lpathn ...
3330Sstevel@tonic-gate  *
3340Sstevel@tonic-gate  * results in a search order of:
3350Sstevel@tonic-gate  *
3360Sstevel@tonic-gate  *	dirlist1 path1 ... pathn dirlist2 LIBPATH
3370Sstevel@tonic-gate  *
3380Sstevel@tonic-gate  * If LD_LIBRARY_PATH has no `;' specified, the pathname(s) supplied are
3390Sstevel@tonic-gate  * all taken as dirlist2.
3400Sstevel@tonic-gate  */
3410Sstevel@tonic-gate uintptr_t
ld_lib_setup(Ofl_desc * ofl)3427359SRod.Evans@Sun.COM ld_lib_setup(Ofl_desc *ofl)
3430Sstevel@tonic-gate {
3440Sstevel@tonic-gate 	char	*path, *cp = NULL;
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate 	/*
3470Sstevel@tonic-gate 	 * Determine whether an LD_LIBRARY_PATH setting is in effect.
3480Sstevel@tonic-gate 	 */
3490Sstevel@tonic-gate 	if (!(ofl->ofl_flags & FLG_OF_IGNENV)) {
3500Sstevel@tonic-gate #if	defined(_ELF64)
3510Sstevel@tonic-gate 		if ((cp = getenv(MSG_ORIG(MSG_LD_LIBPATH_64))) == NULL)
3520Sstevel@tonic-gate #else
3530Sstevel@tonic-gate 		if ((cp = getenv(MSG_ORIG(MSG_LD_LIBPATH_32))) == NULL)
3540Sstevel@tonic-gate #endif
3554734Sab196087 			cp  = getenv(MSG_ORIG(MSG_LD_LIBPATH));
3560Sstevel@tonic-gate 	}
3570Sstevel@tonic-gate 
35812029SRod.Evans@Sun.COM 	if (cp && cp[0]) {
3599131SRod.Evans@Sun.COM 		if ((path = libld_malloc(strlen(cp) + 1)) == NULL)
3600Sstevel@tonic-gate 			return (S_ERROR);
3610Sstevel@tonic-gate 		(void) strcpy(path, cp);
3621618Srie 		DBG_CALL(Dbg_libs_path(ofl->ofl_lml, path, LA_SER_DEFAULT, 0));
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 		/*
3650Sstevel@tonic-gate 		 * Process the first path string (anything up to a null or
3660Sstevel@tonic-gate 		 * a `;');
3670Sstevel@tonic-gate 		 */
3681618Srie 		path = process_lib_path(ofl, &ofl->ofl_ulibdirs, path, FALSE);
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 		/*
3729131SRod.Evans@Sun.COM 		 * By default, -L paths are prepended to the library search
3739131SRod.Evans@Sun.COM 		 * path list, because Lidx == 0.  If a ';' is seen within an
3749131SRod.Evans@Sun.COM 		 * LD_LIBRARY_PATH string, change the insert index so that -L
3759131SRod.Evans@Sun.COM 		 * paths are added following the ';'.
3760Sstevel@tonic-gate 		 */
3770Sstevel@tonic-gate 		if (path) {
3789131SRod.Evans@Sun.COM 			Lidx = aplist_nitems(ofl->ofl_ulibdirs);
3790Sstevel@tonic-gate 			*path = '\0';
3800Sstevel@tonic-gate 			++path;
3811618Srie 			cp = process_lib_path(ofl, &ofl->ofl_ulibdirs, path,
3821618Srie 			    FALSE);
3830Sstevel@tonic-gate 			if (cp == (char *)S_ERROR)
3840Sstevel@tonic-gate 				return (S_ERROR);
3850Sstevel@tonic-gate 			else if (cp)
386*13074SAli.Bahrami@Oracle.COM 				ld_eprintf(ofl, ERR_WARNING,
3871618Srie 				    MSG_INTL(MSG_LIB_MALFORM));
3880Sstevel@tonic-gate 		}
3890Sstevel@tonic-gate 	}
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate 	/*
3920Sstevel@tonic-gate 	 * Add the default LIBPATH or any -YP supplied path.
3930Sstevel@tonic-gate 	 */
3941618Srie 	DBG_CALL(Dbg_libs_yp(ofl->ofl_lml, Plibpath));
3951618Srie 	cp = process_lib_path(ofl, &ofl->ofl_dlibdirs, Plibpath, TRUE);
3960Sstevel@tonic-gate 	if (cp == (char *)S_ERROR)
3970Sstevel@tonic-gate 		return (S_ERROR);
3980Sstevel@tonic-gate 	else if (cp) {
399*13074SAli.Bahrami@Oracle.COM 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_LIB_BADYP));
4000Sstevel@tonic-gate 		return (S_ERROR);
4010Sstevel@tonic-gate 	}
4029131SRod.Evans@Sun.COM 	DBG_CALL(Dbg_libs_init(ofl->ofl_lml, ofl->ofl_ulibdirs,
4039131SRod.Evans@Sun.COM 	    ofl->ofl_dlibdirs));
4040Sstevel@tonic-gate 	return (1);
4050Sstevel@tonic-gate }
406