1 /* 2 * Copyright (c) 2021-2023 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 #ifndef DFX_REGS_H 16 #define DFX_REGS_H 17 18 #include <cstdint> 19 #include <string> 20 #include <memory> 21 #include <sys/types.h> 22 #include <ucontext.h> 23 #include <vector> 24 #include "dfx_define.h" 25 #include "unwinder_define.h" 26 27 namespace OHOS { 28 namespace HiviewDFX { 29 #define FP_MINI_REGS_SIZE 4 30 #define QUT_MINI_REGS_SIZE 7 31 32 class DfxRegs { 33 public: 34 DfxRegs() = default; ~DfxRegs()35 virtual ~DfxRegs() {}; 36 static std::shared_ptr<DfxRegs> Create(); 37 static std::shared_ptr<DfxRegs> CreateFromContext(const ucontext_t &context); 38 39 inline uintptr_t& operator[](size_t reg) { return regsData_[reg]; } 40 RawData()41 void* RawData() { return regsData_.data(); } 42 std::vector<uintptr_t> GetRegsData() const; 43 void SetRegsData(const std::vector<uintptr_t>& regs); 44 45 virtual std::string PrintRegs() const = 0; 46 virtual inline AT_ALWAYS_INLINE void GetFramePointerMiniRegs(void *regs) = 0; 47 48 std::string GetSpecialRegisterName(uintptr_t val) const; 49 protected: 50 std::string PrintSpecialRegs() const; 51 public: 52 uintptr_t fp_ {0}; 53 uintptr_t pc_ {0}; 54 uintptr_t sp_ {0}; 55 uintptr_t lr_ {0}; 56 protected: 57 std::vector<uintptr_t> regsData_ {}; 58 }; 59 60 class DfxRegsArm : public DfxRegs { 61 public: 62 explicit DfxRegsArm(const ucontext_t &context); 63 DfxRegsArm() = default; ~DfxRegsArm()64 ~DfxRegsArm() override {}; 65 std::string PrintRegs() const override; 66 // Get 4 registers(r7/r11/sp/pc) GetFramePointerMiniRegs(void * regs)67 inline AT_ALWAYS_INLINE void GetFramePointerMiniRegs(void *regs) override 68 { 69 #if defined(__arm__) 70 asm volatile( 71 ".align 2\n" 72 "bx pc\n" 73 "nop\n" 74 ".code 32\n" 75 "stmia %[base], {r7, r11}\n" 76 "add %[base], #8\n" 77 "mov r1, r13\n" 78 "mov r2, r15\n" 79 "stmia %[base], {r1, r2}\n" 80 "orr %[base], pc, #1\n" 81 "bx %[base]\n" 82 : [base] "+r"(regs) 83 : 84 : "r1", "r2", "memory"); 85 #endif 86 } 87 }; 88 89 class DfxRegsArm64 : public DfxRegs { 90 public: 91 explicit DfxRegsArm64(const ucontext_t &context); 92 DfxRegsArm64() = default; ~DfxRegsArm64()93 ~DfxRegsArm64() override {}; 94 std::string PrintRegs() const override; 95 // Get 4 registers from x29 to x32. GetFramePointerMiniRegs(void * regs)96 inline AT_ALWAYS_INLINE void GetFramePointerMiniRegs(void *regs) override 97 { 98 #if defined(__aarch64__) 99 asm volatile( 100 "1:\n" 101 "stp x29, x30, [%[base], #0]\n" 102 "mov x12, sp\n" 103 "adr x13, 1b\n" 104 "stp x12, x13, [%[base], #16]\n" 105 : [base] "+r"(regs) 106 : 107 : "x12", "x13", "memory"); 108 #endif 109 } 110 }; 111 112 class DfxRegsX86_64 : public DfxRegs { 113 public: 114 explicit DfxRegsX86_64(const ucontext_t &context); 115 DfxRegsX86_64() = default; ~DfxRegsX86_64()116 ~DfxRegsX86_64() override {}; 117 std::string PrintRegs() const override; 118 inline AT_ALWAYS_INLINE void GetFramePointerMiniRegs(void *regs) override; 119 }; 120 } // namespace HiviewDFX 121 } // namespace OHOS 122 #endif 123