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.
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.
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]
23 * Copyright (c) 1988 AT&T
26 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
29 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
42 #include <sys/sysmacros.h>
47 * Define a list index for "-L" processing. By default, "-L" search paths are
48 * inserted at the beginning of the associated search list. However, should a
49 * ";" be discovered in a LD_LIBRARY_PATH listing, then any new "-L" search
50 * paths are inserted following the ";".
52 static Aliste Lidx
= 0;
55 * Function to handle -YL and -YU substitutions in LIBPATH. It's probably
56 * very unlikely that the link-editor will ever see this, as any use of these
57 * options is normally processed by the compiler driver first and the finished
58 * -YP string is sent to us. The fact that these two options are not even
59 * documented anymore makes it even more unlikely this processing will occur.
62 compat_YL_YU(Ofl_desc
*ofl
, char *path
, int index
)
67 * User supplied "-YL,libdir", this is the pathname that
68 * corresponds for compatibility to -YL (as defined in
69 * sgs/include/paths.h)
71 DBG_CALL(Dbg_libs_ylu(ofl
->ofl_lml
, Llibdir
,
75 } else if (index
== YUDIR
) {
78 * User supplied "-YU,libdir", this is the pathname that
79 * corresponds for compatibility to -YU (as defined in
80 * sgs/include/paths.h)
82 DBG_CALL(Dbg_libs_ylu(ofl
->ofl_lml
, Ulibdir
,
91 process_lib_path(Ofl_desc
*ofl
, APlist
**apl
, char *path
, Boolean subsflag
)
95 Boolean seenflg
= FALSE
;
96 char *dot
= (char *)MSG_ORIG(MSG_STR_DOT
);
98 for (i
= YLDIR
; i
; i
++) {
99 cp
= strpbrk(path
, MSG_ORIG(MSG_STR_PATHTOK
));
103 if (aplist_append(apl
, (subsflag
?
104 compat_YL_YU(ofl
, dot
, i
) : dot
),
105 AL_CNT_OFL_LIBDIRS
) == NULL
)
106 return ((char *)S_ERROR
);
108 } else if (aplist_append(apl
, (subsflag
?
109 compat_YL_YU(ofl
, path
, i
) : path
),
110 AL_CNT_OFL_LIBDIRS
) == NULL
) {
111 return ((char *)S_ERROR
);
119 if (aplist_append(apl
, (subsflag
?
120 compat_YL_YU(ofl
, dot
, i
) : dot
),
121 AL_CNT_OFL_LIBDIRS
) == NULL
)
122 return ((char *)S_ERROR
);
124 } else if (aplist_append(apl
, (subsflag
?
125 compat_YL_YU(ofl
, path
, i
) : path
),
126 AL_CNT_OFL_LIBDIRS
) == NULL
) {
127 return ((char *)S_ERROR
);
137 if (aplist_append(apl
, (subsflag
?
138 compat_YL_YU(ofl
, path
, i
) : path
),
139 AL_CNT_OFL_LIBDIRS
) == NULL
)
140 return ((char *)S_ERROR
);
143 if (aplist_append(apl
, (subsflag
?
144 compat_YL_YU(ofl
, dot
, i
) : dot
),
145 AL_CNT_OFL_LIBDIRS
) == NULL
)
146 return ((char *)S_ERROR
);
151 return (NULL
); /* keep gcc happy */
155 * adds the indicated path to those to be searched for libraries.
158 ld_add_libdir(Ofl_desc
*ofl
, const char *path
)
160 if (aplist_insert(&ofl
->ofl_ulibdirs
, path
,
161 AL_CNT_OFL_LIBDIRS
, Lidx
++) == NULL
)
165 * As -l and -L options can be interspersed, print the library
166 * search paths each time a new path is added.
168 DBG_CALL(Dbg_libs_update(ofl
->ofl_lml
, ofl
->ofl_ulibdirs
,
174 * Process a required library. Combine the directory and filename, and then
175 * append either a `.so' or `.a' suffix and try opening the associated pathname.
178 find_lib_name(const char *dir
, const char *file
, Ofl_desc
*ofl
, Rej_desc
*rej
,
183 char *_path
, path
[PATH_MAX
+ 2];
184 const char *_dir
= dir
;
188 * Determine the size of the directory. The directory and filename are
189 * concatenated into the local buffer which is purposely larger than
190 * PATH_MAX. Should a pathname be created that exceeds the system
191 * limit, the open() will catch it, and a suitable rejection message is
194 if ((dlen
= strlen(dir
)) == 0) {
195 _dir
= (char *)MSG_ORIG(MSG_STR_DOT
);
201 * If we are in dynamic mode try and open the associated shared object.
203 if (ofl
->ofl_flags
& FLG_OF_DYNLIBS
) {
204 (void) snprintf(path
, (PATH_MAX
+ 2), MSG_ORIG(MSG_STR_LIB_SO
),
206 DBG_CALL(Dbg_libs_l(ofl
->ofl_lml
, file
, path
));
207 if ((fd
= open(path
, O_RDONLY
)) != -1) {
209 if ((_path
= libld_malloc(strlen(path
) + 1)) == NULL
)
211 (void) strcpy(_path
, path
);
213 open_ret
= ld_process_open(_path
, &_path
[dlen
], &fd
,
214 ofl
, FLG_IF_NEEDED
, rej
, NULL
);
217 if (open_ret
!= 0 && (flags
& FLG_OF_ADEFLIB
))
218 ld_eprintf(ofl
, ERR_WARNING
,
219 MSG_INTL(MSG_ARG_ASSDEFLIB_FOUND
), dir
,
223 } else if (errno
!= ENOENT
) {
225 * If the open() failed for anything other than the
226 * file not existing, record the error condition.
228 rej
->rej_type
= SGS_REJ_STR
;
229 rej
->rej_str
= strerror(errno
);
230 rej
->rej_name
= strdup(path
);
235 * If we are not in dynamic mode, or a shared object could not be
236 * located, try and open the associated archive.
238 (void) snprintf(path
, (PATH_MAX
+ 2), MSG_ORIG(MSG_STR_LIB_A
),
240 DBG_CALL(Dbg_libs_l(ofl
->ofl_lml
, file
, path
));
241 if ((fd
= open(path
, O_RDONLY
)) != -1) {
243 if ((_path
= libld_malloc(strlen(path
) + 1)) == NULL
)
245 (void) strcpy(_path
, path
);
247 open_ret
= ld_process_open(_path
, &_path
[dlen
], &fd
, ofl
,
248 FLG_IF_NEEDED
, rej
, NULL
);
253 } else if (errno
!= ENOENT
) {
255 * If the open() failed for anything other than the
256 * file not existing, record the error condition.
258 rej
->rej_type
= SGS_REJ_STR
;
259 rej
->rej_str
= strerror(errno
);
260 rej
->rej_name
= strdup(path
);
267 * Take the abbreviated name of a library file (from -lfoo) and searches for the
268 * library. The search path rules are:
270 * o use any user supplied paths, i.e. LD_LIBRARY_PATH and -L, then
272 * o use the default directories, i.e. LIBPATH or -YP.
274 * If we are in dynamic mode and -Bstatic is not in effect, first look for a
275 * shared object with full name: path/libfoo.so; then [or else] look for an
276 * archive with name: path/libfoo.a. If no file is found, it's a fatal error,
277 * otherwise process the file appropriately depending on its type.
279 * If we end up using the default directories and -z assert-deflib has been
280 * turned on, then we pass that information down into find_lib_name which will
281 * warn appropriately if we find a shared object.
284 ld_find_library(const char *name
, Ofl_desc
*ofl
)
289 Rej_desc rej
= { 0 };
290 ofl_flag_t flags
= 0;
293 * Search for this file in any user defined directories.
295 for (APLIST_TRAVERSE(ofl
->ofl_ulibdirs
, idx
, path
)) {
296 Rej_desc _rej
= { 0 };
298 if ((open_ret
= find_lib_name(path
, name
, ofl
, &_rej
,
300 if (_rej
.rej_type
&& (rej
.rej_type
== 0))
307 if (ofl
->ofl_flags
& FLG_OF_ADEFLIB
) {
308 flags
|= FLG_OF_ADEFLIB
;
309 for (APLIST_TRAVERSE(ofl
->ofl_assdeflib
, idx
, path
)) {
310 if (strncmp(name
, path
+ MSG_STR_LIB_SIZE
,
311 MAX(strlen(path
+ MSG_STR_LIB_SIZE
) -
312 MSG_STR_SOEXT_SIZE
, strlen(name
))) == 0) {
313 flags
&= ~FLG_OF_ADEFLIB
;
320 * Finally try the default library search directories.
322 for (APLIST_TRAVERSE(ofl
->ofl_dlibdirs
, idx
, path
)) {
323 Rej_desc _rej
= { 0 };
325 if ((open_ret
= find_lib_name(path
, name
, ofl
, &_rej
,
327 if (_rej
.rej_type
&& (rej
.rej_type
== 0))
336 * If we've got this far we haven't found a shared object or archive.
337 * If an object was found, but was rejected for some reason, print a
338 * diagnostic to that effect, otherwise generate a generic "not found"
342 Conv_reject_desc_buf_t rej_buf
;
344 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(reject
[rej
.rej_type
]),
345 rej
.rej_name
? rej
.rej_name
: MSG_INTL(MSG_STR_UNKNOWN
),
346 conv_reject_desc(&rej
, &rej_buf
, ld_targ
.t_m
.m_mach
));
348 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_LIB_NOTFOUND
), name
);
355 * Inspect the LD_LIBRARY_PATH variable (if the -i options has not been
356 * specified), and set up the directory list from which to search for
357 * libraries. From the man page:
359 * LD_LIBRARY_PATH=dirlist1;dirlist2
361 * ld ... -Lpath1 ... -Lpathn ...
363 * results in a search order of:
365 * dirlist1 path1 ... pathn dirlist2 LIBPATH
367 * If LD_LIBRARY_PATH has no `;' specified, the pathname(s) supplied are
368 * all taken as dirlist2.
371 ld_lib_setup(Ofl_desc
*ofl
)
373 char *path
, *cp
= NULL
;
376 * Determine whether an LD_LIBRARY_PATH setting is in effect.
378 if (!(ofl
->ofl_flags
& FLG_OF_IGNENV
)) {
380 if ((cp
= getenv(MSG_ORIG(MSG_LD_LIBPATH_64
))) == NULL
)
382 if ((cp
= getenv(MSG_ORIG(MSG_LD_LIBPATH_32
))) == NULL
)
384 cp
= getenv(MSG_ORIG(MSG_LD_LIBPATH
));
388 if ((path
= libld_malloc(strlen(cp
) + 1)) == NULL
)
390 (void) strcpy(path
, cp
);
391 DBG_CALL(Dbg_libs_path(ofl
->ofl_lml
, path
, LA_SER_DEFAULT
, 0));
394 * Process the first path string (anything up to a null or
397 path
= process_lib_path(ofl
, &ofl
->ofl_ulibdirs
, path
, FALSE
);
401 * By default, -L paths are prepended to the library search
402 * path list, because Lidx == 0. If a ';' is seen within an
403 * LD_LIBRARY_PATH string, change the insert index so that -L
404 * paths are added following the ';'.
407 Lidx
= aplist_nitems(ofl
->ofl_ulibdirs
);
410 cp
= process_lib_path(ofl
, &ofl
->ofl_ulibdirs
, path
,
412 if (cp
== (char *)S_ERROR
)
415 ld_eprintf(ofl
, ERR_WARNING
,
416 MSG_INTL(MSG_LIB_MALFORM
));
421 * Add the default LIBPATH or any -YP supplied path.
423 DBG_CALL(Dbg_libs_yp(ofl
->ofl_lml
, Plibpath
));
424 cp
= process_lib_path(ofl
, &ofl
->ofl_dlibdirs
, Plibpath
, TRUE
);
425 if (cp
== (char *)S_ERROR
)
428 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_LIB_BADYP
));
431 DBG_CALL(Dbg_libs_init(ofl
->ofl_lml
, ofl
->ofl_ulibdirs
,