| 1 | //===-- Testx86AssemblyInspectionEngine.cpp -------------------------------===// |
| 2 | |
| 3 | // |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 5 | // See https://llvm.org/LICENSE.txt for license information. |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "gtest/gtest.h" |
| 11 | |
| 12 | #include "Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h" |
| 13 | #include "lldb/Core/AddressRange.h" |
| 14 | #include "lldb/Symbol/UnwindPlan.h" |
| 15 | #include "lldb/Utility/ArchSpec.h" |
| 16 | |
| 17 | #include "llvm/Support/TargetSelect.h" |
| 18 | |
| 19 | #include <memory> |
| 20 | #include <vector> |
| 21 | |
| 22 | using namespace lldb; |
| 23 | using namespace lldb_private; |
| 24 | |
| 25 | class Testx86AssemblyInspectionEngine : public testing::Test { |
| 26 | public: |
| 27 | static void SetUpTestCase(); |
| 28 | }; |
| 29 | |
| 30 | void Testx86AssemblyInspectionEngine::SetUpTestCase() { |
| 31 | llvm::InitializeAllTargets(); |
| 32 | llvm::InitializeAllAsmPrinters(); |
| 33 | llvm::InitializeAllTargetMCs(); |
| 34 | llvm::InitializeAllDisassemblers(); |
| 35 | } |
| 36 | |
| 37 | // only defining the register names / numbers that the unwinder is actually |
| 38 | // using today |
| 39 | |
| 40 | // names should match the constants below. These will be the eRegisterKindLLDB |
| 41 | // register numbers. |
| 42 | |
| 43 | const char *x86_64_reg_names[] = {"rax" , "rbx" , "rcx" , "rdx" , "rsp" , "rbp" , |
| 44 | "rsi" , "rdi" , "r8" , "r9" , "r10" , "r11" , |
| 45 | "r12" , "r13" , "r14" , "r15" , "rip" }; |
| 46 | |
| 47 | enum x86_64_regs { |
| 48 | k_rax = 0, |
| 49 | k_rbx = 1, |
| 50 | k_rcx = 2, |
| 51 | k_rdx = 3, |
| 52 | k_rsp = 4, |
| 53 | k_rbp = 5, |
| 54 | k_rsi = 6, |
| 55 | k_rdi = 7, |
| 56 | k_r8 = 8, |
| 57 | k_r9 = 9, |
| 58 | k_r10 = 10, |
| 59 | k_r11 = 11, |
| 60 | k_r12 = 12, |
| 61 | k_r13 = 13, |
| 62 | k_r14 = 14, |
| 63 | k_r15 = 15, |
| 64 | k_rip = 16 |
| 65 | }; |
| 66 | |
| 67 | std::unique_ptr<x86AssemblyInspectionEngine> Getx86_64Inspector() { |
| 68 | |
| 69 | ArchSpec arch("x86_64-apple-macosx" ); |
| 70 | std::unique_ptr<x86AssemblyInspectionEngine> engine( |
| 71 | new x86AssemblyInspectionEngine(arch)); |
| 72 | |
| 73 | std::vector<x86AssemblyInspectionEngine::lldb_reg_info> lldb_regnums; |
| 74 | int i = 0; |
| 75 | for (const auto &name : x86_64_reg_names) { |
| 76 | x86AssemblyInspectionEngine::lldb_reg_info ri; |
| 77 | ri.name = name; |
| 78 | ri.lldb_regnum = i++; |
| 79 | lldb_regnums.push_back(x: ri); |
| 80 | } |
| 81 | |
| 82 | engine->Initialize(reg_info&: lldb_regnums); |
| 83 | return engine; |
| 84 | } |
| 85 | |
| 86 | TEST_F(Testx86AssemblyInspectionEngine, TestSimple64bitFrameFunction) { |
| 87 | std::unique_ptr<x86AssemblyInspectionEngine> engine = Getx86_64Inspector(); |
| 88 | |
| 89 | // 'int main() { }' compiled for x86_64-apple-macosx with clang |
| 90 | uint8_t data[] = { |
| 91 | 0x55, // offset 0 -- pushq %rbp |
| 92 | 0x48, 0x89, 0xe5, // offset 1 -- movq %rsp, %rbp |
| 93 | 0x31, 0xc0, // offset 4 -- xorl %eax, %eax |
| 94 | 0x5d, // offset 6 -- popq %rbp |
| 95 | 0xc3 // offset 7 -- retq |
| 96 | }; |
| 97 | |
| 98 | AddressRange sample_range(0x1000, sizeof(data)); |
| 99 | |
| 100 | UnwindPlan unwind_plan(eRegisterKindLLDB); |
| 101 | EXPECT_FALSE(engine->GetNonCallSiteUnwindPlanFromAssembly( |
| 102 | data, sizeof(data), sample_range, unwind_plan)); |
| 103 | } |
| 104 | |