Bug 909709 - Reuse MOZ_LINKER IsSignalHandlingBroken to disable asm.js signal handlers (r=glandium)
authorLuke Wagner <luke@mozilla.com>
Mon, 16 Sep 2013 12:58:38 -0500
changeset 147432 4e3b6957add0e0f255781b3740d3779f7b31acb2
parent 147431 5b52918bf6f65e793dbe0f87c829d3d7d4874375
child 147433 7912be7f71db2f9306cf0a8bf0c6d25c6d77e3c7
push id33874
push userlwagner@mozilla.com
push dateTue, 17 Sep 2013 14:17:46 +0000
treeherdermozilla-inbound@4e3b6957add0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs909709
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 909709 - Reuse MOZ_LINKER IsSignalHandlingBroken to disable asm.js signal handlers (r=glandium)
configure.in
js/src/Makefile.in
js/src/configure.in
js/src/jit/AsmJSSignalHandlers.cpp
--- a/configure.in
+++ b/configure.in
@@ -9332,16 +9332,17 @@ export MOZ_ZLIB_LIBS
 export MOZ_APP_NAME
 export DONT_POPULATE_VIRTUALENV=1
 export PYTHON
 export MOZILLA_CENTRAL_PATH=$_topsrcdir
 export STLPORT_CPPFLAGS
 export STLPORT_LDFLAGS
 export STLPORT_LIBS
 export JS_STANDALONE=no
+export MOZ_LINKER
 
 if ! test -e js; then
     mkdir js
 fi
 
 AC_OUTPUT_SUBDIRS(js/src)
 ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -387,16 +387,20 @@ CFLAGS += $(MOZ_ZLIB_CFLAGS)
 EXTRA_LIBS += $(MOZ_ZLIB_LIBS)
 # Enable zlib usage if zlib has been located. When building the browser on
 # Windows, MOZ_ZLIB_LIBS is empty because zlib is part of libmozglue. We thus
 # also enable zlib if mozglue is present.
 ifneq (,$(MOZ_ZLIB_LIBS)$(MOZ_GLUE_LDFLAGS))
 DEFINES += -DUSE_ZLIB
 endif
 
+ifdef MOZ_LINKER
+DEFINES += -DMOZ_LINKER
+endif
+
 ifdef MOZ_NATIVE_ICU
 EXTRA_DSO_LDOPTS += $(MOZ_ICU_LIBS)
 else
 SHARED_LIBRARY_LIBS += $(MOZ_ICU_LIBS)
 endif
 
 # Prevent floating point errors caused by VC++ optimizations
 ifdef _MSC_VER
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4111,16 +4111,17 @@ AC_SUBST(LIB_SUFFIX)
 AC_SUBST(OBJ_SUFFIX)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(ASM_SUFFIX)
 AC_SUBST(IMPORT_LIB_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(CXX_VERSION)
 AC_SUBST(MSMANIFEST_TOOL)
+AC_SUBST(MOZ_LINKER)
 
 AC_MSG_CHECKING([for posix_fallocate])
 AC_TRY_LINK([#define _XOPEN_SOURCE 600
   #include <fcntl.h>],
                  [posix_fallocate(0, 0, 0);],
                  [ac_cv___posix_fallocate=true],
                  [ac_cv___posix_fallocate=false])
 
--- a/js/src/jit/AsmJSSignalHandlers.cpp
+++ b/js/src/jit/AsmJSSignalHandlers.cpp
@@ -308,42 +308,44 @@ LookupHeapAccess(const AsmJSModule &modu
 #if defined(JS_CPU_X64)
 # if defined(__DragonFly__)
 #  include <machine/npx.h> // for union savefpu
 # elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__FreeBSD_kernel__)
 #  include <machine/fpu.h> // for struct savefpu/fxsave64
 # endif
 #endif
 
+#if defined(ANDROID)
 // Not all versions of the Android NDK define ucontext_t or mcontext_t.
 // Detect this and provide custom but compatible definitions. Note that these
 // follow the GLibc naming convention to access register values from
 // mcontext_t.
 //
 // See: https://chromiumcodereview.appspot.com/10829122/
 // See: http://code.google.com/p/android/issues/detail?id=34784
-#if defined(ANDROID) && !defined(__BIONIC_HAVE_UCONTEXT_T)
-# if defined(__arm__)
+# if !defined(__BIONIC_HAVE_UCONTEXT_T)
+#  if defined(__arm__)
+
 // GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'.
 // Old versions of the C library <signal.h> didn't define the type.
-#  if !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT)
-#   include <asm/sigcontext.h>
-#  endif
+#   if !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT)
+#    include <asm/sigcontext.h>
+#   endif
 
 typedef struct sigcontext mcontext_t;
 
 typedef struct ucontext {
     uint32_t uc_flags;
     struct ucontext* uc_link;
     stack_t uc_stack;
     mcontext_t uc_mcontext;
     // Other fields are not used so don't define them here.
 } ucontext_t;
 
-# elif defined(__i386__)
+#  elif defined(__i386__)
 // x86 version for Android.
 typedef struct {
     uint32_t gregs[19];
     void* fpregs;
     uint32_t oldmask;
     uint32_t cr2;
 } mcontext_t;
 
@@ -351,18 +353,30 @@ typedef uint32_t kernel_sigset_t[2];  //
 typedef struct ucontext {
     uint32_t uc_flags;
     struct ucontext* uc_link;
     stack_t uc_stack;
     mcontext_t uc_mcontext;
     // Other fields are not used by V8, don't define them here.
 } ucontext_t;
 enum { REG_EIP = 14 };
-# endif
-#endif  // defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T)
+#  endif  // defined(__i386__)
+# endif  // !defined(__BIONIC_HAVE_UCONTEXT_T)
+#endif // defined(ANDROID)
+
+#if defined(ANDROID) && defined(MOZ_LINKER)
+// Apparently, on some Android systems, the signal handler is always passed
+// NULL as the faulting address. This would cause the asm.js signal handler to
+// think that a safe out-of-bounds access was a NULL-deref. This brokenness is
+// already detected by ElfLoader (enabled by MOZ_LINKER), so reuse that check
+// to disable asm.js compilation on systems where the signal handler is broken.
+extern "C" MFBT_API bool IsSignalHandlingBroken();
+#else
+static bool IsSignalHandlingBroken() { return false; }
+#endif // defined(MOZ_LINKER)
 
 #if !defined(XP_WIN)
 # define CONTEXT ucontext_t
 #endif
 
 #if !defined(XP_MACOSX)
 static uint8_t **
 ContextToPC(CONTEXT *context)
@@ -965,16 +979,19 @@ AsmJSFaultHandler(int signum, siginfo_t 
     else
         sPrevHandler.sa_handler(signum);
 }
 #endif
 
 bool
 js::EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt)
 {
+    if (IsSignalHandlingBroken())
+        return false;
+
 #if defined(XP_MACOSX)
     // On OSX, each JSRuntime gets its own handler.
     return rt->asmJSMachExceptionHandler.installed() || rt->asmJSMachExceptionHandler.install(rt);
 #else
     // Assume Windows or Unix. For these platforms, there is a single,
     // process-wide signal handler installed. Take care to only install it once.
     InstallSignalHandlersMutex::Lock lock;
     if (lock.handlersInstalled())