diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2013-07-18 00:49:01 +0000 |
---|---|---|
committer | Keith M Wesolowski <wesolows@foobazco.org> | 2013-07-18 00:49:04 +0000 |
commit | 8cb0d5d22925a6316ff1386fa13a6dbca34cfee7 (patch) | |
tree | d0c8fa919b1a107eee0f392be1ac3091bd23917c | |
parent | ccd723900c0b9504ba6263e7e9d4cdb73a234751 (diff) | |
parent | 3e7c6556c4272555ed6c5ecdbca2bf8a56df6ff5 (diff) | |
download | illumos-joyent-8cb0d5d22925a6316ff1386fa13a6dbca34cfee7.tar.gz |
[illumos-gate merge]
commit 3e7c6556c4272555ed6c5ecdbca2bf8a56df6ff5
3893 lvm: incorrect flag handling
commit 5bc7ce93aca1e9026e3243221a9a0b1a3bc9a32e
3853 __cplusplus change and headers incompatipility with clang
commit 5c069a6c4b95a7360294695998bf1d3b12473abf
3849 implement __cxa_atexit/__cxa_finalize
-rw-r--r-- | usr/src/head/malloc.h | 23 | ||||
-rw-r--r-- | usr/src/head/unistd.h | 8 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/thr_uberdata.h | 11 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/atexit.c | 89 | ||||
-rw-r--r-- | usr/src/lib/libc/port/mapfile-vers | 6 | ||||
-rw-r--r-- | usr/src/uts/common/io/lvm/mirror/mirror.c | 2 |
6 files changed, 112 insertions, 27 deletions
diff --git a/usr/src/head/malloc.h b/usr/src/head/malloc.h index bfb44b801e..8325420861 100644 --- a/usr/src/head/malloc.h +++ b/usr/src/head/malloc.h @@ -26,8 +26,6 @@ #ifndef _MALLOC_H #define _MALLOC_H -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.7 */ - #include <sys/types.h> #ifdef __cplusplus @@ -61,21 +59,38 @@ struct mallinfo { #if defined(__STDC__) +#if (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \ + defined(_XPG3) +#if __cplusplus >= 199711L +namespace std { +#endif + void *malloc(size_t); void free(void *); void *realloc(void *, size_t); +void *calloc(size_t, size_t); + +#if __cplusplus >= 199711L +} /* end of namespace std */ + +using std::malloc; +using std::free; +using std::realloc; +using std::calloc; +#endif /* __cplusplus >= 199711L */ +#endif /* (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || ... */ + int mallopt(int, int); struct mallinfo mallinfo(void); -void *calloc(size_t, size_t); #else void *malloc(); void free(); void *realloc(); +void *calloc(); int mallopt(); struct mallinfo mallinfo(); -void *calloc(); #endif /* __STDC__ */ diff --git a/usr/src/head/unistd.h b/usr/src/head/unistd.h index 43b34fa303..8b9de2208a 100644 --- a/usr/src/head/unistd.h +++ b/usr/src/head/unistd.h @@ -464,7 +464,15 @@ extern ssize_t readlink(const char *_RESTRICT_KYWD, char *_RESTRICT_KYWD, #endif #if (!defined(__XOPEN_OR_POSIX) || (defined(_XPG3) && !defined(_XPG4))) || \ defined(__EXTENSIONS__) +#if __cplusplus >= 199711L +namespace std { +#endif extern int rename(const char *, const char *); +#if __cplusplus >= 199711L +} /* end of namespace std */ + +using std::rename; +#endif /* __cplusplus >= 199711L */ #endif /* (!defined(__XOPEN_OR_POSIX) || (defined(_XPG3)... */ #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) extern int resolvepath(const char *, char *, size_t); diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h index 2b8d000b29..5f67e760e2 100644 --- a/usr/src/lib/libc/inc/thr_uberdata.h +++ b/usr/src/lib/libc/inc/thr_uberdata.h @@ -858,16 +858,25 @@ typedef struct { * atexit() data structures. * See port/gen/atexit.c for details. */ -typedef void (*_exithdlr_func_t) (void); +typedef void (*_exithdlr_func_t) (void*); typedef struct _exthdlr { struct _exthdlr *next; /* next in handler list */ _exithdlr_func_t hdlr; /* handler itself */ + void *arg; /* argument to handler */ + void *dso; /* DSO associated with handler */ } _exthdlr_t; typedef struct { mutex_t exitfns_lock; _exthdlr_t *head; + /* + * exit_frame_monitor is part of a private contract between libc and + * the Sun C++ runtime. + * + * It should be NULL until exit() is called, and thereafter hold the + * frame pointer of the function implementing our exit processing. + */ void *exit_frame_monitor; char exit_pad[64 - /* pad out to 64 bytes */ (sizeof (mutex_t) + sizeof (_exthdlr_t *) + sizeof (void *))]; diff --git a/usr/src/lib/libc/port/gen/atexit.c b/usr/src/lib/libc/port/gen/atexit.c index fd016b5c37..32e54fae11 100644 --- a/usr/src/lib/libc/port/gen/atexit.c +++ b/usr/src/lib/libc/port/gen/atexit.c @@ -52,7 +52,7 @@ * See "thr_uberdata.h" for the definitions of structures used here. */ -static int in_range(_exithdlr_func_t, Lc_addr_range_t[], uint_t count); +static int in_range(void *, Lc_addr_range_t[], uint_t count); extern caddr_t _getfp(void); @@ -88,12 +88,13 @@ atexit_unlocks() (void) mutex_unlock(&__uberdata.atexit_root.exitfns_lock); } + /* - * atexit() is called before the primordial thread is fully set up. + * This is called via atexit() before the primordial thread is fully set up. * Be careful about dereferencing self->ul_uberdata->atexit_root. */ int -atexit(void (*func)(void)) +__cxa_atexit(void (*hdlr)(void *), void *arg, void *dso) { ulwp_t *self; atexit_root_t *arp; @@ -108,36 +109,71 @@ atexit(void (*func)(void)) arp = &self->ul_uberdata->atexit_root; (void) mutex_lock(&arp->exitfns_lock); } - p->hdlr = func; + p->hdlr = hdlr; + p->arg = arg; + p->dso = dso; p->next = arp->head; arp->head = p; + if (self != NULL) (void) mutex_unlock(&arp->exitfns_lock); return (0); } +int +atexit(void (*func)(void)) +{ + return (__cxa_atexit((_exithdlr_func_t)func, NULL, NULL)); +} + +/* + * Note that we may be entered recursively, as we'll call __cxa_finalize(0) at + * exit, one of our handlers is ld.so.1`atexit_fini, and libraries may call + * __cxa_finalize(__dso_handle) from their _fini. + */ void -_exithandle(void) +__cxa_finalize(void *dso) { atexit_root_t *arp = &curthread->ul_uberdata->atexit_root; - _exthdlr_t *p; + _exthdlr_t *p, *o; int cancel_state; /* disable cancellation while running atexit handlers */ (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); (void) mutex_lock(&arp->exitfns_lock); - arp->exit_frame_monitor = _getfp() + STACK_BIAS; + + o = NULL; p = arp->head; while (p != NULL) { - arp->head = p->next; - p->hdlr(); - lfree(p, sizeof (_exthdlr_t)); - p = arp->head; + if ((dso == NULL) || (p->dso == dso)) { + if (o != NULL) + o->next = p->next; + else + arp->head = p->next; + + p->hdlr(p->arg); + lfree(p, sizeof (_exthdlr_t)); + o = NULL; + p = arp->head; + } else { + o = p; + p = p->next; + } } + (void) mutex_unlock(&arp->exitfns_lock); (void) pthread_setcancelstate(cancel_state, NULL); } +void +_exithandle(void) +{ + atexit_root_t *arp = &curthread->ul_uberdata->atexit_root; + + arp->exit_frame_monitor = _getfp() + STACK_BIAS; + __cxa_finalize(NULL); +} + /* * _get_exit_frame_monitor is called by the C++ runtimes. */ @@ -169,7 +205,7 @@ _preexec_sig_unload(Lc_addr_range_t range[], uint_t count) again: handler = sap->sa_handler; if (handler != SIG_DFL && handler != SIG_IGN && - in_range(handler, range, count)) { + in_range((void *)handler, range, count)) { rwlp = &udp->siguaction[sig].sig_lock; lrw_wrlock(rwlp); if (handler != sap->sa_handler) { @@ -213,11 +249,11 @@ _preexec_atfork_unload(Lc_addr_range_t range[], uint_t count) start_again = 0; if (((func = atfp->prepare) != NULL && - in_range(func, range, count)) || + in_range((void *)func, range, count)) || ((func = atfp->parent) != NULL && - in_range(func, range, count)) || + in_range((void *)func, range, count)) || ((func = atfp->child) != NULL && - in_range(func, range, count))) { + in_range((void *)func, range, count))) { if (self->ul_fork) { /* * dlclose() called from a fork handler. @@ -268,7 +304,7 @@ _preexec_tsd_unload(Lc_addr_range_t range[], uint_t count) for (key = 1; key < tsdm->tsdm_nused; key++) { if ((func = tsdm->tsdm_destro[key]) != NULL && func != TSD_UNALLOCATED && - in_range((_exithdlr_func_t)func, range, count)) + in_range((void *)func, range, count)) tsdm->tsdm_destro[key] = NULL; } lmutex_unlock(&tsdm->tsdm_lock); @@ -296,13 +332,24 @@ _preexec_exit_handlers(Lc_addr_range_t range[], uint_t count) o = NULL; p = arp->head; while (p != NULL) { - if (in_range(p->hdlr, range, count)) { + /* + * We call even CXA handlers of functions present in the + * library being unloaded. The specification isn't + * particularly clear on this, and this seems the most sane. + * This is the behaviour of FreeBSD 9.1 (GNU libc leaves the + * handler on the exit list, and crashes at exit time). + * + * This won't cause handlers to be called twice, because + * anything called from a __cxa_finalize call from the + * language runtime will have been removed from the list. + */ + if (in_range((void *)p->hdlr, range, count)) { /* We need to execute this one */ if (o != NULL) o->next = p->next; else arp->head = p->next; - p->hdlr(); + p->hdlr(p->arg); lfree(p, sizeof (_exthdlr_t)); o = NULL; p = arp->head; @@ -322,13 +369,13 @@ _preexec_exit_handlers(Lc_addr_range_t range[], uint_t count) } static int -in_range(_exithdlr_func_t addr, Lc_addr_range_t ranges[], uint_t count) +in_range(void *addr, Lc_addr_range_t ranges[], uint_t count) { uint_t idx; for (idx = 0; idx < count; idx++) { - if ((void *)addr >= ranges[idx].lb && - (void *)addr < ranges[idx].ub) { + if (addr >= ranges[idx].lb && + addr < ranges[idx].ub) { return (1); } } diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 469b73e9ca..ae0034931d 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -91,6 +91,12 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.5 { # common C++ ABI exit handlers + protected: + __cxa_atexit; + __cxa_finalize; +} ILLUMOS_0.4; + SYMBOL_VERSION ILLUMOS_0.4 { # Illumos additions protected: pipe2; diff --git a/usr/src/uts/common/io/lvm/mirror/mirror.c b/usr/src/uts/common/io/lvm/mirror/mirror.c index e138fe2f64..e7893ca8c0 100644 --- a/usr/src/uts/common/io/lvm/mirror/mirror.c +++ b/usr/src/uts/common/io/lvm/mirror/mirror.c @@ -4015,7 +4015,7 @@ mirror_write_strategy(buf_t *pb, int flag, void *private) * completed this resync region */ if ((MD_MNSET_SETNO(MD_UN2SET(un))) && - (!flag & MD_STR_DIRTY_RD)) { + (!(flag & MD_STR_DIRTY_RD))) { if (!IN_RESYNC_REGION(un, ps)) abort_write = 1; } |