xref: /titanic_44/usr/src/cmd/sgs/rtld/common/remove.c (revision 04938e8ba9b4913391f2784b148ad3bc4f6b9fe2)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  *
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * Remove objects.  Objects need removal from a process as part of:
26  *
27  *  o	a dlclose() request
28  *
29  *  o	tearing down a dlopen(), lazy-load, or filter hierarchy that failed to
30  *	completely load
31  *
32  * Any other failure condition will result in process exit (in which case all
33  * we have to do is execute the fini's - tear down is unnecessary).
34  *
35  * Any removal of objects is therefore associated with a dlopen() handle.  There
36  * is a small window between creation of the first dlopen() object and creating
37  * its handle (in which case remove_so() can get rid of the new link-map if
38  * necessary), but other than this all object removal is driven by inspecting
39  * the components of a handle.
40  *
41  * Things to note.  The creation of a link-map, and its addition to the link-map
42  * list occurs in {elf|aout}_new_lm(), if this returns success the link-map is
43  * valid and added, otherwise any steps (allocations) in the process of creating
44  * the link-map would have been undone.  If a failure occurs between creating
45  * the link-map and adding it to a handle, remove_so() is called to remove the
46  * link-map.  If a failures occurs after a handle have been created,
47  * remove_hdl() is called to remove the handle and the link-map.
48  */
49 #pragma ident	"%Z%%M%	%I%	%E% SMI"
50 
51 #include	"_synonyms.h"
52 
53 #include	<string.h>
54 #include	<stdio.h>
55 #include	<unistd.h>
56 #include	<dlfcn.h>
57 #include	<sys/debug.h>
58 #include	<sys/avl.h>
59 #include	<libc_int.h>
60 #include	<debug.h>
61 #include	"_rtld.h"
62 #include	"_audit.h"
63 #include	"_elf.h"
64 #include	"msg.h"
65 
66 /*
67  * Atexit callback provided by libc.  As part of dlclose() determine the address
68  * ranges of all objects that are to be deleted.  Pass this information to
69  * libc's pre-atexit routine.  Libc will purge any registered atexit() calls
70  * related to those objects about to be deleted.
71  */
72 static int
73 purge_exit_handlers(Lm_list *lml, Rt_map **tobj)
74 {
75 	uint_t			num;
76 	Rt_map			**_tobj;
77 	Lc_addr_range_t		*addr, *_addr;
78 	int			error;
79 	int			(*fptr)(Lc_addr_range_t *, uint_t);
80 
81 	/*
82 	 * Has a callback been established?
83 	 */
84 	if ((fptr = lml->lm_lcs[CI_ATEXIT].lc_un.lc_func) == NULL)
85 		return (0);
86 
87 	/*
88 	 * Determine the total number of mapped segments that will be unloaded.
89 	 */
90 	for (num = 0, _tobj = tobj; *_tobj != NULL; _tobj++) {
91 		Rt_map	*lmp = *_tobj;
92 
93 		num += MMAPCNT(lmp);
94 	}
95 
96 	/*
97 	 * Account for a null entry at the end of the address range array.
98 	 */
99 	if (num++ == 0)
100 		return (0);
101 
102 	/*
103 	 * Allocate an array for the address range.
104 	 */
105 	if ((addr = malloc(num * sizeof (Lc_addr_range_t))) == 0)
106 		return (1);
107 
108 	/*
109 	 * Fill the address range with each loadable segments size and address.
110 	 */
111 	for (_tobj = tobj, _addr = addr; *_tobj != NULL; _tobj++) {
112 		Rt_map	*lmp = *_tobj;
113 		Mmap	*mmaps;
114 
115 		for (mmaps = MMAPS(lmp); mmaps->m_vaddr; mmaps++) {
116 			_addr->lb = (void *)mmaps->m_vaddr;
117 			_addr->ub = (void *)(mmaps->m_vaddr + mmaps->m_msize);
118 			_addr++;
119 		}
120 	}
121 	_addr->lb = _addr->ub = 0;
122 
123 	leave(LIST(*tobj));
124 	error = (*fptr)(addr, (num - 1));
125 	(void) enter();
126 
127 	/*
128 	 * If we fail to converse with libc, generate an error message to
129 	 * satisfy any dlerror() usage.
130 	 */
131 	if (error)
132 		eprintf(lml, ERR_FATAL, MSG_INTL(MSG_ARG_ATEXIT), error);
133 
134 	free(addr);
135 	return (error);
136 }
137 
138 /*
139  * Remove any rejection message allocations.
140  */
141 void
142 remove_rej(Rej_desc *rej)
143 {
144 	if (rej && (rej->rej_type)) {
145 		if (rej->rej_name)
146 			free((void *)rej->rej_name);
147 		if (rej->rej_str && (rej->rej_str != MSG_ORIG(MSG_EMG_ENOMEM)))
148 			free((void *)rej->rej_str);
149 	}
150 }
151 
152 /*
153  * Break down a Pnode list.
154  */
155 void
156 remove_pnode(Pnode *pnp)
157 {
158 	Pnode	*opnp;
159 
160 	for (opnp = 0; pnp; opnp = pnp, pnp = pnp->p_next) {
161 		if (pnp->p_name)
162 			free((void *)pnp->p_name);
163 		if (pnp->p_oname)
164 			free((void *)pnp->p_oname);
165 		if (opnp)
166 			free((void *)opnp);
167 	}
168 	if (opnp)
169 		free((void *)opnp);
170 }
171 
172 
173 /*
174  * Remove a link-map list descriptor.  This is called to finalize the removal
175  * of an entire link-map list, after all link-maps have been removed, or none
176  * got added.  As load_one() can process a list of potential candidate objects,
177  * the link-map descriptor must be maintained as each object is processed.  Only
178  * after all objects have been processed can a failure condition finally tear
179  * down the link-map list descriptor.
180  */
181 void
182 remove_lml(Lm_list *lml)
183 {
184 	if (lml && (lml->lm_head == 0)) {
185 		/*
186 		 * As a whole link-map list is being removed, the debuggers
187 		 * would have been alerted of this deletion (or an addition
188 		 * in the case we're here to clean up from a failure).  Set
189 		 * the main link-map list so that a consistent registration
190 		 * can be signaled to the debuggers when we leave ld.so.1.
191 		 */
192 		lml_main.lm_flags |= LML_FLG_DBNOTIF;
193 
194 		if (lml->lm_lmidstr)
195 			free(lml->lm_lmidstr);
196 		if (lml->lm_alp)
197 			free(lml->lm_alp);
198 		if (lml->lm_lists)
199 			free(lml->lm_lists);
200 		if (lml->lm_actaudit)
201 			free(lml->lm_actaudit);
202 
203 		/*
204 		 * Cleanup any pending RTLDINFO in the case where it was
205 		 * allocated but not called (see _relocate_lmc()).
206 		 */
207 		if (lml->lm_rti)
208 			free(lml->lm_rti);
209 		if (lml->lm_fpavl) {
210 			/*
211 			 * As we are freeing the link-map list, all nodes must
212 			 * have previously been removed.
213 			 */
214 			ASSERT(avl_numnodes(lml->lm_fpavl) == 0);
215 			free(lml->lm_fpavl);
216 		}
217 		list_delete(&dynlm_list, lml);
218 		free(lml);
219 	}
220 }
221 
222 /*
223  * Remove a link-map.  This removes a link-map from its associated list and
224  * free's up the link-map itself.  Note, all components that are freed are local
225  * to the link-map, no inter-link-map lists are operated on as these are all
226  * broken down by dlclose() while all objects are still mapped.
227  *
228  * This routine is called from dlclose() to zap individual link-maps after their
229  * interdependencies (DEPENDS(), CALLER(), handles, etc.) have been removed.
230  * This routine is also called from the bowels of load_one() in the case of a
231  * link-map creation failure.
232  */
233 void
234 remove_so(Lm_list *lml, Rt_map *lmp)
235 {
236 	Dyninfo *dip;
237 
238 	if (lmp == 0)
239 		return;
240 
241 	/*
242 	 * Unlink the link map from the link-map list.
243 	 */
244 	if (lml && lmp)
245 		lm_delete(lml, lmp);
246 
247 	/*
248 	 * If this object contributed any local external vectors for the current
249 	 * link-map list, remove the vectors.  If this object contributed any
250 	 * global external vectors we should find some new candidates, or leave
251 	 * this object lying around.
252 	 */
253 	if (lml) {
254 		int	tag;
255 
256 		for (tag = 0; tag < CI_MAX; tag++) {
257 			if (lml->lm_lcs[tag].lc_lmp == lmp) {
258 				lml->lm_lcs[tag].lc_lmp = 0;
259 				lml->lm_lcs[tag].lc_un.lc_val = 0;
260 			}
261 			if (glcs[tag].lc_lmp == lmp) {
262 				ASSERT(glcs[tag].lc_lmp != 0);
263 				glcs[tag].lc_lmp = 0;
264 				glcs[tag].lc_un.lc_val = 0;
265 			}
266 		}
267 	}
268 
269 	DBG_CALL(Dbg_file_delete(lmp));
270 
271 	/*
272 	 * If this is a temporary link-map, put in place to facilitate the
273 	 * link-edit or a relocatable object, then the link-map contains no
274 	 * information that needs to be cleaned up.
275 	 */
276 	if (FLAGS(lmp) & FLG_RT_OBJECT)
277 		return;
278 
279 	/*
280 	 * Unmap the object.
281 	 */
282 	LM_UNMAP_SO(lmp)(lmp);
283 
284 	/*
285 	 * Remove any FullpathNode AVL names if they still exist.
286 	 */
287 	if (FPNODE(lmp))
288 		fpavl_remove(lmp);
289 
290 	/*
291 	 * Remove any alias names.
292 	 */
293 	if (ALIAS(lmp)) {
294 		Aliste	idx;
295 		char	*cp;
296 
297 		for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp))
298 			free(cp);
299 		free(ALIAS(lmp));
300 	}
301 
302 	/*
303 	 * Remove any of this objects filtee infrastructure.  The filtees them-
304 	 * selves have already been removed.
305 	 */
306 	if (((dip = DYNINFO(lmp)) != 0) && (FLAGS1(lmp) & MSK_RT_FILTER)) {
307 		uint_t	cnt, max = DYNINFOCNT(lmp);
308 
309 		for (cnt = 0; cnt < max; cnt++, dip++) {
310 			if (dip->di_info && (dip->di_flags & MSK_DI_FILTER))
311 				remove_pnode((Pnode *)dip->di_info);
312 		}
313 	}
314 	if (dip)
315 		free(DYNINFO(lmp));
316 
317 	/*
318 	 * Deallocate any remaining cruft and free the link-map.
319 	 */
320 	if (RLIST(lmp))
321 		remove_pnode(RLIST(lmp));
322 
323 	if (REFNAME(lmp))
324 		free(REFNAME(lmp));
325 	if (ELFPRV(lmp))
326 		free(ELFPRV(lmp));
327 	if (AUDITORS(lmp))
328 		audit_desc_cleanup(lmp);
329 	if (AUDINFO(lmp))
330 		audit_info_cleanup(lmp);
331 
332 	if (CONDVAR(lmp))
333 		free(CONDVAR(lmp));
334 	/*
335 	 * Note that COPY_R() and COPY_S() reference the same memory
336 	 * location, and that we want to release the memory referenced
337 	 * without regard to which list it logically belongs to. We can
338 	 * use either pointer to do this.
339 	 */
340 	if (COPY_R(lmp))
341 		free(COPY_R(lmp));
342 	if (MMAPS(lmp))
343 		free(MMAPS(lmp));
344 
345 	/*
346 	 * During a dlclose() any groups this object was a part of will have
347 	 * been torn down.  However, we can get here to remove an object that
348 	 * has failed to load, perhaps because its addition to a handle failed.
349 	 * Therefore if this object indicates that its part of a group tear
350 	 * these associations down.
351 	 */
352 	if (GROUPS(lmp) != NULL) {
353 		Aliste	idx1;
354 		Grp_hdl	*ghp;
355 
356 		for (APLIST_TRAVERSE(GROUPS(lmp), idx1, ghp)) {
357 			Grp_desc	*gdp;
358 			Aliste		idx2;
359 
360 			for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
361 				if (gdp->gd_depend != lmp)
362 					continue;
363 
364 				alist_delete(ghp->gh_depends, &idx2);
365 				break;
366 			}
367 		}
368 		free(GROUPS(lmp));
369 	}
370 	if (HANDLES(lmp))
371 		free(HANDLES(lmp));
372 
373 	/*
374 	 * Clean up reglist if needed
375 	 */
376 	if (reglist != (Reglist *)0) {
377 		Reglist	*cur, *prv, *del;
378 
379 		cur = prv = reglist;
380 		while (cur != (Reglist *)0) {
381 			if (cur->rl_lmp == lmp) {
382 				del = cur;
383 				if (cur == reglist) {
384 					reglist = cur->rl_next;
385 					cur = prv = reglist;
386 				} else {
387 					prv->rl_next = cur->rl_next;
388 					cur = cur->rl_next;
389 				}
390 				free(del);
391 			} else {
392 				prv = cur;
393 				cur = cur->rl_next;
394 			}
395 		}
396 	}
397 
398 	/*
399 	 * Finally, free the various names, as these were duplicated so that
400 	 * they were available in core files.  This is left until last, to aid
401 	 * debugging previous elements of the removal process.
402 	 *
403 	 * The original name is set to the pathname by default (see fullpath()),
404 	 * but is overridden if the file is an alternative.  The pathname is set
405 	 * to the name by default (see [aout|elf]_new_lm()), but is overridden
406 	 * if the fullpath/resolve path differs (see fullpath()).  The original
407 	 * name is always duplicated, as it typically exists as a text string
408 	 * (see DT_NEEDED pointer) or was passed in from user code.
409 	 */
410 	if (ORIGNAME(lmp) != PATHNAME(lmp))
411 		free(ORIGNAME(lmp));
412 	if (PATHNAME(lmp) != NAME(lmp))
413 		free(PATHNAME(lmp));
414 	free(NAME(lmp));
415 
416 	free(lmp);
417 }
418 
419 
420 /*
421  * Traverse an objects dependency list removing callers and dependencies.
422  * There's a chicken and egg problem with tearing down link-maps.  Any
423  * relationship between link-maps is maintained on a DEPENDS, and associated
424  * CALLERS list.  These lists can't be broken down at the time a single link-
425  * map is removed as any related link-map may have already been removed.  Thus,
426  * lists between link-maps must be broken down before the individual link-maps
427  * themselves.
428  */
429 void
430 remove_lists(Rt_map *lmp, int lazy)
431 {
432 	Aliste		idx1;
433 	Bnd_desc	*bdp;
434 
435 	/*
436 	 * First, traverse this objects dependencies.
437 	 */
438 	for (APLIST_TRAVERSE(DEPENDS(lmp), idx1, bdp)) {
439 		Rt_map		*dlmp = bdp->b_depend;
440 
441 		/*
442 		 * Remove this object from the dependencies callers.
443 		 */
444 		(void) aplist_delete_value(CALLERS(dlmp), bdp);
445 		free(bdp);
446 	}
447 	if (DEPENDS(lmp)) {
448 		free(DEPENDS(lmp));
449 		DEPENDS(lmp) = NULL;
450 	}
451 
452 	/*
453 	 * Second, traverse this objects callers.
454 	 */
455 	for (APLIST_TRAVERSE(CALLERS(lmp), idx1,  bdp)) {
456 		Rt_map		*clmp = bdp->b_caller;
457 
458 		/*
459 		 * If we're removing an object that was triggered by a lazyload,
460 		 * remove the callers DYNINFO() entry and bump the lazy counts.
461 		 * This reinitialization of the lazy information allows a lazy
462 		 * object to be reloaded again later.  Although we may be
463 		 * breaking down a group of lazyloaded objects because one has
464 		 * failed to relocate, it's possible that one or more of the
465 		 * individual objects can be reloaded without a problem.
466 		 */
467 		if (lazy) {
468 			Dyninfo	*dip;
469 
470 			if ((dip = DYNINFO(clmp)) != 0) {
471 				uint_t	cnt, max = DYNINFOCNT(clmp);
472 
473 				for (cnt = 0; cnt < max; cnt++, dip++) {
474 					if ((dip->di_flags &
475 					    FLG_DI_NEEDED) == 0)
476 						continue;
477 
478 					if (dip->di_info == (void *)lmp) {
479 						dip->di_info = 0;
480 
481 						if (LAZY(clmp)++ == 0)
482 							LIST(clmp)->lm_lazy++;
483 					}
484 				}
485 			}
486 		}
487 
488 		(void) aplist_delete_value(DEPENDS(clmp), bdp);
489 		free(bdp);
490 	}
491 	if (CALLERS(lmp)) {
492 		free(CALLERS(lmp));
493 		CALLERS(lmp) = NULL;
494 	}
495 }
496 
497 /*
498  * Delete any temporary link-map control list.
499  */
500 void
501 remove_cntl(Lm_list *lml, Aliste lmco)
502 {
503 	if (lmco && (lmco != ALIST_OFF_DATA)) {
504 		Aliste	_lmco = lmco;
505 #if	DEBUG
506 		Lm_cntl	*lmc;
507 
508 		lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, lmco);
509 
510 		/*
511 		 * This element should be empty.
512 		 */
513 		ASSERT(lmc->lc_head == 0);
514 #endif
515 		alist_delete_by_offset(lml->lm_lists, &_lmco);
516 	}
517 }
518 
519 /*
520  * If a lazy loaded object, or filtee fails to load, possibly because it, or
521  * one of its dependencies can't be relocated, then tear down any objects
522  * that are apart of this link-map control list.
523  */
524 void
525 remove_incomplete(Lm_list *lml, Aliste lmco)
526 {
527 	Rt_map	*lmp;
528 	Lm_cntl	*lmc;
529 
530 	/* LINTED */
531 	lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, lmco);
532 
533 	/*
534 	 * First, remove any lists that may point between objects.
535 	 */
536 	for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp))
537 		remove_lists(lmp, 1);
538 
539 	/*
540 	 * Finally, remove each object.  remove_so() calls lm_delete(), thus
541 	 * effectively the link-map control head gets updated to point to the
542 	 * next link-map.
543 	 */
544 	while ((lmp = lmc->lc_head) != 0)
545 		remove_so(lml, lmp);
546 
547 	lmc->lc_head = lmc->lc_tail = 0;
548 }
549 
550 /*
551  * Determine whether an object is deletable.
552  */
553 static int
554 is_deletable(APlist **lmalp, APlist **ghalp, Rt_map *lmp)
555 {
556 	Aliste		idx;
557 	Bnd_desc	*bdp;
558 	Grp_hdl		*ghp;
559 
560 	/*
561 	 * If the object hasn't yet been relocated take this as a sign that
562 	 * it's loading failed, thus we're here to cleanup.  If the object is
563 	 * relocated it will only be retained if it was marked non-deletable,
564 	 * and exists on the main link-map control list.
565 	 */
566 	if ((FLAGS(lmp) & FLG_RT_RELOCED) &&
567 	    (MODE(lmp) & RTLD_NODELETE) && (CNTL(lmp) == ALIST_OFF_DATA))
568 		return (0);
569 
570 	/*
571 	 * If this object is the head of a handle that has not been captured as
572 	 * a candidate for deletion, then this object is in use from a dlopen()
573 	 * outside of the scope of this dlclose() family.  Dlopen'ed objects,
574 	 * and filtees, have group descriptors for their callers.  Typically
575 	 * this parent will have callers that are not apart of this dlclose()
576 	 * family, and thus would be caught by the CALLERS test below.  However,
577 	 * if the caller had itself been dlopen'ed, it may not have any explicit
578 	 * callers registered for itself.  Thus, but looking for objects with
579 	 * handles we can ferret out these outsiders.
580 	 */
581 	for (APLIST_TRAVERSE(HANDLES(lmp), idx, ghp)) {
582 		if (aplist_test(ghalp, ghp, 0) != ALE_EXISTS)
583 			return (0);
584 	}
585 
586 	/*
587 	 * If this object is called by any object outside of the family of
588 	 * objects selected for deletion, it can't be deleted.
589 	 */
590 	for (APLIST_TRAVERSE(CALLERS(lmp), idx, bdp)) {
591 		if (aplist_test(lmalp, bdp->b_caller, 0) !=
592 		    ALE_EXISTS)
593 			return (0);
594 	}
595 
596 	/*
597 	 * This object is a candidate for deletion.
598 	 */
599 	return (1);
600 }
601 
602 /*
603  * Collect the groups (handles) and associated objects that are candidates for
604  * deletion.  The criteria for deleting an object is whether it is only refer-
605  * enced from the objects within the groups that are candidates for deletion.
606  */
607 static int
608 gdp_collect(APlist **ghalpp, APlist **lmalpp, Grp_hdl *ghp1)
609 {
610 	Aliste		idx;
611 	Grp_desc	*gdp;
612 	int		action;
613 
614 	/*
615 	 * Add this group to our group collection.  If it isn't added either an
616 	 * allocation has failed, or it already exists.
617 	 */
618 	if ((action = aplist_test(ghalpp, ghp1, AL_CNT_GRPCLCT)) !=
619 	    ALE_CREATE)
620 		return (action);
621 
622 	/*
623 	 * Traverse the dependencies of the group and collect the associated
624 	 * objects.
625 	 */
626 	for (ALIST_TRAVERSE(ghp1->gh_depends, idx, gdp)) {
627 		Rt_map	*lmp = gdp->gd_depend;
628 
629 		/*
630 		 * We only want to process dependencies for deletion.  Although
631 		 * we want to purge group descriptors for parents, we don't want
632 		 * to analyze the parent itself for additional filters or
633 		 * deletion.
634 		 */
635 		if ((gdp->gd_flags & GPD_PARENT) ||
636 		    ((gdp->gd_flags & GPD_ADDEPS) == 0))
637 			continue;
638 
639 		if ((action = aplist_test(lmalpp, lmp, AL_CNT_GRPCLCT)) ==
640 		    ALE_ALLOCFAIL)
641 			return (0);
642 		if (action == ALE_EXISTS)
643 			continue;
644 
645 		/*
646 		 * If this object is a candidate for deletion, determine if the
647 		 * object provides any filtees.  If so, the filter groups are
648 		 * added to the group collection.
649 		 *
650 		 * An object is a candidate for deletion if:
651 		 *
652 		 *  .	the object hasn't yet been relocated, in which case
653 		 *	we're here to clean up a failed load, or
654 		 *  .	the object doesn't reside on the base link-map control
655 		 *	list, in which case a group of objects, typically
656 		 *	lazily loaded, or filtees, need cleaning up, or
657 		 *  .   the object isn't tagged as non-deletable.
658 		 */
659 		if ((((FLAGS(lmp) & FLG_RT_RELOCED) == 0) ||
660 		    (CNTL(lmp) != ALIST_OFF_DATA) ||
661 		    ((MODE(lmp) & RTLD_NODELETE) == 0)) &&
662 		    (FLAGS1(lmp) & MSK_RT_FILTER)) {
663 			Dyninfo	*dip = DYNINFO(lmp);
664 			uint_t	cnt, max = DYNINFOCNT(lmp);
665 
666 			for (cnt = 0; cnt < max; cnt++, dip++) {
667 				Pnode	*pnp;
668 
669 				if ((dip->di_info == 0) ||
670 				    ((dip->di_flags & MSK_DI_FILTER) == 0))
671 					continue;
672 
673 				for (pnp = (Pnode *)dip->di_info; pnp;
674 				    pnp = pnp->p_next) {
675 					Grp_hdl	*ghp2;
676 
677 					if ((pnp->p_len == 0) || ((ghp2 =
678 					    (Grp_hdl *)pnp->p_info) == 0))
679 						continue;
680 
681 					if (gdp_collect(ghalpp, lmalpp,
682 					    ghp2) == 0)
683 						return (0);
684 				}
685 			}
686 		}
687 	}
688 	return (1);
689 }
690 
691 /*
692  * Traverse the list of deletable candidates.  If an object can't be deleted
693  * then neither can its dependencies or filtees.  Any object that is cleared
694  * from being deleted drops the deletion count, plus, if there are no longer
695  * any deletions pending we can discontinue any further processing.
696  */
697 static int
698 remove_rescan(APlist *lmalp, APlist *ghalp, int *delcnt)
699 {
700 	Aliste		idx1;
701 	Rt_map		*lmp;
702 	int		rescan = 0;
703 
704 	for (APLIST_TRAVERSE(lmalp, idx1, lmp)) {
705 		Aliste		idx2;
706 		Bnd_desc	*bdp;
707 		Dyninfo		*dip;
708 		uint_t		cnt, max;
709 
710 		if (FLAGS(lmp) & FLG_RT_DELETE)
711 			continue;
712 
713 		/*
714 		 * As this object can't be deleted, make sure its dependencies
715 		 * aren't deleted either.
716 		 */
717 		for (APLIST_TRAVERSE(DEPENDS(lmp), idx2, bdp)) {
718 			Rt_map	*dlmp = bdp->b_depend;
719 
720 			if (FLAGS(dlmp) & FLG_RT_DELETE) {
721 				FLAGS(dlmp) &= ~FLG_RT_DELETE;
722 				if (--(*delcnt) == 0)
723 					return (0);
724 				rescan = 1;
725 			}
726 		}
727 
728 		/*
729 		 * If this object is a filtee and one of its filters is outside
730 		 * of this dlclose family, then it can't be deleted either.
731 		 */
732 		if ((FLAGS1(lmp) & MSK_RT_FILTER) == 0)
733 			continue;
734 
735 		dip = DYNINFO(lmp);
736 		max = DYNINFOCNT(lmp);
737 
738 		for (cnt = 0; cnt < max; cnt++, dip++) {
739 			Pnode	*pnp;
740 
741 			if ((dip->di_info == 0) ||
742 			    ((dip->di_flags & MSK_DI_FILTER) == 0))
743 				continue;
744 
745 			for (pnp = (Pnode *)dip->di_info; pnp;
746 			    pnp = pnp->p_next) {
747 				Grp_hdl		*ghp;
748 				Grp_desc	*gdp;
749 
750 				if ((pnp->p_len == 0) ||
751 				    ((ghp = (Grp_hdl *)pnp->p_info) == 0))
752 					continue;
753 
754 				if (aplist_test(&ghalp, ghp, 0) ==
755 				    ALE_EXISTS)
756 					continue;
757 
758 				for (ALIST_TRAVERSE(ghp->gh_depends, idx2,
759 				    gdp)) {
760 					Rt_map	*dlmp = gdp->gd_depend;
761 
762 					if (FLAGS(dlmp) & FLG_RT_DELETE) {
763 						FLAGS(dlmp) &= ~FLG_RT_DELETE;
764 						if (--(*delcnt) == 0)
765 							return (0);
766 						rescan = 1;
767 					}
768 				}
769 
770 				/*
771 				 * Remove this group handle from our dynamic
772 				 * deletion list.
773 				 */
774 				(void) aplist_delete_value(ghalp, ghp);
775 			}
776 		}
777 	}
778 	return (rescan);
779 }
780 
781 /*
782  * Cleanup any collection alists we've created.
783  */
784 static void
785 remove_collect(APlist *ghalp, APlist *lmalp)
786 {
787 	if (ghalp)
788 		free(ghalp);
789 	if (lmalp)
790 		free(lmalp);
791 }
792 
793 /*
794  * Remove a handle, leaving the associated objects intact.  Besides the classic
795  * dlopen() usage, handles are used as a means of associating a group of objects
796  * and promoting modes.  Once object promotion is completed, the handle should
797  * be discarded while leaving the associated objects intact.  Leaving the handle
798  * would prevent the object from being deleted (as it looks like it's in use
799  * by another user).
800  */
801 void
802 free_hdl(Grp_hdl *ghp, Rt_map *clmp, uint_t cdflags)
803 {
804 	Grp_desc	*gdp;
805 	Aliste		idx;
806 
807 	if (--(ghp->gh_refcnt) == 0) {
808 		uintptr_t	ndx;
809 
810 		for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {
811 			Rt_map	*lmp = gdp->gd_depend;
812 
813 			if (ghp->gh_ownlmp == lmp)
814 				(void) aplist_delete_value(HANDLES(lmp), ghp);
815 			(void) aplist_delete_value(GROUPS(lmp), ghp);
816 		}
817 		(void) free(ghp->gh_depends);
818 
819 		/* LINTED */
820 		ndx = (uintptr_t)ghp % HDLIST_SZ;
821 		list_delete(&hdl_list[ndx], ghp);
822 
823 		(void) free(ghp);
824 
825 	} else if (clmp) {
826 		/*
827 		 * It's possible that an RTLD_NOW promotion (via GPD_PROMOTE)
828 		 * has associated a caller with a handle that is already in use.
829 		 * In this case, find the caller and either remove the caller
830 		 * from the handle, or if the caller is used for any other
831 		 * reason, clear the promotion flag.
832 		 */
833 		for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {
834 			Rt_map	*lmp = gdp->gd_depend;
835 
836 			if (lmp != clmp)
837 				continue;
838 
839 			if (gdp->gd_flags == cdflags) {
840 				alist_delete(ghp->gh_depends, &idx);
841 				(void) aplist_delete_value(GROUPS(lmp), ghp);
842 			} else {
843 				gdp->gd_flags &= ~cdflags;
844 			}
845 			return;
846 		}
847 	}
848 }
849 
850 /*
851  * If a load operation, using a new link-map control list, has failed, then
852  * forcibly remove the failed objects.  This failure can occur as a result
853  * of a lazy load, a dlopen(), or a filtee load, once the application is
854  * running.  If the link-map control list has not yet started relocation, then
855  * cleanup is simply a process of removing all the objects from the control
856  * list.  If relocation has begun, then other loads may have been triggered to
857  * satisfy the relocations, and thus we need to break down the control list
858  * using handles.
859  *
860  * The objects associated with this load must be part of a unique handle.  In
861  * the case of a dlopen() or filtee request, a handle will have been created.
862  * For a lazyload request, a handle must be generated so that the remove
863  * process can use the handle.
864  *
865  * During the course of processing these objects, other objects (handles) may
866  * have been loaded to satisfy relocation requirements.  After these families
867  * have successfully loaded, they will have been propagated to the same link-map
868  * control list.  The failed objects need to be removed from this list, while
869  * any successfully loaded families can be left alone, and propagated to the
870  * previous link-map control list.  By associating each load request with a
871  * handle, we can isolate the failed objects while not interfering with any
872  * successfully loaded families.
873  */
874 void
875 remove_lmc(Lm_list *lml, Rt_map *clmp, Lm_cntl *lmc, Aliste lmco,
876     const char *name)
877 {
878 	Grp_hdl		*ghp;
879 	Grp_desc	*gdp;
880 	Aliste		idx;
881 	Rt_map		*lmp;
882 
883 	DBG_CALL(Dbg_file_cleanup(lml, name, lmco));
884 
885 	/*
886 	 * Obtain a handle for the first object on the link-map control list.
887 	 * If none exists (which would occur from a lazy load request), and
888 	 * the link-map control list is being relocated, create a handle.
889 	 */
890 	lmp = lmc->lc_head;
891 	if (HANDLES(lmp)) {
892 		ghp = (Grp_hdl *)HANDLES(lmp)->apl_data[0];
893 
894 	} else if (lmc->lc_flags & LMC_FLG_RELOCATING) {
895 		/*
896 		 * Establish a handle, and should anything fail, fall through
897 		 * to remove the link-map control list.
898 		 */
899 		if (((ghp =
900 		    hdl_create(lml, lmc->lc_head, 0, 0, GPD_ADDEPS, 0)) == 0) ||
901 		    (hdl_initialize(ghp, lmc->lc_head, 0, 0) == 0))
902 			lmc->lc_flags &= ~LMC_FLG_RELOCATING;
903 	} else {
904 		ghp = 0;
905 	}
906 
907 	/*
908 	 * If relocation hasn't begun, simply remove all the objects from this
909 	 * list, and any handle that may have been created.
910 	 */
911 	if ((lmc->lc_flags & LMC_FLG_RELOCATING) == 0) {
912 		remove_incomplete(lml, lmco);
913 
914 		if (ghp) {
915 			ghp->gh_refcnt = 1;
916 			free_hdl(ghp, 0, 0);
917 		}
918 		return;
919 	}
920 
921 	ASSERT(ghp != 0);
922 
923 	/*
924 	 * As the objects of this handle are being forcibly removed, first
925 	 * remove any associations to objects on parent link-map control
926 	 * lists.  This breaks the bond between a caller and a hierarchy of
927 	 * dependencies represented by the handle, thus the caller doesn't lock
928 	 * the hierarchy and prevent their deletion from the generic handle
929 	 * processing or remove_hdl().
930 	 *
931 	 * This scenario can be produced when the relocation of a object
932 	 * results in vectoring through a filter that is already loaded.  The
933 	 * filtee may be on the link-map list that is presently being processed,
934 	 * however an association between the filter and filtee would have been
935 	 * established during filtee processing.  It is this association that
936 	 * must be broken to allow the objects on this link-map list to be
937 	 * removed.
938 	 */
939 	for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {
940 		Rt_map	*lmp = gdp->gd_depend;
941 
942 		/*
943 		 * If this object has not been relocated, break down any
944 		 * dependency relationships the object might have established.
945 		 */
946 		if ((FLAGS(lmp) & FLG_RT_RELOCED) == 0)
947 			remove_lists(lmp, 1);
948 
949 		if (CNTL(lmp) == lmco)
950 			continue;
951 
952 		if (gdp->gd_flags & GPD_FILTER) {
953 			Dyninfo	*dip = DYNINFO(lmp);
954 			uint_t	cnt, max = DYNINFOCNT(lmp);
955 
956 			for (cnt = 0; cnt < max; cnt++, dip++) {
957 				Pnode	*pnp;
958 
959 				if ((dip->di_info == 0) ||
960 				    ((dip->di_flags & MSK_DI_FILTER) == 0))
961 					continue;
962 
963 				for (pnp = (Pnode *)dip->di_info; pnp;
964 				    pnp = pnp->p_next) {
965 					if ((Grp_hdl *)pnp->p_info == ghp) {
966 						pnp->p_info = 0;
967 						break;
968 					}
969 				}
970 			}
971 		}
972 		(void) aplist_delete_value(GROUPS(lmp), ghp);
973 		alist_delete(ghp->gh_depends, &idx);
974 	}
975 
976 	/*
977 	 * Having removed any callers, set the group handle reference count to
978 	 * one, and let the generic handle remover delete the associated
979 	 * objects.
980 	 */
981 	ghp->gh_refcnt = 1;
982 	(void) remove_hdl(ghp, clmp, 0);
983 
984 	/*
985 	 * If this link-map control list still contains objects, determine the
986 	 * previous control list and move the objects.
987 	 */
988 	if (lmc->lc_head) {
989 		Lm_cntl *plmc;
990 		Aliste  plmco;
991 
992 		plmco = lmco - lml->lm_lists->al_size;
993 		/* LINTED */
994 		plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco);
995 
996 		lm_move(lml, lmco, plmco, lmc, plmc);
997 	}
998 }
999 
1000 /*
1001  * Remove the objects associated with a handle.  There are two goals here, to
1002  * delete the objects associated with the handle, and to remove the handle
1003  * itself.  Things get a little more complex if the objects selected for
1004  * deletion are filters, in this case we also need to collect their filtees,
1005  * and process the combined groups as a whole.  But, care still must be exer-
1006  * cised to make sure any filtees found aren't being used by filters outside of
1007  * the groups we've collect.  The series of events is basically:
1008  *
1009  *  o	Determine the groups (handles) that might be deletable.
1010  *
1011  *  o	Determine the objects of these handles that can be deleted.
1012  *
1013  *  o	Fire the fini's of those objects selected for deletion.
1014  *
1015  *  o	Remove all inter-dependency linked lists while the objects link-maps
1016  *	are still available.
1017  *
1018  *  o	Remove all deletable objects link-maps and unmap the objects themselves.
1019  *
1020  *  o	Remove the handle descriptors for each deleted object, and hopefully
1021  *	the whole handle.
1022  *
1023  * An handle that can't be deleted is added to an orphans list.  This list is
1024  * revisited any time another dlclose() request results in handle descriptors
1025  * being deleted.  These deleted descriptors can be sufficient to allow the
1026  * final deletion of the orphaned handles.
1027  */
1028 int
1029 remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed)
1030 {
1031 	Rt_map		*lmp;
1032 	int		rescan = 0;
1033 	int		delcnt = 0, rmcnt = 0, error = 0, orphans;
1034 	APlist		*lmalp = NULL, *ghalp = NULL;
1035 	Aliste		idx1, idx2;
1036 	Grp_hdl		*ghp2;
1037 	Grp_desc	*gdp;
1038 	Lm_list		*lml = NULL;
1039 
1040 	/*
1041 	 * Generate the family of groups and objects that are candidates for
1042 	 * deletion.  This consists of the objects that are explicitly defined
1043 	 * as dependencies of this handle, plus any filtee handles and their
1044 	 * associated objects.
1045 	 */
1046 	if (gdp_collect(&ghalp, &lmalp, ghp) == 0) {
1047 		remove_collect(ghalp, lmalp);
1048 		return (0);
1049 	}
1050 
1051 	DBG_CALL(Dbg_file_hdl_title(DBG_HDL_DELETE));
1052 
1053 	/*
1054 	 * Traverse the groups we've collected to determine if any filtees are
1055 	 * included.  If so, and the filtee handle is in use by a filter outside
1056 	 * of the family of objects collected for this deletion, it can not be
1057 	 * removed.
1058 	 */
1059 	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) {
1060 		Grp_hdl	*ghp = ghp2;
1061 
1062 		DBG_CALL(Dbg_file_hdl_collect(ghp, 0));
1063 
1064 		if ((ghp->gh_flags & GPH_FILTEE) == 0)
1065 			continue;
1066 
1067 		/*
1068 		 * Special case for ld.so.1.  There can be multiple instances of
1069 		 * libdl.so.1 using this handle, so although we want the handles
1070 		 * reference count to be decremented, we don't want the handle
1071 		 * removed.
1072 		 */
1073 		if (ghp->gh_flags & GPH_LDSO) {
1074 			DBG_CALL(Dbg_file_hdl_collect(ghp,
1075 			    NAME(lml_rtld.lm_head)));
1076 			aplist_delete(ghalp, &idx1);
1077 			continue;
1078 		}
1079 
1080 		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
1081 			Grp_hdl	*ghp3;
1082 			Aliste	idx3;
1083 
1084 			/*
1085 			 * Determine whether this dependency is the filtee's
1086 			 * parent filter, and that it isn't also an explicit
1087 			 * dependency (in which case it would have added its own
1088 			 * dependencies to the handle).
1089 			 */
1090 			if ((gdp->gd_flags &
1091 			    (GPD_FILTER | GPD_ADDEPS)) != GPD_FILTER)
1092 				continue;
1093 
1094 			if (aplist_test(&lmalp, gdp->gd_depend, 0) ==
1095 			    ALE_EXISTS)
1096 				continue;
1097 
1098 			/*
1099 			 * Remove this group handle from our dynamic deletion
1100 			 * list.  In addition, recompute the list of objects
1101 			 * that are candidates for deletion to continue this
1102 			 * group verification.
1103 			 */
1104 			DBG_CALL(Dbg_file_hdl_collect(ghp,
1105 			    NAME(gdp->gd_depend)));
1106 			aplist_delete(ghalp, &idx1);
1107 
1108 			free(lmalp);
1109 			lmalp = NULL;
1110 			for (APLIST_TRAVERSE(ghalp, idx3, ghp3)) {
1111 				Aliste		idx4;
1112 				Grp_desc	*gdp4;
1113 
1114 				for (ALIST_TRAVERSE(ghp3->gh_depends,
1115 				    idx4, gdp4))  {
1116 					if ((gdp4->gd_flags & GPD_ADDEPS) == 0)
1117 						continue;
1118 					if (aplist_test(&lmalp, gdp4->gd_depend,
1119 					    AL_CNT_GRPCLCT) == ALE_ALLOCFAIL) {
1120 						remove_collect(ghalp, lmalp);
1121 						return (0);
1122 					}
1123 				}
1124 			}
1125 			break;
1126 		}
1127 	}
1128 
1129 	/*
1130 	 * Now that we've collected all the handles dependencies, traverse the
1131 	 * collection determining whether they are a candidate for deletion.
1132 	 */
1133 	for (APLIST_TRAVERSE(lmalp, idx1, lmp)) {
1134 		/*
1135 		 * Establish which link-map list we're dealing with for later
1136 		 * .fini processing.
1137 		 */
1138 		if (lml == 0)
1139 			lml = LIST(lmp);
1140 
1141 		/*
1142 		 * If an object isn't a candidate for deletion we'll have to
1143 		 * rescan the handle insuring that this objects dependencies
1144 		 * aren't deleted either.
1145 		 */
1146 		if (is_deletable(&lmalp, &ghalp, lmp)) {
1147 			FLAGS(lmp) |= FLG_RT_DELETE;
1148 			delcnt++;
1149 		} else
1150 			rescan = 1;
1151 	}
1152 
1153 	/*
1154 	 * Rescan the handle if any objects where found non-deletable.
1155 	 */
1156 	while (rescan)
1157 		rescan = remove_rescan(lmalp, ghalp, &delcnt);
1158 
1159 	/*
1160 	 * Now that we have determined the number of groups that are candidates
1161 	 * for removal, mark each group descriptor as a candidate for removal
1162 	 * from the group.
1163 	 */
1164 	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) {
1165 		for (ALIST_TRAVERSE(ghp2->gh_depends, idx2, gdp))
1166 			gdp->gd_flags |= GPD_REMOVE;
1167 	}
1168 
1169 	/*
1170 	 * Now that we know which objects on this handle can't be deleted
1171 	 * determine whether they still need to remain identified as belonging
1172 	 * to this group to be able to continue binding to one another.
1173 	 */
1174 	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) {
1175 		Grp_hdl	*ghp = ghp2;
1176 
1177 		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
1178 			Aliste		idx3;
1179 			Bnd_desc	*bdp;
1180 
1181 			lmp = gdp->gd_depend;
1182 
1183 			if (FLAGS(lmp) & FLG_RT_DELETE)
1184 				continue;
1185 
1186 			for (APLIST_TRAVERSE(DEPENDS(lmp), idx3, bdp)) {
1187 				Aliste 		idx4;
1188 				Grp_desc	*gdp4;
1189 				Rt_map		*dlmp = bdp->b_depend;
1190 
1191 				/*
1192 				 * If this dependency (dlmp) can be referenced
1193 				 * by the caller (clmp) without being part of
1194 				 * this group (ghp) then belonging to this group
1195 				 * is no longer necessary.  This can occur when
1196 				 * objects are part of multiple handles, or if a
1197 				 * previously deleted handle was moved to the
1198 				 * orphan list and has been reopened.  Note,
1199 				 * first make sure the caller can reference the
1200 				 * dependency with this group, if it can't we
1201 				 * must be bound to a filtee, so there's no need
1202 				 * to remain a part of this group either.
1203 				 */
1204 				if ((callable(lmp, dlmp, 0, 0) == 0) ||
1205 				    callable(lmp, dlmp, ghp, 0))
1206 					continue;
1207 
1208 				if (gdp->gd_flags & GPD_REMOVE)
1209 					gdp->gd_flags &= ~GPD_REMOVE;
1210 
1211 				for (ALIST_TRAVERSE(ghp->gh_depends,
1212 				    idx4, gdp4)) {
1213 					if (gdp4->gd_depend != dlmp)
1214 						continue;
1215 
1216 					if (gdp4->gd_flags & GPD_REMOVE)
1217 						gdp4->gd_flags &= ~GPD_REMOVE;
1218 				}
1219 			}
1220 		}
1221 	}
1222 
1223 	/*
1224 	 * If the owner of a handle can't be deleted and it's handle descriptor
1225 	 * must remain also, don't delete the handle at all.  Leave it for
1226 	 * possible later use.  Although it's left intact, it will still be
1227 	 * moved to the orphans list, as we might be able to revisit it on later
1228 	 * dlclose() operations and finally remove the underlying objects.  Note
1229 	 * that the handle still remains attached to the owner via the HANDLES
1230 	 * list, so that it can be re-associated to the owner if a dlopen()
1231 	 * of this object reoccurs.
1232 	 */
1233 	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) {
1234 		Grp_hdl	*ghp = ghp2;
1235 
1236 		/*
1237 		 * If this handle is already an orphan, or if it's owner is
1238 		 * deletable there's no need to inspect its dependencies.
1239 		 */
1240 		if ((ghp->gh_ownlmp == 0) ||
1241 		    (FLAGS(ghp->gh_ownlmp) & FLG_RT_DELETE))
1242 			continue;
1243 
1244 		/*
1245 		 * Make sure all handle dependencies aren't removed or the
1246 		 * dependencies themselves aren't deleted.
1247 		 */
1248 		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
1249 			lmp = gdp->gd_depend;
1250 
1251 			/*
1252 			 * The first dependency of a non-orphaned handle is the
1253 			 * owner.  If the handle descriptor for this isn't
1254 			 * required there's no need to look at any other of the
1255 			 * handles dependencies.
1256 			 */
1257 			if ((lmp == ghp->gh_ownlmp) &&
1258 			    (gdp->gd_flags & GPD_REMOVE))
1259 				break;
1260 
1261 			if (gdp->gd_flags & GPD_REMOVE)
1262 				gdp->gd_flags &= ~GPD_REMOVE;
1263 			if (FLAGS(lmp) & FLG_RT_DELETE) {
1264 				FLAGS(lmp) &= ~FLG_RT_DELETE;
1265 				delcnt--;
1266 			}
1267 		}
1268 	}
1269 
1270 	/*
1271 	 * Final scan of objects to see if any objects are to to be deleted.
1272 	 * Also - display diagnostic information on what operations are to be
1273 	 * performed on the collected handles before firing .fini's (which
1274 	 * produces additional diagnostics).
1275 	 */
1276 	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) {
1277 		Grp_hdl	*ghp = ghp2;
1278 
1279 		DBG_CALL(Dbg_file_hdl_title(DBG_HDL_DELETE));
1280 
1281 		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
1282 			int	flag;
1283 
1284 			lmp = gdp->gd_depend;
1285 
1286 			/*
1287 			 * Note, we must never delete a parent.  The parent
1288 			 * may already be tagged for deletion from a previous
1289 			 * dlclose(). That dlclose has triggered this dlclose(),
1290 			 * but the parents deletion is the responsibility of the
1291 			 * previous dlclose(), not this one.
1292 			 */
1293 			if ((FLAGS(lmp) & FLG_RT_DELETE) &&
1294 			    ((gdp->gd_flags & GPD_PARENT) == 0)) {
1295 				flag = DBG_DEP_DELETE;
1296 
1297 				/*
1298 				 * Remove any pathnames from the FullpathNode
1299 				 * AVL tree.  As we're about to fire .fini's,
1300 				 * it's possible this object will be required
1301 				 * again, in which case we want to make sure a
1302 				 * new version of the object gets loaded.
1303 				 */
1304 				if (FPNODE(lmp))
1305 					fpavl_remove(lmp);
1306 			} else if (gdp->gd_flags & GPD_REMOVE)
1307 				flag = DBG_DEP_REMOVE;
1308 			else
1309 				flag = DBG_DEP_REMAIN;
1310 
1311 			DBG_CALL(Dbg_file_hdl_action(ghp, lmp, flag, 0));
1312 		}
1313 	}
1314 
1315 	/*
1316 	 * If there are objects to be deleted process their .fini's.
1317 	 */
1318 	if (delcnt) {
1319 		Rt_map	**tobj;
1320 
1321 		/*
1322 		 * If we're being audited tell the audit library that we're
1323 		 * about to go deleting dependencies.
1324 		 */
1325 		if (clmp && ((LIST(clmp)->lm_tflags | FLAGS1(clmp)) &
1326 		    LML_TFLG_AUD_ACTIVITY))
1327 			audit_activity(clmp, LA_ACT_DELETE);
1328 
1329 		/*
1330 		 * Sort and fire all fini's of the objects selected for
1331 		 * deletion.  Note that we have to start our search from the
1332 		 * link-map head - there's no telling whether this object has
1333 		 * dependencies on objects that were loaded before it and which
1334 		 * can now be deleted.  If the tsort() fails because of an
1335 		 * allocation error then that might just be a symptom of why
1336 		 * we're here in the first place - forgo the fini's but
1337 		 * continue to try cleaning up.
1338 		 */
1339 		lml->lm_flags |= LML_FLG_OBJDELETED;
1340 
1341 		if (((tobj = tsort(lml->lm_head, delcnt,
1342 		    (RT_SORT_DELETE | RT_SORT_FWD))) != 0) &&
1343 		    (tobj != (Rt_map **)S_ERROR)) {
1344 			error = purge_exit_handlers(lml, tobj);
1345 			call_fini(lml, tobj);
1346 		}
1347 
1348 		/*
1349 		 * Audit the closure of the dlopen'ed object to any local
1350 		 * auditors.  Any global auditors would have been caught by
1351 		 * call_fini(), but as the link-maps CALLERS was removed
1352 		 * already we do the local auditors explicitly.
1353 		 */
1354 		for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) {
1355 			Grp_hdl	*ghp = ghp2;
1356 			Rt_map	*dlmp = ghp->gh_ownlmp;
1357 
1358 			if (clmp && dlmp &&
1359 			    ((LIST(dlmp)->lm_flags & LML_FLG_NOAUDIT) == 0) &&
1360 			    (FLAGS1(clmp) & LML_TFLG_AUD_OBJCLOSE))
1361 				_audit_objclose(&(AUDITORS(clmp)->ad_list),
1362 				    dlmp);
1363 		}
1364 	}
1365 
1366 	/*
1367 	 * Now that .fini processing (which may have involved new bindings)
1368 	 * is complete, remove all inter-dependency lists from those objects
1369 	 * selected for deletion.
1370 	 */
1371 	for (APLIST_TRAVERSE(lmalp, idx1, lmp)) {
1372 		Dyninfo	*dip;
1373 		uint_t	cnt, max;
1374 
1375 		if (FLAGS(lmp) & FLG_RT_DELETE)
1376 			remove_lists(lmp, 0);
1377 
1378 		/*
1379 		 * Determine whether we're dealing with a filter, and if so
1380 		 * process any inter-dependencies with its filtee's.
1381 		 */
1382 		if ((FLAGS1(lmp) & MSK_RT_FILTER) == 0)
1383 			continue;
1384 
1385 		dip = DYNINFO(lmp);
1386 		max = DYNINFOCNT(lmp);
1387 
1388 		for (cnt = 0; cnt < max; cnt++, dip++) {
1389 			Pnode	*pnp;
1390 
1391 			if ((dip->di_info == 0) ||
1392 			    ((dip->di_flags & MSK_DI_FILTER) == 0))
1393 				continue;
1394 
1395 			for (pnp = (Pnode *)dip->di_info; pnp;
1396 			    pnp = pnp->p_next) {
1397 				Grp_hdl	*ghp;
1398 
1399 				if ((pnp->p_len == 0) ||
1400 				    ((ghp = (Grp_hdl *)pnp->p_info) == 0))
1401 					continue;
1402 
1403 				/*
1404 				 * Determine whether this filtee's handle is a
1405 				 * part of the list of handles being deleted.
1406 				 */
1407 				if (aplist_test(&ghalp, ghp, 0) == ALE_EXISTS) {
1408 					/*
1409 					 * If this handle exists on the deletion
1410 					 * list, then it has been removed.  If
1411 					 * this filter isn't going to be
1412 					 * deleted, sever its reference to the
1413 					 * handle.
1414 					 */
1415 					pnp->p_info = 0;
1416 				} else {
1417 					/*
1418 					 * If this handle isn't on the deletion
1419 					 * list, then it must still exist.  If
1420 					 * this filter is being deleted, make
1421 					 * sure the filtees reference count
1422 					 * gets decremented.
1423 					 */
1424 					if ((FLAGS(lmp) & FLG_RT_DELETE) &&
1425 					    ((gdp->gd_flags &
1426 					    GPD_PARENT) == 0)) {
1427 						(void) dlclose_core(ghp,
1428 						    lmp, lml);
1429 					}
1430 				}
1431 			}
1432 		}
1433 	}
1434 
1435 	/*
1436 	 * If called from dlclose(), determine if there are already handles on
1437 	 * the orphans list that we can reinvestigate.
1438 	 */
1439 	if ((removed == 0) && hdl_list[HDLIST_ORP].head)
1440 		orphans = 1;
1441 	else
1442 		orphans = 0;
1443 
1444 	/*
1445 	 * Finally remove any handle infrastructure and remove any objects
1446 	 * marked for deletion.
1447 	 */
1448 	for (APLIST_TRAVERSE(ghalp, idx1, ghp2)) {
1449 		Grp_hdl	*ghp = ghp2;
1450 
1451 		/*
1452 		 * If we're not dealing with orphaned handles remove this handle
1453 		 * from its present handle list.
1454 		 */
1455 		if (removed == 0) {
1456 			uintptr_t ndx;
1457 
1458 			/* LINTED */
1459 			ndx = (uintptr_t)ghp % HDLIST_SZ;
1460 			list_delete(&hdl_list[ndx], ghp);
1461 		}
1462 
1463 		/*
1464 		 * Traverse each handle dependency.  Retain the dependencies
1465 		 * flags to insure we don't delete any parents (the flags
1466 		 * information is deleted as part of the alist removal that
1467 		 * occurs before we inspect the object for deletion).
1468 		 */
1469 		for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
1470 			uint_t	flags = gdp->gd_flags;
1471 
1472 			if ((flags & GPD_REMOVE) == 0)
1473 				continue;
1474 
1475 			lmp = gdp->gd_depend;
1476 			rmcnt++;
1477 
1478 			/*
1479 			 * If this object is the owner of the handle break that
1480 			 * association in case the handle is retained.
1481 			 */
1482 			if (ghp->gh_ownlmp == lmp) {
1483 				(void) aplist_delete_value(HANDLES(lmp), ghp);
1484 				ghp->gh_ownlmp = 0;
1485 			}
1486 
1487 			(void) aplist_delete_value(GROUPS(lmp), ghp);
1488 			alist_delete(ghp->gh_depends, &idx2);
1489 
1490 			/*
1491 			 * Complete the link-map deletion if appropriate.
1492 			 */
1493 			if ((FLAGS(lmp) & FLG_RT_DELETE) &&
1494 			    ((flags & GPD_PARENT) == 0)) {
1495 				tls_modaddrem(lmp, TM_FLG_MODREM);
1496 				remove_so(LIST(lmp), lmp);
1497 			}
1498 		}
1499 
1500 		/*
1501 		 * If we've deleted all the dependencies of the handle, finalize
1502 		 * the cleanup by removing the handle itself.
1503 		 *
1504 		 * Otherwise we're left with a handle containing one or more
1505 		 * objects that can not be deleted (they're in use by other
1506 		 * handles, non-deletable, etc.), but require to remain a part
1507 		 * of this group to allow them to continue binding to one
1508 		 * another.
1509 		 *
1510 		 * If the handles reference count is zero, or represents a
1511 		 * link-map list (dlopen(0)), then move that handle to the
1512 		 * orphans list.  Should another dlclose() operation occur that
1513 		 * results in the removal of handle descriptors, these orphan
1514 		 * handles are re-examined to determine if their deletion can
1515 		 * be completed.
1516 		 */
1517 		if (ghp->gh_depends->al_nitems == 0) {
1518 			free(ghp->gh_depends);
1519 			free(ghp);
1520 
1521 		} else if ((removed == 0) && (ghp->gh_refcnt == 0) &&
1522 		    ((ghp->gh_flags & GPH_ZERO) == 0)) {
1523 			/*
1524 			 * Move this handle to the orphans list.
1525 			 */
1526 			(void) list_append(&hdl_list[HDLIST_ORP], ghp);
1527 
1528 			if (DBG_ENABLED) {
1529 				DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ORPHAN));
1530 				for (ALIST_TRAVERSE(ghp->gh_depends, idx1, gdp))
1531 					DBG_CALL(Dbg_file_hdl_action(ghp,
1532 					    gdp->gd_depend, DBG_DEP_ORPHAN, 0));
1533 			}
1534 		}
1535 	}
1536 
1537 	/*
1538 	 * If no handle descriptors got removed there's no point in looking for
1539 	 * orphans to process.
1540 	 */
1541 	if (rmcnt == 0)
1542 		orphans = 0;
1543 
1544 	/*
1545 	 * Cleanup any alists we've created.
1546 	 */
1547 	remove_collect(ghalp, lmalp);
1548 
1549 	/*
1550 	 * If orphan processing isn't required we're done.  If our processing
1551 	 * originated from investigating orphans, return the number of handle
1552 	 * descriptors removed as an indication whether orphan processing
1553 	 * should continue.
1554 	 */
1555 	if (orphans == 0) {
1556 		if (removed)
1557 			*removed = rmcnt;
1558 		return (error);
1559 	}
1560 
1561 	/*
1562 	 * Traverse the orphans list as many times as necessary until no
1563 	 * handle removals occur.
1564 	 */
1565 	do {
1566 		List		list;
1567 		Listnode	*lnp;
1568 		Grp_hdl		*ghp, *oghp = 0;
1569 		int		title = 0;
1570 
1571 		/*
1572 		 * Effectively clean the HDLIST_ORP list.  Any object that can't
1573 		 * be removed will be re-added to the list.
1574 		 */
1575 		list = hdl_list[HDLIST_ORP];
1576 		hdl_list[HDLIST_ORP].head = hdl_list[HDLIST_ORP].tail = 0;
1577 
1578 		rescan = 0;
1579 		for (LIST_TRAVERSE(&list, lnp, ghp)) {
1580 			int	_error, _remove;
1581 
1582 			if (title++ == 0)
1583 				DBG_CALL(Dbg_file_del_rescan(ghp->gh_ownlml));
1584 
1585 			if (oghp) {
1586 				list_delete(&list, oghp);
1587 				oghp = 0;
1588 			}
1589 
1590 			if (((_error = remove_hdl(ghp, clmp, &_remove)) != 0) &&
1591 			    (error == 0))
1592 				error = _error;
1593 
1594 			if (_remove)
1595 				rescan++;
1596 
1597 			oghp = ghp;
1598 		}
1599 		if (oghp) {
1600 			list_delete(&list, oghp);
1601 			oghp = 0;
1602 		}
1603 
1604 	} while (rescan && hdl_list[HDLIST_ORP].head);
1605 
1606 	return (error);
1607 }
1608