diff --git a/mfbt/LinuxSignal.h b/mfbt/LinuxSignal.h new file mode 100644 index 00000000000..9b8e1bbbbe0 --- /dev/null +++ b/mfbt/LinuxSignal.h @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_LinuxSignal_h +#define mozilla_LinuxSignal_h + +namespace mozilla { + +#if defined(__arm__) + +// Some (old) Linux kernels on ARM have a bug where a signal handler +// can be called without clearing the IT bits in CPSR first. The result +// is that the first few instructions of the handler could be skipped, +// ultimately resulting in crashes. To workaround this bug, the handler +// on ARM is a trampoline that starts with enough NOP instructions, so +// that even if the IT bits are not cleared, only the NOP instructions +// will be skipped over. + +template +__attribute__((naked)) void +SignalTrampoline(int aSignal, siginfo_t* aInfo, void* aContext) +{ + asm volatile ( + "nop; nop; nop; nop" + : : : "memory"); + + // Because the assembler may generate additional insturctions below, we + // need to ensure NOPs are inserted first by separating them out above. + + asm volatile ( + "bx %0" + : + : "r"(H), "l"(aSignal), "l"(aInfo), "l"(aContext) + : "memory"); +} + +# define MOZ_SIGNAL_TRAMPOLINE(h) (mozilla::SignalTrampoline) + +#else // __arm__ + +# define MOZ_SIGNAL_TRAMPOLINE(h) (h) + +#endif // __arm__ + +} // namespace mozilla + +#endif // mozilla_LinuxSignal_h diff --git a/mfbt/moz.build b/mfbt/moz.build index 81f33ba2a79..90ef1aae540 100644 --- a/mfbt/moz.build +++ b/mfbt/moz.build @@ -78,6 +78,10 @@ if CONFIG['OS_ARCH'] == 'WINNT': EXPORTS.mozilla += [ 'WindowsVersion.h', ] +elif CONFIG['OS_ARCH'] == 'Linux': + EXPORTS.mozilla += [ + 'LinuxSignal.h', + ] UNIFIED_SOURCES = [ 'double-conversion/bignum-dtoa.cc',