1 //===-- PDBFPOProgramToDWARFExpressionTests.cpp -----------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "gtest/gtest.h" 11 12 #include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h" 13 14 #include "lldb/Core/StreamBuffer.h" 15 #include "lldb/Expression/DWARFExpression.h" 16 #include "lldb/Utility/ArchSpec.h" 17 #include "lldb/Utility/DataBufferHeap.h" 18 #include "lldb/Utility/DataExtractor.h" 19 #include "lldb/Utility/StreamString.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 // initial setup 32 ArchSpec arch_spec("i686-pc-windows"); 33 llvm::Triple::ArchType arch_type = arch_spec.GetMachine(); 34 ByteOrder byte_order = arch_spec.GetByteOrder(); 35 uint32_t address_size = arch_spec.GetAddressByteSize(); 36 uint32_t byte_size = arch_spec.GetDataByteSize(); 37 38 // program translation 39 StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); 40 ASSERT_TRUE(TranslateFPOProgramToDWARFExpression( 41 fpo_program, target_register_name, arch_type, stream)); 42 43 // print dwarf expression to comparable textual representation 44 DataBufferSP buffer = 45 std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize()); 46 DataExtractor extractor(buffer, byte_order, address_size, byte_size); 47 48 StreamString result_dwarf_expression; 49 ASSERT_TRUE(DWARFExpression::PrintDWARFExpression( 50 result_dwarf_expression, extractor, address_size, 4, false)); 51 52 // actual check 53 ASSERT_STREQ(expected_dwarf_expression.data(), 54 result_dwarf_expression.GetString().data()); 55 } 56 57 TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentConst) { 58 CheckValidProgramTranslation("$T0 0 = ", "$T0", "DW_OP_constu 0x0"); 59 } 60 61 TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentRegisterRef) { 62 CheckValidProgramTranslation("$T0 $ebp = ", "$T0", "DW_OP_breg6 +0"); 63 } 64 65 TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentExpressionPlus) { 66 CheckValidProgramTranslation("$T0 $ebp 4 + = ", "$T0", 67 "DW_OP_breg6 +0, DW_OP_constu 0x4, DW_OP_plus "); 68 } 69 70 TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentExpressionDeref) { 71 CheckValidProgramTranslation("$T0 $ebp ^ = ", "$T0", 72 "DW_OP_breg6 +0, DW_OP_deref "); 73 } 74 75 TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentExpressionMinus) { 76 CheckValidProgramTranslation( 77 "$T0 $ebp 4 - = ", "$T0", 78 "DW_OP_breg6 +0, DW_OP_constu 0x4, DW_OP_minus "); 79 } 80 81 TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentExpressionAlign) { 82 CheckValidProgramTranslation("$T0 $ebp 128 @ = ", "$T0", 83 "DW_OP_breg6 +0, DW_OP_constu 0x80, DW_OP_lit1 " 84 ", DW_OP_minus , DW_OP_not , DW_OP_and "); 85 } 86 87 TEST(PDBFPOProgramToDWARFExpressionTests, MultipleIndependentAssignments) { 88 CheckValidProgramTranslation("$T1 1 = $T0 0 =", "$T0", "DW_OP_constu 0x0"); 89 } 90 91 TEST(PDBFPOProgramToDWARFExpressionTests, MultipleDependentAssignments) { 92 CheckValidProgramTranslation( 93 "$T1 $ebp 4 + = $T0 $T1 8 - 128 @ = ", "$T0", 94 "DW_OP_breg6 +0, DW_OP_constu 0x4, DW_OP_plus , DW_OP_constu 0x8, " 95 "DW_OP_minus , DW_OP_constu 0x80, DW_OP_lit1 , DW_OP_minus , DW_OP_not , " 96 "DW_OP_and "); 97 } 98 99 TEST(PDBFPOProgramToDWARFExpressionTests, DependencyChain) { 100 CheckValidProgramTranslation("$T1 0 = $T0 $T1 = $ebp $T0 =", "$ebp", 101 "DW_OP_constu 0x0"); 102 } 103 104 /// Invalid programs tests 105 static void 106 CheckInvalidProgramTranslation(llvm::StringRef fpo_program, 107 llvm::StringRef target_register_name) { 108 // initial setup 109 ArchSpec arch_spec("i686-pc-windows"); 110 llvm::Triple::ArchType arch_type = arch_spec.GetMachine(); 111 ByteOrder byte_order = arch_spec.GetByteOrder(); 112 uint32_t address_size = arch_spec.GetAddressByteSize(); 113 114 // program translation 115 StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); 116 EXPECT_FALSE(TranslateFPOProgramToDWARFExpression( 117 fpo_program, target_register_name, arch_type, stream)); 118 EXPECT_EQ(0, stream.GetSize()); 119 } 120 121 TEST(PDBFPOProgramToDWARFExpressionTests, InvalidAssignmentSingle) { 122 CheckInvalidProgramTranslation("$T0 0", "$T0"); 123 } 124 125 TEST(PDBFPOProgramToDWARFExpressionTests, InvalidAssignmentMultiple) { 126 CheckInvalidProgramTranslation("$T1 0 = $T0 0", "$T0"); 127 } 128 129 TEST(PDBFPOProgramToDWARFExpressionTests, UnknownOp) { 130 CheckInvalidProgramTranslation("$T0 $ebp 0 & = ", "$T0"); 131 } 132 133 TEST(PDBFPOProgramToDWARFExpressionTests, InvalidOpBinary) { 134 CheckInvalidProgramTranslation("$T0 0 + = ", "$T0"); 135 } 136 137 TEST(PDBFPOProgramToDWARFExpressionTests, InvalidOpUnary) { 138 CheckInvalidProgramTranslation("$T0 ^ = ", "$T0"); 139 } 140 141 TEST(PDBFPOProgramToDWARFExpressionTests, MissingTargetRegister) { 142 CheckInvalidProgramTranslation("$T1 0 = ", "$T0"); 143 } 144 145 TEST(PDBFPOProgramToDWARFExpressionTests, UnresolvedRegisterReference) { 146 CheckInvalidProgramTranslation("$T0 $abc = ", "$T0"); 147 } 148 149 TEST(PDBFPOProgramToDWARFExpressionTests, 150 UnresolvedRegisterAssignmentReference) { 151 CheckInvalidProgramTranslation("$T2 0 = $T0 $T1 = ", "$T0"); 152 } 153 154 TEST(PDBFPOProgramToDWARFExpressionTests, 155 UnresolvedCyclicRegisterAssignmentReference) { 156 CheckInvalidProgramTranslation("$T1 $T0 = $T0 $T1 = ", "$T0"); 157 } 158 159 TEST(PDBFPOProgramToDWARFExpressionTests, 160 UnresolvedDependentCyclicRegisterAssignmentReference) { 161 CheckInvalidProgramTranslation("$T1 $T0 = $T0 $T1 = $T2 $T1 =", "$T2"); 162 } 163 164 TEST(PDBFPOProgramToDWARFExpressionTests, UnsupportedRASearch) { 165 CheckInvalidProgramTranslation("$T0 .raSearch = ", "$T0"); 166 } 167