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