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 |