• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PANDA_RUNTIME_SIGNAL_HANDLER_H
17 #define PANDA_RUNTIME_SIGNAL_HANDLER_H
18 
19 #include <csignal>
20 #include <cstdint>
21 #include <iostream>
22 #include <vector>
23 #include <libpandabase/macros.h>
24 #include "runtime/include/mem/panda_containers.h"
25 #include "libpandabase/os/sighook.h"
26 
27 namespace ark {
28 
29 class Method;
30 class SignalHandler;
31 
32 bool IsInvalidPointer(uintptr_t addr);
33 bool InAllocatedCodeRange(uintptr_t pc);
34 
35 #ifdef PANDA_TARGET_ARM32
36 #define CONTEXT_PC uc_->uc_mcontext.arm_pc  // NOLINT(cppcoreguidelines-macro-usage)
37 #define CONTEXT_SP uc_->uc_mcontext.arm_sp  // NOLINT(cppcoreguidelines-macro-usage)
38 #define CONTEXT_FP uc_->uc_mcontext.arm_fp  // NOLINT(cppcoreguidelines-macro-usage)
39 #define CONTEXT_LR uc_->uc_mcontext.arm_lr  // NOLINT(cppcoreguidelines-macro-usage)
40 #elif defined(PANDA_TARGET_ARM64)
41 #define CONTEXT_PC uc_->uc_mcontext.pc        // NOLINT(cppcoreguidelines-macro-usage)
42 #define CONTEXT_FP uc_->uc_mcontext.regs[29]  // NOLINT(cppcoreguidelines-macro-usage)
43 #define CONTEXT_LR uc_->uc_mcontext.regs[30]  // NOLINT(cppcoreguidelines-macro-usage)
44 #elif defined(PANDA_TARGET_AMD64)
45 #define CONTEXT_PC uc_->uc_mcontext.gregs[REG_RIP]  // NOLINT(cppcoreguidelines-macro-usage)
46 #define CONTEXT_SP uc_->uc_mcontext.gregs[REG_RSP]  // NOLINT(cppcoreguidelines-macro-usage)
47 #define CONTEXT_FP uc_->uc_mcontext.gregs[REG_RBP]  // NOLINT(cppcoreguidelines-macro-usage)
48 #elif defined(PANDA_TARGET_X86)
49 #define CONTEXT_PC uc_->uc_mcontext.gregs[REG_EIP]  // NOLINT(cppcoreguidelines-macro-usage)
50 #define CONTEXT_SP uc_->uc_mcontext.gregs[REG_ESP]  // NOLINT(cppcoreguidelines-macro-usage)
51 #define CONTEXT_FP uc_->uc_mcontext.gregs[REG_EBP]  // NOLINT(cppcoreguidelines-macro-usage)
52 #endif
53 
54 class SignalContext {
55 public:
SignalContext(void * ucontextRaw)56     explicit SignalContext(void *ucontextRaw)
57     {
58         uc_ = reinterpret_cast<ucontext_t *>(ucontextRaw);
59     }
GetPC()60     uintptr_t GetPC()
61     {
62         return CONTEXT_PC;
63     }
SetPC(uintptr_t pc)64     void SetPC(uintptr_t pc)
65     {
66         CONTEXT_PC = pc;
67     }
GetSP()68     uintptr_t GetSP()
69     {
70 #if defined(PANDA_TARGET_ARM64)
71         auto sc = reinterpret_cast<struct sigcontext *>(&uc_->uc_mcontext);
72         return sc->sp;
73 #else
74         return CONTEXT_SP;
75 #endif
76     }
GetFP()77     uintptr_t *GetFP()
78     {
79         return reinterpret_cast<uintptr_t *>(CONTEXT_FP);
80     }
81 #if (defined(PANDA_TARGET_ARM64) || defined(PANDA_TARGET_ARM32))
GetLR()82     uintptr_t GetLR()
83     {
84         return CONTEXT_LR;
85     }
SetLR(uintptr_t lr)86     void SetLR(uintptr_t lr)
87     {
88         CONTEXT_LR = lr;
89     }
90 #elif defined(PANDA_TARGET_AMD64)
SetSP(uintptr_t sp)91     void SetSP(uintptr_t sp)
92     {
93         CONTEXT_SP = sp;
94     }
95 
96 #endif
97 
98 private:
99     ucontext_t *uc_;
100 };
101 
102 class SignalManager {
103 public:
104     void InitSignals();
105 
IsInitialized()106     bool IsInitialized()
107     {
108         return isInit_;
109     }
110 
111     bool SignalActionHandler(int sig, siginfo_t *info, void *context);
112     bool InOatCode(const siginfo_t *siginfo, const void *context, bool checkBytecodePc) const;
113     bool InOtherCode(int sig, const siginfo_t *info, const void *context) const;
114 
115     void AddHandler(SignalHandler *handler, bool oatCode);
116 
117     void RemoveHandler(SignalHandler *handler);
118     void GetMethodAndReturnPcAndSp(const siginfo_t *siginfo, const void *context, const Method **outMethod,
119                                    const uintptr_t *outReturnPc, const uintptr_t *outSp);
120 
GetAllocator()121     mem::InternalAllocatorPtr GetAllocator()
122     {
123         return allocator_;
124     }
125 
126     void DeleteHandlersArray();
127 
SignalManager(mem::InternalAllocatorPtr allocator)128     explicit SignalManager(mem::InternalAllocatorPtr allocator) : allocator_(allocator) {}
129     SignalManager(SignalManager &&) = delete;
130     SignalManager &operator=(SignalManager &&) = delete;
131     virtual ~SignalManager() = default;
132 
133 private:
134     bool isInit_ {false};
135     mem::InternalAllocatorPtr allocator_;
136     PandaVector<SignalHandler *> oatCodeHandler_;
137     PandaVector<SignalHandler *> otherHandlers_;
138     NO_COPY_SEMANTIC(SignalManager);
139 };
140 
141 class SignalHandler {
142 public:
143     SignalHandler() = default;
144 
145     virtual bool Action(int sig, siginfo_t *siginfo, void *context) = 0;
146 
147     SignalHandler(SignalHandler &&) = delete;
148     SignalHandler &operator=(SignalHandler &&) = delete;
149     virtual ~SignalHandler() = default;
150 
151 private:
152     NO_COPY_SEMANTIC(SignalHandler);
153 };
154 
155 class NullPointerHandler final : public SignalHandler {
156 public:
157     NullPointerHandler() = default;
158 
159     bool Action(int sig, siginfo_t *siginfo, void *context) override;
160 
161     NullPointerHandler(NullPointerHandler &&) = delete;
162     NullPointerHandler &operator=(NullPointerHandler &&) = delete;
163     ~NullPointerHandler() override;
164 
165 private:
166     NO_COPY_SEMANTIC(NullPointerHandler);
167 };
168 
169 class StackOverflowHandler final : public SignalHandler {
170 public:
171     StackOverflowHandler() = default;
172     ~StackOverflowHandler() override = default;
173 
174     NO_COPY_SEMANTIC(StackOverflowHandler);
175     NO_MOVE_SEMANTIC(StackOverflowHandler);
176 
177     bool Action(int sig, siginfo_t *siginfo, void *context) override;
178 };
179 
180 }  // namespace ark
181 
182 #endif  // PANDA_RUNTIME_SIGNAL_HANDLER_H
183