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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/globals.h"
6#include "vm/instructions.h"
7#include "vm/signal_handler.h"
8#include "vm/simulator.h"
9#if defined(HOST_OS_LINUX)
10
11namespace dart {
12
13uintptr_t SignalHandler::GetProgramCounter(const mcontext_t& mcontext) {
14 uintptr_t pc = 0;
15
16#if defined(HOST_ARCH_IA32)
17 pc = static_cast<uintptr_t>(mcontext.gregs[REG_EIP]);
18#elif defined(HOST_ARCH_X64)
19 pc = static_cast<uintptr_t>(mcontext.gregs[REG_RIP]);
20#elif defined(HOST_ARCH_ARM)
21 pc = static_cast<uintptr_t>(mcontext.arm_pc);
22#elif defined(HOST_ARCH_ARM64)
23 pc = static_cast<uintptr_t>(mcontext.pc);
24#else
25#error Unsupported architecture.
26#endif // HOST_ARCH_...
27 return pc;
28}
29
30uintptr_t SignalHandler::GetFramePointer(const mcontext_t& mcontext) {
31 uintptr_t fp = 0;
32
33#if defined(HOST_ARCH_IA32)
34 fp = static_cast<uintptr_t>(mcontext.gregs[REG_EBP]);
35#elif defined(HOST_ARCH_X64)
36 fp = static_cast<uintptr_t>(mcontext.gregs[REG_RBP]);
37#elif defined(HOST_ARCH_ARM)
38 // B1.3.3 Program Status Registers (PSRs)
39 if ((mcontext.arm_cpsr & (1 << 5)) != 0) {
40 // Thumb mode.
41 fp = static_cast<uintptr_t>(mcontext.arm_r7);
42 } else {
43 // ARM mode.
44 fp = static_cast<uintptr_t>(mcontext.arm_fp);
45 }
46#elif defined(HOST_ARCH_ARM64)
47 fp = static_cast<uintptr_t>(mcontext.regs[29]);
48#else
49#error Unsupported architecture.
50#endif // HOST_ARCH_...
51
52 return fp;
53}
54
55uintptr_t SignalHandler::GetCStackPointer(const mcontext_t& mcontext) {
56 uintptr_t sp = 0;
57
58#if defined(HOST_ARCH_IA32)
59 sp = static_cast<uintptr_t>(mcontext.gregs[REG_ESP]);
60#elif defined(HOST_ARCH_X64)
61 sp = static_cast<uintptr_t>(mcontext.gregs[REG_RSP]);
62#elif defined(HOST_ARCH_ARM)
63 sp = static_cast<uintptr_t>(mcontext.arm_sp);
64#elif defined(HOST_ARCH_ARM64)
65 sp = static_cast<uintptr_t>(mcontext.sp);
66#else
67#error Unsupported architecture.
68#endif // HOST_ARCH_...
69 return sp;
70}
71
72uintptr_t SignalHandler::GetDartStackPointer(const mcontext_t& mcontext) {
73#if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
74 return static_cast<uintptr_t>(mcontext.regs[SPREG]);
75#else
76 return GetCStackPointer(mcontext);
77#endif
78}
79
80uintptr_t SignalHandler::GetLinkRegister(const mcontext_t& mcontext) {
81 uintptr_t lr = 0;
82
83#if defined(HOST_ARCH_IA32)
84 lr = 0;
85#elif defined(HOST_ARCH_X64)
86 lr = 0;
87#elif defined(HOST_ARCH_ARM)
88 lr = static_cast<uintptr_t>(mcontext.arm_lr);
89#elif defined(HOST_ARCH_ARM64)
90 lr = static_cast<uintptr_t>(mcontext.regs[30]);
91#else
92#error Unsupported architecture.
93#endif // HOST_ARCH_...
94 return lr;
95}
96
97void SignalHandler::InstallImpl(SignalAction action) {
98 struct sigaction act = {};
99 act.sa_handler = NULL;
100 act.sa_sigaction = action;
101 sigemptyset(&act.sa_mask);
102 act.sa_flags = SA_RESTART | SA_SIGINFO;
103 int r = sigaction(SIGPROF, &act, NULL);
104 ASSERT(r == 0);
105}
106
107void SignalHandler::Remove() {
108 // Ignore future SIGPROF signals because by default SIGPROF will terminate
109 // the process and we may have some signals in flight.
110 struct sigaction act = {};
111 act.sa_handler = SIG_IGN;
112 sigemptyset(&act.sa_mask);
113 act.sa_flags = 0;
114 int r = sigaction(SIGPROF, &act, NULL);
115 ASSERT(r == 0);
116}
117
118} // namespace dart
119
120#endif // defined(HOST_OS_LINUX)
121