1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2023 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#include <gtest/gtest.h>
17800b99b8Sopenharmony_ci
18800b99b8Sopenharmony_ci#include <dlfcn.h>
19800b99b8Sopenharmony_ci#include <securec.h>
20800b99b8Sopenharmony_ci
21800b99b8Sopenharmony_ci#include <ctime>
22800b99b8Sopenharmony_ci#include <cstdio>
23800b99b8Sopenharmony_ci#include <fstream>
24800b99b8Sopenharmony_ci#include <memory>
25800b99b8Sopenharmony_ci#include <string>
26800b99b8Sopenharmony_ci#include <vector>
27800b99b8Sopenharmony_ci
28800b99b8Sopenharmony_ci#include <fcntl.h>
29800b99b8Sopenharmony_ci#include <unistd.h>
30800b99b8Sopenharmony_ci
31800b99b8Sopenharmony_ci#include <sys/stat.h>
32800b99b8Sopenharmony_ci#include <sys/types.h>
33800b99b8Sopenharmony_ci
34800b99b8Sopenharmony_ci#include "string_ex.h"
35800b99b8Sopenharmony_ci
36800b99b8Sopenharmony_ci#include "dfx_define.h"
37800b99b8Sopenharmony_ci#include "dfx_elf.h"
38800b99b8Sopenharmony_ci#include "dfx_instructions.h"
39800b99b8Sopenharmony_ci#include "dfx_log.h"
40800b99b8Sopenharmony_ci#include "dfx_memory.h"
41800b99b8Sopenharmony_ci#include "dfx_regs.h"
42800b99b8Sopenharmony_ci#include "dwarf_cfa_instructions.h"
43800b99b8Sopenharmony_ci#include "dwarf_define.h"
44800b99b8Sopenharmony_ci#include "dwarf_op.h"
45800b99b8Sopenharmony_ci#include "dwarf_section.h"
46800b99b8Sopenharmony_ci#include "thread_context.h"
47800b99b8Sopenharmony_ci#include "unwind_arm64_define.h"
48800b99b8Sopenharmony_ci#include "unwind_loc.h"
49800b99b8Sopenharmony_ci
50800b99b8Sopenharmony_ciusing namespace OHOS::HiviewDFX;
51800b99b8Sopenharmony_ciusing namespace testing::ext;
52800b99b8Sopenharmony_ciusing namespace std;
53800b99b8Sopenharmony_ci#define HEX 16
54800b99b8Sopenharmony_ci#define STACK_VALUE (-8)
55800b99b8Sopenharmony_ci
56800b99b8Sopenharmony_cinamespace OHOS {
57800b99b8Sopenharmony_cinamespace HiviewDFX {
58800b99b8Sopenharmony_ciclass DwarfTest : public testing::Test {
59800b99b8Sopenharmony_cipublic:
60800b99b8Sopenharmony_ci    static void TearDownTestCase(void) {}
61800b99b8Sopenharmony_ci    void SetUp() {}
62800b99b8Sopenharmony_ci    void TearDown() {}
63800b99b8Sopenharmony_ci};
64800b99b8Sopenharmony_ci
65800b99b8Sopenharmony_ciclass DwarfSectionTest : public DwarfSection {
66800b99b8Sopenharmony_cipublic:
67800b99b8Sopenharmony_ci    explicit DwarfSectionTest(std::shared_ptr<DfxMemory> memory) : DwarfSection(memory) {};
68800b99b8Sopenharmony_ci    ~DwarfSectionTest() {};
69800b99b8Sopenharmony_ci    bool ParseFdeTest(uintptr_t addr, FrameDescEntry &fde)
70800b99b8Sopenharmony_ci    {
71800b99b8Sopenharmony_ci        return ParseFde(addr, addr, fde);
72800b99b8Sopenharmony_ci    };
73800b99b8Sopenharmony_ci
74800b99b8Sopenharmony_ci    bool ParseCieTest(uintptr_t cieAddr, CommonInfoEntry &cieInfo)
75800b99b8Sopenharmony_ci    {
76800b99b8Sopenharmony_ci        return ParseCie(cieAddr, cieAddr, cieInfo);
77800b99b8Sopenharmony_ci    };
78800b99b8Sopenharmony_ci};
79800b99b8Sopenharmony_ci
80800b99b8Sopenharmony_cistruct MemoryArea {
81800b99b8Sopenharmony_ci    MemoryArea(uintptr_t addr, std::vector<uint8_t> buffer)
82800b99b8Sopenharmony_ci    {
83800b99b8Sopenharmony_ci        this->addr = addr;
84800b99b8Sopenharmony_ci        this->data = buffer;
85800b99b8Sopenharmony_ci    }
86800b99b8Sopenharmony_ci    uintptr_t addr;
87800b99b8Sopenharmony_ci    std::vector<uint8_t> data;
88800b99b8Sopenharmony_ci};
89800b99b8Sopenharmony_ci
90800b99b8Sopenharmony_ciclass DfxMemoryTest : public DfxMemory {
91800b99b8Sopenharmony_cipublic:
92800b99b8Sopenharmony_ci    DfxMemoryTest() {};
93800b99b8Sopenharmony_ci    virtual ~DfxMemoryTest() {};
94800b99b8Sopenharmony_ci    size_t Read(uintptr_t& addr, void* val, size_t size, bool incre = false) override;
95800b99b8Sopenharmony_ci    void SetBuffer(uintptr_t addr, std::vector<uint8_t> buffer);
96800b99b8Sopenharmony_ci    void Reset();
97800b99b8Sopenharmony_ci    bool increaseAddr = false;
98800b99b8Sopenharmony_ci
99800b99b8Sopenharmony_ciprivate:
100800b99b8Sopenharmony_ci    std::vector<MemoryArea> buffers;
101800b99b8Sopenharmony_ci};
102800b99b8Sopenharmony_ci
103800b99b8Sopenharmony_civoid DfxMemoryTest::Reset()
104800b99b8Sopenharmony_ci{
105800b99b8Sopenharmony_ci    buffers.clear();
106800b99b8Sopenharmony_ci}
107800b99b8Sopenharmony_ci
108800b99b8Sopenharmony_cisize_t DfxMemoryTest::Read(uintptr_t& addr, void* val, size_t size, bool incre)
109800b99b8Sopenharmony_ci{
110800b99b8Sopenharmony_ci    printf("DfxMemoryTest::Request Read:%" PRIxPTR " size:%zu\n", addr, size);
111800b99b8Sopenharmony_ci    for (const auto& buffer : buffers) {
112800b99b8Sopenharmony_ci        if (addr >= buffer.addr &&
113800b99b8Sopenharmony_ci            addr + size <= buffer.addr + buffer.data.size()) {
114800b99b8Sopenharmony_ci            size_t offset = addr - buffer.addr;
115800b99b8Sopenharmony_ci            auto data = const_cast<uint8_t*>(buffer.data.data());
116800b99b8Sopenharmony_ci            (void)memcpy_s(val, size, data + offset, size);
117800b99b8Sopenharmony_ci            if (increaseAddr) {
118800b99b8Sopenharmony_ci                addr = addr + size;
119800b99b8Sopenharmony_ci            }
120800b99b8Sopenharmony_ci            printf("DfxMemoryTest::Read addr:0x%" PRIxPTR "\n", addr);
121800b99b8Sopenharmony_ci            return size;
122800b99b8Sopenharmony_ci        }
123800b99b8Sopenharmony_ci    }
124800b99b8Sopenharmony_ci    return 0;
125800b99b8Sopenharmony_ci}
126800b99b8Sopenharmony_ci
127800b99b8Sopenharmony_civoid DfxMemoryTest::SetBuffer(uintptr_t addr, std::vector<uint8_t> buffer)
128800b99b8Sopenharmony_ci{
129800b99b8Sopenharmony_ci    printf("DfxMemoryTest::SetBuffer:%" PRIxPTR " size:%zu\n", addr, buffer.size());
130800b99b8Sopenharmony_ci    buffers.push_back({addr, buffer});
131800b99b8Sopenharmony_ci}
132800b99b8Sopenharmony_ci
133800b99b8Sopenharmony_ciclass DwarfOpTest : public DwarfOp<uintptr_t> {
134800b99b8Sopenharmony_cipublic:
135800b99b8Sopenharmony_ci    using DwarfOp<uintptr_t>::DwarfOp;
136800b99b8Sopenharmony_ci    bool Test01();
137800b99b8Sopenharmony_ci    bool Test02();
138800b99b8Sopenharmony_ci    bool Test03();
139800b99b8Sopenharmony_ci    bool Test04(std::shared_ptr<DfxMemoryTest> memory);
140800b99b8Sopenharmony_ci    bool Test05(std::shared_ptr<DfxMemoryTest> memory);
141800b99b8Sopenharmony_ci    bool Test06();
142800b99b8Sopenharmony_ci    bool Test07();
143800b99b8Sopenharmony_ci    bool Test08();
144800b99b8Sopenharmony_ci    bool Test09(std::shared_ptr<DfxMemoryTest> memory);
145800b99b8Sopenharmony_ci    bool Test10(std::shared_ptr<DfxMemoryTest> memory);
146800b99b8Sopenharmony_ci    friend class DwarfTest;
147800b99b8Sopenharmony_ci};
148800b99b8Sopenharmony_ci
149800b99b8Sopenharmony_cibool DwarfOpTest::Test01()
150800b99b8Sopenharmony_ci{
151800b99b8Sopenharmony_ci    std::shared_ptr<DfxRegs> regs = std::make_shared<DfxRegsArm64>();
152800b99b8Sopenharmony_ci    uintptr_t addr = 0;
153800b99b8Sopenharmony_ci    return Eval(*(regs.get()), 0, addr);
154800b99b8Sopenharmony_ci}
155800b99b8Sopenharmony_ci
156800b99b8Sopenharmony_cibool DwarfOpTest::Test02()
157800b99b8Sopenharmony_ci{
158800b99b8Sopenharmony_ci    bool ret = false;
159800b99b8Sopenharmony_ci    const uintptr_t value = 10;
160800b99b8Sopenharmony_ci    StackPush(value);
161800b99b8Sopenharmony_ci    ret = (value == stack_.front());
162800b99b8Sopenharmony_ci    StackReset(0);
163800b99b8Sopenharmony_ci    ret &= (0 == stack_.front());
164800b99b8Sopenharmony_ci    return ret;
165800b99b8Sopenharmony_ci}
166800b99b8Sopenharmony_ci
167800b99b8Sopenharmony_cibool DwarfOpTest::Test03()
168800b99b8Sopenharmony_ci{
169800b99b8Sopenharmony_ci    StackReset(0);
170800b99b8Sopenharmony_ci    bool ret = false;
171800b99b8Sopenharmony_ci    const uintptr_t value = 10;
172800b99b8Sopenharmony_ci    StackPush(value);
173800b99b8Sopenharmony_ci    ret = (value == StackPop());
174800b99b8Sopenharmony_ci    ret &= (StackAt(0) == 0);
175800b99b8Sopenharmony_ci    ret &= (StackSize() == 1);
176800b99b8Sopenharmony_ci    return ret;
177800b99b8Sopenharmony_ci}
178800b99b8Sopenharmony_ci
179800b99b8Sopenharmony_cibool DwarfOpTest::Test04(std::shared_ptr<DfxMemoryTest> memory)
180800b99b8Sopenharmony_ci{
181800b99b8Sopenharmony_ci    // OpDerefSize
182800b99b8Sopenharmony_ci    bool ret = false;
183800b99b8Sopenharmony_ci    StackReset(0);
184800b99b8Sopenharmony_ci    std::vector<uint8_t> exprData {
185800b99b8Sopenharmony_ci        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
186800b99b8Sopenharmony_ci    };
187800b99b8Sopenharmony_ci
188800b99b8Sopenharmony_ci    std::vector<uint8_t> valueData {
189800b99b8Sopenharmony_ci        0x08, // U8
190800b99b8Sopenharmony_ci        0x10, 0x11, // U16
191800b99b8Sopenharmony_ci        0x20, 0x21, 0x22, 0x23, // U32
192800b99b8Sopenharmony_ci        0x31, 0x32, 0x33, 0x34, // U32
193800b99b8Sopenharmony_ci        0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,  // U64
194800b99b8Sopenharmony_ci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24,  // U64
195800b99b8Sopenharmony_ci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25,  // U64
196800b99b8Sopenharmony_ci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26,  // U64
197800b99b8Sopenharmony_ci    };
198800b99b8Sopenharmony_ci
199800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(exprData.data());
200800b99b8Sopenharmony_ci    uintptr_t valuePtr = reinterpret_cast<uintptr_t>(valueData.data());
201800b99b8Sopenharmony_ci    memory->SetBuffer(valuePtr, valueData);
202800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, exprData);
203800b99b8Sopenharmony_ci    printf("Test04 exprPtr:%" PRIxPTR " valuePtr:%" PRIxPTR "\n", exprPtr, valuePtr);
204800b99b8Sopenharmony_ci
205800b99b8Sopenharmony_ci    // u8
206800b99b8Sopenharmony_ci    StackPush(valuePtr);
207800b99b8Sopenharmony_ci    OpDerefSize(exprPtr);
208800b99b8Sopenharmony_ci    uintptr_t value = StackPop();
209800b99b8Sopenharmony_ci    uintptr_t expectedValue = 0x08;
210800b99b8Sopenharmony_ci    ret = (value == expectedValue);
211800b99b8Sopenharmony_ci    printf("Test04-u8 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue);
212800b99b8Sopenharmony_ci
213800b99b8Sopenharmony_ci    // u16
214800b99b8Sopenharmony_ci    valuePtr = valuePtr + sizeof(uint8_t);
215800b99b8Sopenharmony_ci    exprPtr = exprPtr + sizeof(uint8_t);
216800b99b8Sopenharmony_ci    StackPush(valuePtr);
217800b99b8Sopenharmony_ci    OpDerefSize(exprPtr);
218800b99b8Sopenharmony_ci    value = StackPop();
219800b99b8Sopenharmony_ci    expectedValue = 0x1110;
220800b99b8Sopenharmony_ci    ret &= (value == expectedValue);
221800b99b8Sopenharmony_ci    printf("Test04-u16 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue);
222800b99b8Sopenharmony_ci
223800b99b8Sopenharmony_ci    // u32
224800b99b8Sopenharmony_ci    valuePtr = valuePtr + sizeof(uint16_t);
225800b99b8Sopenharmony_ci    exprPtr = exprPtr + sizeof(uint8_t);
226800b99b8Sopenharmony_ci    StackPush(valuePtr);
227800b99b8Sopenharmony_ci    OpDerefSize(exprPtr);
228800b99b8Sopenharmony_ci    value = StackPop();
229800b99b8Sopenharmony_ci    expectedValue = 0x23222120;
230800b99b8Sopenharmony_ci    ret &= (value == expectedValue);
231800b99b8Sopenharmony_ci    printf("Test04-u32-0 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue);
232800b99b8Sopenharmony_ci
233800b99b8Sopenharmony_ci    // u32
234800b99b8Sopenharmony_ci    valuePtr = valuePtr + sizeof(uint32_t);
235800b99b8Sopenharmony_ci    exprPtr = exprPtr + sizeof(uint8_t);
236800b99b8Sopenharmony_ci    StackPush(valuePtr);
237800b99b8Sopenharmony_ci    OpDerefSize(exprPtr);
238800b99b8Sopenharmony_ci    value = StackPop();
239800b99b8Sopenharmony_ci    expectedValue = 0x34333231;
240800b99b8Sopenharmony_ci    ret &= (value == expectedValue);
241800b99b8Sopenharmony_ci    printf("Test04-u32-1 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue);
242800b99b8Sopenharmony_ci
243800b99b8Sopenharmony_ci    // u64
244800b99b8Sopenharmony_ci    valuePtr = valuePtr + sizeof(uint32_t);
245800b99b8Sopenharmony_ci    exprPtr = exprPtr + sizeof(uint8_t);
246800b99b8Sopenharmony_ci    StackPush(valuePtr);
247800b99b8Sopenharmony_ci    OpDerefSize(exprPtr);
248800b99b8Sopenharmony_ci    value = StackPop();
249800b99b8Sopenharmony_ci    expectedValue = 0x4847464544434241;
250800b99b8Sopenharmony_ci    ret &= (value == expectedValue);
251800b99b8Sopenharmony_ci    printf("Test04-u64-0 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue);
252800b99b8Sopenharmony_ci    return ret;
253800b99b8Sopenharmony_ci}
254800b99b8Sopenharmony_ci
255800b99b8Sopenharmony_cibool DwarfOpTest::Test05(std::shared_ptr<DfxMemoryTest> memory)
256800b99b8Sopenharmony_ci{
257800b99b8Sopenharmony_ci    bool ret = false;
258800b99b8Sopenharmony_ci    StackReset(0);
259800b99b8Sopenharmony_ci    memory->Reset();
260800b99b8Sopenharmony_ci    std::vector<uint8_t> valueData {
261800b99b8Sopenharmony_ci        0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34,
262800b99b8Sopenharmony_ci    };
263800b99b8Sopenharmony_ci    // OpDeref
264800b99b8Sopenharmony_ci    uintptr_t valuePtr = reinterpret_cast<uintptr_t>(valueData.data());
265800b99b8Sopenharmony_ci    memory->SetBuffer(valuePtr, valueData);
266800b99b8Sopenharmony_ci    OpPush(valuePtr);
267800b99b8Sopenharmony_ci    OpDeref();
268800b99b8Sopenharmony_ci    uintptr_t value = StackPop();
269800b99b8Sopenharmony_ci    uintptr_t expectedValue = 0x3433323134333231;
270800b99b8Sopenharmony_ci    printf("Test05-u64 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue);
271800b99b8Sopenharmony_ci    ret = (value == expectedValue);
272800b99b8Sopenharmony_ci    printf("Test05-01 %d\n", ret);
273800b99b8Sopenharmony_ci    OpPush(valuePtr);
274800b99b8Sopenharmony_ci    OpDup();
275800b99b8Sopenharmony_ci    ret &= (StackAt(0) == valuePtr);
276800b99b8Sopenharmony_ci    printf("Test05-02 %d\n", ret);
277800b99b8Sopenharmony_ci    ret &= (StackAt(1) == valuePtr);
278800b99b8Sopenharmony_ci    printf("Test05-03 %d\n", ret);
279800b99b8Sopenharmony_ci    return ret;
280800b99b8Sopenharmony_ci}
281800b99b8Sopenharmony_ci
282800b99b8Sopenharmony_cibool DwarfOpTest::Test06()
283800b99b8Sopenharmony_ci{
284800b99b8Sopenharmony_ci    // OpDrop OpOver OpSwap OpRot
285800b99b8Sopenharmony_ci    MAYBE_UNUSED bool ret = false;
286800b99b8Sopenharmony_ci    StackReset(0);
287800b99b8Sopenharmony_ci    ret = (StackSize() == 1);
288800b99b8Sopenharmony_ci    OpPush(1);
289800b99b8Sopenharmony_ci    ret &= (StackSize() == 2); // 2:stack_.size()
290800b99b8Sopenharmony_ci
291800b99b8Sopenharmony_ci    OpDrop();
292800b99b8Sopenharmony_ci    ret &= (StackSize() == 1);
293800b99b8Sopenharmony_ci
294800b99b8Sopenharmony_ci    OpPush(1);
295800b99b8Sopenharmony_ci    OpPush(2); // 2:stack_.index
296800b99b8Sopenharmony_ci    ret &= (StackSize() == 3); // 3:stack_.size()
297800b99b8Sopenharmony_ci
298800b99b8Sopenharmony_ci    OpOver();
299800b99b8Sopenharmony_ci    ret &= (StackSize() == 4); // 4:stack_.size()
300800b99b8Sopenharmony_ci    uintptr_t value = StackPop();
301800b99b8Sopenharmony_ci    ret &= (value == 1);
302800b99b8Sopenharmony_ci    ret &= (StackSize() == 3); // 3:stack_.size()
303800b99b8Sopenharmony_ci
304800b99b8Sopenharmony_ci    ret &= (StackAt(0) == 2); // 2:stack.value
305800b99b8Sopenharmony_ci    ret &= (StackAt(1) == 1);
306800b99b8Sopenharmony_ci    OpSwap();
307800b99b8Sopenharmony_ci    ret &= (StackAt(0) == 1);
308800b99b8Sopenharmony_ci    ret &= (StackAt(1) == 2); // 2:stack.value
309800b99b8Sopenharmony_ci
310800b99b8Sopenharmony_ci    OpRot();
311800b99b8Sopenharmony_ci    ret &= (StackAt(0) == 0);
312800b99b8Sopenharmony_ci    ret &= (StackAt(1) == 1);
313800b99b8Sopenharmony_ci    ret &= (StackAt(2) == 2); // 2:stack.value
314800b99b8Sopenharmony_ci    return true;
315800b99b8Sopenharmony_ci}
316800b99b8Sopenharmony_ci
317800b99b8Sopenharmony_cibool DwarfOpTest::Test07()
318800b99b8Sopenharmony_ci{
319800b99b8Sopenharmony_ci    bool ret = false;
320800b99b8Sopenharmony_ci    StackReset(0);
321800b99b8Sopenharmony_ci    intptr_t value = -10;
322800b99b8Sopenharmony_ci    StackPush(value);
323800b99b8Sopenharmony_ci    OpAbs();
324800b99b8Sopenharmony_ci    ret = (static_cast<uintptr_t>(-value) == StackPop());
325800b99b8Sopenharmony_ci
326800b99b8Sopenharmony_ci    StackReset(0);
327800b99b8Sopenharmony_ci    StackPush(0x1122334455667788);
328800b99b8Sopenharmony_ci    StackPush(0xFFFFFFFF00000000);
329800b99b8Sopenharmony_ci    OpAnd();
330800b99b8Sopenharmony_ci    ret &= (0x1122334400000000 == StackPop());
331800b99b8Sopenharmony_ci
332800b99b8Sopenharmony_ci    StackReset(0);
333800b99b8Sopenharmony_ci    StackPush(0x8);
334800b99b8Sopenharmony_ci    StackPush(0x2);
335800b99b8Sopenharmony_ci    OpDiv();
336800b99b8Sopenharmony_ci    ret &= (0x4 == StackPop());
337800b99b8Sopenharmony_ci
338800b99b8Sopenharmony_ci    StackReset(0);
339800b99b8Sopenharmony_ci    StackPush(0x8);
340800b99b8Sopenharmony_ci    StackPush(0x2);
341800b99b8Sopenharmony_ci    OpMinus();
342800b99b8Sopenharmony_ci    ret &= (0x6 == StackPop());
343800b99b8Sopenharmony_ci
344800b99b8Sopenharmony_ci    StackReset(0);
345800b99b8Sopenharmony_ci    StackPush(0x8);
346800b99b8Sopenharmony_ci    StackPush(0x2);
347800b99b8Sopenharmony_ci    OpMod();
348800b99b8Sopenharmony_ci    ret &= (0 == StackPop());
349800b99b8Sopenharmony_ci
350800b99b8Sopenharmony_ci    StackReset(0);
351800b99b8Sopenharmony_ci    StackPush(0x8);
352800b99b8Sopenharmony_ci    StackPush(0x2);
353800b99b8Sopenharmony_ci    OpMul();
354800b99b8Sopenharmony_ci    ret &= (0x10 == StackPop());
355800b99b8Sopenharmony_ci
356800b99b8Sopenharmony_ci    StackReset(0);
357800b99b8Sopenharmony_ci    StackPush(0x8);
358800b99b8Sopenharmony_ci    OpNeg();
359800b99b8Sopenharmony_ci    ret &= (static_cast<uintptr_t>(STACK_VALUE) == StackPop());
360800b99b8Sopenharmony_ci
361800b99b8Sopenharmony_ci    StackReset(0);
362800b99b8Sopenharmony_ci    StackPush(1);
363800b99b8Sopenharmony_ci    OpNot();
364800b99b8Sopenharmony_ci    ret &= (static_cast<uintptr_t>(~1) == StackPop());
365800b99b8Sopenharmony_ci    return ret;
366800b99b8Sopenharmony_ci}
367800b99b8Sopenharmony_ci
368800b99b8Sopenharmony_cibool DwarfOpTest::Test08()
369800b99b8Sopenharmony_ci{
370800b99b8Sopenharmony_ci    bool ret = false;
371800b99b8Sopenharmony_ci    StackReset(0);
372800b99b8Sopenharmony_ci    StackPush(0x2);
373800b99b8Sopenharmony_ci    StackPush(0x2);
374800b99b8Sopenharmony_ci    OpEQ();
375800b99b8Sopenharmony_ci    ret = (1 == StackPop());
376800b99b8Sopenharmony_ci
377800b99b8Sopenharmony_ci    StackReset(0);
378800b99b8Sopenharmony_ci    StackPush(0x2);
379800b99b8Sopenharmony_ci    StackPush(0x3);
380800b99b8Sopenharmony_ci    OpGE();
381800b99b8Sopenharmony_ci    ret &= (0 == StackPop());
382800b99b8Sopenharmony_ci
383800b99b8Sopenharmony_ci    StackReset(0);
384800b99b8Sopenharmony_ci    StackPush(0x2);
385800b99b8Sopenharmony_ci    StackPush(0x3);
386800b99b8Sopenharmony_ci    OpGT();
387800b99b8Sopenharmony_ci    ret &= (0 == StackPop());
388800b99b8Sopenharmony_ci
389800b99b8Sopenharmony_ci    StackReset(0);
390800b99b8Sopenharmony_ci    StackPush(0x2);
391800b99b8Sopenharmony_ci    StackPush(0x3);
392800b99b8Sopenharmony_ci    OpLE();
393800b99b8Sopenharmony_ci    ret &= (1 == StackPop());
394800b99b8Sopenharmony_ci
395800b99b8Sopenharmony_ci    StackReset(0);
396800b99b8Sopenharmony_ci    StackPush(0x2);
397800b99b8Sopenharmony_ci    StackPush(0x3);
398800b99b8Sopenharmony_ci    OpLT();
399800b99b8Sopenharmony_ci    ret &= (1 == StackPop());
400800b99b8Sopenharmony_ci
401800b99b8Sopenharmony_ci    StackReset(0);
402800b99b8Sopenharmony_ci    StackPush(0x2);
403800b99b8Sopenharmony_ci    StackPush(0x3);
404800b99b8Sopenharmony_ci    OpNE();
405800b99b8Sopenharmony_ci    ret &= (1 == StackPop());
406800b99b8Sopenharmony_ci    return ret;
407800b99b8Sopenharmony_ci}
408800b99b8Sopenharmony_ci
409800b99b8Sopenharmony_cibool DwarfOpTest::Test09(std::shared_ptr<DfxMemoryTest> memory)
410800b99b8Sopenharmony_ci{
411800b99b8Sopenharmony_ci    bool ret = false;
412800b99b8Sopenharmony_ci    StackReset(0);
413800b99b8Sopenharmony_ci    memory->Reset();
414800b99b8Sopenharmony_ci    std::vector<uint8_t> exprData {
415800b99b8Sopenharmony_ci        0x10, 0x00,
416800b99b8Sopenharmony_ci    };
417800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(exprData.data());
418800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, exprData);
419800b99b8Sopenharmony_ci    OpPlusULEBConst(exprPtr);
420800b99b8Sopenharmony_ci    uintptr_t value = StackPop();
421800b99b8Sopenharmony_ci    printf("Test09-01 value:%" PRIxPTR "\n", value);
422800b99b8Sopenharmony_ci    ret = (value == 0x10);
423800b99b8Sopenharmony_ci
424800b99b8Sopenharmony_ci    StackReset(0);
425800b99b8Sopenharmony_ci    uintptr_t exprPtrOld = exprPtr;
426800b99b8Sopenharmony_ci    OpSkip(exprPtr);
427800b99b8Sopenharmony_ci    ret &= (exprPtrOld + exprData[0] == exprPtr);
428800b99b8Sopenharmony_ci    printf("Test09-02 exprPtrOld:%" PRIxPTR " exprPtrNew:%" PRIxPTR "\n",
429800b99b8Sopenharmony_ci        exprPtrOld, exprPtr);
430800b99b8Sopenharmony_ci
431800b99b8Sopenharmony_ci    StackReset(0);
432800b99b8Sopenharmony_ci    StackPush(0x2);
433800b99b8Sopenharmony_ci    exprPtr = exprPtrOld;
434800b99b8Sopenharmony_ci    OpBra(exprPtr);
435800b99b8Sopenharmony_ci    ret &= (exprPtrOld + exprData[0] == exprPtr);
436800b99b8Sopenharmony_ci    printf("Test09-03 exprPtrOld:%" PRIxPTR " exprPtrNew:%" PRIxPTR "\n",
437800b99b8Sopenharmony_ci        exprPtrOld, exprPtr);
438800b99b8Sopenharmony_ci
439800b99b8Sopenharmony_ci    StackReset(0);
440800b99b8Sopenharmony_ci    exprPtr = exprPtrOld;
441800b99b8Sopenharmony_ci    OpBra(exprPtr);
442800b99b8Sopenharmony_ci    ret &= (exprPtrOld == exprPtr);
443800b99b8Sopenharmony_ci    printf("Test09-04 exprPtrOld:%" PRIxPTR " exprPtrNew:%" PRIxPTR "\n",
444800b99b8Sopenharmony_ci        exprPtrOld, exprPtr);
445800b99b8Sopenharmony_ci    return ret;
446800b99b8Sopenharmony_ci}
447800b99b8Sopenharmony_ci
448800b99b8Sopenharmony_cibool DwarfOpTest::Test10(std::shared_ptr<DfxMemoryTest> memory)
449800b99b8Sopenharmony_ci{
450800b99b8Sopenharmony_ci    bool ret = false;
451800b99b8Sopenharmony_ci    memory->Reset();
452800b99b8Sopenharmony_ci    std::vector<uint8_t> exprData {
453800b99b8Sopenharmony_ci        0x1e, 0x00,
454800b99b8Sopenharmony_ci    };
455800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(exprData.data());
456800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, exprData);
457800b99b8Sopenharmony_ci
458800b99b8Sopenharmony_ci    StackReset(0);
459800b99b8Sopenharmony_ci    OpLit(DW_OP_lit1);
460800b99b8Sopenharmony_ci    uintptr_t value = StackPop();
461800b99b8Sopenharmony_ci    ret = (value == 0x01);
462800b99b8Sopenharmony_ci    printf("Test10-01 value:%" PRIxPTR " ret:%d\n", value, ret);
463800b99b8Sopenharmony_ci
464800b99b8Sopenharmony_ci    OpLit(DW_OP_lit31);
465800b99b8Sopenharmony_ci    value = StackPop();
466800b99b8Sopenharmony_ci    ret &= (value == 0x1f);
467800b99b8Sopenharmony_ci    printf("Test10-02 value:%" PRIxPTR " ret:%d\n", value, ret);
468800b99b8Sopenharmony_ci
469800b99b8Sopenharmony_ci    StackReset(0);
470800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
471800b99b8Sopenharmony_ci    (*reg)[0] = 0xa;
472800b99b8Sopenharmony_ci    OpReg(DW_OP_reg0, *(reg.get()));
473800b99b8Sopenharmony_ci    value = StackPop();
474800b99b8Sopenharmony_ci    ret &= (value == 0xa);
475800b99b8Sopenharmony_ci    printf("Test10-03 value:%" PRIxPTR " ret:%d\n", value, ret);
476800b99b8Sopenharmony_ci
477800b99b8Sopenharmony_ci    StackReset(0);
478800b99b8Sopenharmony_ci    (*reg)[0x1e] = 0x14;
479800b99b8Sopenharmony_ci    OpRegx(exprPtr, *(reg.get()));
480800b99b8Sopenharmony_ci    value = StackPop();
481800b99b8Sopenharmony_ci    ret &= (value == 0x14);
482800b99b8Sopenharmony_ci    printf("Test10-04 value:%" PRIxPTR " ret:%d\n", value, ret);
483800b99b8Sopenharmony_ci
484800b99b8Sopenharmony_ci    StackReset(0);
485800b99b8Sopenharmony_ci    OpBReg(DW_OP_breg0, exprPtr, *(reg.get()));
486800b99b8Sopenharmony_ci    value = StackPop();
487800b99b8Sopenharmony_ci    ret &= (value == 0x28); // 0xa + 0x1e
488800b99b8Sopenharmony_ci    printf("Test10-05 value:%" PRIxPTR " ret:%d\n", value, ret);
489800b99b8Sopenharmony_ci
490800b99b8Sopenharmony_ci    StackReset(0);
491800b99b8Sopenharmony_ci    OpBRegx(exprPtr, *(reg.get()));
492800b99b8Sopenharmony_ci    value = StackPop();
493800b99b8Sopenharmony_ci    ret &= (value == 0x32); // 0x14 + 0x1e
494800b99b8Sopenharmony_ci    printf("Test10-06 value:%" PRIxPTR " ret:%d\n", value, ret);
495800b99b8Sopenharmony_ci    return ret;
496800b99b8Sopenharmony_ci}
497800b99b8Sopenharmony_ci
498800b99b8Sopenharmony_ciusing RequestFdFunc = int32_t (*)(int32_t);
499800b99b8Sopenharmony_cinamespace {
500800b99b8Sopenharmony_ci/**
501800b99b8Sopenharmony_ci * @tc.name: DwarfTest001
502800b99b8Sopenharmony_ci * @tc.desc: test parse fde in libfaultloggerd_client.so
503800b99b8Sopenharmony_ci * @tc.type: FUNC
504800b99b8Sopenharmony_ci */
505800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest001, TestSize.Level2)
506800b99b8Sopenharmony_ci{
507800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest001: start.";
508800b99b8Sopenharmony_ci    void* handle = dlopen("libjson_stack_formatter.z.so", RTLD_LAZY | RTLD_NODELETE);
509800b99b8Sopenharmony_ci    bool isSuccess = handle != nullptr;
510800b99b8Sopenharmony_ci    if (!isSuccess) {
511800b99b8Sopenharmony_ci        ASSERT_FALSE(isSuccess);
512800b99b8Sopenharmony_ci        printf("Failed to dlopen libfaultloggerd, %s\n", dlerror());
513800b99b8Sopenharmony_ci        return;
514800b99b8Sopenharmony_ci    }
515800b99b8Sopenharmony_ci    RequestFdFunc requestFdFunc = (RequestFdFunc)dlsym(handle,
516800b99b8Sopenharmony_ci        "_ZN4OHOS9HiviewDFX16DfxJsonFormatter15FormatJsonStack" \
517800b99b8Sopenharmony_ci        "ENSt3__h12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERS8_");
518800b99b8Sopenharmony_ci    isSuccess = requestFdFunc != nullptr;
519800b99b8Sopenharmony_ci    if (!isSuccess) {
520800b99b8Sopenharmony_ci        ASSERT_FALSE(isSuccess);
521800b99b8Sopenharmony_ci        printf("Failed to find RequestFdFunc, %s\n", dlerror());
522800b99b8Sopenharmony_ci        return;
523800b99b8Sopenharmony_ci    }
524800b99b8Sopenharmony_ci
525800b99b8Sopenharmony_ci    const uintptr_t pcOffset = 48;
526800b99b8Sopenharmony_ci    uintptr_t pc = reinterpret_cast<uintptr_t>(requestFdFunc) + pcOffset;
527800b99b8Sopenharmony_ci    struct UnwindTableInfo uti;
528800b99b8Sopenharmony_ci    ASSERT_EQ(DfxElf::FindUnwindTableLocal(pc, uti), 0);
529800b99b8Sopenharmony_ci
530800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
531800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
532800b99b8Sopenharmony_ci    DwarfSectionTest dwarfSection(memory);
533800b99b8Sopenharmony_ci    struct UnwindEntryInfo pi;
534800b99b8Sopenharmony_ci    ASSERT_EQ(true, dwarfSection.SearchEntry(pc, uti, pi));
535800b99b8Sopenharmony_ci
536800b99b8Sopenharmony_ci    FrameDescEntry fde;
537800b99b8Sopenharmony_ci    ASSERT_EQ(true, dwarfSection.ParseFdeTest(reinterpret_cast<uintptr_t>(pi.unwindInfo), fde));
538800b99b8Sopenharmony_ci    ASSERT_GT(fde.cieAddr, 0);
539800b99b8Sopenharmony_ci
540800b99b8Sopenharmony_ci    CommonInfoEntry cie;
541800b99b8Sopenharmony_ci    ASSERT_EQ(true, dwarfSection.ParseCieTest(fde.cieAddr, cie));
542800b99b8Sopenharmony_ci
543800b99b8Sopenharmony_ci    RegLocState rsState;
544800b99b8Sopenharmony_ci    DwarfCfaInstructions instructions(memory);
545800b99b8Sopenharmony_ci    ASSERT_EQ(true, instructions.Parse(pc, fde, rsState));
546800b99b8Sopenharmony_ci    /*
547800b99b8Sopenharmony_ci        Version:               1
548800b99b8Sopenharmony_ci        Augmentation:          "zR"
549800b99b8Sopenharmony_ci        Code alignment factor: 1
550800b99b8Sopenharmony_ci        Data alignment factor: -4
551800b99b8Sopenharmony_ci        Return address column: 30
552800b99b8Sopenharmony_ci        Augmentation data:     1b
553800b99b8Sopenharmony_ci        DW_CFA_def_cfa: r31 (sp) ofs 0
554800b99b8Sopenharmony_ci        DW_CFA_nop
555800b99b8Sopenharmony_ci        DW_CFA_nop
556800b99b8Sopenharmony_ci        DW_CFA_nop
557800b99b8Sopenharmony_ci        DW_CFA_nop
558800b99b8Sopenharmony_ci    */
559800b99b8Sopenharmony_ci    ASSERT_EQ(cie.codeAlignFactor, 1);
560800b99b8Sopenharmony_ci    ASSERT_EQ(cie.dataAlignFactor, -4);
561800b99b8Sopenharmony_ci    ASSERT_EQ(cie.returnAddressRegister, 30);
562800b99b8Sopenharmony_ci    ASSERT_EQ(cie.hasAugmentationData, true);
563800b99b8Sopenharmony_ci    ASSERT_EQ(cie.pointerEncoding, 0x1b);
564800b99b8Sopenharmony_ci
565800b99b8Sopenharmony_ci    /*
566800b99b8Sopenharmony_ci        DW_CFA_advance_loc: 20 to 0000000000002718
567800b99b8Sopenharmony_ci        DW_CFA_def_cfa_offset: 112
568800b99b8Sopenharmony_ci        DW_CFA_advance_loc: 28 to 0000000000002734
569800b99b8Sopenharmony_ci        DW_CFA_def_cfa: r29 (x29) ofs 112
570800b99b8Sopenharmony_ci        DW_CFA_offset: r15 (x15) at cfa-8
571800b99b8Sopenharmony_ci        DW_CFA_offset: r19 (x19) at cfa-16
572800b99b8Sopenharmony_ci        DW_CFA_offset: r20 (x20) at cfa-24
573800b99b8Sopenharmony_ci        DW_CFA_offset: r21 (x21) at cfa-32
574800b99b8Sopenharmony_ci        DW_CFA_offset: r22 (x22) at cfa-40
575800b99b8Sopenharmony_ci        DW_CFA_offset: r23 (x23) at cfa-48
576800b99b8Sopenharmony_ci        DW_CFA_offset: r24 (x24) at cfa-56
577800b99b8Sopenharmony_ci        DW_CFA_offset: r25 (x25) at cfa-64
578800b99b8Sopenharmony_ci        DW_CFA_offset: r26 (x26) at cfa-72
579800b99b8Sopenharmony_ci        DW_CFA_offset: r27 (x27) at cfa-80
580800b99b8Sopenharmony_ci        DW_CFA_offset: r28 (x28) at cfa-96
581800b99b8Sopenharmony_ci        DW_CFA_offset: r30 (x30) at cfa-104
582800b99b8Sopenharmony_ci        DW_CFA_offset: r29 (x29) at cfa-112
583800b99b8Sopenharmony_ci    */
584800b99b8Sopenharmony_ci    ASSERT_EQ(fde.pcStart, reinterpret_cast<uintptr_t>(requestFdFunc));
585800b99b8Sopenharmony_ci    ASSERT_EQ(rsState.cfaReg, REG_AARCH64_X29);
586800b99b8Sopenharmony_ci    ASSERT_EQ(rsState.cfaRegOffset, 112); // 112 : DW_CFA_def_cfa: r29 (x29) ofs 112
587800b99b8Sopenharmony_ci
588800b99b8Sopenharmony_ci    size_t qutIdx = 0;
589800b99b8Sopenharmony_ci    if (DfxRegsQut::IsQutReg(static_cast<uint16_t>(REG_AARCH64_X30), qutIdx)) {
590800b99b8Sopenharmony_ci        ASSERT_EQ(static_cast<uint8_t>(rsState.locs[qutIdx].type),
591800b99b8Sopenharmony_ci            static_cast<uint8_t>(REG_LOC_MEM_OFFSET));
592800b99b8Sopenharmony_ci        ASSERT_EQ(rsState.locs[qutIdx].val, -104); // -104: r30 (x30) at cfa-104
593800b99b8Sopenharmony_ci    }
594800b99b8Sopenharmony_ci    if (DfxRegsQut::IsQutReg(static_cast<uint16_t>(REG_AARCH64_X29), qutIdx)) {
595800b99b8Sopenharmony_ci        ASSERT_EQ(static_cast<uint8_t>(rsState.locs[qutIdx].type),
596800b99b8Sopenharmony_ci            static_cast<uint8_t>(REG_LOC_MEM_OFFSET));
597800b99b8Sopenharmony_ci        ASSERT_EQ(rsState.locs[qutIdx].val, -112); // -112: r29 (x29) at cfa-112
598800b99b8Sopenharmony_ci    }
599800b99b8Sopenharmony_ci
600800b99b8Sopenharmony_ci    RegLocState rsState2;
601800b99b8Sopenharmony_ci    ASSERT_EQ(true, instructions.Parse(reinterpret_cast<uintptr_t>(requestFdFunc), fde, rsState2));
602800b99b8Sopenharmony_ci    ASSERT_EQ(rsState2.cfaReg, REG_AARCH64_X31);
603800b99b8Sopenharmony_ci    ASSERT_EQ(rsState2.cfaRegOffset, 0); // DW_CFA_def_cfa: r31 (sp) ofs 0
604800b99b8Sopenharmony_ci
605800b99b8Sopenharmony_ci    RegLocState rsState3;
606800b99b8Sopenharmony_ci    ASSERT_EQ(true, instructions.Parse(reinterpret_cast<uintptr_t>(requestFdFunc) + 24, fde, rsState3));
607800b99b8Sopenharmony_ci    ASSERT_EQ(rsState3.cfaReg, REG_AARCH64_X31);
608800b99b8Sopenharmony_ci    ASSERT_EQ(rsState3.cfaRegOffset, 112); // 112 : DW_CFA_def_cfa_offset: 112
609800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest001: end.";
610800b99b8Sopenharmony_ci}
611800b99b8Sopenharmony_ci
612800b99b8Sopenharmony_cistruct FdeParseResult {
613800b99b8Sopenharmony_ci    int32_t index;
614800b99b8Sopenharmony_ci    uintptr_t relPcStart;
615800b99b8Sopenharmony_ci    uintptr_t relPcEnd;
616800b99b8Sopenharmony_ci    std::vector<std::string> operateResult;
617800b99b8Sopenharmony_ci};
618800b99b8Sopenharmony_ci
619800b99b8Sopenharmony_cistatic std::vector<std::string> cieResult = {
620800b99b8Sopenharmony_ci    "DW_CFA_def_cfa: r31 ofs 0",
621800b99b8Sopenharmony_ci    "DW_CFA_nop",
622800b99b8Sopenharmony_ci    "DW_CFA_nop",
623800b99b8Sopenharmony_ci    "DW_CFA_nop",
624800b99b8Sopenharmony_ci    "DW_CFA_nop"
625800b99b8Sopenharmony_ci};
626800b99b8Sopenharmony_ci
627800b99b8Sopenharmony_civoid PrintOperations(const std::string& msg, std::vector<std::string>& operations)
628800b99b8Sopenharmony_ci{
629800b99b8Sopenharmony_ci    printf("%s\n", msg.c_str());
630800b99b8Sopenharmony_ci    for (const auto& operation : operations) {
631800b99b8Sopenharmony_ci        printf("%s\n", operation.c_str());
632800b99b8Sopenharmony_ci    }
633800b99b8Sopenharmony_ci}
634800b99b8Sopenharmony_ci
635800b99b8Sopenharmony_cibool CheckFdeResult(std::shared_ptr<FdeParseResult> result)
636800b99b8Sopenharmony_ci{
637800b99b8Sopenharmony_ci    std::ifstream infile("/data/test/dwarf_test_aarch64_elf_result2");
638800b99b8Sopenharmony_ci    std::string line;
639800b99b8Sopenharmony_ci    std::vector<std::string> operands;
640800b99b8Sopenharmony_ci    std::vector<std::string> expectedResult = cieResult;
641800b99b8Sopenharmony_ci    expectedResult.insert(std::end(expectedResult),
642800b99b8Sopenharmony_ci        std::begin((*result).operateResult),
643800b99b8Sopenharmony_ci        std::end((*result).operateResult));
644800b99b8Sopenharmony_ci    while (std::getline(infile, line)) {
645800b99b8Sopenharmony_ci        if (line.find("DW_CFA") != std::string::npos) {
646800b99b8Sopenharmony_ci            operands.push_back(line);
647800b99b8Sopenharmony_ci        }
648800b99b8Sopenharmony_ci    }
649800b99b8Sopenharmony_ci
650800b99b8Sopenharmony_ci    if (expectedResult.size() != operands.size()) {
651800b99b8Sopenharmony_ci        printf("Failed to check operations size for index:%d\n", result->index);
652800b99b8Sopenharmony_ci        PrintOperations("Expected result:", expectedResult);
653800b99b8Sopenharmony_ci        PrintOperations("Current result:", operands);
654800b99b8Sopenharmony_ci        return false;
655800b99b8Sopenharmony_ci    }
656800b99b8Sopenharmony_ci
657800b99b8Sopenharmony_ci    printf("CheckFdeResult index:%d\n", result->index);
658800b99b8Sopenharmony_ci    for (size_t i = 0; i < operands.size(); i++) {
659800b99b8Sopenharmony_ci        std::string cfaCmd = OHOS::TrimStr(expectedResult[i]);
660800b99b8Sopenharmony_ci        auto pos = cfaCmd.find(":");
661800b99b8Sopenharmony_ci        if (pos != std::string::npos) {
662800b99b8Sopenharmony_ci            cfaCmd = cfaCmd.substr(0, pos);
663800b99b8Sopenharmony_ci            expectedResult[i] = cfaCmd;
664800b99b8Sopenharmony_ci        }
665800b99b8Sopenharmony_ci
666800b99b8Sopenharmony_ci        if (operands[i].find(cfaCmd) == std::string::npos) {
667800b99b8Sopenharmony_ci            printf("Failed to check operations for index:%d\n", result->index);
668800b99b8Sopenharmony_ci            PrintOperations("Expected result:", expectedResult);
669800b99b8Sopenharmony_ci            PrintOperations("Current result:", operands);
670800b99b8Sopenharmony_ci            return false;
671800b99b8Sopenharmony_ci        }
672800b99b8Sopenharmony_ci    }
673800b99b8Sopenharmony_ci    return true;
674800b99b8Sopenharmony_ci}
675800b99b8Sopenharmony_ci
676800b99b8Sopenharmony_cistd::vector<std::shared_ptr<FdeParseResult>> ParseFdeResultFromFile()
677800b99b8Sopenharmony_ci{
678800b99b8Sopenharmony_ci    std::vector<std::shared_ptr<FdeParseResult>> ret;
679800b99b8Sopenharmony_ci    std::ifstream infile("/data/test/dwarf_test_aarch64_elf_result");
680800b99b8Sopenharmony_ci    std::string line;
681800b99b8Sopenharmony_ci    std::shared_ptr<FdeParseResult> result = nullptr;
682800b99b8Sopenharmony_ci    int32_t index = 0;
683800b99b8Sopenharmony_ci    while (std::getline(infile, line)) {
684800b99b8Sopenharmony_ci        if (line.find("FDE cie=") != std::string::npos) {
685800b99b8Sopenharmony_ci            if (result != nullptr) {
686800b99b8Sopenharmony_ci                ret.push_back(result);
687800b99b8Sopenharmony_ci            }
688800b99b8Sopenharmony_ci            result = std::make_shared<FdeParseResult>();
689800b99b8Sopenharmony_ci            auto pos0 = line.find("pc=");
690800b99b8Sopenharmony_ci            std::string pcRange = line.substr(pos0 + strlen("pc="));
691800b99b8Sopenharmony_ci            auto pos1 = pcRange.find("..");
692800b99b8Sopenharmony_ci            std::string pcStart = pcRange.substr(0, pos1);
693800b99b8Sopenharmony_ci            std::string pcEnd = pcRange.substr(pos1 + strlen(".."));
694800b99b8Sopenharmony_ci            result->relPcStart = std::stoul(pcStart, nullptr, HEX);
695800b99b8Sopenharmony_ci            result->relPcEnd = std::stoul(pcEnd, nullptr, HEX);
696800b99b8Sopenharmony_ci            result->index = index;
697800b99b8Sopenharmony_ci            index++;
698800b99b8Sopenharmony_ci            continue;
699800b99b8Sopenharmony_ci        }
700800b99b8Sopenharmony_ci
701800b99b8Sopenharmony_ci        if (result == nullptr) {
702800b99b8Sopenharmony_ci            continue;
703800b99b8Sopenharmony_ci        }
704800b99b8Sopenharmony_ci
705800b99b8Sopenharmony_ci        if (line.empty()) {
706800b99b8Sopenharmony_ci            continue;
707800b99b8Sopenharmony_ci        }
708800b99b8Sopenharmony_ci
709800b99b8Sopenharmony_ci        if (line.find("ZERO terminator") != std::string::npos) {
710800b99b8Sopenharmony_ci            ret.push_back(result);
711800b99b8Sopenharmony_ci            break;
712800b99b8Sopenharmony_ci        }
713800b99b8Sopenharmony_ci
714800b99b8Sopenharmony_ci        result->operateResult.push_back(line);
715800b99b8Sopenharmony_ci    }
716800b99b8Sopenharmony_ci    return ret;
717800b99b8Sopenharmony_ci}
718800b99b8Sopenharmony_ci
719800b99b8Sopenharmony_ciint32_t RedirectStdErrToFile(const std::string& path)
720800b99b8Sopenharmony_ci{
721800b99b8Sopenharmony_ci    int output = open(path.c_str(), O_RDWR | O_CREAT, 0777);
722800b99b8Sopenharmony_ci    int32_t oldFd = dup(STDERR_FILENO);
723800b99b8Sopenharmony_ci    dup2(output, STDERR_FILENO);
724800b99b8Sopenharmony_ci    close(output);
725800b99b8Sopenharmony_ci    return oldFd;
726800b99b8Sopenharmony_ci}
727800b99b8Sopenharmony_ci
728800b99b8Sopenharmony_ci/**
729800b99b8Sopenharmony_ci * @tc.name: DwarfTest002
730800b99b8Sopenharmony_ci * @tc.desc: test dwarf cfa operations
731800b99b8Sopenharmony_ci * @tc.type: FUNC
732800b99b8Sopenharmony_ci */
733800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest002, TestSize.Level2)
734800b99b8Sopenharmony_ci{
735800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest002: start.";
736800b99b8Sopenharmony_ci    auto elf = DfxElf::Create("/data/test/dwarf_test_aarch64_elf");
737800b99b8Sopenharmony_ci    ASSERT_NE(elf, nullptr);
738800b99b8Sopenharmony_ci    uint64_t loadbase = reinterpret_cast<uint64_t>(elf->GetMmapPtr());
739800b99b8Sopenharmony_ci    elf->SetLoadBase(loadbase);
740800b99b8Sopenharmony_ci    /*
741800b99b8Sopenharmony_ci        7fb92b7000-7fb9326000 r--p 00000000 b3:07 1817 dwarf_test_aarch64_elf
742800b99b8Sopenharmony_ci        7fb9326000-7fb93d1000 r-xp 0006e000 b3:07 1817 dwarf_test_aarch64_elf
743800b99b8Sopenharmony_ci        7fb93d1000-7fb93d3000 r--p 00118000 b3:07 1817 dwarf_test_aarch64_elf
744800b99b8Sopenharmony_ci        7fb93d3000-7fb93d5000 rw-p 00119000 b3:07 1817 dwarf_test_aarch64_elf
745800b99b8Sopenharmony_ci        LOAD 0x000000000006e640 0x000000000006f640 0x000000000006f640
746800b99b8Sopenharmony_ci             0x00000000000a8ec0 0x00000000000a8ec0 R E    0x1000
747800b99b8Sopenharmony_ci    */
748800b99b8Sopenharmony_ci    uint64_t startPc = loadbase + 0x6F640;
749800b99b8Sopenharmony_ci    uint64_t endPc = startPc + 0xa8ec0;
750800b99b8Sopenharmony_ci    printf("startPc:%p endPc:%p\n", reinterpret_cast<void*>(startPc), reinterpret_cast<void*>(endPc));
751800b99b8Sopenharmony_ci    uint64_t mapStart = loadbase + 0x6F000;
752800b99b8Sopenharmony_ci    uint64_t mapEnd = mapStart + 0xab000;
753800b99b8Sopenharmony_ci    const uint64_t offset = 0x6e000;
754800b99b8Sopenharmony_ci    auto map1 = std::make_shared<DfxMap>(mapStart, mapEnd, offset, "r-xp", "dwarf_test_aarch64_elf");
755800b99b8Sopenharmony_ci    UnwindTableInfo info {};
756800b99b8Sopenharmony_ci    ASSERT_EQ(0, elf->FindUnwindTableInfo(startPc + 0x2, map1, info));
757800b99b8Sopenharmony_ci    ASSERT_EQ(info.startPc, startPc);
758800b99b8Sopenharmony_ci    ASSERT_EQ(info.endPc, endPc);
759800b99b8Sopenharmony_ci    ASSERT_NE(info.format, -1);
760800b99b8Sopenharmony_ci    auto testElfFdeResult = ParseFdeResultFromFile();
761800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
762800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
763800b99b8Sopenharmony_ci    DwarfSectionTest dwarfSection(memory);
764800b99b8Sopenharmony_ci    ASSERT_EQ(testElfFdeResult.size(), info.tableLen); // cie
765800b99b8Sopenharmony_ci    int index = 0;
766800b99b8Sopenharmony_ci    for (auto& fdeResult : testElfFdeResult) {
767800b99b8Sopenharmony_ci        auto pc = fdeResult->relPcEnd - 2 + loadbase;
768800b99b8Sopenharmony_ci        ASSERT_GT(pc, fdeResult->relPcStart + loadbase);
769800b99b8Sopenharmony_ci        ASSERT_LT(pc, fdeResult->relPcEnd + loadbase);
770800b99b8Sopenharmony_ci
771800b99b8Sopenharmony_ci        struct UnwindEntryInfo pi;
772800b99b8Sopenharmony_ci        ASSERT_EQ(true, dwarfSection.SearchEntry(pc, info, pi));
773800b99b8Sopenharmony_ci
774800b99b8Sopenharmony_ci        FrameDescEntry fde;
775800b99b8Sopenharmony_ci        ASSERT_EQ(true, dwarfSection.ParseFdeTest(reinterpret_cast<uintptr_t>(pi.unwindInfo), fde));
776800b99b8Sopenharmony_ci        ASSERT_GT(fde.cieAddr, 0);
777800b99b8Sopenharmony_ci        ASSERT_EQ(fde.pcStart, fdeResult->relPcStart + loadbase);
778800b99b8Sopenharmony_ci        ASSERT_EQ(fde.pcEnd, fdeResult->relPcEnd + loadbase);
779800b99b8Sopenharmony_ci
780800b99b8Sopenharmony_ci        CommonInfoEntry cie;
781800b99b8Sopenharmony_ci        ASSERT_EQ(true, dwarfSection.ParseCieTest(fde.cieAddr, cie));
782800b99b8Sopenharmony_ci        remove("/data/test/dwarf_test_aarch64_elf_result2");
783800b99b8Sopenharmony_ci
784800b99b8Sopenharmony_ci        int oldFd = RedirectStdErrToFile("/data/test/dwarf_test_aarch64_elf_result2");
785800b99b8Sopenharmony_ci        ASSERT_GT(oldFd, 0);
786800b99b8Sopenharmony_ci        fprintf(stderr, "currentFdeIndex:%d relPcStart:%p relPcEnd:%p begin\n",
787800b99b8Sopenharmony_ci            index, (void*)fdeResult->relPcStart, (void*)fdeResult->relPcEnd);
788800b99b8Sopenharmony_ci        RegLocState rsState;
789800b99b8Sopenharmony_ci        DwarfCfaInstructions instructions(memory);
790800b99b8Sopenharmony_ci        ASSERT_EQ(true, instructions.Parse(pc, fde, rsState));
791800b99b8Sopenharmony_ci        fprintf(stderr, "currentFdeIndex:%d relPcStart:%p relPcEnd:%p end\n",
792800b99b8Sopenharmony_ci            index, (void*)fdeResult->relPcStart, (void*)fdeResult->relPcEnd);
793800b99b8Sopenharmony_ci        dup2(oldFd, STDERR_FILENO);
794800b99b8Sopenharmony_ci        if (!CheckFdeResult(fdeResult)) {
795800b99b8Sopenharmony_ci            FAIL() << "Failed to check dw_cfa_operations";
796800b99b8Sopenharmony_ci            break;
797800b99b8Sopenharmony_ci        }
798800b99b8Sopenharmony_ci        index++;
799800b99b8Sopenharmony_ci    }
800800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest002: end.\n";
801800b99b8Sopenharmony_ci}
802800b99b8Sopenharmony_ci
803800b99b8Sopenharmony_ci/**
804800b99b8Sopenharmony_ci * @tc.name: DwarfTest003
805800b99b8Sopenharmony_ci * @tc.desc: test dwarf operations
806800b99b8Sopenharmony_ci * @tc.type: FUNC
807800b99b8Sopenharmony_ci */
808800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest003, TestSize.Level2)
809800b99b8Sopenharmony_ci{
810800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest003: start.\n";
811800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
812800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
813800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test01(), false);
814800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test02(), true);
815800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test03(), true);
816800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test04(memory), true);
817800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test05(memory), true);
818800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test06(), true);
819800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test07(), true);
820800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test08(), true);
821800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test09(memory), true);
822800b99b8Sopenharmony_ci    ASSERT_EQ(op.Test10(memory), true);
823800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest003: end.\n";
824800b99b8Sopenharmony_ci}
825800b99b8Sopenharmony_ci
826800b99b8Sopenharmony_ci/**
827800b99b8Sopenharmony_ci * @tc.name: DwarfTest004
828800b99b8Sopenharmony_ci * @tc.desc: test dwarf DW_OP_reserved oprations
829800b99b8Sopenharmony_ci * @tc.type: FUNC
830800b99b8Sopenharmony_ci */
831800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest004, TestSize.Level2)
832800b99b8Sopenharmony_ci{
833800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest004: start.\n";
834800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
835800b99b8Sopenharmony_ci    memory->increaseAddr = true;
836800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
837800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
838800b99b8Sopenharmony_ci        0x08, // size
839800b99b8Sopenharmony_ci        0x01, 0x02, 0x04, 0x05, 0x07, // DW_OP_reserved
840800b99b8Sopenharmony_ci        0x01, 0x02, 0x04, 0x05, 0x07, // DW_OP_reserved
841800b99b8Sopenharmony_ci    };
842800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
843800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
844800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
845800b99b8Sopenharmony_ci    auto ret = op.Eval(*reg.get(), 0, exprPtr);
846800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 0);
847800b99b8Sopenharmony_ci    printf("DwarfTest004:%" PRIxPTR "\n", ret);
848800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest004: end.\n";
849800b99b8Sopenharmony_ci}
850800b99b8Sopenharmony_ci
851800b99b8Sopenharmony_ci/**
852800b99b8Sopenharmony_ci * @tc.name: DwarfTest005
853800b99b8Sopenharmony_ci * @tc.desc: test dwarf DW_OP_addr oprations
854800b99b8Sopenharmony_ci * @tc.type: FUNC
855800b99b8Sopenharmony_ci */
856800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest005, TestSize.Level2)
857800b99b8Sopenharmony_ci{
858800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest005: start.\n";
859800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
860800b99b8Sopenharmony_ci    memory->increaseAddr = true;
861800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
862800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
863800b99b8Sopenharmony_ci        0x0a, // size
864800b99b8Sopenharmony_ci        DW_OP_addr, // DW_OP_addr
865800b99b8Sopenharmony_ci        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
866800b99b8Sopenharmony_ci        DW_OP_deref, 0x01, 0x01, 0x01, 0x01, // DW_OP_deref
867800b99b8Sopenharmony_ci    };
868800b99b8Sopenharmony_ci
869800b99b8Sopenharmony_ci    std::vector<uint8_t> data = {
870800b99b8Sopenharmony_ci        0x02, 0x04, 0x05, 0x07,
871800b99b8Sopenharmony_ci        0x02, 0x04, 0x05, 0x07,
872800b99b8Sopenharmony_ci    };
873800b99b8Sopenharmony_ci
874800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
875800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
876800b99b8Sopenharmony_ci    memory->SetBuffer(0x4, data);
877800b99b8Sopenharmony_ci
878800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
879800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
880800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 0x0705040207050402);
881800b99b8Sopenharmony_ci    printf("DwarfTest005:%" PRIxPTR "\n", ret);
882800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest005: end.\n";
883800b99b8Sopenharmony_ci}
884800b99b8Sopenharmony_ci
885800b99b8Sopenharmony_ci/**
886800b99b8Sopenharmony_ci * @tc.name: DwarfTest006
887800b99b8Sopenharmony_ci * @tc.desc: test dwarf DW_OP_const oprations
888800b99b8Sopenharmony_ci * @tc.type: FUNC
889800b99b8Sopenharmony_ci */
890800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest006, TestSize.Level2)
891800b99b8Sopenharmony_ci{
892800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest006: start.\n";
893800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
894800b99b8Sopenharmony_ci    memory->increaseAddr = true;
895800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
896800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
897800b99b8Sopenharmony_ci        0x2a, // size
898800b99b8Sopenharmony_ci        DW_OP_constu, 0x01,
899800b99b8Sopenharmony_ci        DW_OP_consts, 0x01,
900800b99b8Sopenharmony_ci        DW_OP_const1u, 0x01,
901800b99b8Sopenharmony_ci        DW_OP_const1s, 0x02,
902800b99b8Sopenharmony_ci        DW_OP_const2u, 0x03, 0x04,
903800b99b8Sopenharmony_ci        DW_OP_const2s, 0x04, 0x04,
904800b99b8Sopenharmony_ci        DW_OP_const4u, 0x03, 0x04, 0x03, 0x04,
905800b99b8Sopenharmony_ci        DW_OP_const4s, 0x04, 0x04, 0x03, 0x04,
906800b99b8Sopenharmony_ci        DW_OP_const8u,
907800b99b8Sopenharmony_ci        0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
908800b99b8Sopenharmony_ci        DW_OP_const8s,
909800b99b8Sopenharmony_ci        0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
910800b99b8Sopenharmony_ci        0x01, 0x01, 0x01, 0x01,
911800b99b8Sopenharmony_ci    };
912800b99b8Sopenharmony_ci
913800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
914800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
915800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
916800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
917800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 0x0403040304030403);
918800b99b8Sopenharmony_ci    printf("DwarfTest006:%" PRIxPTR "\n", ret);
919800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest006: end.\n";
920800b99b8Sopenharmony_ci}
921800b99b8Sopenharmony_ci
922800b99b8Sopenharmony_ci/**
923800b99b8Sopenharmony_ci * @tc.name: DwarfTest007
924800b99b8Sopenharmony_ci * @tc.desc: test dwarf DW_OP_litxx oprations
925800b99b8Sopenharmony_ci * @tc.type: FUNC
926800b99b8Sopenharmony_ci */
927800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest007, TestSize.Level2)
928800b99b8Sopenharmony_ci{
929800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest007: start.\n";
930800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
931800b99b8Sopenharmony_ci    memory->increaseAddr = true;
932800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
933800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
934800b99b8Sopenharmony_ci        0x20, // size
935800b99b8Sopenharmony_ci        DW_OP_lit0,
936800b99b8Sopenharmony_ci        DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4,
937800b99b8Sopenharmony_ci        DW_OP_lit5, DW_OP_lit6, DW_OP_lit7, DW_OP_lit8,
938800b99b8Sopenharmony_ci        DW_OP_lit9, DW_OP_lit10, DW_OP_lit11, DW_OP_lit12,
939800b99b8Sopenharmony_ci        DW_OP_lit13, DW_OP_lit14, DW_OP_lit15, DW_OP_lit16,
940800b99b8Sopenharmony_ci        DW_OP_lit17, DW_OP_lit18, DW_OP_lit19, DW_OP_lit20,
941800b99b8Sopenharmony_ci        DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24,
942800b99b8Sopenharmony_ci        DW_OP_lit25, DW_OP_lit26, DW_OP_lit27, DW_OP_lit28,
943800b99b8Sopenharmony_ci        DW_OP_lit29, DW_OP_lit30, DW_OP_lit31,
944800b99b8Sopenharmony_ci        0x01, 0x01, 0x01, 0x01,
945800b99b8Sopenharmony_ci    };
946800b99b8Sopenharmony_ci
947800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
948800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
949800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
950800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
951800b99b8Sopenharmony_ci    ASSERT_EQ(ret, static_cast<uintptr_t>(DW_OP_lit31 - DW_OP_lit0));
952800b99b8Sopenharmony_ci    printf("DwarfTest007:%" PRIxPTR "\n", ret);
953800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest007: end.\n";
954800b99b8Sopenharmony_ci}
955800b99b8Sopenharmony_ci
956800b99b8Sopenharmony_ci/**
957800b99b8Sopenharmony_ci * @tc.name: DwarfTest008
958800b99b8Sopenharmony_ci * @tc.desc: test dwarf DW_OP_regxx oprations
959800b99b8Sopenharmony_ci * @tc.type: FUNC
960800b99b8Sopenharmony_ci */
961800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest008, TestSize.Level2)
962800b99b8Sopenharmony_ci{
963800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest008: start.\n";
964800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
965800b99b8Sopenharmony_ci    memory->increaseAddr = true;
966800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
967800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
968800b99b8Sopenharmony_ci        0x20, // size
969800b99b8Sopenharmony_ci        DW_OP_reg0,
970800b99b8Sopenharmony_ci        DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4,
971800b99b8Sopenharmony_ci        DW_OP_reg5, DW_OP_reg6, DW_OP_reg7, DW_OP_reg8,
972800b99b8Sopenharmony_ci        DW_OP_reg9, DW_OP_reg10, DW_OP_reg11, DW_OP_reg12,
973800b99b8Sopenharmony_ci        DW_OP_reg13, DW_OP_reg14, DW_OP_reg15, DW_OP_reg16,
974800b99b8Sopenharmony_ci        DW_OP_reg17, DW_OP_reg18, DW_OP_reg19, DW_OP_reg20,
975800b99b8Sopenharmony_ci        DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24,
976800b99b8Sopenharmony_ci        DW_OP_reg25, DW_OP_reg26, DW_OP_reg27, DW_OP_reg28,
977800b99b8Sopenharmony_ci        DW_OP_reg29, DW_OP_reg30, DW_OP_reg31,
978800b99b8Sopenharmony_ci        0x01, 0x01, 0x01, 0x01,
979800b99b8Sopenharmony_ci    };
980800b99b8Sopenharmony_ci
981800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
982800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
983800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
984800b99b8Sopenharmony_ci    const uintptr_t result = 0x5544332211;
985800b99b8Sopenharmony_ci    (*reg)[DW_OP_reg31 - DW_OP_reg0] = result;
986800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
987800b99b8Sopenharmony_ci    ASSERT_EQ(ret, result);
988800b99b8Sopenharmony_ci    printf("DwarfTest008:%" PRIxPTR "\n", ret);
989800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest008: end.\n";
990800b99b8Sopenharmony_ci}
991800b99b8Sopenharmony_ci
992800b99b8Sopenharmony_ci/**
993800b99b8Sopenharmony_ci * @tc.name: DwarfTest009
994800b99b8Sopenharmony_ci * @tc.desc: test dwarf DW_OP_nop oprations
995800b99b8Sopenharmony_ci * @tc.type: FUNC
996800b99b8Sopenharmony_ci */
997800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest009, TestSize.Level2)
998800b99b8Sopenharmony_ci{
999800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest009: start.\n";
1000800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
1001800b99b8Sopenharmony_ci    memory->increaseAddr = true;
1002800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
1003800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
1004800b99b8Sopenharmony_ci        0x0a, // size
1005800b99b8Sopenharmony_ci        DW_OP_fbreg,
1006800b99b8Sopenharmony_ci        DW_OP_piece,
1007800b99b8Sopenharmony_ci        DW_OP_xderef,
1008800b99b8Sopenharmony_ci        DW_OP_xderef_size,
1009800b99b8Sopenharmony_ci        DW_OP_nop,
1010800b99b8Sopenharmony_ci        DW_OP_push_object_address,
1011800b99b8Sopenharmony_ci        DW_OP_call2,
1012800b99b8Sopenharmony_ci        DW_OP_call4,
1013800b99b8Sopenharmony_ci        DW_OP_call_ref,
1014800b99b8Sopenharmony_ci        DW_OP_lo_user,
1015800b99b8Sopenharmony_ci        0x01, 0x01, 0x01, 0x01,
1016800b99b8Sopenharmony_ci    };
1017800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
1018800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
1019800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
1020800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
1021800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 0);
1022800b99b8Sopenharmony_ci    printf("DwarfTest009:%" PRIxPTR "\n", ret);
1023800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest009: end.\n";
1024800b99b8Sopenharmony_ci}
1025800b99b8Sopenharmony_ci
1026800b99b8Sopenharmony_ci/**
1027800b99b8Sopenharmony_ci * @tc.name: DwarfTest010
1028800b99b8Sopenharmony_ci * @tc.desc: test dwarf numerical oprations
1029800b99b8Sopenharmony_ci * @tc.type: FUNC
1030800b99b8Sopenharmony_ci */
1031800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest010, TestSize.Level2)
1032800b99b8Sopenharmony_ci{
1033800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest010: start.\n";
1034800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
1035800b99b8Sopenharmony_ci    memory->increaseAddr = true;
1036800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
1037800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
1038800b99b8Sopenharmony_ci        0x09, // size
1039800b99b8Sopenharmony_ci        DW_OP_lit31,
1040800b99b8Sopenharmony_ci        DW_OP_dup,
1041800b99b8Sopenharmony_ci        DW_OP_dup,
1042800b99b8Sopenharmony_ci        DW_OP_swap,
1043800b99b8Sopenharmony_ci        DW_OP_rot,
1044800b99b8Sopenharmony_ci        DW_OP_abs,
1045800b99b8Sopenharmony_ci        DW_OP_and,
1046800b99b8Sopenharmony_ci        DW_OP_div,
1047800b99b8Sopenharmony_ci        0x01, 0x01, 0x01, 0x01,
1048800b99b8Sopenharmony_ci    };
1049800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
1050800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
1051800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
1052800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
1053800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 1);
1054800b99b8Sopenharmony_ci    printf("DwarfTest010:%" PRIxPTR "\n", ret);
1055800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest010: end.\n";
1056800b99b8Sopenharmony_ci}
1057800b99b8Sopenharmony_ci
1058800b99b8Sopenharmony_ci
1059800b99b8Sopenharmony_ci/**
1060800b99b8Sopenharmony_ci * @tc.name: DwarfTest011
1061800b99b8Sopenharmony_ci * @tc.desc: test dwarf numerical oprations 2
1062800b99b8Sopenharmony_ci * @tc.type: FUNC
1063800b99b8Sopenharmony_ci */
1064800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest011, TestSize.Level2)
1065800b99b8Sopenharmony_ci{
1066800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest011: start.\n";
1067800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
1068800b99b8Sopenharmony_ci    memory->increaseAddr = true;
1069800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
1070800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
1071800b99b8Sopenharmony_ci        0x05, // size
1072800b99b8Sopenharmony_ci        DW_OP_lit31,
1073800b99b8Sopenharmony_ci        DW_OP_dup,
1074800b99b8Sopenharmony_ci        DW_OP_over,
1075800b99b8Sopenharmony_ci        DW_OP_drop,
1076800b99b8Sopenharmony_ci        DW_OP_minus,
1077800b99b8Sopenharmony_ci        0x01, 0x01, 0x01, 0x01,
1078800b99b8Sopenharmony_ci    };
1079800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
1080800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
1081800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
1082800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
1083800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 0);
1084800b99b8Sopenharmony_ci    printf("DwarfTest011:%" PRIxPTR "\n", ret);
1085800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest011: end.\n";
1086800b99b8Sopenharmony_ci}
1087800b99b8Sopenharmony_ci
1088800b99b8Sopenharmony_ci/**
1089800b99b8Sopenharmony_ci * @tc.name: DwarfTest012
1090800b99b8Sopenharmony_ci * @tc.desc: test dwarf numerical oprations 3
1091800b99b8Sopenharmony_ci * @tc.type: FUNC
1092800b99b8Sopenharmony_ci */
1093800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest012, TestSize.Level2)
1094800b99b8Sopenharmony_ci{
1095800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest012: start.\n";
1096800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
1097800b99b8Sopenharmony_ci    memory->increaseAddr = true;
1098800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
1099800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
1100800b99b8Sopenharmony_ci        0x09, // size
1101800b99b8Sopenharmony_ci        DW_OP_lit5,
1102800b99b8Sopenharmony_ci        DW_OP_lit2,
1103800b99b8Sopenharmony_ci        DW_OP_mod, // 5 % 2
1104800b99b8Sopenharmony_ci        DW_OP_lit2,
1105800b99b8Sopenharmony_ci        DW_OP_mul, // 1 * 2
1106800b99b8Sopenharmony_ci        DW_OP_lit2,
1107800b99b8Sopenharmony_ci        DW_OP_plus, // 2 + 2
1108800b99b8Sopenharmony_ci        DW_OP_lit4,
1109800b99b8Sopenharmony_ci        DW_OP_eq,
1110800b99b8Sopenharmony_ci        0x01, 0x01, 0x01, 0x01,
1111800b99b8Sopenharmony_ci    };
1112800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
1113800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
1114800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
1115800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
1116800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 1);
1117800b99b8Sopenharmony_ci    printf("DwarfTest012:%" PRIxPTR "\n", ret);
1118800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest012: end.\n";
1119800b99b8Sopenharmony_ci}
1120800b99b8Sopenharmony_ci
1121800b99b8Sopenharmony_ci/**
1122800b99b8Sopenharmony_ci * @tc.name: DwarfTest013
1123800b99b8Sopenharmony_ci * @tc.desc: test dwarf logical oprations
1124800b99b8Sopenharmony_ci * @tc.type: FUNC
1125800b99b8Sopenharmony_ci */
1126800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DwarfTest013, TestSize.Level2)
1127800b99b8Sopenharmony_ci{
1128800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest013: start.\n";
1129800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemoryTest>();
1130800b99b8Sopenharmony_ci    memory->increaseAddr = true;
1131800b99b8Sopenharmony_ci    DwarfOpTest op(memory);
1132800b99b8Sopenharmony_ci    std::vector<uint8_t> opcodes = {
1133800b99b8Sopenharmony_ci        0x0a, // size
1134800b99b8Sopenharmony_ci        DW_OP_lit1, // 1
1135800b99b8Sopenharmony_ci        DW_OP_lit1, // 1
1136800b99b8Sopenharmony_ci        DW_OP_shl,  // 1 << 1
1137800b99b8Sopenharmony_ci        DW_OP_lit1, // 1
1138800b99b8Sopenharmony_ci        DW_OP_shr,  // 2 >> 1
1139800b99b8Sopenharmony_ci        DW_OP_lit1, // 1
1140800b99b8Sopenharmony_ci        DW_OP_shra, // 1
1141800b99b8Sopenharmony_ci        DW_OP_xor,  // 0
1142800b99b8Sopenharmony_ci        DW_OP_lit1, // 1
1143800b99b8Sopenharmony_ci        DW_OP_eq,   // 0
1144800b99b8Sopenharmony_ci        0x01, 0x01, 0x01, 0x01,
1145800b99b8Sopenharmony_ci    };
1146800b99b8Sopenharmony_ci    uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data());
1147800b99b8Sopenharmony_ci    memory->SetBuffer(exprPtr, opcodes);
1148800b99b8Sopenharmony_ci    auto reg = std::make_shared<DfxRegsArm64>();
1149800b99b8Sopenharmony_ci    uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr);
1150800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 0);
1151800b99b8Sopenharmony_ci    printf("DwarfTest013:%" PRIxPTR "\n", ret);
1152800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DwarfTest013: end.\n";
1153800b99b8Sopenharmony_ci}
1154800b99b8Sopenharmony_ci
1155800b99b8Sopenharmony_ci/**
1156800b99b8Sopenharmony_ci * @tc.name: DfxInstructionsTest001
1157800b99b8Sopenharmony_ci * @tc.desc: test DfxInstructions Flush
1158800b99b8Sopenharmony_ci * @tc.type: FUNC
1159800b99b8Sopenharmony_ci */
1160800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, DfxInstructionsTest001, TestSize.Level2)
1161800b99b8Sopenharmony_ci{
1162800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxInstructionsTest001: start.\n";
1163800b99b8Sopenharmony_ci    auto instructions = std::make_shared<DfxInstructions>();
1164800b99b8Sopenharmony_ci    auto regs = DfxRegs::Create();
1165800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>();
1166800b99b8Sopenharmony_ci    RegLoc loc;
1167800b99b8Sopenharmony_ci    uintptr_t val;
1168800b99b8Sopenharmony_ci    loc.type = REG_LOC_VAL_OFFSET;
1169800b99b8Sopenharmony_ci    bool ret = instructions->Flush(*(regs.get()), memory, 0, loc, val);
1170800b99b8Sopenharmony_ci    ASSERT_EQ(ret, true);
1171800b99b8Sopenharmony_ci    loc.type = REG_LOC_VAL_OFFSET;
1172800b99b8Sopenharmony_ci    ret = instructions->Flush(*(regs.get()), nullptr, 0, loc, val);
1173800b99b8Sopenharmony_ci    ASSERT_EQ(ret, false);
1174800b99b8Sopenharmony_ci    loc.type = REG_LOC_MEM_OFFSET;
1175800b99b8Sopenharmony_ci    ret = instructions->Flush(*(regs.get()), memory, 0, loc, val);
1176800b99b8Sopenharmony_ci    ASSERT_EQ(ret, true);
1177800b99b8Sopenharmony_ci    loc.type = REG_LOC_REGISTER;
1178800b99b8Sopenharmony_ci    ret = instructions->Flush(*(regs.get()), memory, 0, loc, val);
1179800b99b8Sopenharmony_ci    ASSERT_EQ(ret, true);
1180800b99b8Sopenharmony_ci    loc.type = REG_LOC_MEM_EXPRESSION;
1181800b99b8Sopenharmony_ci    ret = instructions->Flush(*(regs.get()), memory, 0, loc, val);
1182800b99b8Sopenharmony_ci    ASSERT_EQ(ret, true);
1183800b99b8Sopenharmony_ci    loc.type = REG_LOC_VAL_EXPRESSION;
1184800b99b8Sopenharmony_ci    ret = instructions->Flush(*(regs.get()), memory, 0, loc, val);
1185800b99b8Sopenharmony_ci    ASSERT_EQ(ret, true);
1186800b99b8Sopenharmony_ci    loc.type = REG_LOC_UNUSED;
1187800b99b8Sopenharmony_ci    ret = instructions->Flush(*(regs.get()), memory, 0, loc, val);
1188800b99b8Sopenharmony_ci    ASSERT_EQ(ret, false);
1189800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxInstructionsTest001: end.\n";
1190800b99b8Sopenharmony_ci}
1191800b99b8Sopenharmony_ci
1192800b99b8Sopenharmony_ci/**
1193800b99b8Sopenharmony_ci * @tc.name: LocalThreadContextTest001
1194800b99b8Sopenharmony_ci * @tc.desc: test LocalThreadContext CopyContextAndWaitTimeout
1195800b99b8Sopenharmony_ci * @tc.type: FUNC
1196800b99b8Sopenharmony_ci */
1197800b99b8Sopenharmony_ciHWTEST_F(DwarfTest, LocalThreadContextTest001, TestSize.Level2)
1198800b99b8Sopenharmony_ci{
1199800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "LocalThreadContextTest001: start.\n";
1200800b99b8Sopenharmony_ci    LocalThreadContext instance;
1201800b99b8Sopenharmony_ci    siginfo_t si {0};
1202800b99b8Sopenharmony_ci    si.si_code = DUMP_TYPE_KERNEL;
1203800b99b8Sopenharmony_ci    instance.CopyContextAndWaitTimeout(0, nullptr, nullptr);
1204800b99b8Sopenharmony_ci    instance.CopyContextAndWaitTimeout(0, &si, nullptr);
1205800b99b8Sopenharmony_ci    si.si_code = DUMP_TYPE_LOCAL;
1206800b99b8Sopenharmony_ci    instance.CopyContextAndWaitTimeout(0, &si, nullptr);
1207800b99b8Sopenharmony_ci    std::shared_ptr<ThreadContext> ret = instance.GetThreadContext(-1);
1208800b99b8Sopenharmony_ci    ASSERT_EQ(ret, nullptr);
1209800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>();
1210800b99b8Sopenharmony_ci    uintptr_t addr = 0;
1211800b99b8Sopenharmony_ci    bool cur = memory->ReadString(addr, nullptr, 0, false);
1212800b99b8Sopenharmony_ci    ASSERT_EQ(cur, false);
1213800b99b8Sopenharmony_ci    uintptr_t val = memory->ReadEncodedValue(addr, DW_EH_PE_omit);
1214800b99b8Sopenharmony_ci    ASSERT_EQ(val, 0);
1215800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "LocalThreadContextTest001: end.\n";
1216800b99b8Sopenharmony_ci}
1217800b99b8Sopenharmony_ci}
1218800b99b8Sopenharmony_ci} // namespace HiviewDFX
1219800b99b8Sopenharmony_ci} // namespace OHOS
1220