[Transforms] Silence a warning in SROA.cpp (NFC)
[llvm-project.git] / lldb / unittests / SymbolFile / DWARF / SymbolFileDWARFTests.cpp
blob37ecfea26f36cc0992beaf720b434d08b8cdf9e0
1 //===-- SymbolFileDWARFTests.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 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
13 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
14 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
15 #include "llvm/Support/FileSystem.h"
16 #include "llvm/Support/Path.h"
18 #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
19 #include "Plugins/SymbolFile/DWARF/DWARFDataExtractor.h"
20 #include "Plugins/SymbolFile/DWARF/DWARFDebugAranges.h"
21 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
22 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
23 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
24 #include "TestingSupport/SubsystemRAII.h"
25 #include "TestingSupport/TestUtilities.h"
26 #include "lldb/Core/Address.h"
27 #include "lldb/Core/Module.h"
28 #include "lldb/Core/ModuleSpec.h"
29 #include "lldb/Host/FileSystem.h"
30 #include "lldb/Host/HostInfo.h"
31 #include "lldb/Symbol/CompileUnit.h"
32 #include "lldb/Symbol/LineTable.h"
33 #include "lldb/Utility/ArchSpec.h"
34 #include "lldb/Utility/DataEncoder.h"
35 #include "lldb/Utility/FileSpec.h"
36 #include "lldb/Utility/StreamString.h"
38 using namespace lldb;
39 using namespace lldb_private;
40 using namespace lldb_private::dwarf;
41 using namespace lldb_private::plugin::dwarf;
42 using llvm::DWARFDebugArangeSet;
44 class SymbolFileDWARFTests : public testing::Test {
45 SubsystemRAII<FileSystem, HostInfo, ObjectFilePECOFF, SymbolFileDWARF,
46 TypeSystemClang, SymbolFilePDB>
47 subsystems;
49 public:
50 void SetUp() override {
51 m_dwarf_test_exe = GetInputFilePath("test-dwarf.exe");
54 protected:
55 std::string m_dwarf_test_exe;
58 TEST_F(SymbolFileDWARFTests, TestAbilitiesForDWARF) {
59 // Test that when we have Dwarf debug info, SymbolFileDWARF is used.
60 FileSpec fspec(m_dwarf_test_exe);
61 ArchSpec aspec("i686-pc-windows");
62 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
64 SymbolFile *symfile = module->GetSymbolFile();
65 ASSERT_NE(nullptr, symfile);
66 EXPECT_EQ(symfile->GetPluginName(), SymbolFileDWARF::GetPluginNameStatic());
68 uint32_t expected_abilities = SymbolFile::kAllAbilities;
69 EXPECT_EQ(expected_abilities, symfile->CalculateAbilities());
72 TEST_F(SymbolFileDWARFTests, ParseArangesNonzeroSegmentSize) {
73 // This `.debug_aranges` table header is a valid 32bit big-endian section
74 // according to the DWARFv5 spec:6.2.1, but contains segment selectors which
75 // are not supported by lldb, and should be gracefully rejected
76 const unsigned char binary_data[] = {
77 0, 0, 0, 41, // unit_length (length field not including this field itself)
78 0, 2, // DWARF version number (half)
79 0, 0, 0, 0, // offset into the .debug_info_table (ignored for the purposes
80 // of this test
81 4, // address size
82 1, // segment size
83 // alignment for the first tuple which "begins at an offset that is a
84 // multiple of the size of a single tuple". Tuples are nine bytes in this
85 // example.
86 0, 0, 0, 0, 0, 0,
87 // BEGIN TUPLES
88 1, 0, 0, 0, 4, 0, 0, 0,
89 1, // a 1byte object starting at address 4 in segment 1
90 0, 0, 0, 0, 4, 0, 0, 0,
91 1, // a 1byte object starting at address 4 in segment 0
92 // END TUPLES
93 0, 0, 0, 0, 0, 0, 0, 0, 0 // terminator
95 llvm::DWARFDataExtractor data(llvm::ArrayRef<unsigned char>(binary_data),
96 /*isLittleEndian=*/false, /*AddrSize=*/4);
98 DWARFDebugArangeSet debug_aranges;
99 offset_t off = 0;
100 llvm::Error error = debug_aranges.extract(data, &off);
101 EXPECT_TRUE(bool(error));
102 EXPECT_EQ("non-zero segment selector size in address range table at offset "
103 "0x0 is not supported",
104 llvm::toString(std::move(error)));
105 EXPECT_EQ(off, 12U); // Parser should read no further than the segment size
108 TEST_F(SymbolFileDWARFTests, ParseArangesWithMultipleTerminators) {
109 // This .debug_aranges set has multiple terminator entries which appear in
110 // binaries produced by popular linux compilers and linker combinations. We
111 // must be able to parse all the way through the data for each
112 // DWARFDebugArangeSet. Previously the DWARFDebugArangeSet::extract()
113 // function would stop parsing as soon as we ran into a terminator even
114 // though the length field stated that there was more data that follows. This
115 // would cause the next DWARFDebugArangeSet to be parsed immediately
116 // following the first terminator and it would attempt to decode the
117 // DWARFDebugArangeSet header using the remaining segment + address pairs
118 // from the remaining bytes.
119 unsigned char binary_data[] = {
120 0, 0, 0, 0, // unit_length that will be set correctly after this
121 0, 2, // DWARF version number (uint16_t)
122 0, 0, 0, 255, // CU offset
123 4, // address size
124 0, // segment size
125 0, 0, 0, 0, // alignment for the first tuple
126 // BEGIN TUPLES
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // premature terminator
128 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100)
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // premature terminator
130 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, // [0x2000-0x2010)
131 // END TUPLES
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
134 // Set the big endian length correctly.
135 const offset_t binary_data_size = sizeof(binary_data);
136 binary_data[3] = (uint8_t)binary_data_size - 4;
137 DWARFDataExtractor data;
138 data.SetData(static_cast<const void *>(binary_data), sizeof binary_data,
139 lldb::ByteOrder::eByteOrderBig);
140 DWARFDebugAranges debug_aranges;
141 debug_aranges.extract(data);
142 // Parser should read all terminators to the end of the length specified.
143 ASSERT_EQ(debug_aranges.GetNumRanges(), 2U);
144 EXPECT_EQ(debug_aranges.FindAddress(0x0fff), DW_INVALID_OFFSET);
145 EXPECT_EQ(debug_aranges.FindAddress(0x1000), 255u);
146 EXPECT_EQ(debug_aranges.FindAddress(0x1100 - 1), 255u);
147 EXPECT_EQ(debug_aranges.FindAddress(0x1100), DW_INVALID_OFFSET);
148 EXPECT_EQ(debug_aranges.FindAddress(0x1fff), DW_INVALID_OFFSET);
149 EXPECT_EQ(debug_aranges.FindAddress(0x2000), 255u);
150 EXPECT_EQ(debug_aranges.FindAddress(0x2010 - 1), 255u);
151 EXPECT_EQ(debug_aranges.FindAddress(0x2010), DW_INVALID_OFFSET);
154 TEST_F(SymbolFileDWARFTests, ParseArangesIgnoreEmpty) {
155 // This .debug_aranges set has some address ranges which have zero length
156 // and we ensure that these are ignored by our DWARFDebugArangeSet parser
157 // and not included in the descriptors that are returned.
158 unsigned char binary_data[] = {
159 0, 0, 0, 0, // unit_length that will be set correctly after this
160 0, 2, // DWARF version number (uint16_t)
161 0, 0, 0, 255, // CU offset
162 4, // address size
163 0, // segment size
164 0, 0, 0, 0, // alignment for the first tuple
165 // BEGIN TUPLES
166 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100)
167 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, // [0x1100-0x1100)
168 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, // [0x2000-0x2010)
169 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // [0x2010-0x2010)
170 // END TUPLES
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
173 // Set the big endian length correctly.
174 const offset_t binary_data_size = sizeof(binary_data);
175 binary_data[3] = (uint8_t)binary_data_size - 4;
176 DWARFDataExtractor data;
177 data.SetData(static_cast<const void *>(binary_data), sizeof binary_data,
178 lldb::ByteOrder::eByteOrderBig);
179 DWARFDebugAranges debug_aranges;
180 debug_aranges.extract(data);
181 // Parser should read all terminators to the end of the length specified.
182 // Previously the DWARFDebugArangeSet would stop at the first terminator
183 // entry and leave the offset in the middle of the current
184 // DWARFDebugArangeSet data, and that would cause the next extracted
185 // DWARFDebugArangeSet to fail.
186 ASSERT_EQ(debug_aranges.GetNumRanges(), 2U);
187 EXPECT_EQ(debug_aranges.FindAddress(0x0fff), DW_INVALID_OFFSET);
188 EXPECT_EQ(debug_aranges.FindAddress(0x1000), 255u);
189 EXPECT_EQ(debug_aranges.FindAddress(0x1100 - 1), 255u);
190 EXPECT_EQ(debug_aranges.FindAddress(0x1100), DW_INVALID_OFFSET);
191 EXPECT_EQ(debug_aranges.FindAddress(0x1fff), DW_INVALID_OFFSET);
192 EXPECT_EQ(debug_aranges.FindAddress(0x2000), 255u);
193 EXPECT_EQ(debug_aranges.FindAddress(0x2010 - 1), 255u);
194 EXPECT_EQ(debug_aranges.FindAddress(0x2010), DW_INVALID_OFFSET);
197 TEST_F(SymbolFileDWARFTests, ParseAranges) {
198 // Test we can successfully parse a DWARFDebugAranges. The initial error
199 // checking code had a bug where it would always return an empty address
200 // ranges for everything in .debug_aranges and no error.
201 unsigned char binary_data[] = {
202 0, 0, 0, 0, // unit_length that will be set correctly after this
203 2, 0, // DWARF version number
204 255, 0, 0, 0, // offset into the .debug_info_table
205 8, // address size
206 0, // segment size
207 0, 0, 0, 0, // pad bytes
208 // BEGIN TUPLES
209 // First tuple: [0x1000-0x1100)
210 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Address 0x1000
211 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Size 0x0100
212 // Second tuple: [0x2000-0x2100)
213 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Address 0x2000
214 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Size 0x0100
215 // Terminating tuple
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Terminator
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Terminator
219 // Set the little endian length correctly.
220 binary_data[0] = sizeof(binary_data) - 4;
221 DWARFDataExtractor data;
222 data.SetData(static_cast<const void *>(binary_data), sizeof binary_data,
223 lldb::ByteOrder::eByteOrderLittle);
224 DWARFDebugAranges debug_aranges;
225 debug_aranges.extract(data);
226 EXPECT_EQ(debug_aranges.GetNumRanges(), 2u);
227 EXPECT_EQ(debug_aranges.FindAddress(0x0fff), DW_INVALID_OFFSET);
228 EXPECT_EQ(debug_aranges.FindAddress(0x1000), 255u);
229 EXPECT_EQ(debug_aranges.FindAddress(0x1100 - 1), 255u);
230 EXPECT_EQ(debug_aranges.FindAddress(0x1100), DW_INVALID_OFFSET);
231 EXPECT_EQ(debug_aranges.FindAddress(0x1fff), DW_INVALID_OFFSET);
232 EXPECT_EQ(debug_aranges.FindAddress(0x2000), 255u);
233 EXPECT_EQ(debug_aranges.FindAddress(0x2100 - 1), 255u);
234 EXPECT_EQ(debug_aranges.FindAddress(0x2100), DW_INVALID_OFFSET);
237 TEST_F(SymbolFileDWARFTests, ParseArangesSkipErrors) {
238 // Test we can successfully parse a DWARFDebugAranges that contains some
239 // valid DWARFDebugArangeSet objects and some with errors as long as their
240 // length is set correctly. This helps LLDB ensure that it can parse newer
241 // .debug_aranges version that LLDB currently doesn't support, or ignore
242 // errors in individual DWARFDebugArangeSet objects as long as the length
243 // is set correctly.
244 const unsigned char binary_data[] = {
245 // This DWARFDebugArangeSet is well formed and has a single address range
246 // for [0x1000-0x1100) with a CU offset of 0x00000000.
247 0, 0, 0, 28, // unit_length that will be set correctly after this
248 0, 2, // DWARF version number (uint16_t)
249 0, 0, 0, 0, // CU offset = 0x00000000
250 4, // address size
251 0, // segment size
252 0, 0, 0, 0, // alignment for the first tuple
253 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100)
254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
255 // This DWARFDebugArangeSet has the correct length, but an invalid
256 // version. We need to be able to skip this correctly and ignore it.
257 0, 0, 0, 20, // unit_length that will be set correctly after this
258 0, 44, // invalid DWARF version number (uint16_t)
259 0, 0, 1, 0, // CU offset = 0x00000100
260 4, // address size
261 0, // segment size
262 0, 0, 0, 0, // alignment for the first tuple
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
264 // This DWARFDebugArangeSet is well formed and has a single address range
265 // for [0x2000-0x2100) with a CU offset of 0x00000000.
266 0, 0, 0, 28, // unit_length that will be set correctly after this
267 0, 2, // DWARF version number (uint16_t)
268 0, 0, 2, 0, // CU offset = 0x00000200
269 4, // address size
270 0, // segment size
271 0, 0, 0, 0, // alignment for the first tuple
272 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x2000-0x2100)
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
276 DWARFDataExtractor data;
277 data.SetData(static_cast<const void *>(binary_data), sizeof binary_data,
278 lldb::ByteOrder::eByteOrderBig);
279 DWARFDebugAranges debug_aranges;
280 debug_aranges.extract(data);
281 EXPECT_EQ(debug_aranges.GetNumRanges(), 2u);
282 EXPECT_EQ(debug_aranges.FindAddress(0x0fff), DW_INVALID_OFFSET);
283 EXPECT_EQ(debug_aranges.FindAddress(0x1000), 0u);
284 EXPECT_EQ(debug_aranges.FindAddress(0x1100 - 1), 0u);
285 EXPECT_EQ(debug_aranges.FindAddress(0x1100), DW_INVALID_OFFSET);
286 EXPECT_EQ(debug_aranges.FindAddress(0x1fff), DW_INVALID_OFFSET);
287 EXPECT_EQ(debug_aranges.FindAddress(0x2000), 0x200u);
288 EXPECT_EQ(debug_aranges.FindAddress(0x2100 - 1), 0x200u);
289 EXPECT_EQ(debug_aranges.FindAddress(0x2100), DW_INVALID_OFFSET);