• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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