usr/src/lib/libc/port/gen/atexit.c
author Jon Tibble <meths@btinternet.com>
Thu, 09 Dec 2010 22:32:39 +0100
changeset 13255 4afa820d78b9
parent 8009 cbee40410e7d
child 14083 d1349977b975
permissions -rw-r--r--
298 SPARC build fails in smt_pause.o 478 Build needs fixing for pkgdepend flag day Reviewed by: [email protected] Reviewed by: [email protected] Reviewed by: [email protected] Approved by: [email protected]
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
4570
f93b74ddbdd5 6559990 user-level read/write locks should be much faster
raf
parents: 1219
diff changeset
     5
 * Common Development and Distribution License (the "License").
f93b74ddbdd5 6559990 user-level read/write locks should be much faster
raf
parents: 1219
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
1219
f89f56c2d9ac 6362982 namespace pollution/protection in libc
raf
parents: 0
diff changeset
    21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
5891
0d5c6468bb04 6598890 cancellation code abuses synonyms
raf
parents: 4843
diff changeset
    23
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*	Copyright (c) 1988 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 6515
diff changeset
    30
#pragma weak _atexit = atexit
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 6515
diff changeset
    31
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 6515
diff changeset
    32
#include "lint.h"
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include "thr_uberdata.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include "libc_int.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include "atexit.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include "stdiom.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 * Note that memory is managed by lmalloc()/lfree().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 * Among other reasons, this is occasioned by the insistence of our
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 * brothers sh(1) and csh(1) that they can do malloc, etc., better than
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 * libc can.  Those programs define their own malloc routines, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 * initialize the underlying mechanism in main().  This means that calls
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 * to malloc occuring before main will crash.  The loader calls atexit(3C)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 * before calling main, so we'd better avoid malloc() when it does.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 * Another reason for using lmalloc()/lfree() is that the atexit()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 * list must transcend all link maps.  See the Linker and Libraries
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 * Guide for information on alternate link maps.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 * See "thr_uberdata.h" for the definitions of structures used here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
static int in_range(_exithdlr_func_t, Lc_addr_range_t[], uint_t count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
extern	caddr_t	_getfp(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 * exitfns_lock is declared to be a recursive mutex so that we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 * can hold it while calling out to the registered functions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
 * If they call back to us, we are self-consistent and everything
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
 * works, even the case of calling exit() from functions called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
 * by _exithandle() (recursive exit()).  All that is required is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 * that the registered functions actually return (no longjmp()s).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
 * Because exitfns_lock is declared to be a recursive mutex, we
5891
0d5c6468bb04 6598890 cancellation code abuses synonyms
raf
parents: 4843
diff changeset
    68
 * cannot use it with lmutex_lock()/lmutex_unlock() and we must
0d5c6468bb04 6598890 cancellation code abuses synonyms
raf
parents: 4843
diff changeset
    69
 * use mutex_lock()/mutex_unlock().  This means that atexit()
0d5c6468bb04 6598890 cancellation code abuses synonyms
raf
parents: 4843
diff changeset
    70
 * and exit() are not async-signal-safe.  We make them fork1-safe
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
 * via the atexit_locks()/atexit_unlocks() functions, called from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
 * libc_prepare_atfork()/libc_child_atfork()/libc_parent_atfork()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
 * atexit_locks() and atexit_unlocks() are called on every link map.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
 * Do not use curthread->ul_uberdata->atexit_root for these.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
atexit_locks()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
{
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
    82
	(void) mutex_lock(&__uberdata.atexit_root.exitfns_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
atexit_unlocks()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
{
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
    88
	(void) mutex_unlock(&__uberdata.atexit_root.exitfns_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 * atexit() is called before the primordial thread is fully set up.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
 * Be careful about dereferencing self->ul_uberdata->atexit_root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
int
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 6515
diff changeset
    96
atexit(void (*func)(void))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	ulwp_t *self;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
	atexit_root_t *arp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
	_exthdlr_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
	if ((p = lmalloc(sizeof (_exthdlr_t))) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
	if ((self = __curthread()) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
		arp = &__uberdata.atexit_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
		arp = &self->ul_uberdata->atexit_root;
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
   109
		(void) mutex_lock(&arp->exitfns_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
	p->hdlr = func;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
	p->next = arp->head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
	arp->head = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
	if (self != NULL)
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
   115
		(void) mutex_unlock(&arp->exitfns_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
_exithandle(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
	atexit_root_t *arp = &curthread->ul_uberdata->atexit_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	_exthdlr_t *p;
8009
cbee40410e7d 6767133 exit() is not cancel-safe
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents: 6812
diff changeset
   124
	int cancel_state;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
8009
cbee40410e7d 6767133 exit() is not cancel-safe
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents: 6812
diff changeset
   126
	/* disable cancellation while running atexit handlers */
cbee40410e7d 6767133 exit() is not cancel-safe
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents: 6812
diff changeset
   127
	(void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
   128
	(void) mutex_lock(&arp->exitfns_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
	arp->exit_frame_monitor = _getfp() + STACK_BIAS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
	p = arp->head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	while (p != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
		arp->head = p->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
		p->hdlr();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
		lfree(p, sizeof (_exthdlr_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
		p = arp->head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
	}
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
   137
	(void) mutex_unlock(&arp->exitfns_lock);
8009
cbee40410e7d 6767133 exit() is not cancel-safe
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents: 6812
diff changeset
   138
	(void) pthread_setcancelstate(cancel_state, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
 * _get_exit_frame_monitor is called by the C++ runtimes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
_get_exit_frame_monitor(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	atexit_root_t *arp = &curthread->ul_uberdata->atexit_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	return (&arp->exit_frame_monitor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 * The following is a routine which the loader (ld.so.1) calls when it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
 * processes a dlclose call on an object.  It resets all signal handlers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
 * which fall within the union of the ranges specified by the elements
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
 * of the array range to SIG_DFL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
_preexec_sig_unload(Lc_addr_range_t range[], uint_t count)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	uberdata_t *udp = curthread->ul_uberdata;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	int sig;
4570
f93b74ddbdd5 6559990 user-level read/write locks should be much faster
raf
parents: 1219
diff changeset
   162
	rwlock_t *rwlp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	struct sigaction *sap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
	struct sigaction oact;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	void (*handler)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	for (sig = 1; sig < NSIG; sig++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		sap = (struct sigaction *)&udp->siguaction[sig].sig_uaction;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
again:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
		handler = sap->sa_handler;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
		if (handler != SIG_DFL && handler != SIG_IGN &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
		    in_range(handler, range, count)) {
4570
f93b74ddbdd5 6559990 user-level read/write locks should be much faster
raf
parents: 1219
diff changeset
   173
			rwlp = &udp->siguaction[sig].sig_lock;
f93b74ddbdd5 6559990 user-level read/write locks should be much faster
raf
parents: 1219
diff changeset
   174
			lrw_wrlock(rwlp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
			if (handler != sap->sa_handler) {
4570
f93b74ddbdd5 6559990 user-level read/write locks should be much faster
raf
parents: 1219
diff changeset
   176
				lrw_unlock(rwlp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
				goto again;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
			sap->sa_handler = SIG_DFL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
			sap->sa_flags = SA_SIGINFO;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
			(void) sigemptyset(&sap->sa_mask);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
			if (__sigaction(sig, NULL, &oact) == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
			    oact.sa_handler != SIG_DFL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
			    oact.sa_handler != SIG_IGN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
				(void) __sigaction(sig, sap, NULL);
4570
f93b74ddbdd5 6559990 user-level read/write locks should be much faster
raf
parents: 1219
diff changeset
   186
			lrw_unlock(rwlp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
 * The following is a routine which the loader (ld.so.1) calls when it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
 * processes a dlclose call on an object.  It cancels all atfork() entries
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
 * whose prefork, parent postfork, or child postfork functions fall within
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
 * the union of the ranges specified by the elements of the array range.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
_preexec_atfork_unload(Lc_addr_range_t range[], uint_t count)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
{
4843
5b42fe9ae29d 6590401 fixes for 6418491, 6518780 and 6570016 conspire to break java
raf
parents: 4570
diff changeset
   200
	ulwp_t *self = curthread;
5b42fe9ae29d 6590401 fixes for 6418491, 6518780 and 6570016 conspire to break java
raf
parents: 4570
diff changeset
   201
	uberdata_t *udp = self->ul_uberdata;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	atfork_t *atfork_q;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	atfork_t *atfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	atfork_t *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	void (*func)(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	int start_again;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
   208
	(void) mutex_lock(&udp->atfork_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	if ((atfork_q = udp->atforklist) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
		atfp = atfork_q;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
			next = atfp->forw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
			start_again = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
			if (((func = atfp->prepare) != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
			    in_range(func, range, count)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
			    ((func = atfp->parent) != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
			    in_range(func, range, count)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
			    ((func = atfp->child) != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
			    in_range(func, range, count))) {
4843
5b42fe9ae29d 6590401 fixes for 6418491, 6518780 and 6570016 conspire to break java
raf
parents: 4570
diff changeset
   221
				if (self->ul_fork) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
					 * dlclose() called from a fork handler.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
					 * Deleting the entry would wreak havoc.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
					 * Just null out the function pointers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
					 * and leave the entry in place.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
					atfp->prepare = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
					atfp->parent = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
					atfp->child = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
					continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
				if (atfp == atfork_q) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
					/* deleting the list head member */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
					udp->atforklist = atfork_q = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
					start_again = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
				atfp->forw->back = atfp->back;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
				atfp->back->forw = atfp->forw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
				lfree(atfp, sizeof (atfork_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
				if (atfp == atfork_q) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
					/* we deleted the whole list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
					udp->atforklist = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
		} while ((atfp = next) != atfork_q || start_again);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	}
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
   249
	(void) mutex_unlock(&udp->atfork_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
 * The following is a routine which the loader (ld.so.1) calls when it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
 * processes a dlclose call on an object.  It sets the destructor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
 * function pointer to NULL for all keys whose destructors fall within
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
 * the union of the ranges specified by the elements of the array range.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
 * We don't assign TSD_UNALLOCATED (the equivalent of pthread_key_destroy())
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
 * because the thread may use the key's TSD further on in fini processing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
_preexec_tsd_unload(Lc_addr_range_t range[], uint_t count)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	tsd_metadata_t *tsdm = &curthread->ul_uberdata->tsd_metadata;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	void (*func)(void *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	int key;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
	lmutex_lock(&tsdm->tsdm_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	for (key = 1; key < tsdm->tsdm_nused; key++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		if ((func = tsdm->tsdm_destro[key]) != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		    func != TSD_UNALLOCATED &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
		    in_range((_exithdlr_func_t)func, range, count))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
			tsdm->tsdm_destro[key] = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	lmutex_unlock(&tsdm->tsdm_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
 * The following is a routine which the loader (ld.so.1) calls when it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
 * processes dlclose calls on objects with atexit registrations.  It
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
 * executes the exit handlers that fall within the union of the ranges
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
 * specified by the elements of the array range in the REVERSE ORDER of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
 * their registration.  Do not change this characteristic; it is REQUIRED
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
 * BEHAVIOR.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
_preexec_exit_handlers(Lc_addr_range_t range[], uint_t count)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	atexit_root_t *arp = &curthread->ul_uberdata->atexit_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	_exthdlr_t *o;		/* previous node */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
	_exthdlr_t *p;		/* this node */
8009
cbee40410e7d 6767133 exit() is not cancel-safe
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents: 6812
diff changeset
   291
	int cancel_state;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
8009
cbee40410e7d 6767133 exit() is not cancel-safe
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents: 6812
diff changeset
   293
	/* disable cancellation while running atexit handlers */
cbee40410e7d 6767133 exit() is not cancel-safe
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents: 6812
diff changeset
   294
	(void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
   295
	(void) mutex_lock(&arp->exitfns_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
	o = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
	p = arp->head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
	while (p != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
		if (in_range(p->hdlr, range, count)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
			/* We need to execute this one */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
			if (o != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
				o->next = p->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
				arp->head = p->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
			p->hdlr();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
			lfree(p, sizeof (_exthdlr_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
			o = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
			p = arp->head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
			o = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
			p = p->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
	}
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 5891
diff changeset
   314
	(void) mutex_unlock(&arp->exitfns_lock);
8009
cbee40410e7d 6767133 exit() is not cancel-safe
Roger A. Faulkner <Roger.Faulkner@Sun.COM>
parents: 6812
diff changeset
   315
	(void) pthread_setcancelstate(cancel_state, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
	_preexec_tsd_unload(range, count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
	_preexec_atfork_unload(range, count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
	_preexec_sig_unload(range, count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
in_range(_exithdlr_func_t addr, Lc_addr_range_t ranges[], uint_t count)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	uint_t idx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	for (idx = 0; idx < count; idx++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
		if ((void *)addr >= ranges[idx].lb &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
		    (void *)addr < ranges[idx].ub) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
}