xref: /llvm-project/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp (revision d7796855b87911b8ae6c726ab5df4949f173dbd2)
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