diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2014-04-22 00:14:03 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2015-02-09 15:34:39 -0800 |
commit | 4812581794004eff0af2b765b832403b30bf64ab (patch) | |
tree | fbd18690340f7e88c6aa05dde1f1466ccfcf0861 /usr/src/cmd | |
parent | 1f2ca518aeecee8616fccc0c46a339773faea7d5 (diff) | |
download | illumos-gate-4812581794004eff0af2b765b832403b30bf64ab.tar.gz |
4996 rtld _init race leads to incorrect symbol values
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src/cmd')
-rw-r--r-- | usr/src/cmd/sgs/include/debug.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/sgs/include/rtld.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/sgs/liblddbg/common/liblddbg.msg | 2 | ||||
-rw-r--r-- | usr/src/cmd/sgs/liblddbg/common/llib-llddbg | 2 | ||||
-rw-r--r-- | usr/src/cmd/sgs/liblddbg/common/mapfile-vers | 2 | ||||
-rw-r--r-- | usr/src/cmd/sgs/liblddbg/common/util.c | 13 | ||||
-rw-r--r-- | usr/src/cmd/sgs/packages/common/SUNWonld-README | 1 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/_rtld.h | 1 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/util.c | 23 |
9 files changed, 21 insertions, 29 deletions
diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h index 9db202574d..5f740afe57 100644 --- a/usr/src/cmd/sgs/include/debug.h +++ b/usr/src/cmd/sgs/include/debug.h @@ -502,7 +502,6 @@ extern void Dbg_help(void); #define Dbg_util_intoolate Dbg64_util_intoolate #define Dbg_util_lcinterface Dbg64_util_lcinterface #define Dbg_util_nl Dbg64_util_nl -#define Dbg_util_no_init Dbg64_util_no_init #define Dbg_util_scc_entry Dbg64_util_scc_entry #define Dbg_util_scc_title Dbg64_util_scc_title #define Dbg_util_str Dbg64_util_str @@ -736,7 +735,6 @@ extern void Dbg_help(void); #define Dbg_util_intoolate Dbg32_util_intoolate #define Dbg_util_lcinterface Dbg32_util_lcinterface #define Dbg_util_nl Dbg32_util_nl -#define Dbg_util_no_init Dbg32_util_no_init #define Dbg_util_scc_entry Dbg32_util_scc_entry #define Dbg_util_scc_title Dbg32_util_scc_title #define Dbg_util_str Dbg32_util_str @@ -1051,7 +1049,6 @@ extern void Dbg_util_edge_out(Rt_map *, Rt_map *); extern void Dbg_util_intoolate(Rt_map *); extern void Dbg_util_lcinterface(Rt_map *, int, char *); extern void Dbg_util_nl(Lm_list *, int); -extern void Dbg_util_no_init(Rt_map *); extern void Dbg_util_scc_entry(Rt_map *, uint_t); extern void Dbg_util_scc_title(Lm_list *, int); extern void Dbg_util_str(Lm_list *, const char *); diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h index 344671d515..65eb25c4b1 100644 --- a/usr/src/cmd/sgs/include/rtld.h +++ b/usr/src/cmd/sgs/include/rtld.h @@ -719,7 +719,10 @@ struct rt_map { Capchain *rt_capchain; /* capabilities chain data */ uint_t rt_cntl; /* link-map control list we belong to */ uint_t rt_aflags; /* auditor flags, see LML_TFLG_AUD_ */ + Rt_cond rt_cv; /* for waiting on flags changes */ + Rt_lock rt_lock; /* for coordinating flags changes */ /* address of _init */ + thread_t rt_init_thread; /* thread id in this lm's _init */ void (*rt_init)(void); /* address of _fini */ void (*rt_fini)(void); diff --git a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg index 71f432220f..34c012acab 100644 --- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg +++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg @@ -1102,8 +1102,6 @@ @ MSG_UTL_DYN "dynamically triggered" @ MSG_UTL_DONE "done" -@ MSG_UTL_NOINIT "warning: calling %s whose init has not completed" - @ MSG_UTL_DBNOTIFY "notify debugger: event: %s state: %s" @ MSG_UTL_SCC_TITLE " cycle detected - sorting cyclic dependencies in %s" diff --git a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg index 0b6bfc747b..e3a43c6e0c 100644 --- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg +++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg @@ -502,8 +502,6 @@ void Dbg32_util_lcinterface(Rt_map *, int, char *); void Dbg64_util_lcinterface(Rt_map *, int, char *); void Dbg32_util_nl(Lm_list *, int); void Dbg64_util_nl(Lm_list *, int); -void Dbg32_util_no_init(Rt_map *); -void Dbg64_util_no_init(Rt_map *); void Dbg32_util_scc_entry(Rt_map *, uint_t); void Dbg64_util_scc_entry(Rt_map *, uint_t); void Dbg32_util_scc_title(Lm_list *, int); diff --git a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers index 0e4338fce1..1fac50603d 100644 --- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers +++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers @@ -490,8 +490,6 @@ SYMBOL_VERSION SUNWprivate_4.83 { Dbg64_util_intoolate; Dbg32_util_nl; Dbg64_util_nl; - Dbg32_util_no_init; - Dbg64_util_no_init; Dbg32_util_scc_entry; Dbg64_util_scc_entry; Dbg32_util_scc_title; diff --git a/usr/src/cmd/sgs/liblddbg/common/util.c b/usr/src/cmd/sgs/liblddbg/common/util.c index 02de483a82..575a9bd15f 100644 --- a/usr/src/cmd/sgs/liblddbg/common/util.c +++ b/usr/src/cmd/sgs/liblddbg/common/util.c @@ -66,19 +66,6 @@ Dbg_util_call_init(Rt_map *lmp, int flag) } void -Dbg_util_no_init(Rt_map *lmp) -{ - Lm_list *lml = LIST(lmp); - - if (DBG_NOTCLASS(DBG_C_INIT)) - return; - - Dbg_util_nl(lml, DBG_NL_STD); - dbg_print(lml, MSG_INTL(MSG_UTL_NOINIT), NAME(lmp)); - Dbg_util_nl(lml, DBG_NL_STD); -} - -void Dbg_util_intoolate(Rt_map *lmp) { Lm_list *lml = LIST(lmp); diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index 6688c34255..f303ba6053 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1654,3 +1654,4 @@ Bugid Risk Synopsis 4270 ld(1) argument error reporting is still pretty bad 4383 libelf can't write extended sections when ELF_F_LAYOUT 4959 completely discarded merged string sections will corrupt output objects +4996 rtld _init race leads to incorrect symbol values diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h index 3cbb58fe25..ece14a855e 100644 --- a/usr/src/cmd/sgs/rtld/common/_rtld.h +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h @@ -764,7 +764,6 @@ extern int remove_hdl(Grp_hdl *, Rt_map *, int *); extern void remove_lmc(Lm_list *, Rt_map *, Aliste, const char *); extern void remove_lml(Lm_list *); extern void remove_so(Lm_list *, Rt_map *, Rt_map *); -extern int rt_cond_wait(Rt_cond *, Rt_lock *); extern int rt_critical(void); extern int rt_bind_guard(int); extern int rt_bind_clear(int); diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c index 5f9979ddf0..a702b20e78 100644 --- a/usr/src/cmd/sgs/rtld/common/util.c +++ b/usr/src/cmd/sgs/rtld/common/util.c @@ -627,16 +627,22 @@ is_dep_init(Rt_map *dlmp, Rt_map *clmp) if ((dlmp == clmp) || (rtld_flags & RT_FL_INITFIRST)) return; + (void) rt_mutex_lock(&dlmp->rt_lock); + while (dlmp->rt_init_thread != rt_thr_self() && (FLAGS(dlmp) & + (FLG_RT_RELOCED | FLG_RT_INITCALL | FLG_RT_INITDONE)) == + (FLG_RT_RELOCED | FLG_RT_INITCALL)) { + leave(LIST(dlmp), 0); + (void) _lwp_cond_wait(&dlmp->rt_cv, (mutex_t *)&dlmp->rt_lock); + (void) rt_mutex_unlock(&dlmp->rt_lock); + (void) enter(0); + (void) rt_mutex_lock(&dlmp->rt_lock); + } + (void) rt_mutex_unlock(&dlmp->rt_lock); + if ((FLAGS(dlmp) & (FLG_RT_RELOCED | FLG_RT_INITDONE)) == (FLG_RT_RELOCED | FLG_RT_INITDONE)) return; - if ((FLAGS(dlmp) & (FLG_RT_RELOCED | FLG_RT_INITCALL)) == - (FLG_RT_RELOCED | FLG_RT_INITCALL)) { - DBG_CALL(Dbg_util_no_init(dlmp)); - return; - } - if ((tobj = calloc(2, sizeof (Rt_map *))) != NULL) { tobj[0] = dlmp; call_init(tobj, DBG_INIT_DYN); @@ -717,6 +723,7 @@ call_init(Rt_map **tobj, int flag) continue; FLAGS(lmp) |= FLG_RT_INITCALL; + lmp->rt_init_thread = rt_thr_self(); /* * Establish an initfirst state if necessary - no other inits @@ -752,7 +759,11 @@ call_init(Rt_map **tobj, int flag) * signifies that a .fini must be called should it exist. * Clear the sort field for use in later .fini processing. */ + (void) rt_mutex_lock(&lmp->rt_lock); FLAGS(lmp) |= FLG_RT_INITDONE; + lmp->rt_init_thread = (thread_t)0; + (void) _lwp_cond_broadcast(&lmp->rt_cv); + (void) rt_mutex_unlock(&lmp->rt_lock); SORTVAL(lmp) = -1; /* |