| /* 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 <void (*H)(int, siginfo_t*, void*)> | 
 | __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<h>) | 
 |  | 
 | #else // __arm__ | 
 |  | 
 | # define MOZ_SIGNAL_TRAMPOLINE(h) (h) | 
 |  | 
 | #endif // __arm__ | 
 |  | 
 | } // namespace mozilla | 
 |  | 
 | #endif // mozilla_LinuxSignal_h |