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