Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_SIGNAL_HANDLER_H_ | 5 #ifndef VM_SIGNAL_HANDLER_H_ |
| 6 #define VM_SIGNAL_HANDLER_H_ | 6 #define VM_SIGNAL_HANDLER_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 #include <signal.h> // NOLINT | 29 #include <signal.h> // NOLINT |
| 30 #include <sys/ucontext.h> // NOLINT | 30 #include <sys/ucontext.h> // NOLINT |
| 31 #elif defined(TARGET_OS_WINDOWS) | 31 #elif defined(TARGET_OS_WINDOWS) |
| 32 // Stub out for windows. | 32 // Stub out for windows. |
| 33 struct siginfo_t; | 33 struct siginfo_t; |
| 34 struct mcontext_t; | 34 struct mcontext_t; |
| 35 struct sigset_t { | 35 struct sigset_t { |
| 36 }; | 36 }; |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 | |
| 40 // Old linux kernels on ARM might require a trampoline to | |
| 41 // work around incorrect Thumb -> ARM transitions. See SignalHandlerTrampoline | |
| 42 // below for more details. | |
| 43 #if defined(HOST_ARCH_ARM) && \ | |
|
Florian Schneider
2016/05/02 14:43:43
s/HOST_ARCH_ARM/TARGET_ARCH_ARM/
zra
2016/05/02 15:53:54
I think HOST might be right since we don't want th
| |
| 44 (defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID)) | |
| 45 #define USE_SIGNAL_HANDLER_TRAMPOLINE | |
| 46 #endif | |
| 47 | |
| 48 | |
| 39 namespace dart { | 49 namespace dart { |
| 40 | 50 |
| 41 typedef void (*SignalAction)(int signal, siginfo_t* info, | 51 typedef void (*SignalAction)(int signal, siginfo_t* info, |
| 42 void* context); | 52 void* context); |
| 43 | 53 |
| 44 class SignalHandler : public AllStatic { | 54 class SignalHandler : public AllStatic { |
| 45 public: | 55 public: |
| 46 static void Install(SignalAction action); | 56 template<SignalAction action> |
| 57 static void Install() { | |
| 58 #if defined(USE_SIGNAL_HANDLER_TRAMPOLINE) | |
| 59 InstallImpl(SignalHandlerTrampoline<action>); | |
| 60 #else | |
| 61 InstallImpl(action); | |
| 62 #endif // defined(USE_SIGNAL_HANDLER_TRAMPOLINE) | |
| 63 } | |
| 47 static void Remove(); | 64 static void Remove(); |
| 48 static uintptr_t GetProgramCounter(const mcontext_t& mcontext); | 65 static uintptr_t GetProgramCounter(const mcontext_t& mcontext); |
| 49 static uintptr_t GetFramePointer(const mcontext_t& mcontext); | 66 static uintptr_t GetFramePointer(const mcontext_t& mcontext); |
| 50 static uintptr_t GetCStackPointer(const mcontext_t& mcontext); | 67 static uintptr_t GetCStackPointer(const mcontext_t& mcontext); |
| 51 static uintptr_t GetDartStackPointer(const mcontext_t& mcontext); | 68 static uintptr_t GetDartStackPointer(const mcontext_t& mcontext); |
| 52 static uintptr_t GetLinkRegister(const mcontext_t& mcontext); | 69 static uintptr_t GetLinkRegister(const mcontext_t& mcontext); |
| 70 | |
| 53 private: | 71 private: |
| 72 static void InstallImpl(SignalAction action); | |
| 73 | |
| 74 #if defined(USE_SIGNAL_HANDLER_TRAMPOLINE) | |
| 75 // Work around for a bug in old kernels (only fixed in 3.18 Android kernel): | |
| 76 // | |
| 77 // Kernel does not clear If-Then execution state bits when entering ARM signal | |
| 78 // handler which violates requirements imposed by ARM architecture reference. | |
| 79 // Some CPUs look at these bits even while in ARM mode which causes them | |
| 80 // to skip some instructions in the prologue of the signal handler. | |
| 81 // | |
| 82 // To work around the issue we insert enough NOPs in the prologue to ensure | |
| 83 // that no actual instructions are skipped and then branch to the actual | |
| 84 // signal handler. | |
| 85 // | |
| 86 // For the kernel patch that fixes the issue see: http://git.kernel.org/cgit/l inux/kernel/git/torvalds/linux.git/commit/?id=6ecf830e5029598732e04067e325d94609 7519cb | |
| 87 // | |
| 88 // Note: this function is marked "naked" because we must guarantee that | |
| 89 // our NOPs occur before any compiler generated prologue. | |
| 90 template <SignalAction action> | |
| 91 static __attribute__((naked)) void SignalHandlerTrampoline(int signal, | |
| 92 siginfo_t* info, | |
| 93 void* context_) { | |
| 94 // IT (If-Then) instruction makes up to four instructions that follow it | |
| 95 // conditional. | |
| 96 asm volatile("nop; nop; nop; nop" : : : "memory"); | |
| 97 | |
| 98 // Tail-call into the actual signal handler. | |
| 99 // Note: this code is split into a separate inline assembly block because | |
| 100 // any code that compiler generates to satisfy register constraints must | |
| 101 // be generated after four NOPs. | |
| 102 register int arg0 asm("r0") = signal; | |
| 103 register siginfo_t* arg1 asm("r1") = info; | |
| 104 register void* arg2 asm("r2") = context_; | |
| 105 asm volatile("bx %3" | |
| 106 : | |
| 107 : "r"(arg0), "r"(arg1), "r"(arg2), | |
| 108 "r"(action) | |
| 109 : "memory"); | |
| 110 } | |
| 111 #endif // defined(USE_SIGNAL_HANDLER_TRAMPOLINE) | |
| 54 }; | 112 }; |
| 55 | 113 |
| 56 | 114 |
| 115 #undef USE_SIGNAL_HANDLER_TRAMPOLINE | |
| 116 | |
| 117 | |
| 57 } // namespace dart | 118 } // namespace dart |
| 58 | 119 |
| 59 #endif // VM_SIGNAL_HANDLER_H_ | 120 #endif // VM_SIGNAL_HANDLER_H_ |
| OLD | NEW |