Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(670)

Unified Diff: runtime/vm/signal_handler.h

Issue 1940883002: Work around a kernel bug on Android. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/signal_handler_android.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/signal_handler.h
diff --git a/runtime/vm/signal_handler.h b/runtime/vm/signal_handler.h
index b204c55d55f1b127f781fc8c73b8c50989861b3d..9f1ef93288ca51662bbc4160197441c921bfa6cc 100644
--- a/runtime/vm/signal_handler.h
+++ b/runtime/vm/signal_handler.h
@@ -36,6 +36,16 @@ struct sigset_t {
};
#endif
+
+// Old linux kernels on ARM might require a trampoline to
+// work around incorrect Thumb -> ARM transitions. See SignalHandlerTrampoline
+// below for more details.
+#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
+ (defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID))
+#define USE_SIGNAL_HANDLER_TRAMPOLINE
+#endif
+
+
namespace dart {
typedef void (*SignalAction)(int signal, siginfo_t* info,
@@ -43,17 +53,68 @@ typedef void (*SignalAction)(int signal, siginfo_t* info,
class SignalHandler : public AllStatic {
public:
- static void Install(SignalAction action);
+ template<SignalAction action>
+ static void Install() {
+#if defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
+ InstallImpl(SignalHandlerTrampoline<action>);
+#else
+ InstallImpl(action);
+#endif // defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
+ }
static void Remove();
static uintptr_t GetProgramCounter(const mcontext_t& mcontext);
static uintptr_t GetFramePointer(const mcontext_t& mcontext);
static uintptr_t GetCStackPointer(const mcontext_t& mcontext);
static uintptr_t GetDartStackPointer(const mcontext_t& mcontext);
static uintptr_t GetLinkRegister(const mcontext_t& mcontext);
+
private:
+ static void InstallImpl(SignalAction action);
+
+#if defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
+ // Work around for a bug in old kernels (only fixed in 3.18 Android kernel):
+ //
+ // Kernel does not clear If-Then execution state bits when entering ARM signal
+ // handler which violates requirements imposed by ARM architecture reference.
+ // Some CPUs look at these bits even while in ARM mode which causes them
+ // to skip some instructions in the prologue of the signal handler.
+ //
+ // To work around the issue we insert enough NOPs in the prologue to ensure
+ // that no actual instructions are skipped and then branch to the actual
+ // signal handler.
+ //
+ // For the kernel patch that fixes the issue see: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6ecf830e5029598732e04067e325d946097519cb
+ //
+ // Note: this function is marked "naked" because we must guarantee that
+ // our NOPs occur before any compiler generated prologue.
+ template <SignalAction action>
+ static __attribute__((naked)) void SignalHandlerTrampoline(int signal,
+ siginfo_t* info,
+ void* context_) {
+ // IT (If-Then) instruction makes up to four instructions that follow it
+ // conditional.
+ asm volatile("nop; nop; nop; nop" : : : "memory");
+
+ // Tail-call into the actual signal handler.
+ // Note: this code is split into a separate inline assembly block because
+ // any code that compiler generates to satisfy register constraints must
+ // be generated after four NOPs.
+ register int arg0 asm("r0") = signal;
+ register siginfo_t* arg1 asm("r1") = info;
+ register void* arg2 asm("r2") = context_;
+ asm volatile("bx %3"
+ :
+ : "r"(arg0), "r"(arg1), "r"(arg2),
+ "r"(action)
+ : "memory");
+ }
+#endif // defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
};
+#undef USE_SIGNAL_HANDLER_TRAMPOLINE
+
+
} // namespace dart
#endif // VM_SIGNAL_HANDLER_H_
« no previous file with comments | « no previous file | runtime/vm/signal_handler_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698