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 "dfx_elf.h"
26 #include "dfx_memory.h"
27 #include "unwind_define.h"
28 
29 namespace OHOS {
30 namespace HiviewDFX {
31 class DfxRegs {
32 public:
DfxRegs()33     explicit DfxRegs() : regsData_(REG_LAST) {}
34     virtual ~DfxRegs() = default;
35 
36     static std::shared_ptr<DfxRegs> Create();
37     static std::shared_ptr<DfxRegs> CreateFromUcontext(const ucontext_t& context);
38     static std::shared_ptr<DfxRegs> CreateFromRegs(const UnwindMode mode, const uintptr_t* regs,
39                                                    size_t size);
40     static std::shared_ptr<DfxRegs> CreateRemoteRegs(pid_t pid);
41     virtual void SetFromUcontext(const ucontext_t& context) = 0;
42     virtual void SetFromFpMiniRegs(const uintptr_t* regs, const size_t size) = 0;
43     virtual void SetFromQutMiniRegs(const uintptr_t* regs, const size_t size) = 0;
44     virtual std::string PrintRegs() const = 0;
45     virtual bool SetPcFromReturnAddress(std::shared_ptr<DfxMemory> memory) = 0;
46     virtual bool StepIfSignalFrame(uintptr_t pc, std::shared_ptr<DfxMemory> memory) = 0;
47 
48     inline uintptr_t& operator[](size_t idx) { return regsData_[idx]; }
49 
RawData()50     void* RawData() { return regsData_.data(); }
RegsSize()51     size_t RegsSize() const { return regsData_.size(); }
52     std::vector<uintptr_t> GetRegsData() const;
53     void SetRegsData(const std::vector<uintptr_t>& regsData);
54     void SetRegsData(const uintptr_t* regs, const size_t size);
55     uintptr_t* GetReg(size_t idx);
56     void SetReg(const int idx, const uintptr_t* val);
57 
58     uintptr_t GetSp() const;
59     void SetSp(uintptr_t sp);
60     uintptr_t GetPc() const;
61     void SetPc(uintptr_t pc);
62     uintptr_t GetFp() const;
63     void SetFp(uintptr_t fp);
64     void GetSpecialRegs(uintptr_t& fp, uintptr_t& lr, uintptr_t& sp, uintptr_t& pc) const;
65     void SetSpecialRegs(uintptr_t fp, uintptr_t lr, uintptr_t sp, uintptr_t pc);
66     std::string GetSpecialRegsName(uintptr_t val) const;
67     std::string GetSpecialRegsNameByIndex(int index) const;
68     std::string PrintSpecialRegs() const;
69 protected:
70     std::vector<uintptr_t> regsData_ {};
71 };
72 
73 #if defined(__arm__)
74 class DfxRegsArm : public DfxRegs {
75 public:
76     DfxRegsArm() = default;
77     ~DfxRegsArm() = default;
78     void SetFromUcontext(const ucontext_t& context) override;
79     void SetFromFpMiniRegs(const uintptr_t* regs, const size_t size) override;
80     void SetFromQutMiniRegs(const uintptr_t* regs, const size_t size) override;
81     std::string PrintRegs() const override;
82     bool SetPcFromReturnAddress(std::shared_ptr<DfxMemory> memory) override;
83     bool StepIfSignalFrame(uintptr_t pc, std::shared_ptr<DfxMemory> memory) override;
84 };
85 #endif
86 
87 #if defined(__aarch64__)
88 class DfxRegsArm64 : public DfxRegs {
89 public:
90     DfxRegsArm64() = default;
91     ~DfxRegsArm64() = default;
92     void SetFromUcontext(const ucontext_t& context) override;
93     void SetFromFpMiniRegs(const uintptr_t* regs, const size_t size) override;
94     void SetFromQutMiniRegs(const uintptr_t* regs, const size_t size) override;
95     std::string PrintRegs() const override;
96     bool SetPcFromReturnAddress(std::shared_ptr<DfxMemory> memory) override;
97     bool StepIfSignalFrame(uintptr_t pc, std::shared_ptr<DfxMemory> memory) override;
98 };
99 #endif
100 
101 #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64
102 class DfxRegsRiscv64 : public DfxRegs {
103 public:
104     DfxRegsRiscv64() = default;
105     ~DfxRegsRiscv64() = default;
106     void SetFromUcontext(const ucontext_t& context) override;
107     void SetFromFpMiniRegs(const uintptr_t* regs, const size_t size) override;
108     void SetFromQutMiniRegs(const uintptr_t* regs, const size_t size) override;
109     std::string PrintRegs() const override;
110     bool SetPcFromReturnAddress(std::shared_ptr<DfxMemory> memory) override;
111     bool StepIfSignalFrame(uintptr_t pc, std::shared_ptr<DfxMemory> memory) override;
112 };
113 #endif
114 
115 #if defined(__x86_64__)
116 class DfxRegsX86_64 : public DfxRegs {
117 public:
118     DfxRegsX86_64() = default;
119     ~DfxRegsX86_64() = default;
120     void SetFromUcontext(const ucontext_t& context) override;
121     void SetFromFpMiniRegs(const uintptr_t* regs, const size_t size) override;
122     void SetFromQutMiniRegs(const uintptr_t* regs, const size_t size) override;
123     std::string PrintRegs() const override;
124     bool SetPcFromReturnAddress(std::shared_ptr<DfxMemory> memory) override;
125     bool StepIfSignalFrame(uintptr_t pc, std::shared_ptr<DfxMemory> memory) override;
126 };
127 #endif
128 } // namespace HiviewDFX
129 } // namespace OHOS
130 #endif
131