Disable floating point code/linking when possible.

Unless heap profiling is enabled, disable floating point code and don't
link with libm.  This, in combination with e.g. EXTRA_CFLAGS=-mno-sse on
x64 systems, makes it possible to completely disable floating point
register use.  Some versions of glibc neglect to save/restore
caller-saved floating point registers during dynamic lazy symbol
loading, and the symbol loading code uses whatever malloc the
application happens to have linked/loaded with, the result being
potential floating point register corruption.
This commit is contained in:
Jason Evans 2013-12-05 23:01:50 -08:00
parent dc1bed6227
commit d37d5adee4
3 changed files with 28 additions and 5 deletions

View File

@ -9,6 +9,13 @@ found in the git revision history:
* 3.5.0 (XXX) * 3.5.0 (XXX)
Bug fixes: Bug fixes:
- Unless heap profiling is enabled, disable floating point code and don't link
with libm. This, in combination with e.g. EXTRA_CFLAGS=-mno-sse on x64
systems, makes it possible to completely disable floating point register
use. Some versions of glibc neglect to save/restore caller-saved floating
point registers during dynamic lazy symbol loading, and the symbol loading
code uses whatever malloc the application happens to have linked/loaded
with, the result being potential floating point register corruption.
- Change the default private namespace prefix from empty to je_, and change - Change the default private namespace prefix from empty to je_, and change
--with-private-namespace-prefix so that it prepends an additional prefix --with-private-namespace-prefix so that it prepends an additional prefix
rather than replacing je_. This reduces the likelihood of applications rather than replacing je_. This reduces the likelihood of applications

View File

@ -356,11 +356,6 @@ AC_SUBST([ARFLAGS])
AC_SUBST([AROUT]) AC_SUBST([AROUT])
AC_SUBST([CC_MM]) AC_SUBST([CC_MM])
if test "x$abi" != "xpecoff"; then
dnl Heap profiling uses the log(3) function.
LIBS="$LIBS -lm"
fi
JE_COMPILABLE([__attribute__ syntax], JE_COMPILABLE([__attribute__ syntax],
[static __attribute__((unused)) void foo(void){}], [static __attribute__((unused)) void foo(void){}],
[], [],
@ -774,6 +769,12 @@ if test "x$enable_prof" = "x1" ; then
AC_MSG_ERROR([Heap profiling requires TLS]); AC_MSG_ERROR([Heap profiling requires TLS]);
fi fi
force_tls="1" force_tls="1"
if test "x$abi" != "xpecoff"; then
dnl Heap profiling uses the log(3) function.
LIBS="$LIBS -lm"
fi
AC_DEFINE([JEMALLOC_PROF], [ ]) AC_DEFINE([JEMALLOC_PROF], [ ])
fi fi
AC_SUBST([enable_prof]) AC_SUBST([enable_prof])

View File

@ -320,6 +320,20 @@ prof_tdata_get(bool create)
JEMALLOC_INLINE void JEMALLOC_INLINE void
prof_sample_threshold_update(prof_tdata_t *prof_tdata) prof_sample_threshold_update(prof_tdata_t *prof_tdata)
{ {
/*
* The body of this function is compiled out unless heap profiling is
* enabled, so that it is possible to compile jemalloc with floating
* point support completely disabled. Avoiding floating point code is
* important on memory-constrained systems, but it also enables a
* workaround for versions of glibc that don't properly save/restore
* floating point registers during dynamic lazy symbol loading (which
* internally calls into whatever malloc implementation happens to be
* integrated into the application). Note that some compilers (e.g.
* gcc 4.8) may use floating point registers for fast memory moves, so
* jemalloc must be compiled with such optimizations disabled (e.g.
* -mno-sse) in order for the workaround to be complete.
*/
#ifdef JEMALLOC_PROF
uint64_t r; uint64_t r;
double u; double u;
@ -349,6 +363,7 @@ prof_sample_threshold_update(prof_tdata_t *prof_tdata)
prof_tdata->threshold = (uint64_t)(log(u) / prof_tdata->threshold = (uint64_t)(log(u) /
log(1.0 - (1.0 / (double)((uint64_t)1U << opt_lg_prof_sample)))) log(1.0 - (1.0 / (double)((uint64_t)1U << opt_lg_prof_sample))))
+ (uint64_t)1U; + (uint64_t)1U;
#endif
} }
JEMALLOC_INLINE prof_ctx_t * JEMALLOC_INLINE prof_ctx_t *