1 //===-- PDBFPOProgramToDWARFExpressionTests.cpp ---------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "gtest/gtest.h" 10 11 #include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h" 12 13 #include "lldb/Core/StreamBuffer.h" 14 #include "lldb/Utility/ArchSpec.h" 15 #include "lldb/Utility/DataBufferHeap.h" 16 #include "lldb/Utility/DataExtractor.h" 17 #include "lldb/Utility/StreamString.h" 18 #include "llvm/DebugInfo/DWARF/DWARFExpression.h" 19 20 using namespace lldb; 21 using namespace lldb_private; 22 using namespace lldb_private::npdb; 23 24 /// Valid programs tests 25 26 static void 27 CheckValidProgramTranslation(llvm::StringRef fpo_program, 28 llvm::StringRef target_register_name, 29 llvm::StringRef expected_dwarf_expression) { 30 // program translation 31 StreamBuffer<32> stream(Stream::eBinary, 4, eByteOrderLittle); 32 ASSERT_TRUE(TranslateFPOProgramToDWARFExpression( 33 fpo_program, target_register_name, llvm::Triple::x86, stream)); 34 35 // print dwarf expression to comparable textual representation 36 llvm::DataExtractor extractor({stream.GetData(), stream.GetSize()}, 37 /*IsLittleEndian=*/true, /*AddressSize=*/4); 38 39 std::string result; 40 llvm::raw_string_ostream os(result); 41 llvm::DWARFExpression(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32) 42 .print(os, llvm::DIDumpOptions(), nullptr, nullptr); 43 44 // actual check 45 ASSERT_EQ(expected_dwarf_expression, os.str()); 46 } 47 48 TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentRegisterRef) { 49 CheckValidProgramTranslation("$T0 $ebp = ", "$T0", "DW_OP_breg6 +0"); 50 } 51 52 TEST(PDBFPOProgramToDWARFExpressionTests, MultipleIndependentAssignments) { 53 CheckValidProgramTranslation("$T1 1 = $T0 0 =", "$T0", "DW_OP_consts +0"); 54 } 55 56 TEST(PDBFPOProgramToDWARFExpressionTests, MultipleDependentAssignments) { 57 CheckValidProgramTranslation( 58 "$T1 $ebp 4 + = $T0 $T1 8 - 128 @ = ", "$T0", 59 "DW_OP_breg6 +0, DW_OP_consts +4, DW_OP_plus, DW_OP_consts +8, " 60 "DW_OP_minus, DW_OP_consts +128, DW_OP_lit1, DW_OP_minus, DW_OP_not, " 61 "DW_OP_and"); 62 } 63 64 TEST(PDBFPOProgramToDWARFExpressionTests, DependencyChain) { 65 CheckValidProgramTranslation("$T1 0 = $T0 $T1 = $ebp $T0 =", "$ebp", 66 "DW_OP_consts +0"); 67 } 68 69 /// Invalid programs tests 70 static void 71 CheckInvalidProgramTranslation(llvm::StringRef fpo_program, 72 llvm::StringRef target_register_name) { 73 // initial setup 74 ArchSpec arch_spec("i686-pc-windows"); 75 llvm::Triple::ArchType arch_type = arch_spec.GetMachine(); 76 ByteOrder byte_order = arch_spec.GetByteOrder(); 77 uint32_t address_size = arch_spec.GetAddressByteSize(); 78 79 // program translation 80 StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); 81 EXPECT_FALSE(TranslateFPOProgramToDWARFExpression( 82 fpo_program, target_register_name, arch_type, stream)); 83 EXPECT_EQ((size_t)0, stream.GetSize()); 84 } 85 86 TEST(PDBFPOProgramToDWARFExpressionTests, InvalidAssignmentSingle) { 87 CheckInvalidProgramTranslation("$T0 0", "$T0"); 88 } 89 90 TEST(PDBFPOProgramToDWARFExpressionTests, InvalidAssignmentMultiple) { 91 CheckInvalidProgramTranslation("$T1 0 = $T0 0", "$T0"); 92 } 93 94 TEST(PDBFPOProgramToDWARFExpressionTests, UnknownOp) { 95 CheckInvalidProgramTranslation("$T0 $ebp 0 & = ", "$T0"); 96 } 97 98 TEST(PDBFPOProgramToDWARFExpressionTests, InvalidOpBinary) { 99 CheckInvalidProgramTranslation("$T0 0 + = ", "$T0"); 100 } 101 102 TEST(PDBFPOProgramToDWARFExpressionTests, InvalidOpUnary) { 103 CheckInvalidProgramTranslation("$T0 ^ = ", "$T0"); 104 } 105 106 TEST(PDBFPOProgramToDWARFExpressionTests, MissingTargetRegister) { 107 CheckInvalidProgramTranslation("$T1 0 = ", "$T0"); 108 } 109 110 TEST(PDBFPOProgramToDWARFExpressionTests, UnresolvedRegisterReference) { 111 CheckInvalidProgramTranslation("$T0 $abc = ", "$T0"); 112 } 113 114 TEST(PDBFPOProgramToDWARFExpressionTests, 115 UnresolvedRegisterAssignmentReference) { 116 CheckInvalidProgramTranslation("$T2 0 = $T0 $T1 = ", "$T0"); 117 } 118 119 TEST(PDBFPOProgramToDWARFExpressionTests, 120 UnresolvedCyclicRegisterAssignmentReference) { 121 CheckInvalidProgramTranslation("$T1 $T0 = $T0 $T1 = ", "$T0"); 122 } 123 124 TEST(PDBFPOProgramToDWARFExpressionTests, 125 UnresolvedDependentCyclicRegisterAssignmentReference) { 126 CheckInvalidProgramTranslation("$T1 $T0 = $T0 $T1 = $T2 $T1 =", "$T2"); 127 } 128 129 TEST(PDBFPOProgramToDWARFExpressionTests, UnsupportedRASearch) { 130 CheckInvalidProgramTranslation("$T0 .raSearch = ", "$T0"); 131 } 132