1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <gtest/gtest.h> 17 18#include <dlfcn.h> 19#include <securec.h> 20 21#include <ctime> 22#include <cstdio> 23#include <fstream> 24#include <memory> 25#include <string> 26#include <vector> 27 28#include <fcntl.h> 29#include <unistd.h> 30 31#include <sys/stat.h> 32#include <sys/types.h> 33 34#include "string_ex.h" 35 36#include "dfx_define.h" 37#include "dfx_elf.h" 38#include "dfx_instructions.h" 39#include "dfx_log.h" 40#include "dfx_memory.h" 41#include "dfx_regs.h" 42#include "dwarf_cfa_instructions.h" 43#include "dwarf_define.h" 44#include "dwarf_op.h" 45#include "dwarf_section.h" 46#include "thread_context.h" 47#include "unwind_arm64_define.h" 48#include "unwind_loc.h" 49 50using namespace OHOS::HiviewDFX; 51using namespace testing::ext; 52using namespace std; 53#define HEX 16 54#define STACK_VALUE (-8) 55 56namespace OHOS { 57namespace HiviewDFX { 58class DwarfTest : public testing::Test { 59public: 60 static void TearDownTestCase(void) {} 61 void SetUp() {} 62 void TearDown() {} 63}; 64 65class DwarfSectionTest : public DwarfSection { 66public: 67 explicit DwarfSectionTest(std::shared_ptr<DfxMemory> memory) : DwarfSection(memory) {}; 68 ~DwarfSectionTest() {}; 69 bool ParseFdeTest(uintptr_t addr, FrameDescEntry &fde) 70 { 71 return ParseFde(addr, addr, fde); 72 }; 73 74 bool ParseCieTest(uintptr_t cieAddr, CommonInfoEntry &cieInfo) 75 { 76 return ParseCie(cieAddr, cieAddr, cieInfo); 77 }; 78}; 79 80struct MemoryArea { 81 MemoryArea(uintptr_t addr, std::vector<uint8_t> buffer) 82 { 83 this->addr = addr; 84 this->data = buffer; 85 } 86 uintptr_t addr; 87 std::vector<uint8_t> data; 88}; 89 90class DfxMemoryTest : public DfxMemory { 91public: 92 DfxMemoryTest() {}; 93 virtual ~DfxMemoryTest() {}; 94 size_t Read(uintptr_t& addr, void* val, size_t size, bool incre = false) override; 95 void SetBuffer(uintptr_t addr, std::vector<uint8_t> buffer); 96 void Reset(); 97 bool increaseAddr = false; 98 99private: 100 std::vector<MemoryArea> buffers; 101}; 102 103void DfxMemoryTest::Reset() 104{ 105 buffers.clear(); 106} 107 108size_t DfxMemoryTest::Read(uintptr_t& addr, void* val, size_t size, bool incre) 109{ 110 printf("DfxMemoryTest::Request Read:%" PRIxPTR " size:%zu\n", addr, size); 111 for (const auto& buffer : buffers) { 112 if (addr >= buffer.addr && 113 addr + size <= buffer.addr + buffer.data.size()) { 114 size_t offset = addr - buffer.addr; 115 auto data = const_cast<uint8_t*>(buffer.data.data()); 116 (void)memcpy_s(val, size, data + offset, size); 117 if (increaseAddr) { 118 addr = addr + size; 119 } 120 printf("DfxMemoryTest::Read addr:0x%" PRIxPTR "\n", addr); 121 return size; 122 } 123 } 124 return 0; 125} 126 127void DfxMemoryTest::SetBuffer(uintptr_t addr, std::vector<uint8_t> buffer) 128{ 129 printf("DfxMemoryTest::SetBuffer:%" PRIxPTR " size:%zu\n", addr, buffer.size()); 130 buffers.push_back({addr, buffer}); 131} 132 133class DwarfOpTest : public DwarfOp<uintptr_t> { 134public: 135 using DwarfOp<uintptr_t>::DwarfOp; 136 bool Test01(); 137 bool Test02(); 138 bool Test03(); 139 bool Test04(std::shared_ptr<DfxMemoryTest> memory); 140 bool Test05(std::shared_ptr<DfxMemoryTest> memory); 141 bool Test06(); 142 bool Test07(); 143 bool Test08(); 144 bool Test09(std::shared_ptr<DfxMemoryTest> memory); 145 bool Test10(std::shared_ptr<DfxMemoryTest> memory); 146 friend class DwarfTest; 147}; 148 149bool DwarfOpTest::Test01() 150{ 151 std::shared_ptr<DfxRegs> regs = std::make_shared<DfxRegsArm64>(); 152 uintptr_t addr = 0; 153 return Eval(*(regs.get()), 0, addr); 154} 155 156bool DwarfOpTest::Test02() 157{ 158 bool ret = false; 159 const uintptr_t value = 10; 160 StackPush(value); 161 ret = (value == stack_.front()); 162 StackReset(0); 163 ret &= (0 == stack_.front()); 164 return ret; 165} 166 167bool DwarfOpTest::Test03() 168{ 169 StackReset(0); 170 bool ret = false; 171 const uintptr_t value = 10; 172 StackPush(value); 173 ret = (value == StackPop()); 174 ret &= (StackAt(0) == 0); 175 ret &= (StackSize() == 1); 176 return ret; 177} 178 179bool DwarfOpTest::Test04(std::shared_ptr<DfxMemoryTest> memory) 180{ 181 // OpDerefSize 182 bool ret = false; 183 StackReset(0); 184 std::vector<uint8_t> exprData { 185 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 186 }; 187 188 std::vector<uint8_t> valueData { 189 0x08, // U8 190 0x10, 0x11, // U16 191 0x20, 0x21, 0x22, 0x23, // U32 192 0x31, 0x32, 0x33, 0x34, // U32 193 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // U64 194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, // U64 195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, // U64 196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, // U64 197 }; 198 199 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(exprData.data()); 200 uintptr_t valuePtr = reinterpret_cast<uintptr_t>(valueData.data()); 201 memory->SetBuffer(valuePtr, valueData); 202 memory->SetBuffer(exprPtr, exprData); 203 printf("Test04 exprPtr:%" PRIxPTR " valuePtr:%" PRIxPTR "\n", exprPtr, valuePtr); 204 205 // u8 206 StackPush(valuePtr); 207 OpDerefSize(exprPtr); 208 uintptr_t value = StackPop(); 209 uintptr_t expectedValue = 0x08; 210 ret = (value == expectedValue); 211 printf("Test04-u8 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue); 212 213 // u16 214 valuePtr = valuePtr + sizeof(uint8_t); 215 exprPtr = exprPtr + sizeof(uint8_t); 216 StackPush(valuePtr); 217 OpDerefSize(exprPtr); 218 value = StackPop(); 219 expectedValue = 0x1110; 220 ret &= (value == expectedValue); 221 printf("Test04-u16 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue); 222 223 // u32 224 valuePtr = valuePtr + sizeof(uint16_t); 225 exprPtr = exprPtr + sizeof(uint8_t); 226 StackPush(valuePtr); 227 OpDerefSize(exprPtr); 228 value = StackPop(); 229 expectedValue = 0x23222120; 230 ret &= (value == expectedValue); 231 printf("Test04-u32-0 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue); 232 233 // u32 234 valuePtr = valuePtr + sizeof(uint32_t); 235 exprPtr = exprPtr + sizeof(uint8_t); 236 StackPush(valuePtr); 237 OpDerefSize(exprPtr); 238 value = StackPop(); 239 expectedValue = 0x34333231; 240 ret &= (value == expectedValue); 241 printf("Test04-u32-1 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue); 242 243 // u64 244 valuePtr = valuePtr + sizeof(uint32_t); 245 exprPtr = exprPtr + sizeof(uint8_t); 246 StackPush(valuePtr); 247 OpDerefSize(exprPtr); 248 value = StackPop(); 249 expectedValue = 0x4847464544434241; 250 ret &= (value == expectedValue); 251 printf("Test04-u64-0 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue); 252 return ret; 253} 254 255bool DwarfOpTest::Test05(std::shared_ptr<DfxMemoryTest> memory) 256{ 257 bool ret = false; 258 StackReset(0); 259 memory->Reset(); 260 std::vector<uint8_t> valueData { 261 0x31, 0x32, 0x33, 0x34, 0x31, 0x32, 0x33, 0x34, 262 }; 263 // OpDeref 264 uintptr_t valuePtr = reinterpret_cast<uintptr_t>(valueData.data()); 265 memory->SetBuffer(valuePtr, valueData); 266 OpPush(valuePtr); 267 OpDeref(); 268 uintptr_t value = StackPop(); 269 uintptr_t expectedValue = 0x3433323134333231; 270 printf("Test05-u64 value:%" PRIxPTR " expectedValue:%" PRIxPTR "\n", value, expectedValue); 271 ret = (value == expectedValue); 272 printf("Test05-01 %d\n", ret); 273 OpPush(valuePtr); 274 OpDup(); 275 ret &= (StackAt(0) == valuePtr); 276 printf("Test05-02 %d\n", ret); 277 ret &= (StackAt(1) == valuePtr); 278 printf("Test05-03 %d\n", ret); 279 return ret; 280} 281 282bool DwarfOpTest::Test06() 283{ 284 // OpDrop OpOver OpSwap OpRot 285 MAYBE_UNUSED bool ret = false; 286 StackReset(0); 287 ret = (StackSize() == 1); 288 OpPush(1); 289 ret &= (StackSize() == 2); // 2:stack_.size() 290 291 OpDrop(); 292 ret &= (StackSize() == 1); 293 294 OpPush(1); 295 OpPush(2); // 2:stack_.index 296 ret &= (StackSize() == 3); // 3:stack_.size() 297 298 OpOver(); 299 ret &= (StackSize() == 4); // 4:stack_.size() 300 uintptr_t value = StackPop(); 301 ret &= (value == 1); 302 ret &= (StackSize() == 3); // 3:stack_.size() 303 304 ret &= (StackAt(0) == 2); // 2:stack.value 305 ret &= (StackAt(1) == 1); 306 OpSwap(); 307 ret &= (StackAt(0) == 1); 308 ret &= (StackAt(1) == 2); // 2:stack.value 309 310 OpRot(); 311 ret &= (StackAt(0) == 0); 312 ret &= (StackAt(1) == 1); 313 ret &= (StackAt(2) == 2); // 2:stack.value 314 return true; 315} 316 317bool DwarfOpTest::Test07() 318{ 319 bool ret = false; 320 StackReset(0); 321 intptr_t value = -10; 322 StackPush(value); 323 OpAbs(); 324 ret = (static_cast<uintptr_t>(-value) == StackPop()); 325 326 StackReset(0); 327 StackPush(0x1122334455667788); 328 StackPush(0xFFFFFFFF00000000); 329 OpAnd(); 330 ret &= (0x1122334400000000 == StackPop()); 331 332 StackReset(0); 333 StackPush(0x8); 334 StackPush(0x2); 335 OpDiv(); 336 ret &= (0x4 == StackPop()); 337 338 StackReset(0); 339 StackPush(0x8); 340 StackPush(0x2); 341 OpMinus(); 342 ret &= (0x6 == StackPop()); 343 344 StackReset(0); 345 StackPush(0x8); 346 StackPush(0x2); 347 OpMod(); 348 ret &= (0 == StackPop()); 349 350 StackReset(0); 351 StackPush(0x8); 352 StackPush(0x2); 353 OpMul(); 354 ret &= (0x10 == StackPop()); 355 356 StackReset(0); 357 StackPush(0x8); 358 OpNeg(); 359 ret &= (static_cast<uintptr_t>(STACK_VALUE) == StackPop()); 360 361 StackReset(0); 362 StackPush(1); 363 OpNot(); 364 ret &= (static_cast<uintptr_t>(~1) == StackPop()); 365 return ret; 366} 367 368bool DwarfOpTest::Test08() 369{ 370 bool ret = false; 371 StackReset(0); 372 StackPush(0x2); 373 StackPush(0x2); 374 OpEQ(); 375 ret = (1 == StackPop()); 376 377 StackReset(0); 378 StackPush(0x2); 379 StackPush(0x3); 380 OpGE(); 381 ret &= (0 == StackPop()); 382 383 StackReset(0); 384 StackPush(0x2); 385 StackPush(0x3); 386 OpGT(); 387 ret &= (0 == StackPop()); 388 389 StackReset(0); 390 StackPush(0x2); 391 StackPush(0x3); 392 OpLE(); 393 ret &= (1 == StackPop()); 394 395 StackReset(0); 396 StackPush(0x2); 397 StackPush(0x3); 398 OpLT(); 399 ret &= (1 == StackPop()); 400 401 StackReset(0); 402 StackPush(0x2); 403 StackPush(0x3); 404 OpNE(); 405 ret &= (1 == StackPop()); 406 return ret; 407} 408 409bool DwarfOpTest::Test09(std::shared_ptr<DfxMemoryTest> memory) 410{ 411 bool ret = false; 412 StackReset(0); 413 memory->Reset(); 414 std::vector<uint8_t> exprData { 415 0x10, 0x00, 416 }; 417 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(exprData.data()); 418 memory->SetBuffer(exprPtr, exprData); 419 OpPlusULEBConst(exprPtr); 420 uintptr_t value = StackPop(); 421 printf("Test09-01 value:%" PRIxPTR "\n", value); 422 ret = (value == 0x10); 423 424 StackReset(0); 425 uintptr_t exprPtrOld = exprPtr; 426 OpSkip(exprPtr); 427 ret &= (exprPtrOld + exprData[0] == exprPtr); 428 printf("Test09-02 exprPtrOld:%" PRIxPTR " exprPtrNew:%" PRIxPTR "\n", 429 exprPtrOld, exprPtr); 430 431 StackReset(0); 432 StackPush(0x2); 433 exprPtr = exprPtrOld; 434 OpBra(exprPtr); 435 ret &= (exprPtrOld + exprData[0] == exprPtr); 436 printf("Test09-03 exprPtrOld:%" PRIxPTR " exprPtrNew:%" PRIxPTR "\n", 437 exprPtrOld, exprPtr); 438 439 StackReset(0); 440 exprPtr = exprPtrOld; 441 OpBra(exprPtr); 442 ret &= (exprPtrOld == exprPtr); 443 printf("Test09-04 exprPtrOld:%" PRIxPTR " exprPtrNew:%" PRIxPTR "\n", 444 exprPtrOld, exprPtr); 445 return ret; 446} 447 448bool DwarfOpTest::Test10(std::shared_ptr<DfxMemoryTest> memory) 449{ 450 bool ret = false; 451 memory->Reset(); 452 std::vector<uint8_t> exprData { 453 0x1e, 0x00, 454 }; 455 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(exprData.data()); 456 memory->SetBuffer(exprPtr, exprData); 457 458 StackReset(0); 459 OpLit(DW_OP_lit1); 460 uintptr_t value = StackPop(); 461 ret = (value == 0x01); 462 printf("Test10-01 value:%" PRIxPTR " ret:%d\n", value, ret); 463 464 OpLit(DW_OP_lit31); 465 value = StackPop(); 466 ret &= (value == 0x1f); 467 printf("Test10-02 value:%" PRIxPTR " ret:%d\n", value, ret); 468 469 StackReset(0); 470 auto reg = std::make_shared<DfxRegsArm64>(); 471 (*reg)[0] = 0xa; 472 OpReg(DW_OP_reg0, *(reg.get())); 473 value = StackPop(); 474 ret &= (value == 0xa); 475 printf("Test10-03 value:%" PRIxPTR " ret:%d\n", value, ret); 476 477 StackReset(0); 478 (*reg)[0x1e] = 0x14; 479 OpRegx(exprPtr, *(reg.get())); 480 value = StackPop(); 481 ret &= (value == 0x14); 482 printf("Test10-04 value:%" PRIxPTR " ret:%d\n", value, ret); 483 484 StackReset(0); 485 OpBReg(DW_OP_breg0, exprPtr, *(reg.get())); 486 value = StackPop(); 487 ret &= (value == 0x28); // 0xa + 0x1e 488 printf("Test10-05 value:%" PRIxPTR " ret:%d\n", value, ret); 489 490 StackReset(0); 491 OpBRegx(exprPtr, *(reg.get())); 492 value = StackPop(); 493 ret &= (value == 0x32); // 0x14 + 0x1e 494 printf("Test10-06 value:%" PRIxPTR " ret:%d\n", value, ret); 495 return ret; 496} 497 498using RequestFdFunc = int32_t (*)(int32_t); 499namespace { 500/** 501 * @tc.name: DwarfTest001 502 * @tc.desc: test parse fde in libfaultloggerd_client.so 503 * @tc.type: FUNC 504 */ 505HWTEST_F(DwarfTest, DwarfTest001, TestSize.Level2) 506{ 507 GTEST_LOG_(INFO) << "DwarfTest001: start."; 508 void* handle = dlopen("libjson_stack_formatter.z.so", RTLD_LAZY | RTLD_NODELETE); 509 bool isSuccess = handle != nullptr; 510 if (!isSuccess) { 511 ASSERT_FALSE(isSuccess); 512 printf("Failed to dlopen libfaultloggerd, %s\n", dlerror()); 513 return; 514 } 515 RequestFdFunc requestFdFunc = (RequestFdFunc)dlsym(handle, 516 "_ZN4OHOS9HiviewDFX16DfxJsonFormatter15FormatJsonStack" \ 517 "ENSt3__h12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERS8_"); 518 isSuccess = requestFdFunc != nullptr; 519 if (!isSuccess) { 520 ASSERT_FALSE(isSuccess); 521 printf("Failed to find RequestFdFunc, %s\n", dlerror()); 522 return; 523 } 524 525 const uintptr_t pcOffset = 48; 526 uintptr_t pc = reinterpret_cast<uintptr_t>(requestFdFunc) + pcOffset; 527 struct UnwindTableInfo uti; 528 ASSERT_EQ(DfxElf::FindUnwindTableLocal(pc, uti), 0); 529 530 auto acc = std::make_shared<DfxAccessorsLocal>(); 531 auto memory = std::make_shared<DfxMemory>(acc); 532 DwarfSectionTest dwarfSection(memory); 533 struct UnwindEntryInfo pi; 534 ASSERT_EQ(true, dwarfSection.SearchEntry(pc, uti, pi)); 535 536 FrameDescEntry fde; 537 ASSERT_EQ(true, dwarfSection.ParseFdeTest(reinterpret_cast<uintptr_t>(pi.unwindInfo), fde)); 538 ASSERT_GT(fde.cieAddr, 0); 539 540 CommonInfoEntry cie; 541 ASSERT_EQ(true, dwarfSection.ParseCieTest(fde.cieAddr, cie)); 542 543 RegLocState rsState; 544 DwarfCfaInstructions instructions(memory); 545 ASSERT_EQ(true, instructions.Parse(pc, fde, rsState)); 546 /* 547 Version: 1 548 Augmentation: "zR" 549 Code alignment factor: 1 550 Data alignment factor: -4 551 Return address column: 30 552 Augmentation data: 1b 553 DW_CFA_def_cfa: r31 (sp) ofs 0 554 DW_CFA_nop 555 DW_CFA_nop 556 DW_CFA_nop 557 DW_CFA_nop 558 */ 559 ASSERT_EQ(cie.codeAlignFactor, 1); 560 ASSERT_EQ(cie.dataAlignFactor, -4); 561 ASSERT_EQ(cie.returnAddressRegister, 30); 562 ASSERT_EQ(cie.hasAugmentationData, true); 563 ASSERT_EQ(cie.pointerEncoding, 0x1b); 564 565 /* 566 DW_CFA_advance_loc: 20 to 0000000000002718 567 DW_CFA_def_cfa_offset: 112 568 DW_CFA_advance_loc: 28 to 0000000000002734 569 DW_CFA_def_cfa: r29 (x29) ofs 112 570 DW_CFA_offset: r15 (x15) at cfa-8 571 DW_CFA_offset: r19 (x19) at cfa-16 572 DW_CFA_offset: r20 (x20) at cfa-24 573 DW_CFA_offset: r21 (x21) at cfa-32 574 DW_CFA_offset: r22 (x22) at cfa-40 575 DW_CFA_offset: r23 (x23) at cfa-48 576 DW_CFA_offset: r24 (x24) at cfa-56 577 DW_CFA_offset: r25 (x25) at cfa-64 578 DW_CFA_offset: r26 (x26) at cfa-72 579 DW_CFA_offset: r27 (x27) at cfa-80 580 DW_CFA_offset: r28 (x28) at cfa-96 581 DW_CFA_offset: r30 (x30) at cfa-104 582 DW_CFA_offset: r29 (x29) at cfa-112 583 */ 584 ASSERT_EQ(fde.pcStart, reinterpret_cast<uintptr_t>(requestFdFunc)); 585 ASSERT_EQ(rsState.cfaReg, REG_AARCH64_X29); 586 ASSERT_EQ(rsState.cfaRegOffset, 112); // 112 : DW_CFA_def_cfa: r29 (x29) ofs 112 587 588 size_t qutIdx = 0; 589 if (DfxRegsQut::IsQutReg(static_cast<uint16_t>(REG_AARCH64_X30), qutIdx)) { 590 ASSERT_EQ(static_cast<uint8_t>(rsState.locs[qutIdx].type), 591 static_cast<uint8_t>(REG_LOC_MEM_OFFSET)); 592 ASSERT_EQ(rsState.locs[qutIdx].val, -104); // -104: r30 (x30) at cfa-104 593 } 594 if (DfxRegsQut::IsQutReg(static_cast<uint16_t>(REG_AARCH64_X29), qutIdx)) { 595 ASSERT_EQ(static_cast<uint8_t>(rsState.locs[qutIdx].type), 596 static_cast<uint8_t>(REG_LOC_MEM_OFFSET)); 597 ASSERT_EQ(rsState.locs[qutIdx].val, -112); // -112: r29 (x29) at cfa-112 598 } 599 600 RegLocState rsState2; 601 ASSERT_EQ(true, instructions.Parse(reinterpret_cast<uintptr_t>(requestFdFunc), fde, rsState2)); 602 ASSERT_EQ(rsState2.cfaReg, REG_AARCH64_X31); 603 ASSERT_EQ(rsState2.cfaRegOffset, 0); // DW_CFA_def_cfa: r31 (sp) ofs 0 604 605 RegLocState rsState3; 606 ASSERT_EQ(true, instructions.Parse(reinterpret_cast<uintptr_t>(requestFdFunc) + 24, fde, rsState3)); 607 ASSERT_EQ(rsState3.cfaReg, REG_AARCH64_X31); 608 ASSERT_EQ(rsState3.cfaRegOffset, 112); // 112 : DW_CFA_def_cfa_offset: 112 609 GTEST_LOG_(INFO) << "DwarfTest001: end."; 610} 611 612struct FdeParseResult { 613 int32_t index; 614 uintptr_t relPcStart; 615 uintptr_t relPcEnd; 616 std::vector<std::string> operateResult; 617}; 618 619static std::vector<std::string> cieResult = { 620 "DW_CFA_def_cfa: r31 ofs 0", 621 "DW_CFA_nop", 622 "DW_CFA_nop", 623 "DW_CFA_nop", 624 "DW_CFA_nop" 625}; 626 627void PrintOperations(const std::string& msg, std::vector<std::string>& operations) 628{ 629 printf("%s\n", msg.c_str()); 630 for (const auto& operation : operations) { 631 printf("%s\n", operation.c_str()); 632 } 633} 634 635bool CheckFdeResult(std::shared_ptr<FdeParseResult> result) 636{ 637 std::ifstream infile("/data/test/dwarf_test_aarch64_elf_result2"); 638 std::string line; 639 std::vector<std::string> operands; 640 std::vector<std::string> expectedResult = cieResult; 641 expectedResult.insert(std::end(expectedResult), 642 std::begin((*result).operateResult), 643 std::end((*result).operateResult)); 644 while (std::getline(infile, line)) { 645 if (line.find("DW_CFA") != std::string::npos) { 646 operands.push_back(line); 647 } 648 } 649 650 if (expectedResult.size() != operands.size()) { 651 printf("Failed to check operations size for index:%d\n", result->index); 652 PrintOperations("Expected result:", expectedResult); 653 PrintOperations("Current result:", operands); 654 return false; 655 } 656 657 printf("CheckFdeResult index:%d\n", result->index); 658 for (size_t i = 0; i < operands.size(); i++) { 659 std::string cfaCmd = OHOS::TrimStr(expectedResult[i]); 660 auto pos = cfaCmd.find(":"); 661 if (pos != std::string::npos) { 662 cfaCmd = cfaCmd.substr(0, pos); 663 expectedResult[i] = cfaCmd; 664 } 665 666 if (operands[i].find(cfaCmd) == std::string::npos) { 667 printf("Failed to check operations for index:%d\n", result->index); 668 PrintOperations("Expected result:", expectedResult); 669 PrintOperations("Current result:", operands); 670 return false; 671 } 672 } 673 return true; 674} 675 676std::vector<std::shared_ptr<FdeParseResult>> ParseFdeResultFromFile() 677{ 678 std::vector<std::shared_ptr<FdeParseResult>> ret; 679 std::ifstream infile("/data/test/dwarf_test_aarch64_elf_result"); 680 std::string line; 681 std::shared_ptr<FdeParseResult> result = nullptr; 682 int32_t index = 0; 683 while (std::getline(infile, line)) { 684 if (line.find("FDE cie=") != std::string::npos) { 685 if (result != nullptr) { 686 ret.push_back(result); 687 } 688 result = std::make_shared<FdeParseResult>(); 689 auto pos0 = line.find("pc="); 690 std::string pcRange = line.substr(pos0 + strlen("pc=")); 691 auto pos1 = pcRange.find(".."); 692 std::string pcStart = pcRange.substr(0, pos1); 693 std::string pcEnd = pcRange.substr(pos1 + strlen("..")); 694 result->relPcStart = std::stoul(pcStart, nullptr, HEX); 695 result->relPcEnd = std::stoul(pcEnd, nullptr, HEX); 696 result->index = index; 697 index++; 698 continue; 699 } 700 701 if (result == nullptr) { 702 continue; 703 } 704 705 if (line.empty()) { 706 continue; 707 } 708 709 if (line.find("ZERO terminator") != std::string::npos) { 710 ret.push_back(result); 711 break; 712 } 713 714 result->operateResult.push_back(line); 715 } 716 return ret; 717} 718 719int32_t RedirectStdErrToFile(const std::string& path) 720{ 721 int output = open(path.c_str(), O_RDWR | O_CREAT, 0777); 722 int32_t oldFd = dup(STDERR_FILENO); 723 dup2(output, STDERR_FILENO); 724 close(output); 725 return oldFd; 726} 727 728/** 729 * @tc.name: DwarfTest002 730 * @tc.desc: test dwarf cfa operations 731 * @tc.type: FUNC 732 */ 733HWTEST_F(DwarfTest, DwarfTest002, TestSize.Level2) 734{ 735 GTEST_LOG_(INFO) << "DwarfTest002: start."; 736 auto elf = DfxElf::Create("/data/test/dwarf_test_aarch64_elf"); 737 ASSERT_NE(elf, nullptr); 738 uint64_t loadbase = reinterpret_cast<uint64_t>(elf->GetMmapPtr()); 739 elf->SetLoadBase(loadbase); 740 /* 741 7fb92b7000-7fb9326000 r--p 00000000 b3:07 1817 dwarf_test_aarch64_elf 742 7fb9326000-7fb93d1000 r-xp 0006e000 b3:07 1817 dwarf_test_aarch64_elf 743 7fb93d1000-7fb93d3000 r--p 00118000 b3:07 1817 dwarf_test_aarch64_elf 744 7fb93d3000-7fb93d5000 rw-p 00119000 b3:07 1817 dwarf_test_aarch64_elf 745 LOAD 0x000000000006e640 0x000000000006f640 0x000000000006f640 746 0x00000000000a8ec0 0x00000000000a8ec0 R E 0x1000 747 */ 748 uint64_t startPc = loadbase + 0x6F640; 749 uint64_t endPc = startPc + 0xa8ec0; 750 printf("startPc:%p endPc:%p\n", reinterpret_cast<void*>(startPc), reinterpret_cast<void*>(endPc)); 751 uint64_t mapStart = loadbase + 0x6F000; 752 uint64_t mapEnd = mapStart + 0xab000; 753 const uint64_t offset = 0x6e000; 754 auto map1 = std::make_shared<DfxMap>(mapStart, mapEnd, offset, "r-xp", "dwarf_test_aarch64_elf"); 755 UnwindTableInfo info {}; 756 ASSERT_EQ(0, elf->FindUnwindTableInfo(startPc + 0x2, map1, info)); 757 ASSERT_EQ(info.startPc, startPc); 758 ASSERT_EQ(info.endPc, endPc); 759 ASSERT_NE(info.format, -1); 760 auto testElfFdeResult = ParseFdeResultFromFile(); 761 auto acc = std::make_shared<DfxAccessorsLocal>(); 762 auto memory = std::make_shared<DfxMemory>(acc); 763 DwarfSectionTest dwarfSection(memory); 764 ASSERT_EQ(testElfFdeResult.size(), info.tableLen); // cie 765 int index = 0; 766 for (auto& fdeResult : testElfFdeResult) { 767 auto pc = fdeResult->relPcEnd - 2 + loadbase; 768 ASSERT_GT(pc, fdeResult->relPcStart + loadbase); 769 ASSERT_LT(pc, fdeResult->relPcEnd + loadbase); 770 771 struct UnwindEntryInfo pi; 772 ASSERT_EQ(true, dwarfSection.SearchEntry(pc, info, pi)); 773 774 FrameDescEntry fde; 775 ASSERT_EQ(true, dwarfSection.ParseFdeTest(reinterpret_cast<uintptr_t>(pi.unwindInfo), fde)); 776 ASSERT_GT(fde.cieAddr, 0); 777 ASSERT_EQ(fde.pcStart, fdeResult->relPcStart + loadbase); 778 ASSERT_EQ(fde.pcEnd, fdeResult->relPcEnd + loadbase); 779 780 CommonInfoEntry cie; 781 ASSERT_EQ(true, dwarfSection.ParseCieTest(fde.cieAddr, cie)); 782 remove("/data/test/dwarf_test_aarch64_elf_result2"); 783 784 int oldFd = RedirectStdErrToFile("/data/test/dwarf_test_aarch64_elf_result2"); 785 ASSERT_GT(oldFd, 0); 786 fprintf(stderr, "currentFdeIndex:%d relPcStart:%p relPcEnd:%p begin\n", 787 index, (void*)fdeResult->relPcStart, (void*)fdeResult->relPcEnd); 788 RegLocState rsState; 789 DwarfCfaInstructions instructions(memory); 790 ASSERT_EQ(true, instructions.Parse(pc, fde, rsState)); 791 fprintf(stderr, "currentFdeIndex:%d relPcStart:%p relPcEnd:%p end\n", 792 index, (void*)fdeResult->relPcStart, (void*)fdeResult->relPcEnd); 793 dup2(oldFd, STDERR_FILENO); 794 if (!CheckFdeResult(fdeResult)) { 795 FAIL() << "Failed to check dw_cfa_operations"; 796 break; 797 } 798 index++; 799 } 800 GTEST_LOG_(INFO) << "DwarfTest002: end.\n"; 801} 802 803/** 804 * @tc.name: DwarfTest003 805 * @tc.desc: test dwarf operations 806 * @tc.type: FUNC 807 */ 808HWTEST_F(DwarfTest, DwarfTest003, TestSize.Level2) 809{ 810 GTEST_LOG_(INFO) << "DwarfTest003: start.\n"; 811 auto memory = std::make_shared<DfxMemoryTest>(); 812 DwarfOpTest op(memory); 813 ASSERT_EQ(op.Test01(), false); 814 ASSERT_EQ(op.Test02(), true); 815 ASSERT_EQ(op.Test03(), true); 816 ASSERT_EQ(op.Test04(memory), true); 817 ASSERT_EQ(op.Test05(memory), true); 818 ASSERT_EQ(op.Test06(), true); 819 ASSERT_EQ(op.Test07(), true); 820 ASSERT_EQ(op.Test08(), true); 821 ASSERT_EQ(op.Test09(memory), true); 822 ASSERT_EQ(op.Test10(memory), true); 823 GTEST_LOG_(INFO) << "DwarfTest003: end.\n"; 824} 825 826/** 827 * @tc.name: DwarfTest004 828 * @tc.desc: test dwarf DW_OP_reserved oprations 829 * @tc.type: FUNC 830 */ 831HWTEST_F(DwarfTest, DwarfTest004, TestSize.Level2) 832{ 833 GTEST_LOG_(INFO) << "DwarfTest004: start.\n"; 834 auto memory = std::make_shared<DfxMemoryTest>(); 835 memory->increaseAddr = true; 836 DwarfOpTest op(memory); 837 std::vector<uint8_t> opcodes = { 838 0x08, // size 839 0x01, 0x02, 0x04, 0x05, 0x07, // DW_OP_reserved 840 0x01, 0x02, 0x04, 0x05, 0x07, // DW_OP_reserved 841 }; 842 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 843 memory->SetBuffer(exprPtr, opcodes); 844 auto reg = std::make_shared<DfxRegsArm64>(); 845 auto ret = op.Eval(*reg.get(), 0, exprPtr); 846 ASSERT_EQ(ret, 0); 847 printf("DwarfTest004:%" PRIxPTR "\n", ret); 848 GTEST_LOG_(INFO) << "DwarfTest004: end.\n"; 849} 850 851/** 852 * @tc.name: DwarfTest005 853 * @tc.desc: test dwarf DW_OP_addr oprations 854 * @tc.type: FUNC 855 */ 856HWTEST_F(DwarfTest, DwarfTest005, TestSize.Level2) 857{ 858 GTEST_LOG_(INFO) << "DwarfTest005: start.\n"; 859 auto memory = std::make_shared<DfxMemoryTest>(); 860 memory->increaseAddr = true; 861 DwarfOpTest op(memory); 862 std::vector<uint8_t> opcodes = { 863 0x0a, // size 864 DW_OP_addr, // DW_OP_addr 865 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 866 DW_OP_deref, 0x01, 0x01, 0x01, 0x01, // DW_OP_deref 867 }; 868 869 std::vector<uint8_t> data = { 870 0x02, 0x04, 0x05, 0x07, 871 0x02, 0x04, 0x05, 0x07, 872 }; 873 874 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 875 memory->SetBuffer(exprPtr, opcodes); 876 memory->SetBuffer(0x4, data); 877 878 auto reg = std::make_shared<DfxRegsArm64>(); 879 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 880 ASSERT_EQ(ret, 0x0705040207050402); 881 printf("DwarfTest005:%" PRIxPTR "\n", ret); 882 GTEST_LOG_(INFO) << "DwarfTest005: end.\n"; 883} 884 885/** 886 * @tc.name: DwarfTest006 887 * @tc.desc: test dwarf DW_OP_const oprations 888 * @tc.type: FUNC 889 */ 890HWTEST_F(DwarfTest, DwarfTest006, TestSize.Level2) 891{ 892 GTEST_LOG_(INFO) << "DwarfTest006: start.\n"; 893 auto memory = std::make_shared<DfxMemoryTest>(); 894 memory->increaseAddr = true; 895 DwarfOpTest op(memory); 896 std::vector<uint8_t> opcodes = { 897 0x2a, // size 898 DW_OP_constu, 0x01, 899 DW_OP_consts, 0x01, 900 DW_OP_const1u, 0x01, 901 DW_OP_const1s, 0x02, 902 DW_OP_const2u, 0x03, 0x04, 903 DW_OP_const2s, 0x04, 0x04, 904 DW_OP_const4u, 0x03, 0x04, 0x03, 0x04, 905 DW_OP_const4s, 0x04, 0x04, 0x03, 0x04, 906 DW_OP_const8u, 907 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 908 DW_OP_const8s, 909 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 910 0x01, 0x01, 0x01, 0x01, 911 }; 912 913 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 914 memory->SetBuffer(exprPtr, opcodes); 915 auto reg = std::make_shared<DfxRegsArm64>(); 916 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 917 ASSERT_EQ(ret, 0x0403040304030403); 918 printf("DwarfTest006:%" PRIxPTR "\n", ret); 919 GTEST_LOG_(INFO) << "DwarfTest006: end.\n"; 920} 921 922/** 923 * @tc.name: DwarfTest007 924 * @tc.desc: test dwarf DW_OP_litxx oprations 925 * @tc.type: FUNC 926 */ 927HWTEST_F(DwarfTest, DwarfTest007, TestSize.Level2) 928{ 929 GTEST_LOG_(INFO) << "DwarfTest007: start.\n"; 930 auto memory = std::make_shared<DfxMemoryTest>(); 931 memory->increaseAddr = true; 932 DwarfOpTest op(memory); 933 std::vector<uint8_t> opcodes = { 934 0x20, // size 935 DW_OP_lit0, 936 DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4, 937 DW_OP_lit5, DW_OP_lit6, DW_OP_lit7, DW_OP_lit8, 938 DW_OP_lit9, DW_OP_lit10, DW_OP_lit11, DW_OP_lit12, 939 DW_OP_lit13, DW_OP_lit14, DW_OP_lit15, DW_OP_lit16, 940 DW_OP_lit17, DW_OP_lit18, DW_OP_lit19, DW_OP_lit20, 941 DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24, 942 DW_OP_lit25, DW_OP_lit26, DW_OP_lit27, DW_OP_lit28, 943 DW_OP_lit29, DW_OP_lit30, DW_OP_lit31, 944 0x01, 0x01, 0x01, 0x01, 945 }; 946 947 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 948 memory->SetBuffer(exprPtr, opcodes); 949 auto reg = std::make_shared<DfxRegsArm64>(); 950 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 951 ASSERT_EQ(ret, static_cast<uintptr_t>(DW_OP_lit31 - DW_OP_lit0)); 952 printf("DwarfTest007:%" PRIxPTR "\n", ret); 953 GTEST_LOG_(INFO) << "DwarfTest007: end.\n"; 954} 955 956/** 957 * @tc.name: DwarfTest008 958 * @tc.desc: test dwarf DW_OP_regxx oprations 959 * @tc.type: FUNC 960 */ 961HWTEST_F(DwarfTest, DwarfTest008, TestSize.Level2) 962{ 963 GTEST_LOG_(INFO) << "DwarfTest008: start.\n"; 964 auto memory = std::make_shared<DfxMemoryTest>(); 965 memory->increaseAddr = true; 966 DwarfOpTest op(memory); 967 std::vector<uint8_t> opcodes = { 968 0x20, // size 969 DW_OP_reg0, 970 DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4, 971 DW_OP_reg5, DW_OP_reg6, DW_OP_reg7, DW_OP_reg8, 972 DW_OP_reg9, DW_OP_reg10, DW_OP_reg11, DW_OP_reg12, 973 DW_OP_reg13, DW_OP_reg14, DW_OP_reg15, DW_OP_reg16, 974 DW_OP_reg17, DW_OP_reg18, DW_OP_reg19, DW_OP_reg20, 975 DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24, 976 DW_OP_reg25, DW_OP_reg26, DW_OP_reg27, DW_OP_reg28, 977 DW_OP_reg29, DW_OP_reg30, DW_OP_reg31, 978 0x01, 0x01, 0x01, 0x01, 979 }; 980 981 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 982 memory->SetBuffer(exprPtr, opcodes); 983 auto reg = std::make_shared<DfxRegsArm64>(); 984 const uintptr_t result = 0x5544332211; 985 (*reg)[DW_OP_reg31 - DW_OP_reg0] = result; 986 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 987 ASSERT_EQ(ret, result); 988 printf("DwarfTest008:%" PRIxPTR "\n", ret); 989 GTEST_LOG_(INFO) << "DwarfTest008: end.\n"; 990} 991 992/** 993 * @tc.name: DwarfTest009 994 * @tc.desc: test dwarf DW_OP_nop oprations 995 * @tc.type: FUNC 996 */ 997HWTEST_F(DwarfTest, DwarfTest009, TestSize.Level2) 998{ 999 GTEST_LOG_(INFO) << "DwarfTest009: start.\n"; 1000 auto memory = std::make_shared<DfxMemoryTest>(); 1001 memory->increaseAddr = true; 1002 DwarfOpTest op(memory); 1003 std::vector<uint8_t> opcodes = { 1004 0x0a, // size 1005 DW_OP_fbreg, 1006 DW_OP_piece, 1007 DW_OP_xderef, 1008 DW_OP_xderef_size, 1009 DW_OP_nop, 1010 DW_OP_push_object_address, 1011 DW_OP_call2, 1012 DW_OP_call4, 1013 DW_OP_call_ref, 1014 DW_OP_lo_user, 1015 0x01, 0x01, 0x01, 0x01, 1016 }; 1017 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 1018 memory->SetBuffer(exprPtr, opcodes); 1019 auto reg = std::make_shared<DfxRegsArm64>(); 1020 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 1021 ASSERT_EQ(ret, 0); 1022 printf("DwarfTest009:%" PRIxPTR "\n", ret); 1023 GTEST_LOG_(INFO) << "DwarfTest009: end.\n"; 1024} 1025 1026/** 1027 * @tc.name: DwarfTest010 1028 * @tc.desc: test dwarf numerical oprations 1029 * @tc.type: FUNC 1030 */ 1031HWTEST_F(DwarfTest, DwarfTest010, TestSize.Level2) 1032{ 1033 GTEST_LOG_(INFO) << "DwarfTest010: start.\n"; 1034 auto memory = std::make_shared<DfxMemoryTest>(); 1035 memory->increaseAddr = true; 1036 DwarfOpTest op(memory); 1037 std::vector<uint8_t> opcodes = { 1038 0x09, // size 1039 DW_OP_lit31, 1040 DW_OP_dup, 1041 DW_OP_dup, 1042 DW_OP_swap, 1043 DW_OP_rot, 1044 DW_OP_abs, 1045 DW_OP_and, 1046 DW_OP_div, 1047 0x01, 0x01, 0x01, 0x01, 1048 }; 1049 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 1050 memory->SetBuffer(exprPtr, opcodes); 1051 auto reg = std::make_shared<DfxRegsArm64>(); 1052 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 1053 ASSERT_EQ(ret, 1); 1054 printf("DwarfTest010:%" PRIxPTR "\n", ret); 1055 GTEST_LOG_(INFO) << "DwarfTest010: end.\n"; 1056} 1057 1058 1059/** 1060 * @tc.name: DwarfTest011 1061 * @tc.desc: test dwarf numerical oprations 2 1062 * @tc.type: FUNC 1063 */ 1064HWTEST_F(DwarfTest, DwarfTest011, TestSize.Level2) 1065{ 1066 GTEST_LOG_(INFO) << "DwarfTest011: start.\n"; 1067 auto memory = std::make_shared<DfxMemoryTest>(); 1068 memory->increaseAddr = true; 1069 DwarfOpTest op(memory); 1070 std::vector<uint8_t> opcodes = { 1071 0x05, // size 1072 DW_OP_lit31, 1073 DW_OP_dup, 1074 DW_OP_over, 1075 DW_OP_drop, 1076 DW_OP_minus, 1077 0x01, 0x01, 0x01, 0x01, 1078 }; 1079 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 1080 memory->SetBuffer(exprPtr, opcodes); 1081 auto reg = std::make_shared<DfxRegsArm64>(); 1082 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 1083 ASSERT_EQ(ret, 0); 1084 printf("DwarfTest011:%" PRIxPTR "\n", ret); 1085 GTEST_LOG_(INFO) << "DwarfTest011: end.\n"; 1086} 1087 1088/** 1089 * @tc.name: DwarfTest012 1090 * @tc.desc: test dwarf numerical oprations 3 1091 * @tc.type: FUNC 1092 */ 1093HWTEST_F(DwarfTest, DwarfTest012, TestSize.Level2) 1094{ 1095 GTEST_LOG_(INFO) << "DwarfTest012: start.\n"; 1096 auto memory = std::make_shared<DfxMemoryTest>(); 1097 memory->increaseAddr = true; 1098 DwarfOpTest op(memory); 1099 std::vector<uint8_t> opcodes = { 1100 0x09, // size 1101 DW_OP_lit5, 1102 DW_OP_lit2, 1103 DW_OP_mod, // 5 % 2 1104 DW_OP_lit2, 1105 DW_OP_mul, // 1 * 2 1106 DW_OP_lit2, 1107 DW_OP_plus, // 2 + 2 1108 DW_OP_lit4, 1109 DW_OP_eq, 1110 0x01, 0x01, 0x01, 0x01, 1111 }; 1112 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 1113 memory->SetBuffer(exprPtr, opcodes); 1114 auto reg = std::make_shared<DfxRegsArm64>(); 1115 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 1116 ASSERT_EQ(ret, 1); 1117 printf("DwarfTest012:%" PRIxPTR "\n", ret); 1118 GTEST_LOG_(INFO) << "DwarfTest012: end.\n"; 1119} 1120 1121/** 1122 * @tc.name: DwarfTest013 1123 * @tc.desc: test dwarf logical oprations 1124 * @tc.type: FUNC 1125 */ 1126HWTEST_F(DwarfTest, DwarfTest013, TestSize.Level2) 1127{ 1128 GTEST_LOG_(INFO) << "DwarfTest013: start.\n"; 1129 auto memory = std::make_shared<DfxMemoryTest>(); 1130 memory->increaseAddr = true; 1131 DwarfOpTest op(memory); 1132 std::vector<uint8_t> opcodes = { 1133 0x0a, // size 1134 DW_OP_lit1, // 1 1135 DW_OP_lit1, // 1 1136 DW_OP_shl, // 1 << 1 1137 DW_OP_lit1, // 1 1138 DW_OP_shr, // 2 >> 1 1139 DW_OP_lit1, // 1 1140 DW_OP_shra, // 1 1141 DW_OP_xor, // 0 1142 DW_OP_lit1, // 1 1143 DW_OP_eq, // 0 1144 0x01, 0x01, 0x01, 0x01, 1145 }; 1146 uintptr_t exprPtr = reinterpret_cast<uintptr_t>(opcodes.data()); 1147 memory->SetBuffer(exprPtr, opcodes); 1148 auto reg = std::make_shared<DfxRegsArm64>(); 1149 uintptr_t ret = op.Eval(*reg.get(), 0, exprPtr); 1150 ASSERT_EQ(ret, 0); 1151 printf("DwarfTest013:%" PRIxPTR "\n", ret); 1152 GTEST_LOG_(INFO) << "DwarfTest013: end.\n"; 1153} 1154 1155/** 1156 * @tc.name: DfxInstructionsTest001 1157 * @tc.desc: test DfxInstructions Flush 1158 * @tc.type: FUNC 1159 */ 1160HWTEST_F(DwarfTest, DfxInstructionsTest001, TestSize.Level2) 1161{ 1162 GTEST_LOG_(INFO) << "DfxInstructionsTest001: start.\n"; 1163 auto instructions = std::make_shared<DfxInstructions>(); 1164 auto regs = DfxRegs::Create(); 1165 auto memory = std::make_shared<DfxMemory>(); 1166 RegLoc loc; 1167 uintptr_t val; 1168 loc.type = REG_LOC_VAL_OFFSET; 1169 bool ret = instructions->Flush(*(regs.get()), memory, 0, loc, val); 1170 ASSERT_EQ(ret, true); 1171 loc.type = REG_LOC_VAL_OFFSET; 1172 ret = instructions->Flush(*(regs.get()), nullptr, 0, loc, val); 1173 ASSERT_EQ(ret, false); 1174 loc.type = REG_LOC_MEM_OFFSET; 1175 ret = instructions->Flush(*(regs.get()), memory, 0, loc, val); 1176 ASSERT_EQ(ret, true); 1177 loc.type = REG_LOC_REGISTER; 1178 ret = instructions->Flush(*(regs.get()), memory, 0, loc, val); 1179 ASSERT_EQ(ret, true); 1180 loc.type = REG_LOC_MEM_EXPRESSION; 1181 ret = instructions->Flush(*(regs.get()), memory, 0, loc, val); 1182 ASSERT_EQ(ret, true); 1183 loc.type = REG_LOC_VAL_EXPRESSION; 1184 ret = instructions->Flush(*(regs.get()), memory, 0, loc, val); 1185 ASSERT_EQ(ret, true); 1186 loc.type = REG_LOC_UNUSED; 1187 ret = instructions->Flush(*(regs.get()), memory, 0, loc, val); 1188 ASSERT_EQ(ret, false); 1189 GTEST_LOG_(INFO) << "DfxInstructionsTest001: end.\n"; 1190} 1191 1192/** 1193 * @tc.name: LocalThreadContextTest001 1194 * @tc.desc: test LocalThreadContext CopyContextAndWaitTimeout 1195 * @tc.type: FUNC 1196 */ 1197HWTEST_F(DwarfTest, LocalThreadContextTest001, TestSize.Level2) 1198{ 1199 GTEST_LOG_(INFO) << "LocalThreadContextTest001: start.\n"; 1200 LocalThreadContext instance; 1201 siginfo_t si {0}; 1202 si.si_code = DUMP_TYPE_KERNEL; 1203 instance.CopyContextAndWaitTimeout(0, nullptr, nullptr); 1204 instance.CopyContextAndWaitTimeout(0, &si, nullptr); 1205 si.si_code = DUMP_TYPE_LOCAL; 1206 instance.CopyContextAndWaitTimeout(0, &si, nullptr); 1207 std::shared_ptr<ThreadContext> ret = instance.GetThreadContext(-1); 1208 ASSERT_EQ(ret, nullptr); 1209 auto memory = std::make_shared<DfxMemory>(); 1210 uintptr_t addr = 0; 1211 bool cur = memory->ReadString(addr, nullptr, 0, false); 1212 ASSERT_EQ(cur, false); 1213 uintptr_t val = memory->ReadEncodedValue(addr, DW_EH_PE_omit); 1214 ASSERT_EQ(val, 0); 1215 GTEST_LOG_(INFO) << "LocalThreadContextTest001: end.\n"; 1216} 1217} 1218} // namespace HiviewDFX 1219} // namespace OHOS 1220