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