1 /*
2  * Copyright (c) 2023-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 ARM_EXIDX_H
17 #define ARM_EXIDX_H
18 
19 #include <deque>
20 #include <memory>
21 #include <vector>
22 
23 #include "dfx_errors.h"
24 #include "dfx_memory.h"
25 #include "unwind_context.h"
26 
27 namespace OHOS {
28 namespace HiviewDFX {
29 struct ExidxContext {
30 public:
31     int32_t vsp = 0;
32     uint32_t transformedBits = 0;
33     std::vector<int32_t> regs;
34 
35     void Reset(size_t size = 0);
36     void Transform(uint32_t reg);
37     bool IsTransformed(uint32_t reg);
38     void AddUpVsp(int32_t imm);
39 };
40 
41 class ArmExidx {
42 public:
43     explicit ArmExidx(std::shared_ptr<DfxMemory> memory);
44     virtual ~ArmExidx() = default;
45 
46     bool SearchEntry(uintptr_t pc, struct UnwindTableInfo uti, struct UnwindEntryInfo& uei);
47     bool Step(uintptr_t entryOffset, std::shared_ptr<RegLocState> rs);
48 
GetLastErrorCode()49     const uint16_t& GetLastErrorCode() { return lastErrorData_.GetCode(); }
GetLastErrorAddr()50     const uint64_t& GetLastErrorAddr() { return lastErrorData_.GetAddr(); }
51 
52 private:
53     struct DecodeTable {
54         uint8_t mask;
55         uint8_t result;
56         bool (ArmExidx::*decoder)();
57     };
58 
59     bool Eval(uintptr_t entryOffset);
60     void FlushInstr();
61 
62     void LogRawData();
63     bool ExtractEntryData(uintptr_t entryOffset);
64     bool ExtractEntryTab(uintptr_t tabOffset);
65     bool GetOpCode();
66     bool Decode(DecodeTable decodeTable[], size_t size);
67     bool Decode00xxxxxx();
68     bool Decode01xxxxxx();
69     bool Decode1000iiiiiiiiiiii();
70     bool Decode1001nnnn();
71     bool Decode1010nnnn();
72     bool Decode10110000();
73     bool Decode101100010000iiii();
74     bool Decode10110010uleb128();
75     bool Decode10110011sssscccc();
76     bool Decode101101nn();
77     bool Decode10111nnn();
78     bool Decode11000110sssscccc();
79     bool Decode110001110000iiii();
80     bool Decode1100100nsssscccc();
81     bool Decode11001yyy();
82     bool Decode11000nnn();
83     bool Decode11010nnn();
84     bool Decode11xxxyyy();
85     bool DecodeSpare();
86 
87 protected:
88     UnwindErrorData lastErrorData_;
89     std::shared_ptr<RegLocState> rsState_;
90     std::shared_ptr<DfxMemory> memory_;
91     ExidxContext context_;
92     std::deque<uint8_t> ops_;
93     uint8_t curOp_ = 0;
94     bool isPcSet_ = false;
95 };
96 } // namespace HiviewDFX
97 } // namespace OHOS
98 #endif
99