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