1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License.
5800b99b8Sopenharmony_ci * You may obtain a copy of the License at
6800b99b8Sopenharmony_ci *
7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8800b99b8Sopenharmony_ci *
9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and
13800b99b8Sopenharmony_ci * limitations under the License.
14800b99b8Sopenharmony_ci */
15800b99b8Sopenharmony_ci
16800b99b8Sopenharmony_ci#ifndef ARM_EXIDX_H
17800b99b8Sopenharmony_ci#define ARM_EXIDX_H
18800b99b8Sopenharmony_ci
19800b99b8Sopenharmony_ci#include <deque>
20800b99b8Sopenharmony_ci#include <memory>
21800b99b8Sopenharmony_ci#include <vector>
22800b99b8Sopenharmony_ci
23800b99b8Sopenharmony_ci#include "dfx_errors.h"
24800b99b8Sopenharmony_ci#include "dfx_memory.h"
25800b99b8Sopenharmony_ci#include "unwind_context.h"
26800b99b8Sopenharmony_ci
27800b99b8Sopenharmony_cinamespace OHOS {
28800b99b8Sopenharmony_cinamespace HiviewDFX {
29800b99b8Sopenharmony_cistruct ExidxContext {
30800b99b8Sopenharmony_cipublic:
31800b99b8Sopenharmony_ci    int32_t vsp = 0;
32800b99b8Sopenharmony_ci    uint32_t transformedBits = 0;
33800b99b8Sopenharmony_ci    std::vector<int32_t> regs;
34800b99b8Sopenharmony_ci
35800b99b8Sopenharmony_ci    void Reset(size_t size = 0);
36800b99b8Sopenharmony_ci    void Transform(uint32_t reg);
37800b99b8Sopenharmony_ci    bool IsTransformed(uint32_t reg);
38800b99b8Sopenharmony_ci    void AddUpVsp(int32_t imm);
39800b99b8Sopenharmony_ci};
40800b99b8Sopenharmony_ci
41800b99b8Sopenharmony_ciclass ArmExidx {
42800b99b8Sopenharmony_cipublic:
43800b99b8Sopenharmony_ci    explicit ArmExidx(std::shared_ptr<DfxMemory> memory);
44800b99b8Sopenharmony_ci    virtual ~ArmExidx() = default;
45800b99b8Sopenharmony_ci
46800b99b8Sopenharmony_ci    bool SearchEntry(uintptr_t pc, struct UnwindTableInfo uti, struct UnwindEntryInfo& uei);
47800b99b8Sopenharmony_ci    bool Step(uintptr_t entryOffset, std::shared_ptr<RegLocState> rs);
48800b99b8Sopenharmony_ci
49800b99b8Sopenharmony_ci    const uint16_t& GetLastErrorCode() { return lastErrorData_.GetCode(); }
50800b99b8Sopenharmony_ci    const uint64_t& GetLastErrorAddr() { return lastErrorData_.GetAddr(); }
51800b99b8Sopenharmony_ci
52800b99b8Sopenharmony_ciprivate:
53800b99b8Sopenharmony_ci    struct DecodeTable {
54800b99b8Sopenharmony_ci        uint8_t mask;
55800b99b8Sopenharmony_ci        uint8_t result;
56800b99b8Sopenharmony_ci        bool (ArmExidx::*decoder)();
57800b99b8Sopenharmony_ci    };
58800b99b8Sopenharmony_ci
59800b99b8Sopenharmony_ci    bool Eval(uintptr_t entryOffset);
60800b99b8Sopenharmony_ci    void FlushInstr();
61800b99b8Sopenharmony_ci
62800b99b8Sopenharmony_ci    void LogRawData();
63800b99b8Sopenharmony_ci    bool ExtractEntryData(uintptr_t entryOffset);
64800b99b8Sopenharmony_ci    bool ExtractEntryTab(uintptr_t tabOffset);
65800b99b8Sopenharmony_ci    bool GetOpCode();
66800b99b8Sopenharmony_ci    bool Decode(DecodeTable decodeTable[], size_t size);
67800b99b8Sopenharmony_ci    bool Decode00xxxxxx();
68800b99b8Sopenharmony_ci    bool Decode01xxxxxx();
69800b99b8Sopenharmony_ci    bool Decode1000iiiiiiiiiiii();
70800b99b8Sopenharmony_ci    bool Decode1001nnnn();
71800b99b8Sopenharmony_ci    bool Decode1010nnnn();
72800b99b8Sopenharmony_ci    bool Decode10110000();
73800b99b8Sopenharmony_ci    bool Decode101100010000iiii();
74800b99b8Sopenharmony_ci    bool Decode10110010uleb128();
75800b99b8Sopenharmony_ci    bool Decode10110011sssscccc();
76800b99b8Sopenharmony_ci    bool Decode101101nn();
77800b99b8Sopenharmony_ci    bool Decode10111nnn();
78800b99b8Sopenharmony_ci    bool Decode11000110sssscccc();
79800b99b8Sopenharmony_ci    bool Decode110001110000iiii();
80800b99b8Sopenharmony_ci    bool Decode1100100nsssscccc();
81800b99b8Sopenharmony_ci    bool Decode11001yyy();
82800b99b8Sopenharmony_ci    bool Decode11000nnn();
83800b99b8Sopenharmony_ci    bool Decode11010nnn();
84800b99b8Sopenharmony_ci    bool Decode11xxxyyy();
85800b99b8Sopenharmony_ci    bool DecodeSpare();
86800b99b8Sopenharmony_ci
87800b99b8Sopenharmony_ciprotected:
88800b99b8Sopenharmony_ci    UnwindErrorData lastErrorData_;
89800b99b8Sopenharmony_ci    std::shared_ptr<RegLocState> rsState_;
90800b99b8Sopenharmony_ci    std::shared_ptr<DfxMemory> memory_;
91800b99b8Sopenharmony_ci    ExidxContext context_;
92800b99b8Sopenharmony_ci    std::deque<uint8_t> ops_;
93800b99b8Sopenharmony_ci    uint8_t curOp_ = 0;
94800b99b8Sopenharmony_ci    bool isPcSet_ = false;
95800b99b8Sopenharmony_ci};
96800b99b8Sopenharmony_ci} // namespace HiviewDFX
97800b99b8Sopenharmony_ci} // namespace OHOS
98800b99b8Sopenharmony_ci#endif
99