xref: /illumos-gate/usr/src/cmd/sgs/rtld/common/analyze.c (revision 37b407883a45b878109bb872aba0145ef4101cec)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  *	Copyright (c) 1988 AT&T
24  *	  All Rights Reserved
25  *
26  *
27  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include	"_synonyms.h"
33 
34 #include	<string.h>
35 #include	<stdio.h>
36 #include	<unistd.h>
37 #include	<sys/stat.h>
38 #include	<sys/mman.h>
39 #include	<fcntl.h>
40 #include	<limits.h>
41 #include	<dlfcn.h>
42 #include	<errno.h>
43 #include	<link.h>
44 #include	"_rtld.h"
45 #include	"_audit.h"
46 #include	"_elf.h"
47 #include	"msg.h"
48 #include	"debug.h"
49 #include	"conv.h"
50 
51 static Fct *	vector[] = {
52 	&elf_fct,
53 #ifdef A_OUT
54 	&aout_fct,
55 #endif
56 	0
57 };
58 
59 /*
60  * If a load filter flag is in effect, and this object is a filter, trigger the
61  * loading of all its filtees.  The load filter flag is in effect when creating
62  * configuration files, or when under the control of ldd(1), or the LD_LOADFLTR
63  * environment variable is set, or this object was built with the -zloadfltr
64  * flag.  Otherwise, filtee loading is deferred until triggered by a relocation.
65  */
66 static void
67 load_filtees(Rt_map *lmp)
68 {
69 	if ((FLAGS1(lmp) & MSK_RT_FILTER) &&
70 	    ((FLAGS(lmp) & FLG_RT_LOADFLTR) ||
71 	    (LIST(lmp)->lm_tflags & LML_TFLG_LOADFLTR))) {
72 		Dyninfo *	dip =  DYNINFO(lmp);
73 		uint_t		cnt, max = DYNINFOCNT(lmp);
74 		Slookup		sl;
75 
76 		sl.sl_name = 0;
77 		sl.sl_hash = 0;
78 		sl.sl_imap = sl.sl_cmap = lmp;
79 
80 		for (cnt = 0; cnt < max; cnt++, dip++) {
81 			if (((dip->di_flags & MSK_DI_FILTER) == 0) ||
82 			    ((dip->di_flags & FLG_DI_AUXFLTR) &&
83 			    (rtld_flags & RT_FL_NOAUXFLTR)))
84 				continue;
85 			(void) elf_lookup_filtee(&sl, 0, 0, cnt);
86 		}
87 	}
88 }
89 
90 /*
91  * Analyze one or more link-maps of a link map control list.  This routine is
92  * called at startup to continue the processing of the main executable.  It is
93  * also called each time a new set of objects are loaded, ie. from filters,
94  * lazy-loaded objects, or dlopen().
95  *
96  * In each instance we traverse the link-map control list starting with the
97  * initial object.  As dependencies are analyzed they are added to the link-map
98  * control list.  Thus the list grows as we traverse it - this results in the
99  * breadth first ordering of all needed objects.
100  */
101 int
102 analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)
103 {
104 	Rt_map	*lmp = nlmp;
105 	Lm_cntl	*nlmc;
106 	int	ret = 1;
107 
108 	/*
109 	 * If this link-map control list is being analyzed, return.  The object
110 	 * that has just been added will be picked up by the existing analysis
111 	 * thread.  Note, this is only really meaningful during process init-
112 	 * ialization, as objects are added to the main link-map control list.
113 	 * Following this initialization, each family of objects that are loaded
114 	 * are added to a new link-map control list.
115 	 */
116 	/* LINTED */
117 	nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco);
118 	if (nlmc->lc_flags & LMC_FLG_ANALYZING)
119 		return (1);
120 
121 	/*
122 	 * If this object doesn't belong to the present link-map control list
123 	 * then it must already have been analyzed, or it is in the process of
124 	 * being analyzed prior to us recursing into this analysis.  In either
125 	 * case, ignore the object as it's already being taken care of.
126 	 */
127 	if (nlmco != CNTL(nlmp))
128 		return (1);
129 
130 	nlmc->lc_flags |= LMC_FLG_ANALYZING;
131 
132 	for (; lmp; lmp = (Rt_map *)NEXT(lmp)) {
133 		if (FLAGS(lmp) &
134 		    (FLG_RT_ANALZING | FLG_RT_ANALYZED | FLG_RT_DELETE))
135 			continue;
136 
137 		/*
138 		 * Indicate that analyzing is under way.
139 		 */
140 		FLAGS(lmp) |= FLG_RT_ANALZING;
141 
142 		/*
143 		 * If this link map represents a relocatable object, then we
144 		 * need to finish the link-editing of the object at this point.
145 		 */
146 		if (FLAGS(lmp) & FLG_RT_OBJECT) {
147 			if (elf_obj_fini(lml, lmp) == 0) {
148 				if (lml->lm_flags & LML_FLG_TRC_ENABLE)
149 					continue;
150 				ret = 0;
151 				break;
152 			}
153 		}
154 
155 		DBG_CALL(Dbg_file_analyze(lmp));
156 
157 		/*
158 		 * Establish any dependencies this object requires.
159 		 */
160 		if (LM_NEEDED(lmp)(lml, nlmco, lmp) == 0) {
161 			if (lml->lm_flags & LML_FLG_TRC_ENABLE)
162 				continue;
163 			ret = 0;
164 			break;
165 		}
166 
167 		FLAGS(lmp) &= ~FLG_RT_ANALZING;
168 		FLAGS(lmp) |= FLG_RT_ANALYZED;
169 
170 		/*
171 		 * If we're building a configuration file, determine if this
172 		 * object is a filter and if so load its filtees.  This
173 		 * traversal is only necessary for crle(1), as typical use of
174 		 * an object will load filters as part of relocation processing.
175 		 */
176 		if (MODE(nlmp) & RTLD_CONFGEN)
177 			load_filtees(lmp);
178 
179 		/*
180 		 * If an interposer has been added, it will have been inserted
181 		 * in the link-map before the link we're presently analyzing.
182 		 * Break out of this analysis loop and return to the head of
183 		 * the link-map control list to analyze the interposer.  Note
184 		 * that this rescan preserves the breadth first loading of
185 		 * dependencies.
186 		 */
187 		if (nlmc->lc_flags & LMC_FLG_REANALYZE) {
188 			nlmc->lc_flags &= ~LMC_FLG_REANALYZE;
189 			lmp = nlmc->lc_head;
190 		}
191 	}
192 
193 	nlmc->lc_flags &= ~LMC_FLG_ANALYZING;
194 
195 	return (ret);
196 }
197 
198 /*
199  * Copy relocation test.  If the symbol definition is within .bss, then it's
200  * zero filled, and as the destination is within .bss, we can skip copying
201  * zero's to zero's.  However, if the destination object has a MOVE table, it's
202  * .bss might contain non-zero data, in which case copy it regardless.
203  */
204 static int
205 copy_zerobits(Rt_map *dlmp, Sym *dsym)
206 {
207 	if ((FLAGS(dlmp) & FLG_RT_MOVE) == 0) {
208 		Mmap	*mmaps;
209 		caddr_t	daddr = (caddr_t)dsym->st_value;
210 
211 		if ((FLAGS(dlmp) & FLG_RT_FIXED) == 0)
212 			daddr += ADDR(dlmp);
213 
214 		for (mmaps = MMAPS(dlmp); mmaps->m_vaddr; mmaps++) {
215 			if ((mmaps->m_fsize != mmaps->m_msize) &&
216 			    (daddr >= (mmaps->m_vaddr + mmaps->m_fsize)) &&
217 			    (daddr < (mmaps->m_vaddr + mmaps->m_msize)))
218 				return (1);
219 		}
220 	}
221 	return (0);
222 }
223 
224 /*
225  * Relocate an individual object.
226  */
227 static int
228 relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now)
229 {
230 	/*
231 	 * If we're running under ldd(1), and haven't been asked to trace any
232 	 * warnings, skip any actual relocation processing.
233 	 */
234 	if (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) ||
235 	    (lml->lm_flags & LML_FLG_TRC_WARN)) {
236 
237 		if (relocated)
238 			(*relocated)++;
239 
240 		if ((LM_RELOC(lmp)(lmp, now) == 0) &&
241 		    ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
242 			return (0);
243 	}
244 	return (1);
245 }
246 
247 /*
248  * Relocate the objects on a link-map control list.
249  */
250 static int
251 _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated)
252 {
253 	Rt_map	*lmp;
254 
255 	for (lmp = nlmp; lmp; lmp = (Rt_map *)NEXT(lmp)) {
256 		/*
257 		 * If this object has already been relocated, we're done.  If
258 		 * this object is being deleted, skip it, there's probably a
259 		 * relocation error somewhere that's causing this deletion.
260 		 */
261 		if (FLAGS(lmp) &
262 		    (FLG_RT_RELOCING | FLG_RT_RELOCED | FLG_RT_DELETE))
263 			continue;
264 
265 		/*
266 		 * Indicate that relocation processing is under way.
267 		 */
268 		FLAGS(lmp) |= FLG_RT_RELOCING;
269 
270 		/*
271 		 * Relocate the object.
272 		 */
273 		if (relocate_so(lml, lmp, relocated, 0) == 0)
274 			return (0);
275 
276 		/*
277 		 * Indicate that the objects relocation is complete.
278 		 */
279 		FLAGS(lmp) &= ~FLG_RT_RELOCING;
280 		FLAGS(lmp) |= FLG_RT_RELOCED;
281 
282 		/*
283 		 * Mark this object's init is available for harvesting.  Under
284 		 * ldd(1) this marking is necessary for -i (tsort) gathering.
285 		 */
286 		lml->lm_init++;
287 
288 		/*
289 		 * None of the following processing is necessary under ldd().
290 		 */
291 		if ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) {
292 			/*
293 			 * Process any move data.
294 			 */
295 			if (FLAGS(lmp) & FLG_RT_MOVE)
296 				move_data(lmp);
297 
298 			/*
299 			 * Process any DT_SUNW_RTLDINFO information now the
300 			 * object is relocated, and remove the RTLDINFO
301 			 * infrastructure as it won't be needed anymore.
302 			 *
303 			 * We wait until lmp == lm_info_lmp, as it's at this
304 			 * stage we know the object contributing RTLDINFO has
305 			 * been properly relocated.
306 			 */
307 			if ((FCT(lmp) == &elf_fct) && (lml->lm_rtldinfo) &&
308 			    (lmp == lml->lm_info_lmp)) {
309 				Aliste		off;
310 				Lc_interface **	funcs;
311 
312 				for (ALIST_TRAVERSE(lml->lm_rtldinfo,
313 				    off, funcs))
314 					get_lcinterface(lmp, *funcs);
315 				free(lml->lm_rtldinfo);
316 				lml->lm_rtldinfo = 0;
317 			}
318 		}
319 
320 		/*
321 		 * Determine if this object is a filter, and if a load filter
322 		 * flag is in effect, trigger the loading of all its filtees.
323 		 */
324 		load_filtees(lmp);
325 	}
326 
327 	/*
328 	 * Perform special copy relocations.  These are only meaningful for
329 	 * dynamic executables (fixed and head of their link-map list).  If
330 	 * this ever has to change then the infrastructure of COPY() has to
331 	 * change as presently this element is used to capture both receiver
332 	 * and supplier of copy data.
333 	 */
334 	if ((FLAGS(nlmp) & FLG_RT_FIXED) && (nlmp == LIST(nlmp)->lm_head) &&
335 	    (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) ||
336 	    (lml->lm_flags & LML_FLG_TRC_WARN))) {
337 		Rt_map **	lmpp;
338 		Aliste		off1;
339 		Word		tracing;
340 
341 #if	defined(__sparc) || defined(__amd64)
342 /* XX64 don't need this once the compilers are fixed */
343 #elif	defined(i386)
344 		if (elf_copy_gen(nlmp) == 0)
345 			return (0);
346 #endif
347 
348 		if (COPY(nlmp) == 0)
349 			return (1);
350 
351 		if ((LIST(nlmp)->lm_flags & LML_FLG_TRC_ENABLE) &&
352 		    (((rtld_flags & RT_FL_SILENCERR) == 0) ||
353 		    (LIST(nlmp)->lm_flags & LML_FLG_TRC_VERBOSE)))
354 			tracing = 1;
355 		else
356 			tracing = 0;
357 
358 		DBG_CALL(Dbg_util_nl());
359 
360 		for (ALIST_TRAVERSE(COPY(nlmp), off1, lmpp)) {
361 			Rt_map *	lmp = *lmpp;
362 			Rel_copy *	rcp;
363 			Aliste		off2;
364 
365 			for (ALIST_TRAVERSE(COPY(lmp), off2, rcp)) {
366 				int zero;
367 
368 				/*
369 				 * Only copy the bits if it's from non-zero
370 				 * filled memory.
371 				 */
372 				zero = copy_zerobits(rcp->r_dlmp, rcp->r_dsym);
373 				DBG_CALL(Dbg_reloc_copy(NAME(rcp->r_dlmp),
374 				    NAME(nlmp), rcp->r_name, zero));
375 				if (zero)
376 					continue;
377 
378 				(void) memcpy(rcp->r_radd, rcp->r_dadd,
379 				    rcp->r_size);
380 
381 				if ((tracing == 0) || ((FLAGS1(rcp->r_dlmp) &
382 				    FL1_RT_DISPREL) == 0))
383 					continue;
384 
385 				(void) printf(MSG_INTL(MSG_LDD_REL_CPYDISP),
386 				    demangle(rcp->r_name), NAME(rcp->r_dlmp));
387 			}
388 		}
389 
390 		DBG_CALL(Dbg_util_nl());
391 
392 		free(COPY(nlmp));
393 		COPY(nlmp) = 0;
394 	}
395 	return (1);
396 }
397 
398 int
399 relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)
400 {
401 	int	lret = 1, pret = 1;
402 	Alist	*alp;
403 	Aliste	plmco;
404 	Lm_cntl	*plmc, *nlmc;
405 
406 	/*
407 	 * If this link-map control list is being relocated, return.  The object
408 	 * that has just been added will be picked up by the existing relocation
409 	 * thread.  Note, this is only really meaningful during process init-
410 	 * ialization, as objects are added to the main link-map control list.
411 	 * Following this initialization, each family of objects that are loaded
412 	 * are added to a new link-map control list.
413 	 */
414 	/* LINTED */
415 	nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco);
416 
417 	if (nlmc->lc_flags & LMC_FLG_RELOCATING)
418 		return (1);
419 
420 	nlmc->lc_flags |= LMC_FLG_RELOCATING;
421 
422 	/*
423 	 * Relocate one or more link-maps of a link map control list.  If this
424 	 * object doesn't belong to the present link-map control list then it
425 	 * must already have been relocated, or it is in the process of being
426 	 * relocated prior to us recursing into this relocation.  In either
427 	 * case, ignore the object as it's already being taken care of, however,
428 	 * fall through and capture any relocation promotions that might have
429 	 * been established from the reference mode of this object.
430 	 *
431 	 * If we're generating a configuration file using crle(1), two passes
432 	 * may be involved.  Under the first pass, RTLD_CONFGEN is set.  Under
433 	 * this pass, crle() loads objects into the process address space.  No
434 	 * relocation is necessary at this point, we simply need to analyze the
435 	 * objects to insure any directly bound dependencies, filtees, etc.
436 	 * get loaded. Although we skip the relocation, fall through to insure
437 	 * any control lists are maintained appropriately.
438 	 *
439 	 * If objects are to be dldump(3c)'ed, crle(1) makes a second pass,
440 	 * using RTLD_NOW and RTLD_CONFGEN.  The RTLD_NOW effectively carries
441 	 * out the relocations of all loaded objects.
442 	 */
443 	if ((nlmco == CNTL(nlmp)) &&
444 	    ((MODE(nlmp) & (RTLD_NOW | RTLD_CONFGEN)) != RTLD_CONFGEN)) {
445 		int	relocated = 0;
446 
447 		/*
448 		 * Determine whether the initial link-map control list has
449 		 * started relocation.  From this point, should any interposing
450 		 * objects be added to this link-map control list, the objects
451 		 * are demoted to standard objects.  Their interposition can't
452 		 * be guaranteed once relocations have been carried out.
453 		 */
454 		if (nlmco == ALO_DATA)
455 			lml->lm_flags |= LML_FLG_STARTREL;
456 
457 		/*
458 		 * Relocate the link-map control list.
459 		 */
460 		lret = _relocate_lmc(lml, nlmp, &relocated);
461 
462 		/*
463 		 * At this point we've completed the addition of a new group of
464 		 * objects, either the initial objects that start the process
465 		 * (called from setup()), a group added through lazy loading or
466 		 * filters, or from a dlopen() request.  Indicate to the
467 		 * debuggers that new objects have been added.
468 		 */
469 		if (relocated && lret &&
470 		    ((lml->lm_flags & LML_FLG_DBNOTIF) == 0))
471 			rd_event(lml, RD_DLACTIVITY, RT_ADD);
472 	}
473 
474 	/*
475 	 * Determine the new, and previous link-map control lists.
476 	 */
477 	if (nlmco == ALO_DATA)
478 		plmc = nlmc;
479 	else {
480 		plmco = nlmco - lml->lm_lists->al_size;
481 		/* LINTED */
482 		plmc = (Lm_cntl *)((char *)lml->lm_lists + plmco);
483 	}
484 
485 	/*
486 	 * Having completed this control list of objects, they can now be bound
487 	 * to from other objects.  Move this control list to the control list
488 	 * that precedes it.  Although this control list may have only bound to
489 	 * controls lists much higher up the control list stack, it must only
490 	 * be moved up one control list so as to preserve the link-map order
491 	 * that may have already been traversed in search of symbols.
492 	 */
493 	if (lret && (nlmco != ALO_DATA) && nlmc->lc_head)
494 		lm_move(lml, nlmco, plmco, nlmc, plmc);
495 
496 	/*
497 	 * Determine whether existing objects that have already been relocated,
498 	 * need any additional relocations performed.  This can occur when new
499 	 * objects are loaded with RTLD_NOW, and these new objects have
500 	 * dependencies on objects that are already loaded.  Note, that we peel
501 	 * any relocation promotions off of one control list at a time.  This
502 	 * prevents relocations from being bound to objects that might yet fail
503 	 * to relocate themselves.
504 	 */
505 	while ((alp = plmc->lc_now) != 0) {
506 		Aliste	off;
507 		Rt_map	**lmpp;
508 
509 		/*
510 		 * Remove the relocation promotion list, as performing more
511 		 * relocations may result in discovering more objects that need
512 		 * promotion.
513 		 */
514 		plmc->lc_now = 0;
515 
516 		for (ALIST_TRAVERSE(alp, off, lmpp)) {
517 			Rt_map	*lmp = *lmpp;
518 
519 			/*
520 			 * If the original relocation of the link-map control
521 			 * list failed, or one of the relocation promotions of
522 			 * this loop has failed, demote any pending objects
523 			 * relocation mode.
524 			 */
525 			if ((lret == 0) || (pret == 0)) {
526 				MODE(lmp) &= ~RTLD_NOW;
527 				MODE(lmp) |= RTLD_LAZY;
528 				continue;
529 			}
530 
531 			/*
532 			 * If a relocation fails, save the error condition.
533 			 * It's possible that all new objects on the original
534 			 * link-map control list have been relocated
535 			 * successfully, but if the user request requires
536 			 * promoting objects that have already been loaded, we
537 			 * have to indicate that this operation couldn't be
538 			 * performed.  The unrelocated objects are in use on
539 			 * another control list, and may continue to be used.
540 			 * If the .plt that resulted in the error is called,
541 			 * then the process will receive a fatal error at that
542 			 * time.  But, the .plt may never be called.
543 			 */
544 			if (relocate_so(lml, lmp, 0, 1) == 0)
545 				pret = 0;
546 		}
547 
548 		/*
549 		 * Having promoted any objects, determine whether additional
550 		 * dependencies were added, and if so move them to the previous
551 		 * link-map control list.
552 		 */
553 		if ((nlmco != ALO_DATA) && nlmc->lc_head)
554 			lm_move(lml, nlmco, plmco, nlmc, plmc);
555 
556 		(void) free(alp);
557 	}
558 
559 	nlmc->lc_flags &= ~LMC_FLG_RELOCATING;
560 
561 	if (lret && pret)
562 		return (1);
563 	else
564 		return (0);
565 }
566 
567 /*
568  * Inherit the first rejection message for possible later diagnostics.
569  *
570  * Any attempt to process a file that is unsuccessful, should be accompanied
571  * with an error diagnostic.  However, some operations like searching for a
572  * simple filename, involve trying numerous paths, and an error message for each
573  * lookup is not required.  Although a multiple search can fail, it's possible
574  * that a file was found, but was rejected because it was the wrong type.
575  * To satisfy these possibilities, the first failure is recorded as a rejection
576  * message, and this message is used later for a more specific diagnostic.
577  *
578  * File searches are focused at load_one(), and from here a rejection descriptor
579  * is passed down to various child routines.  If these child routines can
580  * process multiple files, then they will maintain their own rejection desc-
581  * riptor.  This is filled in for any failures, and a diagnostic produced to
582  * reflect the failure.  The child routines then employ rejection_inherit() to
583  * pass the first rejection message back to load_one().
584  *
585  * Note that the name, and rejection string must be duplicated, as the name
586  * buffer and error string buffer (see conv_ routines) may be reused for
587  * additional processing or rejection messages.
588  *
589  * As this routine is called to clean up after a failed open, remove any
590  * resolved pathname that might have been allocated as the file was processed.
591  */
592 void
593 rejection_inherit(Rej_desc *rej1, Rej_desc *rej2, Fdesc *fdp)
594 {
595 	if (rej2->rej_type && (rej1->rej_type == 0)) {
596 		rej1->rej_type = rej2->rej_type;
597 		rej1->rej_info = rej2->rej_info;
598 		rej1->rej_flag = rej2->rej_flag;
599 		if (rej2->rej_name)
600 			rej1->rej_name = strdup(rej2->rej_name);
601 		if (rej2->rej_str) {
602 			if ((rej1->rej_str = strdup(rej2->rej_str)) == 0)
603 				rej1->rej_str = MSG_ORIG(MSG_EMG_ENOMEM);
604 		}
605 	}
606 	if (fdp && fdp->fd_nname && fdp->fd_pname &&
607 	    (fdp->fd_pname != fdp->fd_nname)) {
608 		free((void *)fdp->fd_pname);
609 		fdp->fd_pname = 0;
610 	}
611 }
612 
613 /*
614  * Determine the object type of a file.
615  */
616 Fct *
617 are_u_this(Rej_desc *rej, int fd, struct stat *status, const char *name)
618 {
619 	int	i;
620 	char	*maddr = 0;
621 
622 	fmap->fm_fsize = status->st_size;
623 
624 	/*
625 	 * If this is a directory (which can't be mmap()'ed) generate a precise
626 	 * error message.
627 	 */
628 	if ((status->st_mode & S_IFMT) == S_IFDIR) {
629 		rej->rej_type = SGS_REJ_STR;
630 		rej->rej_str = strerror(EISDIR);
631 		return (0);
632 	}
633 
634 	/*
635 	 * Map in the first page of the file.  When this buffer is first used,
636 	 * the mapping is a single system page.  This is typically enough to
637 	 * inspect the ehdr and phdrs of the file, and can be reused for each
638 	 * file that get loaded.  If a larger mapping is required to read the
639 	 * ehdr and phdrs, a new mapping is created (see elf_map_it()).  This
640 	 * new mapping is again used for each new file loaded.  Some objects,
641 	 * such as filters, only take up one page, and in this case this mapping
642 	 * will suffice for the file.
643 	 */
644 	maddr = mmap(fmap->fm_maddr, fmap->fm_msize, (PROT_READ | PROT_EXEC),
645 	    fmap->fm_mflags, fd, 0);
646 #if defined(MAP_ALIGN)
647 	if ((maddr == MAP_FAILED) && (errno == EINVAL)) {
648 		/*
649 		 * If the mapping failed, and we used MAP_ALIGN, assume we're
650 		 * on a system that doesn't support this option.  Try again
651 		 * without MAP_ALIGN.
652 		 */
653 		if (fmap->fm_mflags & MAP_ALIGN) {
654 			rtld_flags2 |= RT_FL2_NOMALIGN;
655 			fmap_setup();
656 
657 			maddr = (char *)mmap(fmap->fm_maddr, fmap->fm_msize,
658 			    (PROT_READ | PROT_EXEC), fmap->fm_mflags, fd, 0);
659 		}
660 	}
661 #endif
662 	if (maddr == MAP_FAILED) {
663 		rej->rej_type = SGS_REJ_STR;
664 		rej->rej_str = strerror(errno);
665 		return (0);
666 	}
667 
668 	/*
669 	 * From now on we will re-use fmap->fm_maddr as the mapping address
670 	 * so we augment the flags with MAP_FIXED and drop any MAP_ALIGN.
671 	 */
672 	fmap->fm_maddr = maddr;
673 	fmap->fm_mflags |= MAP_FIXED;
674 #if defined(MAP_ALIGN)
675 	fmap->fm_mflags &= ~MAP_ALIGN;
676 #endif
677 
678 	/*
679 	 * Search through the object vectors to determine what kind of
680 	 * object we have.
681 	 */
682 	for (i = 0; vector[i]; i++) {
683 		if ((vector[i]->fct_are_u_this)(rej))
684 			return (vector[i]);
685 		else if (rej->rej_type) {
686 			Rt_map	*lmp;
687 
688 			/*
689 			 * If this object is an explicitly defined shared
690 			 * object under inspection by ldd, and contains a
691 			 * incompatible hardware capabilities requirement, then
692 			 * inform the user, but continue processing.
693 			 *
694 			 * XXXX - ldd -v for any rej failure.
695 			 */
696 			if ((rej->rej_type == SGS_REJ_HWCAP_1) &&
697 			    (lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) &&
698 			    ((lmp = lml_main.lm_head) != 0) &&
699 			    (FLAGS1(lmp) & FL1_RT_LDDSTUB) &&
700 			    (NEXT(lmp) == 0)) {
701 				(void) printf(MSG_INTL(MSG_LDD_GEN_HWCAP_1),
702 				    name, rej->rej_str);
703 				return (vector[i]);
704 			}
705 			return (0);
706 		}
707 	}
708 
709 	/*
710 	 * Unknown file type.
711 	 */
712 	rej->rej_type = SGS_REJ_UNKFILE;
713 	return (0);
714 }
715 
716 
717 /*
718  * Function that determines whether a file name has already been loaded; if so,
719  * returns a pointer to its link map structure; else returns a NULL pointer.
720  */
721 static int
722 _is_so_matched(const char *name, const char *str, int base)
723 {
724 	const char	*_str;
725 
726 	if (base && ((_str = strrchr(str, '/')) != NULL))
727 		_str++;
728 	else
729 		_str = str;
730 
731 	return (strcmp(name, _str));
732 }
733 
734 static Rt_map *
735 is_so_matched(Rt_map *lmp, const char *name, int base)
736 {
737 	Aliste		off;
738 	const char	**cpp;
739 
740 	/*
741 	 * Typically, dependencies are specified as simple file names
742 	 * (DT_NEEDED == libc.so.1), which are expanded to full pathnames to
743 	 * open the file.  The full pathname is NAME(), and the original name
744 	 * is maintained on the ALIAS() list. Look through the ALIAS list first,
745 	 * as this is most likely to match other dependency uses.
746 	 */
747 	for (ALIST_TRAVERSE(ALIAS(lmp), off, cpp)) {
748 		if (_is_so_matched(name, *cpp, base) == 0)
749 			return (lmp);
750 	}
751 
752 	/*
753 	 * Finally compare full paths, this is sometimes useful for catching
754 	 * filter names, or for those that dlopen() the dynamic executable.
755 	 */
756 	if (_is_so_matched(name, NAME(lmp), base) == 0)
757 		return (lmp);
758 
759 	if (PATHNAME(lmp) != NAME(lmp)) {
760 		if (_is_so_matched(name, PATHNAME(lmp), base) == 0)
761 			return (lmp);
762 	}
763 	return (0);
764 }
765 
766 Rt_map *
767 is_so_loaded(Lm_list *lml, const char *name, int base)
768 {
769 	Rt_map		*lmp;
770 	const char	*_name;
771 	avl_index_t	where;
772 	Lm_cntl		*lmc;
773 	Aliste		off;
774 
775 	/*
776 	 * If we've been asked to do a basename search, first determine if
777 	 * the pathname is registered in the FullpathNode AVL tree.
778 	 */
779 	if (base && (name[0] == '/') &&
780 	    ((lmp = fpavl_loaded(lml, name, &where)) != NULL) &&
781 	    ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0))
782 		return (lmp);
783 
784 	/*
785 	 * If we've been asked to do a basename search reduce the input name
786 	 * to its basename.
787 	 */
788 	if (base && ((_name = strrchr(name, '/')) != NULL))
789 		_name++;
790 	else
791 		_name = name;
792 
793 	/*
794 	 * Loop through the callers link-map lists.
795 	 */
796 	for (ALIST_TRAVERSE(lml->lm_lists, off, lmc)) {
797 		for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) {
798 			if (FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE))
799 				continue;
800 
801 			if (is_so_matched(lmp, _name, base))
802 				return (lmp);
803 		}
804 	}
805 	return ((Rt_map *)0);
806 }
807 
808 
809 /*
810  * Tracing is enabled by the LD_TRACE_LOADED_OPTIONS environment variable which
811  * is normally set from ldd(1).  For each link map we load, print the load name
812  * and the full pathname of the shared object.
813  */
814 /* ARGSUSED4 */
815 static void
816 trace_so(Rt_map *clmp, Rej_desc *rej, const char *name, const char *path,
817     int alter, const char *nfound)
818 {
819 	const char	*str = MSG_ORIG(MSG_STR_EMPTY);
820 	const char	*reject = MSG_ORIG(MSG_STR_EMPTY);
821 	char		_reject[PATH_MAX];
822 
823 	/*
824 	 * The first time through trace_so() will only have lddstub on the
825 	 * link-map list and the preloaded shared object is supplied as "path".
826 	 * As we don't want to print this shared object as a dependency, but
827 	 * instead inspect *its* dependencies, return.
828 	 */
829 	if (FLAGS1(clmp) & FL1_RT_LDDSTUB)
830 		return;
831 
832 	/*
833 	 * Without any rejection info, this is a supplied not-found condition.
834 	 */
835 	if (rej && (rej->rej_type == 0)) {
836 		(void) printf(nfound, name);
837 		return;
838 	}
839 
840 	/*
841 	 * If rejection information exists then establish what object was
842 	 * found and the reason for its rejection.
843 	 */
844 	if (rej) {
845 		/* LINTED */
846 		(void) snprintf(_reject, PATH_MAX,
847 		    MSG_INTL(ldd_reject[rej->rej_type]), conv_reject_str(rej));
848 		if (rej->rej_name)
849 			path = rej->rej_name;
850 		reject = (char *)_reject;
851 
852 		/*
853 		 * Was an alternative pathname defined (from a configuration
854 		 * file).
855 		 */
856 		if (rej->rej_flag & FLG_FD_ALTER)
857 			str = MSG_INTL(MSG_LDD_FIL_ALTER);
858 	} else {
859 		if (alter)
860 			str = MSG_INTL(MSG_LDD_FIL_ALTER);
861 	}
862 
863 	/*
864 	 * If the load name isn't a full pathname print its associated pathname
865 	 * together with all the other information we've gathered.
866 	 */
867 	if (*name == '/')
868 	    (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), path, str, reject);
869 	else
870 	    (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), name, path, str, reject);
871 }
872 
873 
874 /*
875  * Establish a link-map mode, initializing it if it has just been loaded, or
876  * potentially updating it if it already exists.
877  */
878 int
879 update_mode(Rt_map *lmp, int omode, int nmode)
880 {
881 	int	pmode = 0;
882 
883 	/*
884 	 * A newly loaded object hasn't had its mode set yet.  Modes are used to
885 	 * load dependencies, so don't propagate any parent or no-load flags, as
886 	 * these would adversely affect this objects ability to load any of its
887 	 * dependencies that aren't already loaded.  RTLD_FIRST is applicable to
888 	 * this objects handle creation only, and should not be propagated.
889 	 */
890 	if ((FLAGS(lmp) & FLG_RT_MODESET) == 0) {
891 		MODE(lmp) |= nmode & ~(RTLD_PARENT | RTLD_NOLOAD | RTLD_FIRST);
892 		FLAGS(lmp) |= FLG_RT_MODESET;
893 		return (1);
894 	}
895 
896 	/*
897 	 * Establish any new overriding modes.  RTLD_LAZY and RTLD_NOW should be
898 	 * represented individually (this is historic, as these two flags were
899 	 * the only flags originally available to dlopen()).  Other flags are
900 	 * accumulative, but have a hierarchy of preference.
901 	 */
902 	if ((omode & RTLD_LAZY) && (nmode & RTLD_NOW)) {
903 		MODE(lmp) &= ~RTLD_LAZY;
904 		pmode |= RTLD_NOW;
905 	}
906 
907 	pmode |= ((~omode & nmode) &
908 	    (RTLD_GLOBAL | RTLD_WORLD | RTLD_NODELETE));
909 	if (pmode) {
910 		DBG_CALL(Dbg_file_mode_promote(NAME(lmp), pmode));
911 		MODE(lmp) |= pmode;
912 	}
913 
914 	/*
915 	 * If this load is an RTLD_NOW request and the object has already been
916 	 * loaded non-RTLD_NOW, append this object to the relocation-now list
917 	 * of the objects associated control list.  Note, if the object hasn't
918 	 * yet been relocated, setting its MODE() to RTLD_NOW will establish
919 	 * full relocation processing when it eventually gets relocated.
920 	 */
921 	if ((pmode & RTLD_NOW) &&
922 	    (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))) {
923 		Lm_cntl	*lmc;
924 
925 		/* LINTED */
926 		lmc = (Lm_cntl *)((char *)(LIST(lmp)->lm_lists) + CNTL(lmp));
927 		(void) alist_append(&(lmc->lc_now), &lmp, sizeof (Rt_map *),
928 		    AL_CNT_LMNOW);
929 	}
930 
931 #ifdef	SIEBEL_DISABLE
932 	/*
933 	 * For patch backward compatibility the following .init collection
934 	 * is disabled.
935 	 */
936 	if (rtld_flags & RT_FL_DISFIX_1)
937 		return (pmode);
938 #endif
939 
940 	/*
941 	 * If this objects init has been collected but not yet been called, mark
942 	 * it as uncollected.  This object will be added to the tsort() that
943 	 * follows this operation which may compensate for insufficient binding
944 	 * information used by the tsort() it was originally part of.  For
945 	 * example, a new dlopen() hierarchy may bind to uninitialized objects
946 	 * that are already loaded, or a dlopen(RTLD_NOW) can establish new
947 	 * bindings between already loaded objects that require the tsort()
948 	 * information be recomputed.
949 	 */
950 	if ((FLAGS(lmp) & (FLG_RT_INITCLCT | FLG_RT_INITCALL)) ==
951 	    FLG_RT_INITCLCT) {
952 		FLAGS(lmp) &= ~FLG_RT_INITCLCT;
953 		LIST(lmp)->lm_init++;
954 		LIST(lmp)->lm_flags |= LML_FLG_BNDUNINIT;
955 	}
956 
957 	return (pmode);
958 }
959 
960 /*
961  * Determine whether an alias name already exists, and if not create one.  This
962  * is typically used to retain dependency names, such as "libc.so.1", which
963  * would have been expanded to full path names when they were loaded.  The
964  * full path names (NAME() and possibly PATHNAME()) are maintained as Fullpath
965  * AVL nodes, and thus would have been matched by fpavl_loaded() during
966  * file_open().
967  */
968 int
969 append_alias(Rt_map *lmp, const char *str, int *added)
970 {
971 	Aliste	off;
972 	char	**cpp, *cp;
973 
974 	/*
975 	 * Determine if this filename is already on the alias list.
976 	 */
977 	for (ALIST_TRAVERSE(ALIAS(lmp), off, cpp)) {
978 		if (strcmp(*cpp, str) == 0)
979 			return (1);
980 	}
981 
982 	/*
983 	 * This is a new alias, append it to the alias list.
984 	 */
985 	if ((cp = strdup(str)) == 0)
986 		return (0);
987 
988 	if (alist_append(&ALIAS(lmp), &cp, sizeof (char *),
989 	    AL_CNT_ALIAS) == 0) {
990 		free(cp);
991 		return (0);
992 	}
993 	if (added)
994 		*added = 1;
995 	return (1);
996 }
997 
998 /*
999  * Determine whether a file is already loaded by comparing device and inode
1000  * values.
1001  */
1002 static Rt_map *
1003 is_devinode_loaded(struct stat *status, Lm_list *lml, const char *name,
1004     uint_t flags)
1005 {
1006 	Lm_cntl	*lmc;
1007 	Aliste	off;
1008 
1009 	/*
1010 	 * If this is an auditor, it will have been opened on a new link-map.
1011 	 * To prevent multiple occurrances of the same auditor on multiple
1012 	 * link-maps, search the head of each link-map list and see if this
1013 	 * object is already loaded as an auditor.
1014 	 */
1015 	if (flags & FLG_RT_AUDIT) {
1016 		Lm_list *	lml;
1017 		Listnode *	lnp;
1018 
1019 		for (LIST_TRAVERSE(&dynlm_list, lnp, lml)) {
1020 			Rt_map	*nlmp = lml->lm_head;
1021 
1022 			if (nlmp && ((FLAGS(nlmp) &
1023 			    (FLG_RT_AUDIT | FLG_RT_DELETE)) == FLG_RT_AUDIT) &&
1024 			    (STDEV(nlmp) == status->st_dev) &&
1025 			    (STINO(nlmp) == status->st_ino))
1026 				return (nlmp);
1027 		}
1028 		return ((Rt_map *)0);
1029 	}
1030 
1031 	/*
1032 	 * If the file has been found determine from the new files status
1033 	 * information if this file is actually linked to one we already have
1034 	 * mapped.  This catches symlink names not caught by is_so_loaded().
1035 	 */
1036 	for (ALIST_TRAVERSE(lml->lm_lists, off, lmc)) {
1037 		Rt_map	*nlmp;
1038 
1039 		for (nlmp = lmc->lc_head; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) {
1040 			if ((FLAGS(nlmp) & FLG_RT_DELETE) ||
1041 			    (FLAGS1(nlmp) & FL1_RT_LDDSTUB))
1042 				continue;
1043 
1044 			if ((STDEV(nlmp) != status->st_dev) ||
1045 			    (STINO(nlmp) != status->st_ino))
1046 				continue;
1047 
1048 			if (lml->lm_flags & LML_FLG_TRC_VERBOSE) {
1049 				if (*name == '/')
1050 				    (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH),
1051 					name, MSG_ORIG(MSG_STR_EMPTY),
1052 					MSG_ORIG(MSG_STR_EMPTY));
1053 				else
1054 				    (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV),
1055 					name, NAME(nlmp),
1056 					MSG_ORIG(MSG_STR_EMPTY),
1057 					MSG_ORIG(MSG_STR_EMPTY));
1058 			}
1059 			return (nlmp);
1060 		}
1061 	}
1062 	return ((Rt_map *)0);
1063 }
1064 
1065 /*
1066  * Generate any error messages indicating a file could not be found.  When
1067  * preloading or auditing a secure application, it can be a little more helpful
1068  * to indicate that a search of secure directories has failed, so adjust the
1069  * messages accordingly.
1070  */
1071 void
1072 file_notfound(Lm_list *lml, const char *name, Rt_map *clmp, uint_t flags,
1073     Rej_desc * rej)
1074 {
1075 	int	secure = 0;
1076 
1077 	if ((rtld_flags & RT_FL_SECURE) &&
1078 	    (flags & (FLG_RT_PRELOAD | FLG_RT_AUDIT)))
1079 		secure++;
1080 
1081 	if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
1082 		/*
1083 		 * Under ldd(1), auxiliary filtees that can't be loaded are
1084 		 * ignored, unless verbose errors are requested.
1085 		 */
1086 		if ((rtld_flags & RT_FL_SILENCERR) &&
1087 		    ((lml->lm_flags & LML_FLG_TRC_VERBOSE) == 0))
1088 			return;
1089 
1090 		if (secure)
1091 			trace_so(clmp, rej, name, 0, 0,
1092 			    MSG_INTL(MSG_LDD_SEC_NFOUND));
1093 		else
1094 			trace_so(clmp, rej, name, 0, 0,
1095 			    MSG_INTL(MSG_LDD_FIL_NFOUND));
1096 		return;
1097 	}
1098 
1099 	if (rej->rej_type) {
1100 		eprintf(ERR_FATAL, MSG_INTL(err_reject[rej->rej_type]),
1101 		    rej->rej_name ? rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN),
1102 		    conv_reject_str(rej));
1103 		return;
1104 	}
1105 
1106 	if (secure)
1107 		eprintf(ERR_FATAL, MSG_INTL(MSG_SEC_OPEN), name);
1108 	else
1109 		eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), name,
1110 		    strerror(ENOENT));
1111 }
1112 
1113 static int
1114 file_open(int err, Lm_list *lml, const char *oname, const char *nname,
1115     Rt_map *clmp, uint_t flags, Fdesc * fdesc, Rej_desc *rej)
1116 {
1117 	struct stat	status;
1118 	Rt_map		*nlmp;
1119 
1120 	fdesc->fd_oname = oname;
1121 
1122 	if ((err == 0) && (fdesc->fd_flags & FLG_FD_ALTER))
1123 		DBG_CALL(Dbg_file_config_obj(oname, 0, nname));
1124 
1125 	/*
1126 	 * If we're dealing with a full pathname, determine whether this
1127 	 * pathname is already known.  Other pathnames fall through to the
1128 	 * dev/inode check, as even though the pathname may look the same as
1129 	 * one previously used, the process may have changed directory.
1130 	 */
1131 	if ((err == 0) && (nname[0] == '/')) {
1132 		if ((nlmp = fpavl_loaded(lml, nname,
1133 		    &(fdesc->fd_avlwhere))) != NULL) {
1134 			fdesc->fd_nname = nname;
1135 			fdesc->fd_lmp = nlmp;
1136 			return (1);
1137 		}
1138 	}
1139 
1140 	if ((err == 0) && ((stat(nname, &status)) != -1)) {
1141 		char	path[PATH_MAX];
1142 		int	fd, size, added;
1143 
1144 		/*
1145 		 * If this path has been constructed as part of expanding a
1146 		 * HWCAP directory, ignore any subdirectories.  For any other
1147 		 * reference that expands to a directory, fall through to
1148 		 * contruct a meaningful rejection message.
1149 		 */
1150 		if ((flags & FLG_RT_HWCAP) &&
1151 		    ((status.st_mode & S_IFMT) == S_IFDIR))
1152 			return (0);
1153 
1154 		/*
1155 		 * Resolve the filename and determine whether the resolved name
1156 		 * is already known.  Typically, the previous fpavl_loaded()
1157 		 * will have caught this, as both NAME() and PATHNAME() for a
1158 		 * link-map are recorded in the FullNode AVL tree.  However,
1159 		 * instances exist where a file can be replaced (loop-back
1160 		 * mounts, bfu, etc.), and reference is made to the original
1161 		 * file through a symbolic link.  By checking the pathname here,
1162 		 * we don't fall through to the dev/inode check and conclude
1163 		 * that a new file should be loaded.
1164 		 */
1165 		if ((nname[0] == '/') && (rtld_flags & RT_FL_EXECNAME) &&
1166 		    ((size = resolvepath(nname, path, (PATH_MAX - 1))) > 0)) {
1167 			path[size] = '\0';
1168 
1169 			if (strcmp(nname, path)) {
1170 				if ((nlmp = fpavl_loaded(lml, path,
1171 				    &(fdesc->fd_avlwhere))) != NULL) {
1172 					added = 0;
1173 
1174 					if (append_alias(nlmp, nname,
1175 					    &added) == 0)
1176 						return (0);
1177 					if (added)
1178 						DBG_CALL(Dbg_file_skip(nname,
1179 						    NAME(nlmp)));
1180 					fdesc->fd_nname = nname;
1181 					fdesc->fd_lmp = nlmp;
1182 					return (1);
1183 				}
1184 
1185 				/*
1186 				 * If this pathname hasn't been loaded, save
1187 				 * the resolved pathname so that it doesn't
1188 				 * have to be recomputed as part of fullpath()
1189 				 * processing.
1190 				 */
1191 				if ((fdesc->fd_pname = strdup(path)) == 0)
1192 					return (0);
1193 			} else {
1194 				/*
1195 				 * If the resolved name doesn't differ from the
1196 				 * original, save it without duplication.
1197 				 * Having fd_pname set indicates that no further
1198 				 * resolvepath processing is necessary.
1199 				 */
1200 				fdesc->fd_pname = nname;
1201 			}
1202 		}
1203 
1204 		if (nlmp = is_devinode_loaded(&status, lml, nname, flags)) {
1205 			added = 0;
1206 
1207 			if (append_alias(nlmp, nname, &added) == 0)
1208 				return (0);
1209 			if (added) {
1210 				if ((nname[0] == '/') && (fpavl_insert(lml,
1211 				    nlmp, nname, 0) == 0))
1212 					return (0);
1213 				DBG_CALL(Dbg_file_skip(nname, NAME(nlmp)));
1214 			}
1215 			fdesc->fd_nname = nname;
1216 			fdesc->fd_lmp = nlmp;
1217 			return (1);
1218 		}
1219 
1220 		if ((fd = open(nname, O_RDONLY, 0)) == -1) {
1221 			/*
1222 			 * As the file must exist for the previous stat() to
1223 			 * have succeeded, record the error condition.
1224 			 */
1225 			rej->rej_type = SGS_REJ_STR;
1226 			rej->rej_str = strerror(errno);
1227 		} else {
1228 			Fct	*ftp;
1229 
1230 			if ((ftp = are_u_this(rej, fd, &status, nname)) != 0) {
1231 				fdesc->fd_nname = nname;
1232 				fdesc->fd_ftp = ftp;
1233 				fdesc->fd_dev = status.st_dev;
1234 				fdesc->fd_ino = status.st_ino;
1235 				fdesc->fd_fd = fd;
1236 
1237 				/*
1238 				 * Trace that this open has succeeded.
1239 				 */
1240 				if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
1241 				    trace_so(clmp, 0, oname, nname,
1242 					(fdesc->fd_flags & FLG_FD_ALTER), 0);
1243 				}
1244 				return (1);
1245 			}
1246 			(void) close(fd);
1247 		}
1248 
1249 	} else if (errno != ENOENT) {
1250 		/*
1251 		 * If the open() failed for anything other than the file not
1252 		 * existing, record the error condition.
1253 		 */
1254 		rej->rej_type = SGS_REJ_STR;
1255 		rej->rej_str = strerror(errno);
1256 	}
1257 
1258 	/*
1259 	 * Indicate any rejection.
1260 	 */
1261 	if (rej->rej_type) {
1262 		rej->rej_name = nname;
1263 		rej->rej_flag = (fdesc->fd_flags & FLG_FD_ALTER);
1264 		DBG_CALL(Dbg_file_rejected(rej));
1265 	}
1266 	return (0);
1267 }
1268 
1269 /*
1270  * Find a full pathname (it contains a "/").
1271  */
1272 int
1273 find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
1274     Fdesc * fdesc, Rej_desc *rej)
1275 {
1276 	int	err = 0;
1277 
1278 	/*
1279 	 * If directory configuration exists determine if this path is known.
1280 	 */
1281 	if (rtld_flags & RT_FL_DIRCFG) {
1282 		Rtc_obj		*obj;
1283 		const char	*aname;
1284 
1285 		if ((obj = elf_config_ent(oname, (Word)elf_hash(oname),
1286 		    0, &aname)) != 0) {
1287 			/*
1288 			 * If the configuration file states that this path is a
1289 			 * directory, or the path is explicitly defined as
1290 			 * non-existent (ie. a unused platform specific
1291 			 * library), then go no further.
1292 			 */
1293 			if (obj->co_flags & RTC_OBJ_DIRENT) {
1294 				err = EISDIR;
1295 			} else if ((obj->co_flags &
1296 			    (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
1297 			    RTC_OBJ_NOEXIST) {
1298 				err = ENOENT;
1299 			} else if ((obj->co_flags & RTC_OBJ_ALTER) &&
1300 			    (rtld_flags & RT_FL_OBJALT) && (lml == &lml_main)) {
1301 				int	ret;
1302 
1303 				fdesc->fd_flags |= FLG_FD_ALTER;
1304 				/*
1305 				 * Attempt to open the alternative path.  If
1306 				 * this fails, and the alternative is flagged
1307 				 * as optional, fall through to open the
1308 				 * original path.
1309 				 */
1310 				DBG_CALL(Dbg_libs_found(aname, FLG_FD_ALTER));
1311 				if (((ret = file_open(0, lml, oname, aname,
1312 				    clmp, flags, fdesc, rej)) != 0) ||
1313 				    ((obj->co_flags & RTC_OBJ_OPTINAL) == 0))
1314 					return (ret);
1315 
1316 				fdesc->fd_flags &= ~FLG_FD_ALTER;
1317 			}
1318 		}
1319 	}
1320 	DBG_CALL(Dbg_libs_found(oname, 0));
1321 	return (file_open(err, lml, oname, oname, clmp, flags, fdesc, rej));
1322 }
1323 
1324 /*
1325  * Find a simple filename (it doesn't contain a "/").
1326  */
1327 static int
1328 _find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp,
1329     uint_t flags, Fdesc * fdesc, Rej_desc *rej, Pnode * dir, int aflag)
1330 {
1331 	DBG_CALL(Dbg_libs_found(nname, aflag));
1332 	if ((lml->lm_flags & LML_FLG_TRC_SEARCH) &&
1333 	    ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) {
1334 		(void) printf(MSG_INTL(MSG_LDD_PTH_TRYING), nname, aflag ?
1335 		    MSG_INTL(MSG_LDD_FIL_ALTER) : MSG_ORIG(MSG_STR_EMPTY));
1336 	}
1337 
1338 	/*
1339 	 * If we're being audited tell the audit library of the file we're about
1340 	 * to go search for.  The audit library may offer an alternative
1341 	 * dependency, or indicate that this dependency should be ignored.
1342 	 */
1343 	if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
1344 		char	*aname = audit_objsearch(clmp, nname, dir->p_orig);
1345 
1346 		if (aname == 0)
1347 			return (0);
1348 		nname = aname;
1349 	}
1350 	return (file_open(0, lml, oname, nname, clmp, flags, fdesc, rej));
1351 }
1352 
1353 static int
1354 find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
1355     Fdesc * fdesc, Rej_desc *rej, Pnode * dir, Word * strhash, size_t olen)
1356 {
1357 	static Rtc_obj	Obj = { 0 };
1358 	Rtc_obj *	dobj;
1359 	const char	*nname = oname;
1360 
1361 	if (dir->p_name == 0)
1362 		return (0);
1363 	if (dir->p_info) {
1364 		dobj = (Rtc_obj *)dir->p_info;
1365 		if ((dobj->co_flags &
1366 		    (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1367 			return (0);
1368 	} else
1369 		dobj = 0;
1370 
1371 	/*
1372 	 * If configuration information exists see if this directory/file
1373 	 * combination exists.
1374 	 */
1375 	if ((rtld_flags & RT_FL_DIRCFG) &&
1376 	    ((dobj == 0) || (dobj->co_id != 0))) {
1377 		Rtc_obj		*fobj;
1378 		const char	*alt = 0;
1379 
1380 		/*
1381 		 * If this pnode has not yet been searched for in the
1382 		 * configuration file go find it.
1383 		 */
1384 		if (dobj == 0) {
1385 			dobj = elf_config_ent(dir->p_name,
1386 			    (Word)elf_hash(dir->p_name), 0, 0);
1387 			if (dobj == 0)
1388 				dobj = &Obj;
1389 			dir->p_info = (void *)dobj;
1390 
1391 			if ((dobj->co_flags & (RTC_OBJ_NOEXIST |
1392 			    RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1393 				return (0);
1394 		}
1395 
1396 		/*
1397 		 * If we found a directory search for the file.
1398 		 */
1399 		if (dobj->co_id != 0) {
1400 			if (*strhash == 0)
1401 				*strhash = (Word)elf_hash(nname);
1402 			fobj = elf_config_ent(nname, *strhash,
1403 			    dobj->co_id, &alt);
1404 
1405 			/*
1406 			 * If this object specifically does not exist, or the
1407 			 * object can't be found in a know-all-entries
1408 			 * directory, continue looking.  If the object does
1409 			 * exist determine if an alternative object exists.
1410 			 */
1411 			if (fobj == 0) {
1412 				if (dobj->co_flags & RTC_OBJ_ALLENTS)
1413 					return (0);
1414 			} else {
1415 				if ((fobj->co_flags & (RTC_OBJ_NOEXIST |
1416 				    RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1417 					return (0);
1418 
1419 				if ((fobj->co_flags & RTC_OBJ_ALTER) &&
1420 				    (rtld_flags & RT_FL_OBJALT) &&
1421 				    (lml == &lml_main)) {
1422 					int	ret;
1423 
1424 					fdesc->fd_flags |= FLG_FD_ALTER;
1425 					/*
1426 					 * Attempt to open the alternative path.
1427 					 * If this fails, and the alternative is
1428 					 * flagged as optional, fall through to
1429 					 * open the original path.
1430 					 */
1431 					ret = _find_file(lml, oname, alt, clmp,
1432 					    flags, fdesc, rej, dir, 1);
1433 					if (ret || ((fobj->co_flags &
1434 					    RTC_OBJ_OPTINAL) == 0))
1435 						return (ret);
1436 
1437 					fdesc->fd_flags &= ~FLG_FD_ALTER;
1438 				}
1439 			}
1440 		}
1441 	}
1442 
1443 	/*
1444 	 * Protect ourselves from building an invalid pathname.
1445 	 */
1446 	if ((olen + dir->p_len + 1) >= PATH_MAX) {
1447 		eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), nname,
1448 		    strerror(ENAMETOOLONG));
1449 			return (0);
1450 	}
1451 	if ((nname = (LM_GET_SO(clmp)(dir->p_name, nname))) == 0)
1452 		return (0);
1453 
1454 	return (_find_file(lml, oname, nname, clmp, flags, fdesc, rej, dir, 0));
1455 }
1456 
1457 /*
1458  * A unique file has been opened.  Create a link-map to represent it, and
1459  * process the various names by which it can be referenced.
1460  */
1461 static Rt_map *
1462 load_file(Lm_list *lml, Aliste lmco, Fdesc * fdesc)
1463 {
1464 	const char	*oname = fdesc->fd_oname;
1465 	const char	*nname = fdesc->fd_nname;
1466 	Rt_map		*nlmp;
1467 
1468 	/*
1469 	 * Typically we call fct_map_so() with the full pathname of the opened
1470 	 * file (nname) and the name that started the search (oname), thus for
1471 	 * a typical dependency on libc this would be /usr/lib/libc.so.1 and
1472 	 * libc.so.1 (DT_NEEDED).  The original name is maintained on an ALIAS
1473 	 * list for comparison when bringing in new dependencies.  If the user
1474 	 * specified name as a full path (from a dlopen() for example) then
1475 	 * there's no need to create an ALIAS.
1476 	 */
1477 	if (strcmp(oname, nname) == 0)
1478 		oname = 0;
1479 
1480 	/*
1481 	 * A new file has been opened, now map it into the process.  Close the
1482 	 * original file so as not to accumulate file descriptors.
1483 	 */
1484 	nlmp = ((fdesc->fd_ftp)->fct_map_so)(lml, lmco, nname, oname,
1485 	    fdesc->fd_fd);
1486 	(void) close(fdesc->fd_fd);
1487 	fdesc->fd_fd = 0;
1488 
1489 	if (nlmp == 0)
1490 		return (0);
1491 
1492 	/*
1493 	 * Save the dev/inode information for later comparisons.
1494 	 */
1495 	STDEV(nlmp) = fdesc->fd_dev;
1496 	STINO(nlmp) = fdesc->fd_ino;
1497 
1498 	/*
1499 	 * Insert the names of this link-map into the FullpathNode AVL tree.
1500 	 * Save both the NAME() and PATHNAME() is they differ.
1501 	 *
1502 	 * If this is an OBJECT file, don't insert it yet as this is only a
1503 	 * temporary link-map.  During elf_obj_fini() the final link-map is
1504 	 * created, and its names will be inserted in the FullpathNode AVL
1505 	 * tree at that time.
1506 	 */
1507 	if ((FLAGS(nlmp) & FLG_RT_OBJECT) == 0) {
1508 		/*
1509 		 * Update the objects full path information if necessary.
1510 		 */
1511 		if (FLAGS1(nlmp) & FL1_RT_RELATIVE) {
1512 			(void) fullpath(nlmp, fdesc->fd_pname);
1513 			fdesc->fd_pname = 0;
1514 		}
1515 
1516 		if ((NAME(nlmp)[0] == '/') && (fpavl_insert(lml, nlmp,
1517 		    NAME(nlmp), fdesc->fd_avlwhere) == 0)) {
1518 			remove_so(lml, nlmp);
1519 			return (0);
1520 		}
1521 		if (((NAME(nlmp)[0] != '/') ||
1522 		    (NAME(nlmp) != PATHNAME(nlmp))) &&
1523 		    (fpavl_insert(lml, nlmp, PATHNAME(nlmp), 0) == 0)) {
1524 			remove_so(lml, nlmp);
1525 			return (0);
1526 		}
1527 	}
1528 
1529 	/*
1530 	 * If we're processing an alternative object reset the original name
1531 	 * for possible $ORIGIN processing.
1532 	 */
1533 	if (fdesc->fd_flags & FLG_FD_ALTER) {
1534 		const char	*odir;
1535 		char		*ndir;
1536 		size_t		olen;
1537 
1538 		FLAGS(nlmp) |= FLG_RT_ALTER;
1539 
1540 		/*
1541 		 * If we were given a pathname containing a slash then the
1542 		 * original name is still in oname.  Otherwise the original
1543 		 * directory is in dir->p_name (which is all we need for
1544 		 * $ORIGIN).
1545 		 */
1546 		if (fdesc->fd_flags & FLG_FD_SLASH) {
1547 			char	*ofil;
1548 
1549 			odir = oname;
1550 			ofil = strrchr(oname, '/');
1551 			olen = ofil - odir + 1;
1552 		} else {
1553 			odir = fdesc->fd_odir;
1554 			olen = strlen(odir) + 1;
1555 		}
1556 
1557 		if ((ndir = (char *)malloc(olen)) == 0) {
1558 			remove_so(lml, nlmp);
1559 			return (0);
1560 		}
1561 		(void) strncpy(ndir, odir, olen);
1562 		ndir[--olen] = '\0';
1563 
1564 		ORIGNAME(nlmp) = ndir;
1565 		DIRSZ(nlmp) = olen;
1566 	}
1567 
1568 	/*
1569 	 * Identify this as a new object.
1570 	 */
1571 	FLAGS(nlmp) |= FLG_RT_NEWLOAD;
1572 
1573 	/*
1574 	 * Report module loads to TLS module activity.
1575 	 */
1576 	if (nlmp)
1577 		tls_modactivity(nlmp, TM_FLG_MODADD);
1578 
1579 	return (nlmp);
1580 }
1581 
1582 /*
1583  * This function loads the named file and returns a pointer to its link map.
1584  * It is assumed that the caller has already checked that the file is not
1585  * already loaded before calling this function (refer is_so_loaded()).
1586  * Find and open the file, map it into memory, add it to the end of the list
1587  * of link maps and return a pointer to the new link map.  Return 0 on error.
1588  */
1589 static Rt_map *
1590 load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
1591     uint_t flags, Fdesc *fdp, Rej_desc *rej)
1592 {
1593 	char		*name;
1594 	uint_t		slash = 0;
1595 	size_t		olen;
1596 	Fdesc		fdesc, _fdesc = { 0 };
1597 	Pnode		*dir;
1598 	Rt_map		*nlmp;
1599 
1600 	/*
1601 	 * If the file is the run time linker then it's already loaded.
1602 	 */
1603 	if (interp && (strcmp(oname, NAME(lml_rtld.lm_head)) == 0))
1604 		return (lml_rtld.lm_head);
1605 
1606 	/*
1607 	 * If this isn't a hardware capabilites pathname, which is already a
1608 	 * full, duplicated pathname, determine whether the pathname contains
1609 	 * a slash, and if not determine the input filename (for max path
1610 	 * length verification).
1611 	 */
1612 	if ((flags & FLG_RT_HWCAP) == 0) {
1613 		const char	*str;
1614 
1615 		for (str = oname; *str; str++) {
1616 			if (*str == '/') {
1617 				slash++;
1618 				break;
1619 			}
1620 		}
1621 		if (slash == 0)
1622 			olen = (str - oname) + 1;
1623 	}
1624 
1625 	/*
1626 	 * If we are passed a 'null' link-map this means that this is the first
1627 	 * object to be loaded on this link-map list.  In that case we set the
1628 	 * link-map to ld.so.1's link-map.
1629 	 *
1630 	 * This link-map is referenced to determine what lookup rules to use
1631 	 * when searching for files.  By using ld.so.1's we are defaulting to
1632 	 * ELF look-up rules.
1633 	 *
1634 	 * Note: This case happens when loading the first object onto
1635 	 *	 the plt_tracing link-map.
1636 	 */
1637 	if (clmp == 0)
1638 		clmp = lml_rtld.lm_head;
1639 
1640 	/*
1641 	 * If this path resulted from a $HWCAP specification, then the best
1642 	 * hardware capability object has already been establish, and is
1643 	 * available in the calling file descriptor.  Perform some minor book-
1644 	 * keeping so that we can fall through into common code.
1645 	 */
1646 	if (flags & FLG_RT_HWCAP) {
1647 		fdesc = *fdp;
1648 
1649 		/*
1650 		 * Restablish the Fmap structure to reflect this objects
1651 		 * original initial page mapping.  Make sure any present Fmap
1652 		 * mapping is removed before overwriting the structure.
1653 		 */
1654 		if (fdesc.fd_lmp == 0) {
1655 #if	defined(MAP_ALIGN)
1656 			if (fmap->fm_maddr &&
1657 			    ((fmap->fm_mflags & MAP_ALIGN) == 0))
1658 #else
1659 			if (fmap->fm_maddr)
1660 #endif
1661 				(void) munmap(fmap->fm_maddr, fmap->fm_msize);
1662 			*fmap = fdesc.fd_fmap;
1663 
1664 			/*
1665 			 * Obtain the avl index for this object.
1666 			 */
1667 			(void) fpavl_loaded(lml, fdesc.fd_nname,
1668 			    &(fdesc.fd_avlwhere));
1669 		} else {
1670 			/*
1671 			 * If this object is already loaded, we're done.
1672 			 */
1673 			return (fdesc.fd_lmp);
1674 		}
1675 
1676 	} else if (slash) {
1677 		Rej_desc	_rej = { 0 };
1678 
1679 		fdesc = _fdesc;
1680 		fdesc.fd_flags = FLG_FD_SLASH;
1681 
1682 		if (find_path(lml, oname, clmp, flags, &fdesc, &_rej) == 0) {
1683 			rejection_inherit(rej, &_rej, &fdesc);
1684 			return (0);
1685 		}
1686 
1687 		/*
1688 		 * If this object is already loaded, we're done.
1689 		 */
1690 		if (fdesc.fd_lmp)
1691 			return (fdesc.fd_lmp);
1692 
1693 	} else {
1694 		/*
1695 		 * No '/' - for each directory on list, make a pathname using
1696 		 * that directory and filename and try to open that file.
1697 		 */
1698 		Pnode *		dirlist = (Pnode *)0;
1699 		Word		strhash = 0;
1700 
1701 		DBG_CALL(Dbg_libs_find(oname));
1702 
1703 #if	!defined(ISSOLOAD_BASENAME_DISABLED)
1704 		if ((nlmp = is_so_loaded(lml, oname, 0)))
1705 			return (nlmp);
1706 #endif
1707 		/*
1708 		 * Make sure we clear the file descriptor new name in case the
1709 		 * following directory search doesn't provide any directories
1710 		 * (odd, but this can be forced with a -znodefaultlib test).
1711 		 */
1712 		fdesc = _fdesc;
1713 		for (dir = get_next_dir(&dirlist, clmp, flags); dir;
1714 		    dir = get_next_dir(&dirlist, clmp, flags)) {
1715 			Rej_desc	_rej = { 0 };
1716 
1717 			fdesc = _fdesc;
1718 
1719 			/*
1720 			 * Try and locate this file.  Make sure to clean up
1721 			 * any rejection information should the file have
1722 			 * been found, but not appropriate.
1723 			 */
1724 			if (find_file(lml, oname, clmp, flags, &fdesc, &_rej,
1725 			    dir, &strhash, olen) == 0) {
1726 				rejection_inherit(rej, &_rej, &fdesc);
1727 				continue;
1728 			}
1729 
1730 			/*
1731 			 * If this object is already loaded, we're done.
1732 			 */
1733 			if (fdesc.fd_lmp)
1734 				return (fdesc.fd_lmp);
1735 
1736 			fdesc.fd_odir = dir->p_name;
1737 			break;
1738 		}
1739 
1740 		/*
1741 		 * If the file couldn't be loaded, do another comparison of
1742 		 * loaded files using just the basename.  This catches folks
1743 		 * who may have loaded multiple full pathname files (possibly
1744 		 * from setxid applications) to satisfy dependency relationships
1745 		 * (i.e., a file might have a dependency on foo.so.1 which has
1746 		 * already been opened using its full pathname).
1747 		 */
1748 		if (fdesc.fd_nname == 0)
1749 			return (is_so_loaded(lml, oname, 1));
1750 	}
1751 
1752 	/*
1753 	 * Duplicate the file name so that NAME() is available in core files.
1754 	 * Note, that hardware capability names are already duplicated, but
1755 	 * they get duplicated once more to insure consistent cleanup in the
1756 	 * event of an error condition.
1757 	 */
1758 	if ((name = strdup(fdesc.fd_nname)) == 0) {
1759 		(void) close(fdesc.fd_fd);
1760 		return (0);
1761 	}
1762 	if (fdesc.fd_nname == fdesc.fd_pname)
1763 		fdesc.fd_nname = fdesc.fd_pname = name;
1764 	else
1765 		fdesc.fd_nname = name;
1766 
1767 	/*
1768 	 * Finish mapping the file and return the link-map descriptor.  Note,
1769 	 * if this request originated from a HWCAP request, re-establish the
1770 	 * fdesc information.  For single paged objects, such as filters, the
1771 	 * original mapping may have been sufficient to capture the file, thus
1772 	 * this mapping needs to be reset to insure it doesn't mistakenly get
1773 	 * unmapped as part of HWCAP cleanup.
1774 	 */
1775 	nlmp = load_file(lml, lmco, &fdesc);
1776 
1777 	if (flags & FLG_RT_HWCAP) {
1778 		fdp->fd_fmap.fm_maddr = fmap->fm_maddr;
1779 		fdp->fd_fmap.fm_mflags = fmap->fm_mflags;
1780 		fdp->fd_pname = fdesc.fd_pname;
1781 		fdp->fd_fd = fdesc.fd_fd;
1782 	}
1783 
1784 	return (nlmp);
1785 }
1786 
1787 /*
1788  * Trace an attempt to load an object.
1789  */
1790 const char *
1791 load_trace(Lm_list *lml, const char *name, Rt_map *clmp)
1792 {
1793 	/*
1794 	 * First generate any ldd(1) diagnostics.
1795 	 */
1796 	if ((lml->lm_flags & (LML_FLG_TRC_VERBOSE | LML_FLG_TRC_SEARCH)) &&
1797 	    ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0))
1798 		(void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, NAME(clmp));
1799 
1800 	/*
1801 	 * If we're being audited tell the audit library of the file we're
1802 	 * about to go search for.
1803 	 */
1804 	if (((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_ACTIVITY) &&
1805 	    (lml == LIST(clmp)))
1806 		audit_activity(clmp, LA_ACT_ADD);
1807 
1808 	if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
1809 		char	*_name;
1810 
1811 		/*
1812 		 * The auditor can indicate that this object should be ignored.
1813 		 */
1814 		if ((_name = audit_objsearch(clmp, name, LA_SER_ORIG)) == 0) {
1815 			eprintf(ERR_FATAL, MSG_INTL(MSG_GEN_AUDITERM), name);
1816 			return (0);
1817 		}
1818 
1819 		/*
1820 		 * The auditor can provide an alternative name.
1821 		 */
1822 		if (_name != name) {
1823 			free((void *)name);
1824 			name = strdup(_name);
1825 		}
1826 	}
1827 	return (name);
1828 }
1829 
1830 /*
1831  * Having loaded an object and created a link-map to describe it, finish
1832  * processing this stage, including verifying any versioning requirements,
1833  * updating the objects mode, creating a handle if necessary, and adding this
1834  * object to existing handles if required.
1835  */
1836 static int
1837 load_finish(Lm_list *lml, const char *name, Rt_map * clmp, int nmode,
1838     uint_t flags, Grp_hdl ** hdl, Rt_map * nlmp)
1839 {
1840 	Aliste		off;
1841 	Grp_hdl		*ghp, **ghpp;
1842 	int		promote;
1843 
1844 	/*
1845 	 * If this dependency is associated with a required version insure that
1846 	 * the version is present in the loaded file.
1847 	 */
1848 	if (((rtld_flags & RT_FL_NOVERSION) == 0) &&
1849 	    (FCT(clmp) == &elf_fct) && VERNEED(clmp) &&
1850 	    (LM_VERIFY_VERS(clmp)(name, clmp, nlmp) == 0))
1851 		return (0);
1852 
1853 	/*
1854 	 * If this object has indicated that it should be isolated as a group
1855 	 * (DT_FLAGS_1 contains DF_1_GROUP - object was built with -B group),
1856 	 * or if the callers direct bindings indicate it should be isolated as
1857 	 * a group (DYNINFO flags contains FLG_DI_GROUP - dependency followed
1858 	 * -zgroupperm), establish the appropriate mode.
1859 	 *
1860 	 * The intent of an object defining itself as a group is to isolate the
1861 	 * relocation of the group within its own members, however, unless
1862 	 * opened through dlopen(), in which case we assume dlsym() will be used
1863 	 * to located symbols in the new object, we still need to associate it
1864 	 * with the caller for it to be bound with.  This is equivalent to a
1865 	 * dlopen(RTLD_GROUP) and dlsym() using the returned handle.
1866 	 */
1867 	if ((FLAGS(nlmp) | flags) & FLG_RT_SETGROUP) {
1868 		nmode &= ~RTLD_WORLD;
1869 		nmode |= RTLD_GROUP;
1870 
1871 		/*
1872 		 * If the object wasn't explicitly dlopen()'ed associate it with
1873 		 * the parent.
1874 		 */
1875 		if (flags != FLG_RT_HANDLE)
1876 			nmode |= RTLD_PARENT;
1877 	}
1878 
1879 	/*
1880 	 * Establish new mode and flags.
1881 	 *
1882 	 * For patch backward compatibility, the following use of update_mode()
1883 	 * is disabled.
1884 	 */
1885 #ifdef	SIEBEL_DISABLE
1886 	if (rtld_flags & RT_FL_DISFIX_1)
1887 		promote = MODE(nlmp) |=
1888 		    (nmode & ~(RTLD_PARENT | RTLD_NOLOAD | RTLD_FIRST));
1889 	else
1890 #endif
1891 		promote = update_mode(nlmp, MODE(nlmp), nmode);
1892 
1893 	FLAGS(nlmp) |= flags;
1894 
1895 	/*
1896 	 * If we've been asked to establish a handle create one for this object.
1897 	 * Or, if this object has already been analyzed, but this reference
1898 	 * requires that the mode of the object be promoted, also create a
1899 	 * handle to propagate the new modes to all this objects dependencies.
1900 	 */
1901 	if (((FLAGS(nlmp) | flags) & FLG_RT_HANDLE) || (promote &&
1902 	    (FLAGS(nlmp) & FLG_RT_ANALYZED))) {
1903 		uint_t	oflags, hflags = 0;
1904 
1905 		if (nmode & RTLD_PARENT)
1906 			hflags |=  GPH_PARENT;
1907 		if (nmode & RTLD_FIRST)
1908 			hflags |=  GPH_FIRST;
1909 
1910 		/*
1911 		 * Now that a handle is being created, remove this state from
1912 		 * the object so that it doesn't mistakenly get inherited by
1913 		 * a dependency.
1914 		 */
1915 		oflags = FLAGS(nlmp);
1916 		FLAGS(nlmp) &= ~FLG_RT_HANDLE;
1917 
1918 		if ((ghp = hdl_create(lml, nlmp, clmp, hflags)) == 0)
1919 			return (0);
1920 
1921 		/*
1922 		 * Add any dependencies that are already loaded, to the handle.
1923 		 */
1924 		if (hdl_initialize(ghp, nlmp, clmp, nmode, promote) == 0)
1925 			return (0);
1926 
1927 		if (hdl)
1928 			*hdl = ghp;
1929 
1930 		/*
1931 		 * If we were asked to create a handle, we're done.  Otherwise,
1932 		 * remove the handle. The handle was only used to establish this
1933 		 * objects dependencies and promote any modes, so we don't want
1934 		 * this handle preventing the objects deletion.  Fall through to
1935 		 * carry out any group processing.
1936 		 */
1937 		if ((oflags | flags) & FLG_RT_HANDLE)
1938 			return (1);
1939 
1940 		free_hdl(ghp);
1941 	}
1942 
1943 	/*
1944 	 * If the caller isn't part of a group we're done.
1945 	 */
1946 	if (GROUPS(clmp) == 0)
1947 		return (1);
1948 
1949 	/*
1950 	 * Determine if our caller is already associated with a handle, if so
1951 	 * we need to add this object to any handles that already exist.
1952 	 * Traverse the list of groups our caller is a member of and add this
1953 	 * new link-map to those groups.
1954 	 */
1955 	DBG_CALL(Dbg_file_hdl_title(DBG_DEP_ADD));
1956 	for (ALIST_TRAVERSE(GROUPS(clmp), off, ghpp)) {
1957 		Aliste		off1;
1958 		Grp_desc	*gdp;
1959 		int		exist;
1960 		Rt_map		**lmpp;
1961 		Alist		*lmalp = 0;
1962 
1963 		ghp = *ghpp;
1964 
1965 		/*
1966 		 * If the caller doesn't indicate that its dependencies should
1967 		 * be added to a handle, ignore it.  This case identifies a
1968 		 * parent of a dlopen(RTLD_PARENT) request.
1969 		 */
1970 		for (ALIST_TRAVERSE(ghp->gh_depends, off1, gdp)) {
1971 			if (gdp->gd_depend == clmp)
1972 				break;
1973 		}
1974 		if ((gdp->gd_flags & GPD_ADDEPS) == 0)
1975 			continue;
1976 
1977 		if ((exist = hdl_add(ghp, nlmp,
1978 		    (GPD_AVAIL | GPD_ADDEPS))) == 0)
1979 			return (0);
1980 
1981 		/*
1982 		 * If this member already exists then its dependencies will
1983 		 * have already been processed.
1984 		 */
1985 		if (exist == ALE_EXISTS)
1986 			continue;
1987 
1988 		/*
1989 		 * If the object we've added has just been opened, it will not
1990 		 * yet have been processed for its dependencies, these will be
1991 		 * added on later calls to load_one().  If it doesn't have any
1992 		 * dependencies we're also done.
1993 		 */
1994 		if (((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0) ||
1995 		    (DEPENDS(nlmp) == 0))
1996 			continue;
1997 
1998 		/*
1999 		 * Otherwise, this object exists and has dependencies, so add
2000 		 * all of its dependencies to the handle were operating on.
2001 		 */
2002 		if (alist_append(&lmalp, &nlmp, sizeof (Rt_map *),
2003 		    AL_CNT_DEPCLCT) == 0)
2004 			return (0);
2005 
2006 		for (ALIST_TRAVERSE(lmalp, off1, lmpp)) {
2007 			Rt_map *	dlmp1 = *lmpp;
2008 			Aliste		off2;
2009 			Bnd_desc **	bdpp;
2010 
2011 			/*
2012 			 * Add any dependencies of this dependency to the
2013 			 * dynamic dependency list so they can be further
2014 			 * processed.
2015 			 */
2016 			for (ALIST_TRAVERSE(DEPENDS(dlmp1), off2, bdpp)) {
2017 				Bnd_desc *	bdp = *bdpp;
2018 				Rt_map *	dlmp2 = bdp->b_depend;
2019 
2020 				if ((bdp->b_flags & BND_NEEDED) == 0)
2021 					continue;
2022 
2023 				if (alist_test(&lmalp, dlmp2, sizeof (Rt_map *),
2024 				    AL_CNT_DEPCLCT) == 0) {
2025 					free(lmalp);
2026 					return (0);
2027 				}
2028 			}
2029 
2030 			if (nlmp == dlmp1)
2031 				continue;
2032 
2033 			if ((exist = hdl_add(ghp, dlmp1,
2034 			    (GPD_AVAIL | GPD_ADDEPS))) != 0) {
2035 				if (exist == ALE_CREATE)
2036 				    (void) update_mode(dlmp1, MODE(dlmp1),
2037 					nmode);
2038 				continue;
2039 			}
2040 			free(lmalp);
2041 			return (0);
2042 		}
2043 		free(lmalp);
2044 	}
2045 	return (1);
2046 }
2047 
2048 /*
2049  * The central routine for loading shared objects.  Insures ldd() diagnostics,
2050  * handles and any other related additions are all done in one place.
2051  */
2052 Rt_map *
2053 load_path(Lm_list *lml, Aliste lmco, const char *name, Rt_map *clmp,
2054     int nmode, uint_t flags, Grp_hdl ** hdl, Fdesc *fdp, Rej_desc *rej)
2055 {
2056 	Rt_map	*nlmp;
2057 
2058 	if ((nmode & RTLD_NOLOAD) == 0) {
2059 		/*
2060 		 * If this isn't a noload request attempt to load the file.
2061 		 */
2062 		if ((name = load_trace(lml, name, clmp)) == 0)
2063 			return (0);
2064 
2065 		if ((nlmp = load_so(lml, lmco, name, clmp, flags,
2066 		    fdp, rej)) == 0)
2067 			return (0);
2068 
2069 		/*
2070 		 * If we've loaded a library which identifies itself as not
2071 		 * being dlopen()'able catch it here.  Let non-dlopen()'able
2072 		 * objects through under RTLD_CONFGEN as they're only being
2073 		 * mapped to be dldump()'ed.
2074 		 */
2075 		if ((rtld_flags & RT_FL_APPLIC) && ((FLAGS(nlmp) &
2076 		    (FLG_RT_NOOPEN | FLG_RT_RELOCED)) == FLG_RT_NOOPEN) &&
2077 		    ((nmode & RTLD_CONFGEN) == 0)) {
2078 			Rej_desc	_rej = { 0 };
2079 
2080 			_rej.rej_name = name;
2081 			_rej.rej_type = SGS_REJ_STR;
2082 			_rej.rej_str = MSG_INTL(MSG_GEN_NOOPEN);
2083 			DBG_CALL(Dbg_file_rejected(&_rej));
2084 			rejection_inherit(rej, &_rej, fdp);
2085 			remove_so(lml, nlmp);
2086 			return (0);
2087 		}
2088 	} else {
2089 		/*
2090 		 * If it's a NOLOAD request - check to see if the object
2091 		 * has already been loaded.
2092 		 */
2093 		/* LINTED */
2094 		if ((nlmp = is_so_loaded(lml, name, 0)) ||
2095 		    (nlmp = is_so_loaded(lml, name, 1))) {
2096 			if ((lml->lm_flags & LML_FLG_TRC_VERBOSE) &&
2097 			    ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) {
2098 				(void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name,
2099 					NAME(clmp));
2100 				if (*name == '/')
2101 				    (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH),
2102 					name, MSG_ORIG(MSG_STR_EMPTY),
2103 					MSG_ORIG(MSG_STR_EMPTY));
2104 				else
2105 				    (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV),
2106 					name, NAME(nlmp),
2107 					MSG_ORIG(MSG_STR_EMPTY),
2108 					MSG_ORIG(MSG_STR_EMPTY));
2109 			}
2110 		} else {
2111 			Rej_desc	_rej = { 0 };
2112 
2113 			_rej.rej_name = name;
2114 			_rej.rej_type = SGS_REJ_STR;
2115 			_rej.rej_str = strerror(ENOENT);
2116 			DBG_CALL(Dbg_file_rejected(&_rej));
2117 			rejection_inherit(rej, &_rej, 0);
2118 			return (0);
2119 		}
2120 	}
2121 
2122 	/*
2123 	 * Finish processing this loaded object.
2124 	 */
2125 	if (load_finish(lml, name, clmp, nmode, flags, hdl, nlmp) == 0) {
2126 		FLAGS(nlmp) &= ~FLG_RT_NEWLOAD;
2127 
2128 		/*
2129 		 * If this object has already been analyzed, then it is in use,
2130 		 * so even though this operation has failed, it should not be
2131 		 * torn down.
2132 		 */
2133 		if ((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0)
2134 			remove_so(lml, nlmp);
2135 		return (0);
2136 	}
2137 
2138 	/*
2139 	 * If this object is new, and we're being audited, tell the audit
2140 	 * library of the file we've just opened.  Note, if the new link-map
2141 	 * requires local auditing of its dependencies we also register its
2142 	 * opening.
2143 	 */
2144 	if (FLAGS(nlmp) & FLG_RT_NEWLOAD) {
2145 		FLAGS(nlmp) &= ~FLG_RT_NEWLOAD;
2146 
2147 		if (((lml->lm_tflags | FLAGS1(clmp) | FLAGS1(nlmp)) &
2148 		    LML_TFLG_AUD_MASK) && (((lml->lm_flags |
2149 		    LIST(clmp)->lm_flags) & LML_FLG_NOAUDIT) == 0)) {
2150 			if (audit_objopen(clmp, nlmp) == 0) {
2151 				remove_so(lml, nlmp);
2152 				return (0);
2153 			}
2154 		}
2155 	}
2156 	return (nlmp);
2157 }
2158 
2159 /*
2160  * Load one object from a possible list of objects.  Typically, for requests
2161  * such as NEEDED's, only one object is specified.  However, this object could
2162  * be specified using $ISALIST or $HWCAP, in which case only the first object
2163  * that can be loaded is used (ie. the best).
2164  */
2165 Rt_map *
2166 load_one(Lm_list *lml, Aliste lmco, Pnode *pnp, Rt_map *clmp, int mode,
2167     uint_t flags, Grp_hdl ** hdl)
2168 {
2169 	Rej_desc	rej = { 0 };
2170 	Pnode   	*tpnp;
2171 	const char	*name;
2172 	Rt_map		*tlmp;
2173 
2174 	for (tpnp = pnp; tpnp && tpnp->p_name; tpnp = tpnp->p_next) {
2175 		/*
2176 		 * A Hardware capabilities requirement can itself expand into
2177 		 * a number of candidates.
2178 		 */
2179 		if (tpnp->p_orig & PN_TKN_HWCAP) {
2180 			if ((tlmp = load_hwcap(lml, lmco, tpnp->p_name, clmp,
2181 			    mode, (flags | FLG_RT_HWCAP), hdl, &rej)) != 0) {
2182 				remove_rej(&rej);
2183 				return (tlmp);
2184 			}
2185 		} else {
2186 			if ((tlmp = load_path(lml, lmco, tpnp->p_name, clmp,
2187 			    mode, flags, hdl, 0, &rej)) != 0) {
2188 				remove_rej(&rej);
2189 				return (tlmp);
2190 			}
2191 		}
2192 	}
2193 
2194 	/*
2195 	 * If this pathname originated from an expanded token, use the original
2196 	 * for any diagnostic output.
2197 	 */
2198 	if ((name = pnp->p_oname) == 0)
2199 		name = pnp->p_name;
2200 
2201 	file_notfound(lml, name, clmp, flags, &rej);
2202 	remove_rej(&rej);
2203 	return (0);
2204 }
2205 
2206 /*
2207  * While processing direct or group bindings, determine whether the object to
2208  * which we've bound can be interposed upon.  In this context, copy relocations
2209  * are a form of interposition.
2210  */
2211 static Sym *
2212 lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list * lml,
2213     Sym * sym)
2214 {
2215 	Rt_map *	lmp;
2216 	Slookup		sl;
2217 
2218 	/*
2219 	 * If we've bound to a copy relocation definition then we need to assign
2220 	 * this binding to the original copy reference.  Fabricate an inter-
2221 	 * position diagnostic, as this is a legitimate form of interposition.
2222 	 */
2223 	if (FLAGS1(*dlmp) & FL1_RT_COPYTOOK) {
2224 		Rel_copy	*rcp;
2225 		Aliste		off;
2226 
2227 		for (ALIST_TRAVERSE(COPY(*dlmp), off, rcp)) {
2228 			if ((sym == rcp->r_dsym) || (sym->st_value &&
2229 			    (sym->st_value == rcp->r_dsym->st_value))) {
2230 				*dlmp = rcp->r_rlmp;
2231 				*binfo |=
2232 				    (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF);
2233 				return (rcp->r_rsym);
2234 			}
2235 		}
2236 	}
2237 
2238 	if ((lml->lm_flags & LML_FLG_INTRPOSE) == 0)
2239 		return ((Sym *)0);
2240 
2241 	/*
2242 	 * Traverse the list of known interposers to determine whether any
2243 	 * offer the same symbol.  Note, the head of the link-map could be
2244 	 * identified as an interposer.  If it is, make sure we only look for
2245 	 * symbol definitions.  Otherwise, skip the head of the link-map, so
2246 	 * that we don't bind to any .plt references, or copy-relocations
2247 	 * unintentionally.
2248 	 */
2249 	lmp = lml->lm_head;
2250 	sl = *slp;
2251 	if (((FLAGS(lmp) & FLG_RT_INTRPOSE) == 0) || (sl.sl_flags & LKUP_COPY))
2252 		lmp = (Rt_map *)NEXT(lmp);
2253 	else
2254 		sl.sl_flags &= ~LKUP_SPEC;
2255 
2256 	for (; lmp; lmp = (Rt_map *)NEXT(lmp)) {
2257 		if (FLAGS(lmp) & FLG_RT_DELETE)
2258 			continue;
2259 		if ((FLAGS(lmp) & FLG_RT_INTRPOSE) == 0)
2260 			break;
2261 
2262 		if (callable(lmp, *dlmp, 0)) {
2263 			sl.sl_imap = lmp;
2264 			if (sym = SYMINTP(lmp)(&sl, dlmp, binfo)) {
2265 				*binfo |= DBG_BINFO_INTERPOSE;
2266 				return (sym);
2267 			}
2268 		}
2269 	}
2270 	return ((Sym *)0);
2271 }
2272 
2273 /*
2274  * If an object specifies direct bindings (it contains a syminfo structure
2275  * describing where each binding was established during link-editing, and the
2276  * object was built -Bdirect), then look for the symbol in the specific object.
2277  */
2278 static Sym *
2279 lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip,
2280     Rt_map *lmp)
2281 {
2282 	Rt_map	*clmp = slp->sl_cmap;
2283 	Sym	*sym;
2284 	Slookup	sl;
2285 
2286 	/*
2287 	 * If a direct binding resolves to the definition of a copy relocated
2288 	 * variable, it must be redirected to the copy (in the executable) that
2289 	 * will eventually be made.  Typically, this redirection occurs in
2290 	 * lookup_sym_interpose().  But, there's an edge condition.  If a
2291 	 * directly bound executable contains pic code, there may be a
2292 	 * reference to a definition that will eventually have a copy made.
2293 	 * However, this copy relocation may not yet have occurred, because
2294 	 * the relocation making this reference comes before the relocation
2295 	 * that will create the copy.
2296 	 * Under direct bindings, the syminfo indicates that a copy will be
2297 	 * taken (SYMINFO_FLG_COPY).  This can only be set in an executable.
2298 	 * Thus, the caller must be the executable, so bind to the destination
2299 	 * of the copy within the executable.
2300 	 */
2301 	if (((slp->sl_flags & LKUP_COPY) == 0) &&
2302 	    (sip->si_flags & SYMINFO_FLG_COPY)) {
2303 
2304 		slp->sl_imap = LIST(clmp)->lm_head;
2305 		if (sym = SYMINTP(clmp)(slp, dlmp, binfo))
2306 			*binfo |= (DBG_BINFO_DIRECT | DBG_BINFO_COPYREF);
2307 		return (sym);
2308 	}
2309 
2310 	/*
2311 	 * If we need to direct bind to our parent start looking in each caller
2312 	 * link map.
2313 	 */
2314 	sl = *slp;
2315 	sl.sl_flags |= LKUP_DIRECT;
2316 	sym = 0;
2317 
2318 	if (sip->si_boundto == SYMINFO_BT_PARENT) {
2319 		Aliste		off;
2320 		Bnd_desc **	bdpp;
2321 
2322 		for (ALIST_TRAVERSE(CALLERS(clmp), off, bdpp)) {
2323 			sl.sl_imap = lmp = (*bdpp)->b_caller;
2324 			if ((sym = SYMINTP(lmp)(&sl, dlmp, binfo)) != 0)
2325 				break;
2326 		}
2327 	} else {
2328 		/*
2329 		 * If we need to direct bind to anything else look in the
2330 		 * link map associated with this symbol reference.
2331 		 */
2332 		if (sip->si_boundto == SYMINFO_BT_SELF)
2333 			sl.sl_imap = lmp = clmp;
2334 		else
2335 			sl.sl_imap = lmp;
2336 
2337 		if (lmp)
2338 			sym = SYMINTP(lmp)(&sl, dlmp, binfo);
2339 	}
2340 
2341 	if (sym)
2342 		*binfo |= DBG_BINFO_DIRECT;
2343 
2344 	/*
2345 	 * If we've bound to an object, determine whether that object can be
2346 	 * interposed upon for this symbol.
2347 	 */
2348 	if (sym && (LIST(*dlmp)->lm_head != *dlmp) &&
2349 	    (LIST(*dlmp) == LIST(clmp))) {
2350 		Sym *	isym;
2351 
2352 		if ((isym = lookup_sym_interpose(slp, dlmp, binfo,
2353 		    LIST(*dlmp), sym)) != 0)
2354 			return (isym);
2355 	}
2356 
2357 	return (sym);
2358 }
2359 
2360 static Sym *
2361 _lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo,
2362     Aliste off)
2363 {
2364 	Rt_map	*lmp;
2365 
2366 	/*
2367 	 * Copy relocations should start their search after the head of the
2368 	 * main link-map control list.
2369 	 */
2370 	if ((off == ALO_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp)
2371 		lmp = (Rt_map *)NEXT(ilmp);
2372 	else
2373 		lmp = ilmp;
2374 
2375 	for (; lmp; lmp = (Rt_map *)NEXT(lmp)) {
2376 		if (callable(slp->sl_cmap, lmp, 0)) {
2377 			Sym	*sym;
2378 
2379 			slp->sl_imap = lmp;
2380 			if ((sym = SYMINTP(lmp)(slp, dlmp, binfo)) != 0)
2381 				return (sym);
2382 		}
2383 	}
2384 	return (0);
2385 }
2386 
2387 static Sym *
2388 _lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo)
2389 {
2390 	Rt_map	*lmp;
2391 
2392 	for (lmp = ilmp; lmp; lmp = (Rt_map *)NEXT(lmp)) {
2393 		if (LAZY(lmp) == 0)
2394 			continue;
2395 		if (callable(slp->sl_cmap, lmp, 0)) {
2396 			Sym	*sym;
2397 
2398 			slp->sl_imap = lmp;
2399 			if ((sym = elf_lazy_find_sym(slp, dlmp, binfo)) != 0)
2400 				return (sym);
2401 		}
2402 	}
2403 	return (0);
2404 }
2405 
2406 /*
2407  * Symbol lookup routine.  Takes an ELF symbol name, and a list of link maps to
2408  * search (if the flag indicates LKUP_FIRST only the first link map of the list
2409  * is searched ie. we've been called from dlsym()).
2410  * If successful, return a pointer to the symbol table entry and a pointer to
2411  * the link map of the enclosing object.  Else return a null pointer.
2412  *
2413  * To improve elf performance, we first compute the elf hash value and pass
2414  * it to each find_sym() routine.  The elf function will use this value to
2415  * locate the symbol, the a.out function will simply ignore it.
2416  */
2417 Sym *
2418 lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
2419 {
2420 	const char	*name = slp->sl_name;
2421 	Rt_map		*clmp = slp->sl_cmap;
2422 	Rt_map		*ilmp = slp->sl_imap, *lmp;
2423 	uint_t		flags = slp->sl_flags;
2424 	ulong_t		rsymndx;
2425 	Sym		*sym = 0;
2426 	Syminfo		*sip;
2427 	Slookup		sl;
2428 
2429 	if (slp->sl_hash == 0)
2430 		slp->sl_hash = elf_hash(name);
2431 	*binfo = 0;
2432 
2433 	/*
2434 	 * Search the initial link map for the required symbol (this category is
2435 	 * selected by dlsym(), where individual link maps are searched for a
2436 	 * required symbol.  Therefore, we know we have permission to look at
2437 	 * the link map).
2438 	 */
2439 	if (flags & LKUP_FIRST)
2440 		return (SYMINTP(ilmp)(slp, dlmp, binfo));
2441 
2442 	/*
2443 	 * Determine whether this lookup can be satisfied by an objects direct,
2444 	 * or lazy binding information.  This is triggered by a relocation from
2445 	 * the object (hence rsymndx is set).
2446 	 */
2447 	if (((rsymndx = slp->sl_rsymndx) != 0) &&
2448 	    ((sip = SYMINFO(clmp)) != 0)) {
2449 
2450 		/*
2451 		 * Find the corresponding Syminfo entry for the original
2452 		 * referencing symbol.
2453 		 */
2454 		/* LINTED */
2455 		sip = (Syminfo *)((char *)sip + (rsymndx * SYMINENT(clmp)));
2456 
2457 		/*
2458 		 * If the symbol information indicates a direct binding,
2459 		 * determine the link map that is required to satisfy the
2460 		 * binding.  Note, if the dependency can not be found, but a
2461 		 * direct binding isn't required, we will still fall through
2462 		 * to perform any default symbol search.
2463 		 */
2464 		if (sip->si_flags & SYMINFO_FLG_DIRECT) {
2465 			uint_t	bound = sip->si_boundto;
2466 
2467 			lmp = 0;
2468 			if (bound < SYMINFO_BT_LOWRESERVE)
2469 				lmp = elf_lazy_load(clmp, bound, name);
2470 
2471 			/*
2472 			 * If direct bindings have been disabled, and this isn't
2473 			 * a translator, skip any direct binding now that we've
2474 			 * insured the resolving object has been loaded.
2475 			 *
2476 			 * If we need to direct bind to anything, we look in
2477 			 * ourselves, our parent, or in the link map we've just
2478 			 * loaded.  Otherwise, even though we may have lazily
2479 			 * loaded an object we still continue to search for
2480 			 * symbols from the head of the link map list.
2481 			 */
2482 			if (((FLAGS(clmp) & FLG_RT_TRANS) ||
2483 			    (!(LIST(clmp)->lm_tflags & LML_TFLG_NODIRECT))) &&
2484 			    ((FLAGS(clmp) & FLG_RT_DIRECT) ||
2485 			    (sip->si_flags & SYMINFO_FLG_DIRECTBIND))) {
2486 				sym = lookup_sym_direct(slp, dlmp, binfo,
2487 				    sip, lmp);
2488 
2489 				/*
2490 				 * If this direct binding has been disabled
2491 				 * (presumably because the symbol definition has
2492 				 * been changed since the referring object was
2493 				 * built), fall back to a standard symbol
2494 				 * search.
2495 				 */
2496 				if ((*binfo & BINFO_DIRECTDIS) == 0)
2497 					return (sym);
2498 			}
2499 		}
2500 	}
2501 
2502 	sl = *slp;
2503 
2504 	/*
2505 	 * If the referencing object has the DF_SYMBOLIC flag set, look in the
2506 	 * referencing object for the symbol first.  Failing that, fall back to
2507 	 * our generic search.
2508 	 */
2509 	if (FLAGS1(clmp) & FL1_RT_SYMBOLIC) {
2510 		sl.sl_imap = clmp;
2511 		if (sym = SYMINTP(clmp)(&sl, dlmp, binfo))
2512 			return (sym);
2513 	}
2514 
2515 	/*
2516 	 * If this lookup originates from a standard relocation, then traverse
2517 	 * all link-map lists inspecting any object that is available to this
2518 	 * caller.  Otherwise, traverse the link-map list associate with the
2519 	 * caller.
2520 	 */
2521 	if (flags & LKUP_ALLCNTLIST) {
2522 		Aliste	off;
2523 		Lm_cntl	*lmc;
2524 
2525 		sym = 0;
2526 
2527 		for (ALIST_TRAVERSE(LIST(clmp)->lm_lists, off, lmc)) {
2528 			if ((sym = _lookup_sym(lmc->lc_head, &sl, dlmp,
2529 			    binfo, off)) != 0)
2530 				break;
2531 		}
2532 	} else
2533 		sym = _lookup_sym(ilmp, &sl, dlmp, binfo, ALO_DATA);
2534 
2535 	/*
2536 	 * To allow transitioning into a world of lazy loading dependencies see
2537 	 * if this link map contains objects that have lazy dependencies still
2538 	 * outstanding.  If so, and we haven't been able to locate a non-weak
2539 	 * symbol reference, start bringing in any lazy dependencies to see if
2540 	 * the reference can be satisfied.  Use of dlsym(RTLD_PROBE) sets the
2541 	 * LKUP_NOFALBACK flag, and this flag disables this fall back.
2542 	 */
2543 	if ((sym == 0) && ((sl.sl_flags & LKUP_NOFALBACK) == 0)) {
2544 		if ((lmp = ilmp) == 0)
2545 			lmp = LIST(clmp)->lm_head;
2546 		if ((flags & LKUP_WEAK) || (LIST(lmp)->lm_lazy == 0))
2547 			return ((Sym *)0);
2548 
2549 		DBG_CALL(Dbg_syms_lazy_rescan(name));
2550 
2551 		/*
2552 		 * If this request originated from a dlsym(RTLD_NEXT) then start
2553 		 * looking for dependencies from the caller, otherwise use the
2554 		 * initial link-map.
2555 		 */
2556 		if (flags & LKUP_NEXT)
2557 			sym = _lazy_find_sym(clmp, &sl, dlmp, binfo);
2558 		else {
2559 			Aliste	off;
2560 			Lm_cntl	*lmc;
2561 
2562 			for (ALIST_TRAVERSE(LIST(clmp)->lm_lists, off, lmc)) {
2563 				sl.sl_flags |= LKUP_NOFALBACK;
2564 				if ((sym = _lazy_find_sym(lmc->lc_head, &sl,
2565 				    dlmp, binfo)) != 0)
2566 					break;
2567 			}
2568 		}
2569 	}
2570 
2571 	/*
2572 	 * If the caller is restricted to a symbol search within its group,
2573 	 * determine if it is necessary to follow a binding from outside of
2574 	 * the group.
2575 	 */
2576 	if (sym && ((MODE(clmp) & (RTLD_GROUP | RTLD_WORLD)) == RTLD_GROUP)) {
2577 		Sym *	isym;
2578 
2579 		if ((isym = lookup_sym_interpose(slp, dlmp, binfo, LIST(*dlmp),
2580 		    sym)) != 0)
2581 			return (isym);
2582 	}
2583 	return (sym);
2584 }
2585 
2586 /*
2587  * Associate a binding descriptor with a caller and its dependency, or update
2588  * an existing descriptor.
2589  */
2590 int
2591 bind_one(Rt_map * clmp, Rt_map * dlmp, uint_t flags)
2592 {
2593 	Bnd_desc **	bdpp, * bdp;
2594 	Aliste		off;
2595 	int		found = ALE_CREATE;
2596 
2597 	/*
2598 	 * Determine whether a binding descriptor already exists between the
2599 	 * two objects.
2600 	 */
2601 	for (ALIST_TRAVERSE(DEPENDS(clmp), off, bdpp)) {
2602 		bdp = *bdpp;
2603 
2604 		if (bdp->b_depend == dlmp) {
2605 			found = ALE_EXISTS;
2606 			break;
2607 		}
2608 	}
2609 
2610 	if (found == ALE_CREATE) {
2611 		/*
2612 		 * Create a new binding descriptor.
2613 		 */
2614 		if ((bdp = malloc(sizeof (Bnd_desc))) == 0)
2615 			return (0);
2616 
2617 		bdp->b_caller = clmp;
2618 		bdp->b_depend = dlmp;
2619 		bdp->b_flags = 0;
2620 
2621 		/*
2622 		 * Append the binding descriptor to the caller and the
2623 		 * dependency.
2624 		 */
2625 		if (alist_append(&DEPENDS(clmp), &bdp,
2626 		    sizeof (Bnd_desc *), AL_CNT_DEPENDS) == 0)
2627 			return (0);
2628 
2629 		if (alist_append(&CALLERS(dlmp), &bdp,
2630 		    sizeof (Bnd_desc *), AL_CNT_CALLERS) == 0)
2631 			return (0);
2632 	}
2633 
2634 	if ((found == ALE_CREATE) || ((bdp->b_flags & flags) != flags)) {
2635 		bdp->b_flags |= flags;
2636 
2637 		if (flags & BND_REFER)
2638 			FLAGS1(dlmp) |= FL1_RT_USED;
2639 
2640 		DBG_CALL(Dbg_file_bind_entry(bdp));
2641 	}
2642 	return (found);
2643 }
2644 
2645 /*
2646  * Cleanup after relocation processing.
2647  */
2648 int
2649 relocate_finish(Rt_map *lmp, Alist *bound, int textrel, int ret)
2650 {
2651 	DBG_CALL(Dbg_reloc_run(NAME(lmp), 0, ret, DBG_REL_FINISH));
2652 
2653 	/*
2654 	 * Establish bindings to all objects that have been bound to.
2655 	 */
2656 	if (bound) {
2657 		Aliste	off;
2658 		Rt_map	**lmpp;
2659 
2660 		if (ret) {
2661 			for (ALIST_TRAVERSE(bound, off, lmpp)) {
2662 				if (bind_one(lmp, *lmpp, BND_REFER) == 0) {
2663 					ret = 0;
2664 					break;
2665 				}
2666 			}
2667 		}
2668 		free(bound);
2669 	}
2670 
2671 	/*
2672 	 * If we write enabled the text segment to perform these relocations
2673 	 * re-protect by disabling writes.
2674 	 */
2675 	if (textrel)
2676 		(void) LM_SET_PROT(lmp)(lmp, 0);
2677 
2678 	return (ret);
2679 }
2680