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