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 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma weak _atexit = atexit 31 32 #include "lint.h" 33 #include "thr_uberdata.h" 34 #include "libc_int.h" 35 #include "atexit.h" 36 #include "stdiom.h" 37 38 /* 39 * Note that memory is managed by lmalloc()/lfree(). 40 * 41 * Among other reasons, this is occasioned by the insistence of our 42 * brothers sh(1) and csh(1) that they can do malloc, etc., better than 43 * libc can. Those programs define their own malloc routines, and 44 * initialize the underlying mechanism in main(). This means that calls 45 * to malloc occuring before main will crash. The loader calls atexit(3C) 46 * before calling main, so we'd better avoid malloc() when it does. 47 * 48 * Another reason for using lmalloc()/lfree() is that the atexit() 49 * list must transcend all link maps. See the Linker and Libraries 50 * Guide for information on alternate link maps. 51 * 52 * See "thr_uberdata.h" for the definitions of structures used here. 53 */ 54 55 static int in_range(void *, Lc_addr_range_t[], uint_t count); 56 57 extern caddr_t _getfp(void); 58 59 /* 60 * exitfns_lock is declared to be a recursive mutex so that we 61 * can hold it while calling out to the registered functions. 62 * If they call back to us, we are self-consistent and everything 63 * works, even the case of calling exit() from functions called 64 * by _exithandle() (recursive exit()). All that is required is 65 * that the registered functions actually return (no longjmp()s). 66 * 67 * Because exitfns_lock is declared to be a recursive mutex, we 68 * cannot use it with lmutex_lock()/lmutex_unlock() and we must 69 * use mutex_lock()/mutex_unlock(). This means that atexit() 70 * and exit() are not async-signal-safe. We make them fork1-safe 71 * via the atexit_locks()/atexit_unlocks() functions, called from 72 * libc_prepare_atfork()/libc_child_atfork()/libc_parent_atfork() 73 */ 74 75 /* 76 * atexit_locks() and atexit_unlocks() are called on every link map. 77 * Do not use curthread->ul_uberdata->atexit_root for these. 78 */ 79 void 80 atexit_locks() 81 { 82 (void) mutex_lock(&__uberdata.atexit_root.exitfns_lock); 83 } 84 85 void 86 atexit_unlocks() 87 { 88 (void) mutex_unlock(&__uberdata.atexit_root.exitfns_lock); 89 } 90 91 92 /* 93 * This is called via atexit() before the primordial thread is fully set up. 94 * Be careful about dereferencing self->ul_uberdata->atexit_root. 95 */ 96 int 97 __cxa_atexit(void (*hdlr)(void *), void *arg, void *dso) 98 { 99 ulwp_t *self; 100 atexit_root_t *arp; 101 _exthdlr_t *p; 102 103 if ((p = lmalloc(sizeof (_exthdlr_t))) == NULL) 104 return (-1); 105 106 if ((self = __curthread()) == NULL) 107 arp = &__uberdata.atexit_root; 108 else { 109 arp = &self->ul_uberdata->atexit_root; 110 (void) mutex_lock(&arp->exitfns_lock); 111 } 112 p->hdlr = hdlr; 113 p->arg = arg; 114 p->dso = dso; 115 p->next = arp->head; 116 arp->head = p; 117 118 if (self != NULL) 119 (void) mutex_unlock(&arp->exitfns_lock); 120 return (0); 121 } 122 123 int 124 atexit(void (*func)(void)) 125 { 126 return (__cxa_atexit((_exithdlr_func_t)func, NULL, NULL)); 127 } 128 129 /* 130 * Note that we may be entered recursively, as we'll call __cxa_finalize(0) at 131 * exit, one of our handlers is ld.so.1`atexit_fini, and libraries may call 132 * __cxa_finalize(__dso_handle) from their _fini. 133 */ 134 void 135 __cxa_finalize(void *dso) 136 { 137 atexit_root_t *arp = &curthread->ul_uberdata->atexit_root; 138 _exthdlr_t *p, *o; 139 int cancel_state; 140 141 /* disable cancellation while running atexit handlers */ 142 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); 143 (void) mutex_lock(&arp->exitfns_lock); 144 145 o = NULL; 146 p = arp->head; 147 while (p != NULL) { 148 if ((dso == NULL) || (p->dso == dso)) { 149 if (o != NULL) 150 o->next = p->next; 151 else 152 arp->head = p->next; 153 154 p->hdlr(p->arg); 155 lfree(p, sizeof (_exthdlr_t)); 156 o = NULL; 157 p = arp->head; 158 } else { 159 o = p; 160 p = p->next; 161 } 162 } 163 164 (void) mutex_unlock(&arp->exitfns_lock); 165 (void) pthread_setcancelstate(cancel_state, NULL); 166 } 167 168 void 169 _exithandle(void) 170 { 171 atexit_root_t *arp = &curthread->ul_uberdata->atexit_root; 172 173 arp->exit_frame_monitor = _getfp() + STACK_BIAS; 174 __cxa_finalize(NULL); 175 } 176 177 /* 178 * _get_exit_frame_monitor is called by the C++ runtimes. 179 */ 180 void * 181 _get_exit_frame_monitor(void) 182 { 183 atexit_root_t *arp = &curthread->ul_uberdata->atexit_root; 184 return (&arp->exit_frame_monitor); 185 } 186 187 /* 188 * The following is a routine which the loader (ld.so.1) calls when it 189 * processes a dlclose call on an object. It resets all signal handlers 190 * which fall within the union of the ranges specified by the elements 191 * of the array range to SIG_DFL. 192 */ 193 static void 194 _preexec_sig_unload(Lc_addr_range_t range[], uint_t count) 195 { 196 uberdata_t *udp = curthread->ul_uberdata; 197 int sig; 198 rwlock_t *rwlp; 199 struct sigaction *sap; 200 struct sigaction oact; 201 void (*handler)(); 202 203 for (sig = 1; sig < NSIG; sig++) { 204 sap = (struct sigaction *)&udp->siguaction[sig].sig_uaction; 205 again: 206 handler = sap->sa_handler; 207 if (handler != SIG_DFL && handler != SIG_IGN && 208 in_range((void *)handler, range, count)) { 209 rwlp = &udp->siguaction[sig].sig_lock; 210 lrw_wrlock(rwlp); 211 if (handler != sap->sa_handler) { 212 lrw_unlock(rwlp); 213 goto again; 214 } 215 sap->sa_handler = SIG_DFL; 216 sap->sa_flags = SA_SIGINFO; 217 (void) sigemptyset(&sap->sa_mask); 218 if (__sigaction(sig, NULL, &oact) == 0 && 219 oact.sa_handler != SIG_DFL && 220 oact.sa_handler != SIG_IGN) 221 (void) __sigaction(sig, sap, NULL); 222 lrw_unlock(rwlp); 223 } 224 } 225 } 226 227 /* 228 * The following is a routine which the loader (ld.so.1) calls when it 229 * processes a dlclose call on an object. It cancels all atfork() entries 230 * whose prefork, parent postfork, or child postfork functions fall within 231 * the union of the ranges specified by the elements of the array range. 232 */ 233 static void 234 _preexec_atfork_unload(Lc_addr_range_t range[], uint_t count) 235 { 236 ulwp_t *self = curthread; 237 uberdata_t *udp = self->ul_uberdata; 238 atfork_t *atfork_q; 239 atfork_t *atfp; 240 atfork_t *next; 241 void (*func)(void); 242 int start_again; 243 244 (void) mutex_lock(&udp->atfork_lock); 245 if ((atfork_q = udp->atforklist) != NULL) { 246 atfp = atfork_q; 247 do { 248 next = atfp->forw; 249 start_again = 0; 250 251 if (((func = atfp->prepare) != NULL && 252 in_range((void *)func, range, count)) || 253 ((func = atfp->parent) != NULL && 254 in_range((void *)func, range, count)) || 255 ((func = atfp->child) != NULL && 256 in_range((void *)func, range, count))) { 257 if (self->ul_fork) { 258 /* 259 * dlclose() called from a fork handler. 260 * Deleting the entry would wreak havoc. 261 * Just null out the function pointers 262 * and leave the entry in place. 263 */ 264 atfp->prepare = NULL; 265 atfp->parent = NULL; 266 atfp->child = NULL; 267 continue; 268 } 269 if (atfp == atfork_q) { 270 /* deleting the list head member */ 271 udp->atforklist = atfork_q = next; 272 start_again = 1; 273 } 274 atfp->forw->back = atfp->back; 275 atfp->back->forw = atfp->forw; 276 lfree(atfp, sizeof (atfork_t)); 277 if (atfp == atfork_q) { 278 /* we deleted the whole list */ 279 udp->atforklist = NULL; 280 break; 281 } 282 } 283 } while ((atfp = next) != atfork_q || start_again); 284 } 285 (void) mutex_unlock(&udp->atfork_lock); 286 } 287 288 /* 289 * The following is a routine which the loader (ld.so.1) calls when it 290 * processes a dlclose call on an object. It sets the destructor 291 * function pointer to NULL for all keys whose destructors fall within 292 * the union of the ranges specified by the elements of the array range. 293 * We don't assign TSD_UNALLOCATED (the equivalent of pthread_key_destroy()) 294 * because the thread may use the key's TSD further on in fini processing. 295 */ 296 static void 297 _preexec_tsd_unload(Lc_addr_range_t range[], uint_t count) 298 { 299 tsd_metadata_t *tsdm = &curthread->ul_uberdata->tsd_metadata; 300 void (*func)(void *); 301 int key; 302 303 lmutex_lock(&tsdm->tsdm_lock); 304 for (key = 1; key < tsdm->tsdm_nused; key++) { 305 if ((func = tsdm->tsdm_destro[key]) != NULL && 306 func != TSD_UNALLOCATED && 307 in_range((void *)func, range, count)) 308 tsdm->tsdm_destro[key] = NULL; 309 } 310 lmutex_unlock(&tsdm->tsdm_lock); 311 } 312 313 /* 314 * The following is a routine which the loader (ld.so.1) calls when it 315 * processes dlclose calls on objects with atexit registrations. It 316 * executes the exit handlers that fall within the union of the ranges 317 * specified by the elements of the array range in the REVERSE ORDER of 318 * their registration. Do not change this characteristic; it is REQUIRED 319 * BEHAVIOR. 320 */ 321 int 322 _preexec_exit_handlers(Lc_addr_range_t range[], uint_t count) 323 { 324 atexit_root_t *arp = &curthread->ul_uberdata->atexit_root; 325 _exthdlr_t *o; /* previous node */ 326 _exthdlr_t *p; /* this node */ 327 int cancel_state; 328 329 /* disable cancellation while running atexit handlers */ 330 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); 331 (void) mutex_lock(&arp->exitfns_lock); 332 o = NULL; 333 p = arp->head; 334 while (p != NULL) { 335 /* 336 * We call even CXA handlers of functions present in the 337 * library being unloaded. The specification isn't 338 * particularly clear on this, and this seems the most sane. 339 * This is the behaviour of FreeBSD 9.1 (GNU libc leaves the 340 * handler on the exit list, and crashes at exit time). 341 * 342 * This won't cause handlers to be called twice, because 343 * anything called from a __cxa_finalize call from the 344 * language runtime will have been removed from the list. 345 */ 346 if (in_range((void *)p->hdlr, range, count)) { 347 /* We need to execute this one */ 348 if (o != NULL) 349 o->next = p->next; 350 else 351 arp->head = p->next; 352 p->hdlr(p->arg); 353 lfree(p, sizeof (_exthdlr_t)); 354 o = NULL; 355 p = arp->head; 356 } else { 357 o = p; 358 p = p->next; 359 } 360 } 361 (void) mutex_unlock(&arp->exitfns_lock); 362 (void) pthread_setcancelstate(cancel_state, NULL); 363 364 _preexec_tsd_unload(range, count); 365 _preexec_atfork_unload(range, count); 366 _preexec_sig_unload(range, count); 367 368 return (0); 369 } 370 371 static int 372 in_range(void *addr, Lc_addr_range_t ranges[], uint_t count) 373 { 374 uint_t idx; 375 376 for (idx = 0; idx < count; idx++) { 377 if (addr >= ranges[idx].lb && 378 addr < ranges[idx].ub) { 379 return (1); 380 } 381 } 382 383 return (0); 384 } 385