xref: /llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp (revision f78a48cfaf9d3e616d9bbedd81f68ff159342ffb)
1 //===- llvm/unittest/DebugInfo/DWARFExpressionCompactPrinterTest.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 "DwarfGenerator.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
12 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
13 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
14 #include "llvm/MC/MCInstrInfo.h"
15 #include "llvm/MC/MCRegisterInfo.h"
16 #include "llvm/MC/TargetRegistry.h"
17 #include "llvm/Support/DataExtractor.h"
18 #include "llvm/Support/TargetSelect.h"
19 #include "llvm/Testing/Support/Error.h"
20 #include "gtest/gtest.h"
21 
22 using namespace llvm;
23 using namespace dwarf;
24 
25 namespace {
26 class DWARFExpressionCompactPrinterTest : public ::testing::Test {
27 public:
28   std::unique_ptr<MCRegisterInfo> MRI;
29 
30   DWARFExpressionCompactPrinterTest() {
31     InitializeAllTargets();
32     InitializeAllTargetMCs();
33     InitializeAllAsmPrinters();
34 
35     std::string TripleName = "armv8a-linux-gnueabi";
36     std::string ErrorStr;
37 
38     const Target *TheTarget =
39         TargetRegistry::lookupTarget(TripleName, ErrorStr);
40 
41     if (!TheTarget)
42       return;
43 
44     MRI.reset(TheTarget->createMCRegInfo(TripleName));
45   }
46 
47   void TestExprPrinter(ArrayRef<uint8_t> ExprData, StringRef Expected);
48 };
49 } // namespace
50 
51 void DWARFExpressionCompactPrinterTest::TestExprPrinter(
52     ArrayRef<uint8_t> ExprData, StringRef Expected) {
53   // If we didn't build ARM, do not run the test.
54   if (!MRI)
55     GTEST_SKIP();
56 
57   // Print the expression, passing in the subprogram DIE, and check that the
58   // result is as expected.
59   std::string Result;
60   raw_string_ostream OS(Result);
61   DataExtractor DE(ExprData, true, 8);
62   DWARFExpression Expr(DE, 8);
63 
64   auto GetRegName = [&](uint64_t DwarfRegNum, bool IsEH) -> StringRef {
65     if (std::optional<MCRegister> LLVMRegNum =
66             this->MRI->getLLVMRegNum(DwarfRegNum, IsEH))
67       if (const char *RegName = this->MRI->getName(*LLVMRegNum))
68         return llvm::StringRef(RegName);
69     OS << "<unknown register " << DwarfRegNum << ">";
70     return {};
71   };
72 
73   Expr.printCompact(OS, GetRegName);
74   EXPECT_EQ(OS.str(), Expected);
75 }
76 
77 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_reg0) {
78   TestExprPrinter({DW_OP_reg0}, "R0");
79 }
80 
81 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_reg10) {
82   TestExprPrinter({DW_OP_reg10}, "R10");
83 }
84 
85 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_regx) {
86   TestExprPrinter({DW_OP_regx, 0x80, 0x02}, "D0");
87 }
88 
89 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg0) {
90   TestExprPrinter({DW_OP_breg0, 0x04}, "[R0+4]");
91 }
92 
93 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg0_large_offset) {
94   TestExprPrinter({DW_OP_breg0, 0x80, 0x02}, "[R0+256]");
95 }
96 
97 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg13) {
98   TestExprPrinter({DW_OP_breg13, 0x10}, "[SP+16]");
99 }
100 
101 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg13_zero_offset) {
102   TestExprPrinter({DW_OP_breg13, 0x00}, "[SP]");
103 }
104 
105 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg0_negative) {
106   TestExprPrinter({DW_OP_breg0, 0x70}, "[R0-16]");
107 }
108 
109 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_bregx) {
110   TestExprPrinter({DW_OP_bregx, 0x0d, 0x28}, "[SP+40]");
111 }
112 
113 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_stack_value) {
114   TestExprPrinter({DW_OP_breg13, 0x04, DW_OP_stack_value}, "SP+4");
115 }
116 
117 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_entry_value) {
118   TestExprPrinter({DW_OP_entry_value, 0x01, DW_OP_reg0, DW_OP_stack_value},
119                   "entry(R0)");
120 }
121 
122 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_entry_value_mem) {
123   TestExprPrinter(
124       {DW_OP_entry_value, 0x02, DW_OP_breg13, 0x10, DW_OP_stack_value},
125       "entry([SP+16])");
126 }
127 
128 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_nop) {
129   TestExprPrinter({DW_OP_nop}, "<stack of size 0, expected 1>");
130 }
131 
132 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_LLVM_nop) {
133   TestExprPrinter({DW_OP_LLVM_user, DW_OP_LLVM_nop},
134                   "<stack of size 0, expected 1>");
135 }
136 
137 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_nop_OP_reg) {
138   TestExprPrinter({DW_OP_nop, DW_OP_reg0}, "R0");
139 }
140 
141 TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_LLVM_nop_OP_reg) {
142   TestExprPrinter({DW_OP_LLVM_user, DW_OP_LLVM_nop, DW_OP_reg0}, "R0");
143 }
144