1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2022 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#include <ctime>
18800b99b8Sopenharmony_ci#include <securec.h>
19800b99b8Sopenharmony_ci#include <string>
20800b99b8Sopenharmony_ci#include <vector>
21800b99b8Sopenharmony_ci
22800b99b8Sopenharmony_ci#include "dfx_elf.h"
23800b99b8Sopenharmony_ci#include "dfx_maps.h"
24800b99b8Sopenharmony_ci#include "dfx_memory.h"
25800b99b8Sopenharmony_ci#include "dfx_regs.h"
26800b99b8Sopenharmony_ci#include "dfx_regs_get.h"
27800b99b8Sopenharmony_ci#include "dfx_symbols.h"
28800b99b8Sopenharmony_ci#include "dfx_ptrace.h"
29800b99b8Sopenharmony_ci#include "dfx_test_util.h"
30800b99b8Sopenharmony_ci#include "dwarf_define.h"
31800b99b8Sopenharmony_ci#include "stack_util.h"
32800b99b8Sopenharmony_ci
33800b99b8Sopenharmony_ciusing namespace OHOS::HiviewDFX;
34800b99b8Sopenharmony_ciusing namespace testing::ext;
35800b99b8Sopenharmony_ciusing namespace std;
36800b99b8Sopenharmony_ci
37800b99b8Sopenharmony_cinamespace OHOS {
38800b99b8Sopenharmony_cinamespace HiviewDFX {
39800b99b8Sopenharmony_ciclass DfxMemoryTest : public testing::Test {
40800b99b8Sopenharmony_cipublic:
41800b99b8Sopenharmony_ci    static void SetUpTestCase(void) {}
42800b99b8Sopenharmony_ci    static void TearDownTestCase(void) {}
43800b99b8Sopenharmony_ci    void SetUp() {}
44800b99b8Sopenharmony_ci    void TearDown() {}
45800b99b8Sopenharmony_ci};
46800b99b8Sopenharmony_ci
47800b99b8Sopenharmony_cinamespace {
48800b99b8Sopenharmony_ci/**
49800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest001
50800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class ReadReg
51800b99b8Sopenharmony_ci * @tc.type: FUNC
52800b99b8Sopenharmony_ci */
53800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest001, TestSize.Level2)
54800b99b8Sopenharmony_ci{
55800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest001: start.";
56800b99b8Sopenharmony_ci    uintptr_t regs[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
57800b99b8Sopenharmony_ci    UnwindContext ctx;
58800b99b8Sopenharmony_ci    ctx.regs = DfxRegs::CreateFromRegs(UnwindMode::DWARF_UNWIND, regs, sizeof(regs) / sizeof(regs[0]));
59800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
60800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
61800b99b8Sopenharmony_ci    memory->SetCtx(&ctx);
62800b99b8Sopenharmony_ci    uintptr_t value;
63800b99b8Sopenharmony_ci    bool ret = memory->ReadReg(0, &value);
64800b99b8Sopenharmony_ci    EXPECT_EQ(true, ret) << "DfxMemoryTest001: ret" << ret;
65800b99b8Sopenharmony_ci    EXPECT_EQ(static_cast<uintptr_t>(0x1), value) << "DfxMemoryTest001: value" << value;
66800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest001: end.";
67800b99b8Sopenharmony_ci}
68800b99b8Sopenharmony_ci
69800b99b8Sopenharmony_ci/**
70800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest002
71800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read
72800b99b8Sopenharmony_ci * @tc.type: FUNC
73800b99b8Sopenharmony_ci */
74800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest002, TestSize.Level2)
75800b99b8Sopenharmony_ci{
76800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest002: start.";
77800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
78800b99b8Sopenharmony_ci
79800b99b8Sopenharmony_ci    uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
80800b99b8Sopenharmony_ci    uintptr_t value;
81800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
82800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
83800b99b8Sopenharmony_ci    bool ret = memory->ReadUptr(addr, &value, false);
84800b99b8Sopenharmony_ci    EXPECT_EQ(true, ret) << "DfxMemoryTest002: ret:" << ret;
85800b99b8Sopenharmony_ci
86800b99b8Sopenharmony_ci
87800b99b8Sopenharmony_ci    uint64_t tmp;
88800b99b8Sopenharmony_ci    memory->Read(addr, &tmp, sizeof(uint8_t), false);
89800b99b8Sopenharmony_ci    ASSERT_EQ(tmp, 0x01);
90800b99b8Sopenharmony_ci
91800b99b8Sopenharmony_ci    memory->Read(addr, &tmp, sizeof(uint16_t), false);
92800b99b8Sopenharmony_ci    ASSERT_EQ(tmp, 0x0201);
93800b99b8Sopenharmony_ci
94800b99b8Sopenharmony_ci    memory->Read(addr, &tmp, sizeof(uint32_t), false);
95800b99b8Sopenharmony_ci    ASSERT_EQ(tmp, 0x04030201);
96800b99b8Sopenharmony_ci
97800b99b8Sopenharmony_ci    memory->Read(addr, &tmp, sizeof(uint64_t), false);
98800b99b8Sopenharmony_ci    ASSERT_EQ(tmp, 0x0807060504030201);
99800b99b8Sopenharmony_ci
100800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest002: end.";
101800b99b8Sopenharmony_ci}
102800b99b8Sopenharmony_ci
103800b99b8Sopenharmony_ci/**
104800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest003
105800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read
106800b99b8Sopenharmony_ci * @tc.type: FUNC
107800b99b8Sopenharmony_ci */
108800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest003, TestSize.Level2)
109800b99b8Sopenharmony_ci{
110800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest003: start.";
111800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
112800b99b8Sopenharmony_ci    UnwindContext ctx;
113800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
114800b99b8Sopenharmony_ci    ASSERT_TRUE(GetSelfStackRange(ctx.stackBottom, ctx.stackTop));
115800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
116800b99b8Sopenharmony_ci    memory->SetCtx(&ctx);
117800b99b8Sopenharmony_ci    uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
118800b99b8Sopenharmony_ci    uintptr_t value;
119800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->ReadUptr(addr, &value, false));
120800b99b8Sopenharmony_ci#if defined(__arm__)
121800b99b8Sopenharmony_ci    ASSERT_EQ(value, 0x04030201);
122800b99b8Sopenharmony_ci#elif defined(__aarch64__)
123800b99b8Sopenharmony_ci    ASSERT_EQ(value, 0x0807060504030201);
124800b99b8Sopenharmony_ci#endif
125800b99b8Sopenharmony_ci
126800b99b8Sopenharmony_ci    uint64_t tmp;
127800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint8_t), false));
128800b99b8Sopenharmony_ci    ASSERT_EQ(tmp, 0x01);
129800b99b8Sopenharmony_ci
130800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint16_t), false));
131800b99b8Sopenharmony_ci    ASSERT_EQ(tmp, 0x0201);
132800b99b8Sopenharmony_ci
133800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint32_t), false));
134800b99b8Sopenharmony_ci    ASSERT_EQ(tmp, 0x04030201);
135800b99b8Sopenharmony_ci
136800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint64_t), false));
137800b99b8Sopenharmony_ci    ASSERT_EQ(tmp, 0x0807060504030201);
138800b99b8Sopenharmony_ci
139800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest003: end.";
140800b99b8Sopenharmony_ci}
141800b99b8Sopenharmony_ci
142800b99b8Sopenharmony_ci/**
143800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest004
144800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read
145800b99b8Sopenharmony_ci * @tc.type: FUNC
146800b99b8Sopenharmony_ci */
147800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest004, TestSize.Level2)
148800b99b8Sopenharmony_ci{
149800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest004: start.";
150800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
151800b99b8Sopenharmony_ci    UnwindContext ctx;
152800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
153800b99b8Sopenharmony_ci    ASSERT_TRUE(GetSelfStackRange(ctx.stackBottom, ctx.stackTop));
154800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
155800b99b8Sopenharmony_ci    memory->SetCtx(&ctx);
156800b99b8Sopenharmony_ci    uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
157800b99b8Sopenharmony_ci    uint8_t tmp8;
158800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->ReadU8(addr, &tmp8, false));
159800b99b8Sopenharmony_ci    ASSERT_EQ(tmp8, 0x01);
160800b99b8Sopenharmony_ci    uint16_t tmp16;
161800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->ReadU16(addr, &tmp16, false));
162800b99b8Sopenharmony_ci    ASSERT_EQ(tmp16, 0x0201);
163800b99b8Sopenharmony_ci    uint32_t tmp32;
164800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->ReadU32(addr, &tmp32, false));
165800b99b8Sopenharmony_ci    ASSERT_EQ(tmp32, 0x04030201);
166800b99b8Sopenharmony_ci    uint64_t tmp64;
167800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->ReadU64(addr, &tmp64, false));
168800b99b8Sopenharmony_ci    ASSERT_EQ(tmp64, 0x0807060504030201);
169800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest004: end.";
170800b99b8Sopenharmony_ci}
171800b99b8Sopenharmony_ci
172800b99b8Sopenharmony_ci/**
173800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest005
174800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read
175800b99b8Sopenharmony_ci * @tc.type: FUNC
176800b99b8Sopenharmony_ci */
177800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest005, TestSize.Level2)
178800b99b8Sopenharmony_ci{
179800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest005: start.";
180800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
181800b99b8Sopenharmony_ci    UnwindContext ctx;
182800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
183800b99b8Sopenharmony_ci    ASSERT_TRUE(GetSelfStackRange(ctx.stackBottom, ctx.stackTop));
184800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
185800b99b8Sopenharmony_ci    memory->SetCtx(&ctx);
186800b99b8Sopenharmony_ci    uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
187800b99b8Sopenharmony_ci    uintptr_t valuePrel32;
188800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->ReadPrel31(addr, &valuePrel32));
189800b99b8Sopenharmony_ci    ASSERT_EQ(valuePrel32, 0x04030201 + addr);
190800b99b8Sopenharmony_ci    char testStr[] = "Test ReadString Func";
191800b99b8Sopenharmony_ci    std::string resultStr;
192800b99b8Sopenharmony_ci    uintptr_t addrStr = reinterpret_cast<uintptr_t>(&testStr[0]);
193800b99b8Sopenharmony_ci    ASSERT_TRUE(memory->ReadString(addrStr, &resultStr, sizeof(testStr)/sizeof(char), false));
194800b99b8Sopenharmony_ci    ASSERT_EQ(testStr, resultStr);
195800b99b8Sopenharmony_ci    ASSERT_EQ(memory->ReadUleb128(addr), 1U);
196800b99b8Sopenharmony_ci    ASSERT_EQ(memory->ReadSleb128(addr), 2);
197800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest005: end.";
198800b99b8Sopenharmony_ci}
199800b99b8Sopenharmony_ci
200800b99b8Sopenharmony_ci/**
201800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest006
202800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read
203800b99b8Sopenharmony_ci * @tc.type: FUNC
204800b99b8Sopenharmony_ci */
205800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest006, TestSize.Level2)
206800b99b8Sopenharmony_ci{
207800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest006: start.";
208800b99b8Sopenharmony_ci    UnwindContext ctx;
209800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
210800b99b8Sopenharmony_ci    ASSERT_TRUE(GetSelfStackRange(ctx.stackBottom, ctx.stackTop));
211800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
212800b99b8Sopenharmony_ci    memory->SetCtx(&ctx);
213800b99b8Sopenharmony_ci    ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_absptr), sizeof(uintptr_t));
214800b99b8Sopenharmony_ci    ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata1), 1);
215800b99b8Sopenharmony_ci    ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata2), 2);
216800b99b8Sopenharmony_ci    ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata4), 4);
217800b99b8Sopenharmony_ci    ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata8), 8);
218800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest006: end.";
219800b99b8Sopenharmony_ci}
220800b99b8Sopenharmony_ci
221800b99b8Sopenharmony_ci/**
222800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest007
223800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class ReadReg in remote case
224800b99b8Sopenharmony_ci * @tc.type: FUNC
225800b99b8Sopenharmony_ci */
226800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest007, TestSize.Level2)
227800b99b8Sopenharmony_ci{
228800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest007: start.";
229800b99b8Sopenharmony_ci    uintptr_t regs[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
230800b99b8Sopenharmony_ci    UnwindContext ctx;
231800b99b8Sopenharmony_ci    ctx.regs = DfxRegs::CreateFromRegs(UnwindMode::DWARF_UNWIND, regs, sizeof(regs) / sizeof(regs[0]));
232800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsRemote>();
233800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
234800b99b8Sopenharmony_ci    memory->SetCtx(&ctx);
235800b99b8Sopenharmony_ci    uintptr_t value;
236800b99b8Sopenharmony_ci    bool ret = memory->ReadReg(0, &value);
237800b99b8Sopenharmony_ci    EXPECT_EQ(true, ret) << "DfxMemoryTest007: ret" << ret;
238800b99b8Sopenharmony_ci    EXPECT_EQ(static_cast<uintptr_t>(0x1), value) << "DfxMemoryTest007: value" << value;
239800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest007: end.";
240800b99b8Sopenharmony_ci}
241800b99b8Sopenharmony_ci/**
242800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest008
243800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read in remote case
244800b99b8Sopenharmony_ci * @tc.type: FUNC
245800b99b8Sopenharmony_ci */
246800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest008, TestSize.Level2)
247800b99b8Sopenharmony_ci{
248800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest008: start.";
249800b99b8Sopenharmony_ci    static pid_t pid = getpid();
250800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
251800b99b8Sopenharmony_ci    pid_t child = fork();
252800b99b8Sopenharmony_ci    if (child == 0) {
253800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
254800b99b8Sopenharmony_ci        DfxPtrace::Attach(pid);
255800b99b8Sopenharmony_ci        uintptr_t value;
256800b99b8Sopenharmony_ci        UnwindContext ctx;
257800b99b8Sopenharmony_ci        ctx.pid = pid;
258800b99b8Sopenharmony_ci        auto acc = std::make_shared<DfxAccessorsRemote>();
259800b99b8Sopenharmony_ci        auto memory = std::make_shared<DfxMemory>(acc);
260800b99b8Sopenharmony_ci        memory->SetCtx(&ctx);
261800b99b8Sopenharmony_ci        uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
262800b99b8Sopenharmony_ci        bool ret = memory->ReadUptr(addr, &value, false);
263800b99b8Sopenharmony_ci        EXPECT_EQ(true, ret) << "DfxMemoryTest008: ret:" << ret;
264800b99b8Sopenharmony_ci        uint64_t tmp;
265800b99b8Sopenharmony_ci        memory->Read(addr, &tmp, sizeof(uint8_t), false);
266800b99b8Sopenharmony_ci        EXPECT_EQ(tmp, 0x01);
267800b99b8Sopenharmony_ci
268800b99b8Sopenharmony_ci        memory->Read(addr, &tmp, sizeof(uint16_t), false);
269800b99b8Sopenharmony_ci        EXPECT_EQ(tmp, 0x0201);
270800b99b8Sopenharmony_ci
271800b99b8Sopenharmony_ci        memory->Read(addr, &tmp, sizeof(uint32_t), false);
272800b99b8Sopenharmony_ci        EXPECT_EQ(tmp, 0x04030201);
273800b99b8Sopenharmony_ci
274800b99b8Sopenharmony_ci        memory->Read(addr, &tmp, sizeof(uint64_t), false);
275800b99b8Sopenharmony_ci        EXPECT_EQ(tmp, 0x0807060504030201);
276800b99b8Sopenharmony_ci        DfxPtrace::Detach(pid);
277800b99b8Sopenharmony_ci        _exit(0);
278800b99b8Sopenharmony_ci    }
279800b99b8Sopenharmony_ci    int status;
280800b99b8Sopenharmony_ci    int ret = wait(&status);
281800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
282800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest008: end.";
283800b99b8Sopenharmony_ci}
284800b99b8Sopenharmony_ci
285800b99b8Sopenharmony_ci/**
286800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest009
287800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read in remote case
288800b99b8Sopenharmony_ci * @tc.type: FUNC
289800b99b8Sopenharmony_ci */
290800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest009, TestSize.Level2)
291800b99b8Sopenharmony_ci{
292800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest009: start.";
293800b99b8Sopenharmony_ci    static pid_t pid = getpid();
294800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
295800b99b8Sopenharmony_ci    pid_t child = fork();
296800b99b8Sopenharmony_ci    if (child == 0) {
297800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
298800b99b8Sopenharmony_ci        DfxPtrace::Attach(pid);
299800b99b8Sopenharmony_ci        UnwindContext ctx;
300800b99b8Sopenharmony_ci        ctx.pid = pid;
301800b99b8Sopenharmony_ci        auto acc = std::make_shared<DfxAccessorsRemote>();
302800b99b8Sopenharmony_ci        auto memory = std::make_shared<DfxMemory>(acc);
303800b99b8Sopenharmony_ci        memory->SetCtx(&ctx);
304800b99b8Sopenharmony_ci        uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
305800b99b8Sopenharmony_ci        uintptr_t value;
306800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->ReadUptr(addr, &value, false));
307800b99b8Sopenharmony_ci#if defined(__arm__)
308800b99b8Sopenharmony_ci        ASSERT_EQ(value, 0x04030201);
309800b99b8Sopenharmony_ci#elif defined(__aarch64__)
310800b99b8Sopenharmony_ci        ASSERT_EQ(value, 0x0807060504030201);
311800b99b8Sopenharmony_ci#endif
312800b99b8Sopenharmony_ci
313800b99b8Sopenharmony_ci        uint64_t tmp;
314800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint8_t), false));
315800b99b8Sopenharmony_ci        ASSERT_EQ(tmp, 0x01);
316800b99b8Sopenharmony_ci
317800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint16_t), false));
318800b99b8Sopenharmony_ci        ASSERT_EQ(tmp, 0x0201);
319800b99b8Sopenharmony_ci
320800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint32_t), false));
321800b99b8Sopenharmony_ci        ASSERT_EQ(tmp, 0x04030201);
322800b99b8Sopenharmony_ci
323800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint64_t), false));
324800b99b8Sopenharmony_ci        ASSERT_EQ(tmp, 0x0807060504030201);
325800b99b8Sopenharmony_ci        DfxPtrace::Detach(pid);
326800b99b8Sopenharmony_ci        _exit(0);
327800b99b8Sopenharmony_ci    }
328800b99b8Sopenharmony_ci    int status;
329800b99b8Sopenharmony_ci    int ret = wait(&status);
330800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
331800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest009: end.";
332800b99b8Sopenharmony_ci}
333800b99b8Sopenharmony_ci
334800b99b8Sopenharmony_ci/**
335800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest010
336800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read in remote case
337800b99b8Sopenharmony_ci * @tc.type: FUNC
338800b99b8Sopenharmony_ci */
339800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest010, TestSize.Level2)
340800b99b8Sopenharmony_ci{
341800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest010: start.";
342800b99b8Sopenharmony_ci    static pid_t pid = getpid();
343800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
344800b99b8Sopenharmony_ci    pid_t child = fork();
345800b99b8Sopenharmony_ci    if (child == 0) {
346800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
347800b99b8Sopenharmony_ci        DfxPtrace::Attach(pid);
348800b99b8Sopenharmony_ci
349800b99b8Sopenharmony_ci        UnwindContext ctx;
350800b99b8Sopenharmony_ci        ctx.pid = pid;
351800b99b8Sopenharmony_ci        auto acc = std::make_shared<DfxAccessorsRemote>();
352800b99b8Sopenharmony_ci        auto memory = std::make_shared<DfxMemory>(acc);
353800b99b8Sopenharmony_ci        memory->SetCtx(&ctx);
354800b99b8Sopenharmony_ci        uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
355800b99b8Sopenharmony_ci        uint8_t tmp8;
356800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->ReadU8(addr, &tmp8, false));
357800b99b8Sopenharmony_ci        ASSERT_EQ(tmp8, 0x01);
358800b99b8Sopenharmony_ci        uint16_t tmp16;
359800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->ReadU16(addr, &tmp16, false));
360800b99b8Sopenharmony_ci        ASSERT_EQ(tmp16, 0x0201);
361800b99b8Sopenharmony_ci        uint32_t tmp32;
362800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->ReadU32(addr, &tmp32, false));
363800b99b8Sopenharmony_ci        ASSERT_EQ(tmp32, 0x04030201);
364800b99b8Sopenharmony_ci        uint64_t tmp64;
365800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->ReadU64(addr, &tmp64, false));
366800b99b8Sopenharmony_ci        ASSERT_EQ(tmp64, 0x0807060504030201);
367800b99b8Sopenharmony_ci        DfxPtrace::Detach(pid);
368800b99b8Sopenharmony_ci        _exit(0);
369800b99b8Sopenharmony_ci    }
370800b99b8Sopenharmony_ci    int status;
371800b99b8Sopenharmony_ci    int ret = wait(&status);
372800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
373800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest010: end.";
374800b99b8Sopenharmony_ci}
375800b99b8Sopenharmony_ci
376800b99b8Sopenharmony_ci/**
377800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest011
378800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read in remote case
379800b99b8Sopenharmony_ci * @tc.type: FUNC
380800b99b8Sopenharmony_ci */
381800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest011, TestSize.Level2)
382800b99b8Sopenharmony_ci{
383800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest011: start.";
384800b99b8Sopenharmony_ci    static pid_t pid = getpid();
385800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
386800b99b8Sopenharmony_ci    char testStr[] = "Test ReadString Func";
387800b99b8Sopenharmony_ci    pid_t child = fork();
388800b99b8Sopenharmony_ci    if (child == 0) {
389800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
390800b99b8Sopenharmony_ci        DfxPtrace::Attach(getppid());
391800b99b8Sopenharmony_ci        UnwindContext ctx;
392800b99b8Sopenharmony_ci        ctx.pid = getppid();
393800b99b8Sopenharmony_ci        auto acc = std::make_shared<DfxAccessorsRemote>();
394800b99b8Sopenharmony_ci        auto memory = std::make_shared<DfxMemory>(acc);
395800b99b8Sopenharmony_ci        memory->SetCtx(&ctx);
396800b99b8Sopenharmony_ci        uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
397800b99b8Sopenharmony_ci        std::string resultStr;
398800b99b8Sopenharmony_ci        uintptr_t addrStr = reinterpret_cast<uintptr_t>(&testStr[0]);
399800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->ReadString(addrStr, &resultStr, sizeof(testStr)/sizeof(char), false));
400800b99b8Sopenharmony_ci        ASSERT_EQ(testStr, resultStr);
401800b99b8Sopenharmony_ci        ASSERT_TRUE(memory->ReadString(addrStr, &resultStr, sizeof(testStr)/sizeof(char), true));
402800b99b8Sopenharmony_ci        ASSERT_EQ(testStr, resultStr);
403800b99b8Sopenharmony_ci        ASSERT_EQ(memory->ReadUleb128(addr), 1U);
404800b99b8Sopenharmony_ci        ASSERT_EQ(memory->ReadSleb128(addr), 2);
405800b99b8Sopenharmony_ci        DfxPtrace::Detach(pid);
406800b99b8Sopenharmony_ci        _exit(0);
407800b99b8Sopenharmony_ci    }
408800b99b8Sopenharmony_ci    int status;
409800b99b8Sopenharmony_ci    int ret = wait(&status);
410800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
411800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest011: end.";
412800b99b8Sopenharmony_ci}
413800b99b8Sopenharmony_ci
414800b99b8Sopenharmony_ci/**
415800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest012
416800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read in remote case
417800b99b8Sopenharmony_ci * @tc.type: FUNC
418800b99b8Sopenharmony_ci */
419800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest012, TestSize.Level2)
420800b99b8Sopenharmony_ci{
421800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest012: start.";
422800b99b8Sopenharmony_ci    static pid_t pid = getpid();
423800b99b8Sopenharmony_ci    pid_t child = fork();
424800b99b8Sopenharmony_ci    if (child == 0) {
425800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
426800b99b8Sopenharmony_ci        DfxPtrace::Attach(pid);
427800b99b8Sopenharmony_ci        UnwindContext ctx;
428800b99b8Sopenharmony_ci        ctx.pid = pid;
429800b99b8Sopenharmony_ci        auto acc = std::make_shared<DfxAccessorsRemote>();
430800b99b8Sopenharmony_ci        auto memory = std::make_shared<DfxMemory>(acc);
431800b99b8Sopenharmony_ci        memory->SetCtx(&ctx);
432800b99b8Sopenharmony_ci        ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_absptr), sizeof(uintptr_t));
433800b99b8Sopenharmony_ci        ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata1), 1);
434800b99b8Sopenharmony_ci        ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata2), 2);
435800b99b8Sopenharmony_ci        ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata4), 4);
436800b99b8Sopenharmony_ci        ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata8), 8);
437800b99b8Sopenharmony_ci        DfxPtrace::Detach(pid);
438800b99b8Sopenharmony_ci        _exit(0);
439800b99b8Sopenharmony_ci    }
440800b99b8Sopenharmony_ci    int status;
441800b99b8Sopenharmony_ci    int ret = wait(&status);
442800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
443800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest012: end.";
444800b99b8Sopenharmony_ci}
445800b99b8Sopenharmony_ci
446800b99b8Sopenharmony_ci/**
447800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest013
448800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class Read in error case
449800b99b8Sopenharmony_ci * @tc.type: FUNC
450800b99b8Sopenharmony_ci */
451800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest013, TestSize.Level2)
452800b99b8Sopenharmony_ci{
453800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest013: start.";
454800b99b8Sopenharmony_ci    auto acc = std::make_shared<DfxAccessorsLocal>();
455800b99b8Sopenharmony_ci    auto memory = std::make_shared<DfxMemory>(acc);
456800b99b8Sopenharmony_ci    uintptr_t val;
457800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->ReadReg(0, &val));
458800b99b8Sopenharmony_ci    uintptr_t regs[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
459800b99b8Sopenharmony_ci    UnwindContext ctx;
460800b99b8Sopenharmony_ci    ctx.regs = DfxRegs::CreateFromRegs(UnwindMode::DWARF_UNWIND, regs, sizeof(regs) / sizeof(regs[0]));
461800b99b8Sopenharmony_ci    memory->SetCtx(&ctx);
462800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->ReadReg(-1, &val));
463800b99b8Sopenharmony_ci
464800b99b8Sopenharmony_ci    uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
465800b99b8Sopenharmony_ci    uintptr_t addr = reinterpret_cast<uintptr_t>(&values[0]);
466800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->ReadMem(addr, nullptr));
467800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->ReadUptr(addr, nullptr, false));
468800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->Read(addr, nullptr, sizeof(uint8_t), false));
469800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->ReadU8(addr, nullptr, false));
470800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->ReadU16(addr, nullptr, false));
471800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->ReadU32(addr, nullptr, false));
472800b99b8Sopenharmony_ci    EXPECT_FALSE(memory->ReadU64(addr, nullptr, false));
473800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest013: end.";
474800b99b8Sopenharmony_ci}
475800b99b8Sopenharmony_ci
476800b99b8Sopenharmony_ci/**
477800b99b8Sopenharmony_ci * @tc.name: DfxMemoryTest014
478800b99b8Sopenharmony_ci * @tc.desc: test DfxMemory class ReadProcMemByPid
479800b99b8Sopenharmony_ci * @tc.type: FUNC
480800b99b8Sopenharmony_ci */
481800b99b8Sopenharmony_ciHWTEST_F(DfxMemoryTest, DfxMemoryTest014, TestSize.Level2)
482800b99b8Sopenharmony_ci{
483800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest014: start.";
484800b99b8Sopenharmony_ci    std::string res = ExecuteCommands("uname");
485800b99b8Sopenharmony_ci    bool linuxKernel = res.find("Linux") != std::string::npos;
486800b99b8Sopenharmony_ci    if (linuxKernel) {
487800b99b8Sopenharmony_ci        ASSERT_TRUE(linuxKernel);
488800b99b8Sopenharmony_ci        return;
489800b99b8Sopenharmony_ci    }
490800b99b8Sopenharmony_ci    pid_t pid = GetProcessPid(FOUNDATION_NAME);
491800b99b8Sopenharmony_ci    auto maps = DfxMaps::Create(pid);
492800b99b8Sopenharmony_ci    std::vector<std::shared_ptr<DfxMap>> shmmMaps;
493800b99b8Sopenharmony_ci    ASSERT_TRUE(maps->FindMapsByName("[shmm]", shmmMaps));
494800b99b8Sopenharmony_ci    std::shared_ptr<DfxMap> shmmMap = nullptr;
495800b99b8Sopenharmony_ci    for (auto map : shmmMaps) {
496800b99b8Sopenharmony_ci        if (map->IsMapExec()) {
497800b99b8Sopenharmony_ci            shmmMap = map;
498800b99b8Sopenharmony_ci            break;
499800b99b8Sopenharmony_ci        }
500800b99b8Sopenharmony_ci    }
501800b99b8Sopenharmony_ci    ASSERT_TRUE(shmmMap != nullptr);
502800b99b8Sopenharmony_ci    auto shmmData = std::make_shared<std::vector<uint8_t>>(shmmMap->end - shmmMap->begin);
503800b99b8Sopenharmony_ci    DfxMemory::ReadProcMemByPid(pid, shmmMap->begin, shmmData->data(), shmmMap->end - shmmMap->begin);
504800b99b8Sopenharmony_ci    auto shmmElf = std::make_shared<DfxElf>(shmmData->data(), shmmMap->end - shmmMap->begin);
505800b99b8Sopenharmony_ci    ASSERT_TRUE(shmmElf->IsValid());
506800b99b8Sopenharmony_ci    std::vector<DfxSymbol> shmmSyms;
507800b99b8Sopenharmony_ci    DfxSymbols::ParseSymbols(shmmSyms, shmmElf, "");
508800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "shmm symbols size" << shmmSyms.size();
509800b99b8Sopenharmony_ci    ASSERT_GT(shmmSyms.size(), 0);
510800b99b8Sopenharmony_ci    for (auto& sym : shmmSyms) {
511800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << sym.ToDebugString();
512800b99b8Sopenharmony_ci    }
513800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxMemoryTest014 : end.";
514800b99b8Sopenharmony_ci}
515800b99b8Sopenharmony_ci}
516800b99b8Sopenharmony_ci} // namespace HiviewDFX
517800b99b8Sopenharmony_ci} // namespace OHOS
518