[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / lldb / unittests / Symbol / TestDWARFCallFrameInfo.cpp
blob86a6cf0cacb144fb8a95c683c026fd4aa194922b
1 //===-- TestDWARFCallFrameInfo.cpp ----------------------------------------===//
2 //
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #include "gtest/gtest.h"
12 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
13 #include "Plugins/Process/Utility/RegisterContext_x86.h"
14 #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
15 #include "TestingSupport/SubsystemRAII.h"
16 #include "TestingSupport/TestUtilities.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ModuleSpec.h"
20 #include "lldb/Core/Section.h"
21 #include "lldb/Host/FileSystem.h"
22 #include "lldb/Host/HostInfo.h"
23 #include "lldb/Symbol/DWARFCallFrameInfo.h"
24 #include "lldb/Utility/StreamString.h"
25 #include "llvm/Testing/Support/Error.h"
27 #include "llvm/Support/FileUtilities.h"
28 #include "llvm/Support/Path.h"
29 #include "llvm/Support/Program.h"
30 #include "llvm/Support/raw_ostream.h"
32 using namespace lldb_private;
33 using namespace lldb;
35 class DWARFCallFrameInfoTest : public testing::Test {
36 SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
37 subsystems;
39 protected:
40 void TestBasic(DWARFCallFrameInfo::Type type, llvm::StringRef symbol);
43 namespace lldb_private {
44 static std::ostream &operator<<(std::ostream &OS, const UnwindPlan::Row &row) {
45 StreamString SS;
46 row.Dump(SS, nullptr, nullptr, 0);
47 return OS << SS.GetData();
49 } // namespace lldb_private
51 static UnwindPlan::Row GetExpectedRow0() {
52 UnwindPlan::Row row;
53 row.SetOffset(0);
54 row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rsp_x86_64, 8);
55 row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false);
56 return row;
59 static UnwindPlan::Row GetExpectedRow1() {
60 UnwindPlan::Row row;
61 row.SetOffset(1);
62 row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rsp_x86_64, 16);
63 row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false);
64 row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rbp_x86_64, -16, false);
65 return row;
68 static UnwindPlan::Row GetExpectedRow2() {
69 UnwindPlan::Row row;
70 row.SetOffset(4);
71 row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp_x86_64, 16);
72 row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rip_x86_64, -8, false);
73 row.SetRegisterLocationToAtCFAPlusOffset(dwarf_rbp_x86_64, -16, false);
74 return row;
77 void DWARFCallFrameInfoTest::TestBasic(DWARFCallFrameInfo::Type type,
78 llvm::StringRef symbol) {
79 auto ExpectedFile = TestFile::fromYaml(R"(
80 --- !ELF
81 FileHeader:
82 Class: ELFCLASS64
83 Data: ELFDATA2LSB
84 Type: ET_DYN
85 Machine: EM_X86_64
86 Entry: 0x0000000000000260
87 Sections:
88 - Name: .text
89 Type: SHT_PROGBITS
90 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
91 Address: 0x0000000000000260
92 AddressAlign: 0x0000000000000010
93 Content: 554889E5897DFC8B45FC5DC30F1F4000554889E5897DFC8B45FC5DC30F1F4000554889E5897DFC8B45FC5DC3
94 #0000000000000260 <eh_frame>:
95 # 260: 55 push %rbp
96 # 261: 48 89 e5 mov %rsp,%rbp
97 # 264: 89 7d fc mov %edi,-0x4(%rbp)
98 # 267: 8b 45 fc mov -0x4(%rbp),%eax
99 # 26a: 5d pop %rbp
100 # 26b: c3 retq
101 # 26c: 0f 1f 40 00 nopl 0x0(%rax)
103 #0000000000000270 <debug_frame3>:
104 # 270: 55 push %rbp
105 # 271: 48 89 e5 mov %rsp,%rbp
106 # 274: 89 7d fc mov %edi,-0x4(%rbp)
107 # 277: 8b 45 fc mov -0x4(%rbp),%eax
108 # 27a: 5d pop %rbp
109 # 27b: c3 retq
110 # 27c: 0f 1f 40 00 nopl 0x0(%rax)
112 #0000000000000280 <debug_frame4>:
113 # 280: 55 push %rbp
114 # 281: 48 89 e5 mov %rsp,%rbp
115 # 284: 89 7d fc mov %edi,-0x4(%rbp)
116 # 287: 8b 45 fc mov -0x4(%rbp),%eax
117 # 28a: 5d pop %rbp
118 # 28b: c3 retq
119 - Name: .eh_frame
120 Type: SHT_X86_64_UNWIND
121 Flags: [ SHF_ALLOC ]
122 Address: 0x0000000000000290
123 AddressAlign: 0x0000000000000008
124 Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C000000B0FFFFFF0C00000000410E108602430D0600000000000000
125 #00000000 0000000000000014 00000000 CIE
126 # Version: 1
127 # Augmentation: "zR"
128 # Code alignment factor: 1
129 # Data alignment factor: -8
130 # Return address column: 16
131 # Augmentation data: 1b
133 # DW_CFA_def_cfa: r7 (rsp) ofs 8
134 # DW_CFA_offset: r16 (rip) at cfa-8
135 # DW_CFA_nop
136 # DW_CFA_nop
138 #00000018 000000000000001c 0000001c FDE cie=00000000 pc=ffffffffffffffd0..ffffffffffffffdc
139 # DW_CFA_advance_loc: 1 to ffffffffffffffd1
140 # DW_CFA_def_cfa_offset: 16
141 # DW_CFA_offset: r6 (rbp) at cfa-16
142 # DW_CFA_advance_loc: 3 to ffffffffffffffd4
143 # DW_CFA_def_cfa_register: r6 (rbp)
144 # DW_CFA_nop
145 # DW_CFA_nop
146 # DW_CFA_nop
147 # DW_CFA_nop
148 # DW_CFA_nop
149 # DW_CFA_nop
150 # DW_CFA_nop
151 - Name: .debug_frame
152 Type: SHT_PROGBITS
153 AddressAlign: 0x0000000000000008
154 Content: 14000000FFFFFFFF03000178100C070890010000000000001C0000000000000070020000000000000C00000000000000410E108602430D0614000000FFFFFFFF040008000178100C07089001000000001C0000003800000080020000000000000C00000000000000410E108602430D06
155 #00000000 0000000000000014 ffffffff CIE
156 # Version: 3
157 # Augmentation: ""
158 # Code alignment factor: 1
159 # Data alignment factor: -8
160 # Return address column: 16
162 # DW_CFA_def_cfa: r7 (rsp) ofs 8
163 # DW_CFA_offset: r16 (rip) at cfa-8
164 # DW_CFA_nop
165 # DW_CFA_nop
166 # DW_CFA_nop
167 # DW_CFA_nop
168 # DW_CFA_nop
169 # DW_CFA_nop
171 #00000018 000000000000001c 00000000 FDE cie=00000000 pc=0000000000000270..000000000000027c
172 # DW_CFA_advance_loc: 1 to 0000000000000271
173 # DW_CFA_def_cfa_offset: 16
174 # DW_CFA_offset: r6 (rbp) at cfa-16
175 # DW_CFA_advance_loc: 3 to 0000000000000274
176 # DW_CFA_def_cfa_register: r6 (rbp)
178 #00000038 0000000000000014 ffffffff CIE
179 # Version: 4
180 # Augmentation: ""
181 # Pointer Size: 8
182 # Segment Size: 0
183 # Code alignment factor: 1
184 # Data alignment factor: -8
185 # Return address column: 16
187 # DW_CFA_def_cfa: r7 (rsp) ofs 8
188 # DW_CFA_offset: r16 (rip) at cfa-8
189 # DW_CFA_nop
190 # DW_CFA_nop
191 # DW_CFA_nop
192 # DW_CFA_nop
194 #00000050 000000000000001c 00000038 FDE cie=00000038 pc=0000000000000280..000000000000028c
195 # DW_CFA_advance_loc: 1 to 0000000000000281
196 # DW_CFA_def_cfa_offset: 16
197 # DW_CFA_offset: r6 (rbp) at cfa-16
198 # DW_CFA_advance_loc: 3 to 0000000000000284
199 # DW_CFA_def_cfa_register: r6 (rbp)
200 Symbols:
201 - Name: eh_frame
202 Type: STT_FUNC
203 Section: .text
204 Value: 0x0000000000000260
205 Size: 0x000000000000000C
206 Binding: STB_GLOBAL
207 - Name: debug_frame3
208 Type: STT_FUNC
209 Section: .text
210 Value: 0x0000000000000270
211 Size: 0x000000000000000C
212 Binding: STB_GLOBAL
213 - Name: debug_frame4
214 Type: STT_FUNC
215 Section: .text
216 Value: 0x0000000000000280
217 Size: 0x000000000000000C
218 Binding: STB_GLOBAL
220 )");
221 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
223 auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
224 SectionList *list = module_sp->GetSectionList();
225 ASSERT_NE(nullptr, list);
227 auto section_sp = list->FindSectionByType(type == DWARFCallFrameInfo::EH
228 ? eSectionTypeEHFrame
229 : eSectionTypeDWARFDebugFrame,
230 false);
231 ASSERT_NE(nullptr, section_sp);
233 DWARFCallFrameInfo cfi(*module_sp->GetObjectFile(), section_sp, type);
235 const Symbol *sym = module_sp->FindFirstSymbolWithNameAndType(
236 ConstString(symbol), eSymbolTypeAny);
237 ASSERT_NE(nullptr, sym);
239 UnwindPlan plan(eRegisterKindGeneric);
240 ASSERT_TRUE(cfi.GetUnwindPlan(sym->GetAddress(), plan));
241 ASSERT_EQ(3, plan.GetRowCount());
242 EXPECT_EQ(GetExpectedRow0(), *plan.GetRowAtIndex(0));
243 EXPECT_EQ(GetExpectedRow1(), *plan.GetRowAtIndex(1));
244 EXPECT_EQ(GetExpectedRow2(), *plan.GetRowAtIndex(2));
247 TEST_F(DWARFCallFrameInfoTest, Basic_dwarf3) {
248 TestBasic(DWARFCallFrameInfo::DWARF, "debug_frame3");
251 TEST_F(DWARFCallFrameInfoTest, Basic_dwarf4) {
252 TestBasic(DWARFCallFrameInfo::DWARF, "debug_frame4");
255 TEST_F(DWARFCallFrameInfoTest, Basic_eh) {
256 TestBasic(DWARFCallFrameInfo::EH, "eh_frame");