1 | //===- llvm/unittest/DebugInfo/DWARFDebugInfoTest.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 "DwarfUtils.h" |
11 | #include "llvm/ADT/ArrayRef.h" |
12 | #include "llvm/ADT/StringExtras.h" |
13 | #include "llvm/ADT/StringRef.h" |
14 | #include "llvm/BinaryFormat/Dwarf.h" |
15 | #include "llvm/CodeGen/AsmPrinter.h" |
16 | #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" |
17 | #include "llvm/DebugInfo/DWARF/DWARFContext.h" |
18 | #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" |
19 | #include "llvm/DebugInfo/DWARF/DWARFDie.h" |
20 | #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" |
21 | #include "llvm/DebugInfo/DWARF/DWARFVerifier.h" |
22 | #include "llvm/MC/MCContext.h" |
23 | #include "llvm/MC/MCSectionELF.h" |
24 | #include "llvm/MC/MCStreamer.h" |
25 | #include "llvm/MC/TargetRegistry.h" |
26 | #include "llvm/Object/ObjectFile.h" |
27 | #include "llvm/ObjectYAML/DWARFEmitter.h" |
28 | #include "llvm/Support/Error.h" |
29 | #include "llvm/Support/MemoryBuffer.h" |
30 | #include "llvm/Support/TargetSelect.h" |
31 | #include "llvm/TargetParser/Triple.h" |
32 | #include "llvm/Testing/Support/Error.h" |
33 | #include "gtest/gtest.h" |
34 | #include <string> |
35 | |
36 | // AIX doesn't support debug_str_offsets or debug_addr sections |
37 | #ifdef _AIX |
38 | #define NO_SUPPORT_DEBUG_STR_OFFSETS |
39 | #define NO_SUPPORT_DEBUG_ADDR |
40 | #endif |
41 | |
42 | using namespace llvm; |
43 | using namespace dwarf; |
44 | using namespace utils; |
45 | |
46 | namespace { |
47 | |
48 | template <uint16_t Version, class AddrType, class RefAddrType> |
49 | void TestAllForms() { |
50 | Triple Triple = getDefaultTargetTripleForAddrSize(AddrSize: sizeof(AddrType)); |
51 | if (!isConfigurationSupported(T&: Triple)) |
52 | GTEST_SKIP(); |
53 | |
54 | // Test that we can decode all DW_FORM values correctly. |
55 | const AddrType AddrValue = (AddrType)0x0123456789abcdefULL; |
56 | const AddrType AddrxValue = (AddrType)0x4231abcd4231abcdULL; |
57 | const AddrType Addrx1Value = (AddrType)0x0000aaaabbbbccccULL; |
58 | const AddrType Addrx2Value = (AddrType)0xf00123f00456f000ULL; |
59 | const AddrType Addrx3Value = (AddrType)0xABABA000B111C222ULL; |
60 | const AddrType Addrx4Value = (AddrType)0xa1b2c3d4e5f6e5d4ULL; |
61 | |
62 | const uint8_t BlockData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; |
63 | const uint32_t BlockSize = sizeof(BlockData); |
64 | const RefAddrType RefAddr = 0x12345678; |
65 | const uint8_t Data1 = 0x01U; |
66 | const uint16_t Data2 = 0x2345U; |
67 | const uint32_t Data4 = 0x6789abcdU; |
68 | const uint64_t Data8 = 0x0011223344556677ULL; |
69 | const uint64_t Data8_2 = 0xAABBCCDDEEFF0011ULL; |
70 | const uint8_t Data16[16] = {1, 2, 3, 4, 5, 6, 7, 8, |
71 | 9, 10, 11, 12, 13, 14, 15, 16}; |
72 | const int64_t SData = INT64_MIN; |
73 | const int64_t ICSData = INT64_MAX; // DW_FORM_implicit_const SData |
74 | const uint64_t UData[] = {UINT64_MAX - 1, UINT64_MAX - 2, UINT64_MAX - 3, |
75 | UINT64_MAX - 4, UINT64_MAX - 5, UINT64_MAX - 6, |
76 | UINT64_MAX - 7, UINT64_MAX - 8, UINT64_MAX - 9}; |
77 | #define UDATA_1 18446744073709551614ULL |
78 | const uint32_t Dwarf32Values[] = {1, 2, 3, 4, 5, 6, 7, 8}; |
79 | const char *StringValue = "Hello" ; |
80 | const char *StrpValue = "World" ; |
81 | const char *StrxValue = "Indexed" ; |
82 | const char *Strx1Value = "Indexed1" ; |
83 | const char *Strx2Value = "Indexed2" ; |
84 | const char *Strx3Value = "Indexed3" ; |
85 | const char *Strx4Value = "Indexed4" ; |
86 | |
87 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
88 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
89 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
90 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
91 | dwarfgen::DIE CUDie = CU.getUnitDIE(); |
92 | |
93 | if (Version >= 5) { |
94 | CUDie.addStrOffsetsBaseAttribute(); |
95 | CUDie.addAddrBaseAttribute(); |
96 | } |
97 | |
98 | uint16_t Attr = DW_AT_lo_user; |
99 | |
100 | //---------------------------------------------------------------------- |
101 | // Test address forms |
102 | //---------------------------------------------------------------------- |
103 | const auto Attr_DW_FORM_addr = static_cast<dwarf::Attribute>(Attr++); |
104 | CUDie.addAttribute(Attr_DW_FORM_addr, DW_FORM_addr, AddrValue); |
105 | |
106 | const auto Attr_DW_FORM_addrx = static_cast<dwarf::Attribute>(Attr++); |
107 | const auto Attr_DW_FORM_addrx1 = static_cast<dwarf::Attribute>(Attr++); |
108 | const auto Attr_DW_FORM_addrx2 = static_cast<dwarf::Attribute>(Attr++); |
109 | const auto Attr_DW_FORM_addrx3 = static_cast<dwarf::Attribute>(Attr++); |
110 | const auto Attr_DW_FORM_addrx4 = static_cast<dwarf::Attribute>(Attr++); |
111 | |
112 | if (Version >= 5) { |
113 | CUDie.addAttribute(Attr_DW_FORM_addrx, DW_FORM_addrx, AddrxValue); |
114 | CUDie.addAttribute(Attr_DW_FORM_addrx1, DW_FORM_addrx1, Addrx1Value); |
115 | CUDie.addAttribute(Attr_DW_FORM_addrx2, DW_FORM_addrx2, Addrx2Value); |
116 | CUDie.addAttribute(Attr_DW_FORM_addrx3, DW_FORM_addrx3, Addrx3Value); |
117 | CUDie.addAttribute(Attr_DW_FORM_addrx4, DW_FORM_addrx4, Addrx4Value); |
118 | } |
119 | |
120 | //---------------------------------------------------------------------- |
121 | // Test block forms |
122 | //---------------------------------------------------------------------- |
123 | const auto Attr_DW_FORM_block = static_cast<dwarf::Attribute>(Attr++); |
124 | CUDie.addAttribute(Attr: Attr_DW_FORM_block, Form: DW_FORM_block, P: BlockData, S: BlockSize); |
125 | |
126 | const auto Attr_DW_FORM_block1 = static_cast<dwarf::Attribute>(Attr++); |
127 | CUDie.addAttribute(Attr: Attr_DW_FORM_block1, Form: DW_FORM_block1, P: BlockData, S: BlockSize); |
128 | |
129 | const auto Attr_DW_FORM_block2 = static_cast<dwarf::Attribute>(Attr++); |
130 | CUDie.addAttribute(Attr: Attr_DW_FORM_block2, Form: DW_FORM_block2, P: BlockData, S: BlockSize); |
131 | |
132 | const auto Attr_DW_FORM_block4 = static_cast<dwarf::Attribute>(Attr++); |
133 | CUDie.addAttribute(Attr: Attr_DW_FORM_block4, Form: DW_FORM_block4, P: BlockData, S: BlockSize); |
134 | |
135 | // We handle data16 as a block form. |
136 | const auto Attr_DW_FORM_data16 = static_cast<dwarf::Attribute>(Attr++); |
137 | if (Version >= 5) |
138 | CUDie.addAttribute(Attr: Attr_DW_FORM_data16, Form: DW_FORM_data16, P: Data16, S: 16); |
139 | |
140 | //---------------------------------------------------------------------- |
141 | // Test data forms |
142 | //---------------------------------------------------------------------- |
143 | const auto Attr_DW_FORM_data1 = static_cast<dwarf::Attribute>(Attr++); |
144 | CUDie.addAttribute(Attr: Attr_DW_FORM_data1, Form: DW_FORM_data1, U: Data1); |
145 | |
146 | const auto Attr_DW_FORM_data2 = static_cast<dwarf::Attribute>(Attr++); |
147 | CUDie.addAttribute(Attr: Attr_DW_FORM_data2, Form: DW_FORM_data2, U: Data2); |
148 | |
149 | const auto Attr_DW_FORM_data4 = static_cast<dwarf::Attribute>(Attr++); |
150 | CUDie.addAttribute(Attr: Attr_DW_FORM_data4, Form: DW_FORM_data4, U: Data4); |
151 | |
152 | const auto Attr_DW_FORM_data8 = static_cast<dwarf::Attribute>(Attr++); |
153 | CUDie.addAttribute(Attr: Attr_DW_FORM_data8, Form: DW_FORM_data8, U: Data8); |
154 | |
155 | //---------------------------------------------------------------------- |
156 | // Test string forms |
157 | //---------------------------------------------------------------------- |
158 | const auto Attr_DW_FORM_string = static_cast<dwarf::Attribute>(Attr++); |
159 | CUDie.addAttribute(Attr: Attr_DW_FORM_string, Form: DW_FORM_string, String: StringValue); |
160 | |
161 | const auto Attr_DW_FORM_strx = static_cast<dwarf::Attribute>(Attr++); |
162 | const auto Attr_DW_FORM_strx1 = static_cast<dwarf::Attribute>(Attr++); |
163 | const auto Attr_DW_FORM_strx2 = static_cast<dwarf::Attribute>(Attr++); |
164 | const auto Attr_DW_FORM_strx3 = static_cast<dwarf::Attribute>(Attr++); |
165 | const auto Attr_DW_FORM_strx4 = static_cast<dwarf::Attribute>(Attr++); |
166 | if (Version >= 5) { |
167 | CUDie.addAttribute(Attr: Attr_DW_FORM_strx, Form: DW_FORM_strx, String: StrxValue); |
168 | CUDie.addAttribute(Attr: Attr_DW_FORM_strx1, Form: DW_FORM_strx1, String: Strx1Value); |
169 | CUDie.addAttribute(Attr: Attr_DW_FORM_strx2, Form: DW_FORM_strx2, String: Strx2Value); |
170 | CUDie.addAttribute(Attr: Attr_DW_FORM_strx3, Form: DW_FORM_strx3, String: Strx3Value); |
171 | CUDie.addAttribute(Attr: Attr_DW_FORM_strx4, Form: DW_FORM_strx4, String: Strx4Value); |
172 | } |
173 | |
174 | const auto Attr_DW_FORM_strp = static_cast<dwarf::Attribute>(Attr++); |
175 | CUDie.addAttribute(Attr: Attr_DW_FORM_strp, Form: DW_FORM_strp, String: StrpValue); |
176 | |
177 | //---------------------------------------------------------------------- |
178 | // Test reference forms |
179 | //---------------------------------------------------------------------- |
180 | const auto Attr_DW_FORM_ref_addr = static_cast<dwarf::Attribute>(Attr++); |
181 | CUDie.addAttribute(Attr_DW_FORM_ref_addr, DW_FORM_ref_addr, RefAddr); |
182 | |
183 | const auto Attr_DW_FORM_ref1 = static_cast<dwarf::Attribute>(Attr++); |
184 | CUDie.addAttribute(Attr: Attr_DW_FORM_ref1, Form: DW_FORM_ref1, U: Data1); |
185 | |
186 | const auto Attr_DW_FORM_ref2 = static_cast<dwarf::Attribute>(Attr++); |
187 | CUDie.addAttribute(Attr: Attr_DW_FORM_ref2, Form: DW_FORM_ref2, U: Data2); |
188 | |
189 | const auto Attr_DW_FORM_ref4 = static_cast<dwarf::Attribute>(Attr++); |
190 | CUDie.addAttribute(Attr: Attr_DW_FORM_ref4, Form: DW_FORM_ref4, U: Data4); |
191 | |
192 | const auto Attr_DW_FORM_ref8 = static_cast<dwarf::Attribute>(Attr++); |
193 | CUDie.addAttribute(Attr: Attr_DW_FORM_ref8, Form: DW_FORM_ref8, U: Data8); |
194 | |
195 | const auto Attr_DW_FORM_ref_sig8 = static_cast<dwarf::Attribute>(Attr++); |
196 | if (Version >= 4) |
197 | CUDie.addAttribute(Attr: Attr_DW_FORM_ref_sig8, Form: DW_FORM_ref_sig8, U: Data8_2); |
198 | |
199 | const auto Attr_DW_FORM_ref_udata = static_cast<dwarf::Attribute>(Attr++); |
200 | CUDie.addAttribute(Attr: Attr_DW_FORM_ref_udata, Form: DW_FORM_ref_udata, U: UData[0]); |
201 | |
202 | //---------------------------------------------------------------------- |
203 | // Test flag forms |
204 | //---------------------------------------------------------------------- |
205 | const auto Attr_DW_FORM_flag_true = static_cast<dwarf::Attribute>(Attr++); |
206 | CUDie.addAttribute(Attr: Attr_DW_FORM_flag_true, Form: DW_FORM_flag, U: true); |
207 | |
208 | const auto Attr_DW_FORM_flag_false = static_cast<dwarf::Attribute>(Attr++); |
209 | CUDie.addAttribute(Attr: Attr_DW_FORM_flag_false, Form: DW_FORM_flag, U: false); |
210 | |
211 | const auto Attr_DW_FORM_flag_present = static_cast<dwarf::Attribute>(Attr++); |
212 | if (Version >= 4) |
213 | CUDie.addAttribute(Attr: Attr_DW_FORM_flag_present, Form: DW_FORM_flag_present); |
214 | |
215 | //---------------------------------------------------------------------- |
216 | // Test SLEB128 based forms |
217 | //---------------------------------------------------------------------- |
218 | const auto Attr_DW_FORM_sdata = static_cast<dwarf::Attribute>(Attr++); |
219 | CUDie.addAttribute(Attr: Attr_DW_FORM_sdata, Form: DW_FORM_sdata, U: SData); |
220 | |
221 | const auto Attr_DW_FORM_implicit_const = |
222 | static_cast<dwarf::Attribute>(Attr++); |
223 | if (Version >= 5) |
224 | CUDie.addAttribute(Attr: Attr_DW_FORM_implicit_const, Form: DW_FORM_implicit_const, |
225 | U: ICSData); |
226 | |
227 | //---------------------------------------------------------------------- |
228 | // Test ULEB128 based forms |
229 | //---------------------------------------------------------------------- |
230 | const auto Attr_DW_FORM_udata = static_cast<dwarf::Attribute>(Attr++); |
231 | CUDie.addAttribute(Attr: Attr_DW_FORM_udata, Form: DW_FORM_udata, U: UData[0]); |
232 | |
233 | //---------------------------------------------------------------------- |
234 | // Test DWARF32/DWARF64 forms |
235 | //---------------------------------------------------------------------- |
236 | const auto Attr_DW_FORM_GNU_ref_alt = static_cast<dwarf::Attribute>(Attr++); |
237 | CUDie.addAttribute(Attr: Attr_DW_FORM_GNU_ref_alt, Form: DW_FORM_GNU_ref_alt, |
238 | U: Dwarf32Values[0]); |
239 | |
240 | const auto Attr_DW_FORM_sec_offset = static_cast<dwarf::Attribute>(Attr++); |
241 | if (Version >= 4) |
242 | CUDie.addAttribute(Attr: Attr_DW_FORM_sec_offset, Form: DW_FORM_sec_offset, |
243 | U: Dwarf32Values[1]); |
244 | |
245 | //---------------------------------------------------------------------- |
246 | // Add an address at the end to make sure we can decode this value |
247 | //---------------------------------------------------------------------- |
248 | const auto Attr_Last = static_cast<dwarf::Attribute>(Attr++); |
249 | CUDie.addAttribute(Attr_Last, DW_FORM_addr, AddrValue); |
250 | |
251 | //---------------------------------------------------------------------- |
252 | // Generate the DWARF |
253 | //---------------------------------------------------------------------- |
254 | StringRef FileBytes = DG->generate(); |
255 | MemoryBufferRef FileBuffer(FileBytes, "dwarf" ); |
256 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
257 | EXPECT_TRUE((bool)Obj); |
258 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
259 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
260 | EXPECT_EQ(NumCUs, 1u); |
261 | DWARFCompileUnit *U = |
262 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
263 | auto DieDG = U->getUnitDIE(ExtractUnitDIEOnly: false); |
264 | EXPECT_TRUE(DieDG.isValid()); |
265 | |
266 | //---------------------------------------------------------------------- |
267 | // Test address forms |
268 | //---------------------------------------------------------------------- |
269 | EXPECT_EQ(AddrValue, toAddress(DieDG.find(Attr_DW_FORM_addr), 0)); |
270 | |
271 | if (Version >= 5) { |
272 | auto = toAddress(V: DieDG.find(Attr: Attr_DW_FORM_addrx)); |
273 | EXPECT_TRUE(ExtractedAddrxValue.has_value()); |
274 | EXPECT_EQ(AddrxValue, *ExtractedAddrxValue); |
275 | |
276 | auto = toAddress(V: DieDG.find(Attr: Attr_DW_FORM_addrx1)); |
277 | EXPECT_TRUE(ExtractedAddrx1Value.has_value()); |
278 | EXPECT_EQ(Addrx1Value, *ExtractedAddrx1Value); |
279 | |
280 | auto = toAddress(V: DieDG.find(Attr: Attr_DW_FORM_addrx2)); |
281 | EXPECT_TRUE(ExtractedAddrx2Value.has_value()); |
282 | EXPECT_EQ(Addrx2Value, *ExtractedAddrx2Value); |
283 | |
284 | auto = toAddress(V: DieDG.find(Attr: Attr_DW_FORM_addrx3)); |
285 | EXPECT_TRUE(ExtractedAddrx3Value.has_value()); |
286 | EXPECT_EQ(Addrx3Value, *ExtractedAddrx3Value); |
287 | |
288 | auto = toAddress(V: DieDG.find(Attr: Attr_DW_FORM_addrx4)); |
289 | EXPECT_TRUE(ExtractedAddrx1Value.has_value()); |
290 | EXPECT_EQ(Addrx4Value, *ExtractedAddrx4Value); |
291 | } |
292 | |
293 | //---------------------------------------------------------------------- |
294 | // Test block forms |
295 | //---------------------------------------------------------------------- |
296 | std::optional<DWARFFormValue> FormValue; |
297 | ArrayRef<uint8_t> ; |
298 | std::optional<ArrayRef<uint8_t>> BlockDataOpt; |
299 | |
300 | FormValue = DieDG.find(Attr: Attr_DW_FORM_block); |
301 | EXPECT_TRUE((bool)FormValue); |
302 | BlockDataOpt = FormValue->getAsBlock(); |
303 | EXPECT_TRUE(BlockDataOpt.has_value()); |
304 | ExtractedBlockData = *BlockDataOpt; |
305 | EXPECT_EQ(ExtractedBlockData.size(), BlockSize); |
306 | EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0); |
307 | |
308 | FormValue = DieDG.find(Attr: Attr_DW_FORM_block1); |
309 | EXPECT_TRUE((bool)FormValue); |
310 | BlockDataOpt = FormValue->getAsBlock(); |
311 | EXPECT_TRUE(BlockDataOpt.has_value()); |
312 | ExtractedBlockData = *BlockDataOpt; |
313 | EXPECT_EQ(ExtractedBlockData.size(), BlockSize); |
314 | EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0); |
315 | |
316 | FormValue = DieDG.find(Attr: Attr_DW_FORM_block2); |
317 | EXPECT_TRUE((bool)FormValue); |
318 | BlockDataOpt = FormValue->getAsBlock(); |
319 | EXPECT_TRUE(BlockDataOpt.has_value()); |
320 | ExtractedBlockData = *BlockDataOpt; |
321 | EXPECT_EQ(ExtractedBlockData.size(), BlockSize); |
322 | EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0); |
323 | |
324 | FormValue = DieDG.find(Attr: Attr_DW_FORM_block4); |
325 | EXPECT_TRUE((bool)FormValue); |
326 | BlockDataOpt = FormValue->getAsBlock(); |
327 | EXPECT_TRUE(BlockDataOpt.has_value()); |
328 | ExtractedBlockData = *BlockDataOpt; |
329 | EXPECT_EQ(ExtractedBlockData.size(), BlockSize); |
330 | EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0); |
331 | |
332 | // Data16 is handled like a block. |
333 | if (Version >= 5) { |
334 | FormValue = DieDG.find(Attr: Attr_DW_FORM_data16); |
335 | EXPECT_TRUE((bool)FormValue); |
336 | BlockDataOpt = FormValue->getAsBlock(); |
337 | EXPECT_TRUE(BlockDataOpt.has_value()); |
338 | ExtractedBlockData = *BlockDataOpt; |
339 | EXPECT_EQ(ExtractedBlockData.size(), 16u); |
340 | EXPECT_TRUE(memcmp(ExtractedBlockData.data(), Data16, 16) == 0); |
341 | } |
342 | |
343 | //---------------------------------------------------------------------- |
344 | // Test data forms |
345 | //---------------------------------------------------------------------- |
346 | EXPECT_EQ(Data1, toUnsigned(DieDG.find(Attr_DW_FORM_data1), 0)); |
347 | EXPECT_EQ(Data2, toUnsigned(DieDG.find(Attr_DW_FORM_data2), 0)); |
348 | EXPECT_EQ(Data4, toUnsigned(DieDG.find(Attr_DW_FORM_data4), 0)); |
349 | EXPECT_EQ(Data8, toUnsigned(DieDG.find(Attr_DW_FORM_data8), 0)); |
350 | |
351 | //---------------------------------------------------------------------- |
352 | // Test string forms |
353 | //---------------------------------------------------------------------- |
354 | auto = toString(V: DieDG.find(Attr: Attr_DW_FORM_string)); |
355 | EXPECT_TRUE((bool)ExtractedStringValue); |
356 | EXPECT_STREQ(StringValue, *ExtractedStringValue); |
357 | |
358 | if (Version >= 5) { |
359 | auto = toString(V: DieDG.find(Attr: Attr_DW_FORM_strx)); |
360 | EXPECT_TRUE((bool)ExtractedStrxValue); |
361 | EXPECT_STREQ(StrxValue, *ExtractedStrxValue); |
362 | |
363 | auto = toString(V: DieDG.find(Attr: Attr_DW_FORM_strx1)); |
364 | EXPECT_TRUE((bool)ExtractedStrx1Value); |
365 | EXPECT_STREQ(Strx1Value, *ExtractedStrx1Value); |
366 | |
367 | auto = toString(V: DieDG.find(Attr: Attr_DW_FORM_strx2)); |
368 | EXPECT_TRUE((bool)ExtractedStrx2Value); |
369 | EXPECT_STREQ(Strx2Value, *ExtractedStrx2Value); |
370 | |
371 | auto = toString(V: DieDG.find(Attr: Attr_DW_FORM_strx3)); |
372 | EXPECT_TRUE((bool)ExtractedStrx3Value); |
373 | EXPECT_STREQ(Strx3Value, *ExtractedStrx3Value); |
374 | |
375 | auto = toString(V: DieDG.find(Attr: Attr_DW_FORM_strx4)); |
376 | EXPECT_TRUE((bool)ExtractedStrx4Value); |
377 | EXPECT_STREQ(Strx4Value, *ExtractedStrx4Value); |
378 | } |
379 | |
380 | auto = toString(V: DieDG.find(Attr: Attr_DW_FORM_strp)); |
381 | EXPECT_TRUE((bool)ExtractedStrpValue); |
382 | EXPECT_STREQ(StrpValue, *ExtractedStrpValue); |
383 | |
384 | //---------------------------------------------------------------------- |
385 | // Test reference forms |
386 | //---------------------------------------------------------------------- |
387 | EXPECT_EQ(RefAddr, toReference(DieDG.find(Attr_DW_FORM_ref_addr), 0)); |
388 | EXPECT_EQ(Data1, toReference(DieDG.find(Attr_DW_FORM_ref1), 0)); |
389 | EXPECT_EQ(Data2, toReference(DieDG.find(Attr_DW_FORM_ref2), 0)); |
390 | EXPECT_EQ(Data4, toReference(DieDG.find(Attr_DW_FORM_ref4), 0)); |
391 | EXPECT_EQ(Data8, toReference(DieDG.find(Attr_DW_FORM_ref8), 0)); |
392 | if (Version >= 4) { |
393 | EXPECT_EQ(Data8_2, toReference(DieDG.find(Attr_DW_FORM_ref_sig8), 0)); |
394 | } |
395 | EXPECT_EQ(UData[0], toReference(DieDG.find(Attr_DW_FORM_ref_udata), 0)); |
396 | |
397 | //---------------------------------------------------------------------- |
398 | // Test flag forms |
399 | //---------------------------------------------------------------------- |
400 | EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_true), 0)); |
401 | EXPECT_EQ(0ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_false), 1)); |
402 | if (Version >= 4) { |
403 | EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_present), 0)); |
404 | } |
405 | |
406 | //---------------------------------------------------------------------- |
407 | // Test SLEB128 based forms |
408 | //---------------------------------------------------------------------- |
409 | EXPECT_EQ(SData, toSigned(DieDG.find(Attr_DW_FORM_sdata), 0)); |
410 | if (Version >= 5) { |
411 | EXPECT_EQ(ICSData, toSigned(DieDG.find(Attr_DW_FORM_implicit_const), 0)); |
412 | } |
413 | |
414 | //---------------------------------------------------------------------- |
415 | // Test ULEB128 based forms |
416 | //---------------------------------------------------------------------- |
417 | EXPECT_EQ(UData[0], toUnsigned(DieDG.find(Attr_DW_FORM_udata), 0)); |
418 | |
419 | //---------------------------------------------------------------------- |
420 | // Test DWARF32/DWARF64 forms |
421 | //---------------------------------------------------------------------- |
422 | EXPECT_EQ(Dwarf32Values[0], |
423 | toReference(DieDG.find(Attr_DW_FORM_GNU_ref_alt), 0)); |
424 | if (Version >= 4) { |
425 | EXPECT_EQ(Dwarf32Values[1], |
426 | toSectionOffset(DieDG.find(Attr_DW_FORM_sec_offset), 0)); |
427 | } |
428 | |
429 | //---------------------------------------------------------------------- |
430 | // Add an address at the end to make sure we can decode this value |
431 | //---------------------------------------------------------------------- |
432 | EXPECT_EQ(AddrValue, toAddress(DieDG.find(Attr_Last), 0)); |
433 | } |
434 | |
435 | TEST(DWARFDebugInfo, TestDWARF32Version2Addr4AllForms) { |
436 | // Test that we can decode all forms for DWARF32, version 2, with 4 byte |
437 | // addresses. |
438 | typedef uint32_t AddrType; |
439 | // DW_FORM_ref_addr are the same as the address type in DWARF32 version 2. |
440 | typedef AddrType RefAddrType; |
441 | TestAllForms<2, AddrType, RefAddrType>(); |
442 | } |
443 | |
444 | TEST(DWARFDebugInfo, TestDWARF32Version2Addr8AllForms) { |
445 | // Test that we can decode all forms for DWARF32, version 2, with 4 byte |
446 | // addresses. |
447 | typedef uint64_t AddrType; |
448 | // DW_FORM_ref_addr are the same as the address type in DWARF32 version 2. |
449 | typedef AddrType RefAddrType; |
450 | TestAllForms<2, AddrType, RefAddrType>(); |
451 | } |
452 | |
453 | TEST(DWARFDebugInfo, TestDWARF32Version3Addr4AllForms) { |
454 | // Test that we can decode all forms for DWARF32, version 3, with 4 byte |
455 | // addresses. |
456 | typedef uint32_t AddrType; |
457 | // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later. |
458 | typedef uint32_t RefAddrType; |
459 | TestAllForms<3, AddrType, RefAddrType>(); |
460 | } |
461 | |
462 | TEST(DWARFDebugInfo, TestDWARF32Version3Addr8AllForms) { |
463 | // Test that we can decode all forms for DWARF32, version 3, with 8 byte |
464 | // addresses. |
465 | typedef uint64_t AddrType; |
466 | // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later |
467 | typedef uint32_t RefAddrType; |
468 | TestAllForms<3, AddrType, RefAddrType>(); |
469 | } |
470 | |
471 | TEST(DWARFDebugInfo, TestDWARF32Version4Addr4AllForms) { |
472 | // Test that we can decode all forms for DWARF32, version 4, with 4 byte |
473 | // addresses. |
474 | typedef uint32_t AddrType; |
475 | // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later |
476 | typedef uint32_t RefAddrType; |
477 | TestAllForms<4, AddrType, RefAddrType>(); |
478 | } |
479 | |
480 | TEST(DWARFDebugInfo, TestDWARF32Version4Addr8AllForms) { |
481 | // Test that we can decode all forms for DWARF32, version 4, with 8 byte |
482 | // addresses. |
483 | typedef uint64_t AddrType; |
484 | // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later |
485 | typedef uint32_t RefAddrType; |
486 | TestAllForms<4, AddrType, RefAddrType>(); |
487 | } |
488 | |
489 | #ifdef NO_SUPPORT_DEBUG_STR_OFFSETS |
490 | TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version5Addr4AllForms) { |
491 | #else |
492 | TEST(DWARFDebugInfo, TestDWARF32Version5Addr4AllForms) { |
493 | #endif |
494 | // Test that we can decode all forms for DWARF32, version 5, with 4 byte |
495 | // addresses. |
496 | typedef uint32_t AddrType; |
497 | // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later |
498 | typedef uint32_t RefAddrType; |
499 | TestAllForms<5, AddrType, RefAddrType>(); |
500 | } |
501 | |
502 | #ifdef NO_SUPPORT_DEBUG_STR_OFFSETS |
503 | TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version5Addr8AllForms) { |
504 | #else |
505 | TEST(DWARFDebugInfo, TestDWARF32Version5Addr8AllForms) { |
506 | #endif |
507 | // Test that we can decode all forms for DWARF32, version 5, with 8 byte |
508 | // addresses. |
509 | typedef uint64_t AddrType; |
510 | // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later |
511 | typedef uint32_t RefAddrType; |
512 | TestAllForms<5, AddrType, RefAddrType>(); |
513 | } |
514 | |
515 | template <uint16_t Version, class AddrType> void TestChildren() { |
516 | Triple Triple = getDefaultTargetTripleForAddrSize(AddrSize: sizeof(AddrType)); |
517 | if (!isConfigurationSupported(T&: Triple)) |
518 | GTEST_SKIP(); |
519 | |
520 | // Test that we can decode DW_FORM_ref_addr values correctly in DWARF 2 with |
521 | // 4 byte addresses. DW_FORM_ref_addr values should be 4 bytes when using |
522 | // 8 byte addresses. |
523 | |
524 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
525 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
526 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
527 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
528 | dwarfgen::DIE CUDie = CU.getUnitDIE(); |
529 | |
530 | CUDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "/tmp/main.c" ); |
531 | CUDie.addAttribute(Attr: DW_AT_language, Form: DW_FORM_data2, U: DW_LANG_C); |
532 | |
533 | dwarfgen::DIE SubprogramDie = CUDie.addChild(Tag: DW_TAG_subprogram); |
534 | SubprogramDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "main" ); |
535 | SubprogramDie.addAttribute(Attr: DW_AT_low_pc, Form: DW_FORM_addr, U: 0x1000U); |
536 | SubprogramDie.addAttribute(Attr: DW_AT_high_pc, Form: DW_FORM_addr, U: 0x2000U); |
537 | |
538 | dwarfgen::DIE IntDie = CUDie.addChild(Tag: DW_TAG_base_type); |
539 | IntDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "int" ); |
540 | IntDie.addAttribute(Attr: DW_AT_encoding, Form: DW_FORM_data1, U: DW_ATE_signed); |
541 | IntDie.addAttribute(Attr: DW_AT_byte_size, Form: DW_FORM_data1, U: 4); |
542 | |
543 | dwarfgen::DIE ArgcDie = SubprogramDie.addChild(Tag: DW_TAG_formal_parameter); |
544 | ArgcDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "argc" ); |
545 | // ArgcDie.addAttribute(DW_AT_type, DW_FORM_ref4, IntDie); |
546 | ArgcDie.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref_addr, RefDie&: IntDie); |
547 | |
548 | StringRef FileBytes = DG->generate(); |
549 | MemoryBufferRef FileBuffer(FileBytes, "dwarf" ); |
550 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
551 | EXPECT_TRUE((bool)Obj); |
552 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
553 | |
554 | // Verify the number of compile units is correct. |
555 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
556 | EXPECT_EQ(NumCUs, 1u); |
557 | DWARFCompileUnit *U = |
558 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
559 | |
560 | // Get the compile unit DIE is valid. |
561 | auto DieDG = U->getUnitDIE(ExtractUnitDIEOnly: false); |
562 | EXPECT_TRUE(DieDG.isValid()); |
563 | |
564 | // Verify the first child of the compile unit DIE is our subprogram. |
565 | auto SubprogramDieDG = DieDG.getFirstChild(); |
566 | EXPECT_TRUE(SubprogramDieDG.isValid()); |
567 | EXPECT_EQ(SubprogramDieDG.getTag(), DW_TAG_subprogram); |
568 | |
569 | // Verify the first child of the subprogram is our formal parameter. |
570 | auto ArgcDieDG = SubprogramDieDG.getFirstChild(); |
571 | EXPECT_TRUE(ArgcDieDG.isValid()); |
572 | EXPECT_EQ(ArgcDieDG.getTag(), DW_TAG_formal_parameter); |
573 | |
574 | // Verify our formal parameter has a NULL tag sibling. |
575 | auto NullDieDG = ArgcDieDG.getSibling(); |
576 | EXPECT_TRUE(NullDieDG.isValid()); |
577 | if (NullDieDG) { |
578 | EXPECT_EQ(NullDieDG.getTag(), DW_TAG_null); |
579 | EXPECT_TRUE(!NullDieDG.getSibling().isValid()); |
580 | EXPECT_TRUE(!NullDieDG.getFirstChild().isValid()); |
581 | } |
582 | |
583 | // Verify the sibling of our subprogram is our integer base type. |
584 | auto IntDieDG = SubprogramDieDG.getSibling(); |
585 | EXPECT_TRUE(IntDieDG.isValid()); |
586 | EXPECT_EQ(IntDieDG.getTag(), DW_TAG_base_type); |
587 | |
588 | // Verify the sibling of our subprogram is our integer base is a NULL tag. |
589 | NullDieDG = IntDieDG.getSibling(); |
590 | EXPECT_TRUE(NullDieDG.isValid()); |
591 | if (NullDieDG) { |
592 | EXPECT_EQ(NullDieDG.getTag(), DW_TAG_null); |
593 | EXPECT_TRUE(!NullDieDG.getSibling().isValid()); |
594 | EXPECT_TRUE(!NullDieDG.getFirstChild().isValid()); |
595 | } |
596 | |
597 | // Verify the previous sibling of our subprogram is our integer base type. |
598 | IntDieDG = NullDieDG.getPreviousSibling(); |
599 | EXPECT_TRUE(IntDieDG.isValid()); |
600 | EXPECT_EQ(IntDieDG.getTag(), DW_TAG_base_type); |
601 | } |
602 | |
603 | TEST(DWARFDebugInfo, TestDWARF32Version2Addr4Children) { |
604 | // Test that we can decode all forms for DWARF32, version 2, with 4 byte |
605 | // addresses. |
606 | typedef uint32_t AddrType; |
607 | TestChildren<2, AddrType>(); |
608 | } |
609 | |
610 | TEST(DWARFDebugInfo, TestDWARF32Version2Addr8Children) { |
611 | // Test that we can decode all forms for DWARF32, version 2, with 8 byte |
612 | // addresses. |
613 | typedef uint64_t AddrType; |
614 | TestChildren<2, AddrType>(); |
615 | } |
616 | |
617 | TEST(DWARFDebugInfo, TestDWARF32Version3Addr4Children) { |
618 | // Test that we can decode all forms for DWARF32, version 3, with 4 byte |
619 | // addresses. |
620 | typedef uint32_t AddrType; |
621 | TestChildren<3, AddrType>(); |
622 | } |
623 | |
624 | TEST(DWARFDebugInfo, TestDWARF32Version3Addr8Children) { |
625 | // Test that we can decode all forms for DWARF32, version 3, with 8 byte |
626 | // addresses. |
627 | typedef uint64_t AddrType; |
628 | TestChildren<3, AddrType>(); |
629 | } |
630 | |
631 | TEST(DWARFDebugInfo, TestDWARF32Version4Addr4Children) { |
632 | // Test that we can decode all forms for DWARF32, version 4, with 4 byte |
633 | // addresses. |
634 | typedef uint32_t AddrType; |
635 | TestChildren<4, AddrType>(); |
636 | } |
637 | |
638 | TEST(DWARFDebugInfo, TestDWARF32Version4Addr8Children) { |
639 | // Test that we can decode all forms for DWARF32, version 4, with 8 byte |
640 | // addresses. |
641 | typedef uint64_t AddrType; |
642 | TestChildren<4, AddrType>(); |
643 | } |
644 | |
645 | template <uint16_t Version, class AddrType> void TestReferences() { |
646 | Triple Triple = getDefaultTargetTripleForAddrSize(AddrSize: sizeof(AddrType)); |
647 | if (!isConfigurationSupported(T&: Triple)) |
648 | GTEST_SKIP(); |
649 | |
650 | // Test that we can decode DW_FORM_refXXX values correctly in DWARF. |
651 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
652 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
653 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
654 | dwarfgen::CompileUnit &CU1 = DG->addCompileUnit(); |
655 | dwarfgen::CompileUnit &CU2 = DG->addCompileUnit(); |
656 | |
657 | dwarfgen::DIE CU1Die = CU1.getUnitDIE(); |
658 | CU1Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "/tmp/main.c" ); |
659 | CU1Die.addAttribute(Attr: DW_AT_language, Form: DW_FORM_data2, U: DW_LANG_C); |
660 | |
661 | dwarfgen::DIE CU1TypeDie = CU1Die.addChild(Tag: DW_TAG_base_type); |
662 | CU1TypeDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "int" ); |
663 | CU1TypeDie.addAttribute(Attr: DW_AT_encoding, Form: DW_FORM_data1, U: DW_ATE_signed); |
664 | CU1TypeDie.addAttribute(Attr: DW_AT_byte_size, Form: DW_FORM_data1, U: 4); |
665 | |
666 | dwarfgen::DIE CU1Ref1Die = CU1Die.addChild(Tag: DW_TAG_variable); |
667 | CU1Ref1Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU1Ref1" ); |
668 | CU1Ref1Die.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref1, RefDie&: CU1TypeDie); |
669 | |
670 | dwarfgen::DIE CU1Ref2Die = CU1Die.addChild(Tag: DW_TAG_variable); |
671 | CU1Ref2Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU1Ref2" ); |
672 | CU1Ref2Die.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref2, RefDie&: CU1TypeDie); |
673 | |
674 | dwarfgen::DIE CU1Ref4Die = CU1Die.addChild(Tag: DW_TAG_variable); |
675 | CU1Ref4Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU1Ref4" ); |
676 | CU1Ref4Die.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref4, RefDie&: CU1TypeDie); |
677 | |
678 | dwarfgen::DIE CU1Ref8Die = CU1Die.addChild(Tag: DW_TAG_variable); |
679 | CU1Ref8Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU1Ref8" ); |
680 | CU1Ref8Die.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref8, RefDie&: CU1TypeDie); |
681 | |
682 | dwarfgen::DIE CU1RefAddrDie = CU1Die.addChild(Tag: DW_TAG_variable); |
683 | CU1RefAddrDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU1RefAddr" ); |
684 | CU1RefAddrDie.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref_addr, RefDie&: CU1TypeDie); |
685 | |
686 | dwarfgen::DIE CU2Die = CU2.getUnitDIE(); |
687 | CU2Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "/tmp/foo.c" ); |
688 | CU2Die.addAttribute(Attr: DW_AT_language, Form: DW_FORM_data2, U: DW_LANG_C); |
689 | |
690 | dwarfgen::DIE CU2TypeDie = CU2Die.addChild(Tag: DW_TAG_base_type); |
691 | CU2TypeDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "float" ); |
692 | CU2TypeDie.addAttribute(Attr: DW_AT_encoding, Form: DW_FORM_data1, U: DW_ATE_float); |
693 | CU2TypeDie.addAttribute(Attr: DW_AT_byte_size, Form: DW_FORM_data1, U: 4); |
694 | |
695 | dwarfgen::DIE CU2Ref1Die = CU2Die.addChild(Tag: DW_TAG_variable); |
696 | CU2Ref1Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU2Ref1" ); |
697 | CU2Ref1Die.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref1, RefDie&: CU2TypeDie); |
698 | |
699 | dwarfgen::DIE CU2Ref2Die = CU2Die.addChild(Tag: DW_TAG_variable); |
700 | CU2Ref2Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU2Ref2" ); |
701 | CU2Ref2Die.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref2, RefDie&: CU2TypeDie); |
702 | |
703 | dwarfgen::DIE CU2Ref4Die = CU2Die.addChild(Tag: DW_TAG_variable); |
704 | CU2Ref4Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU2Ref4" ); |
705 | CU2Ref4Die.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref4, RefDie&: CU2TypeDie); |
706 | |
707 | dwarfgen::DIE CU2Ref8Die = CU2Die.addChild(Tag: DW_TAG_variable); |
708 | CU2Ref8Die.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU2Ref8" ); |
709 | CU2Ref8Die.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref8, RefDie&: CU2TypeDie); |
710 | |
711 | dwarfgen::DIE CU2RefAddrDie = CU2Die.addChild(Tag: DW_TAG_variable); |
712 | CU2RefAddrDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU2RefAddr" ); |
713 | CU2RefAddrDie.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref_addr, RefDie&: CU2TypeDie); |
714 | |
715 | // Refer to a type in CU1 from CU2 |
716 | dwarfgen::DIE CU2ToCU1RefAddrDie = CU2Die.addChild(Tag: DW_TAG_variable); |
717 | CU2ToCU1RefAddrDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU2ToCU1RefAddr" ); |
718 | CU2ToCU1RefAddrDie.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref_addr, RefDie&: CU1TypeDie); |
719 | |
720 | // Refer to a type in CU2 from CU1 |
721 | dwarfgen::DIE CU1ToCU2RefAddrDie = CU1Die.addChild(Tag: DW_TAG_variable); |
722 | CU1ToCU2RefAddrDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "CU1ToCU2RefAddr" ); |
723 | CU1ToCU2RefAddrDie.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref_addr, RefDie&: CU2TypeDie); |
724 | |
725 | StringRef FileBytes = DG->generate(); |
726 | MemoryBufferRef FileBuffer(FileBytes, "dwarf" ); |
727 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
728 | EXPECT_TRUE((bool)Obj); |
729 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
730 | |
731 | // Verify the number of compile units is correct. |
732 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
733 | EXPECT_EQ(NumCUs, 2u); |
734 | DWARFCompileUnit *U1 = |
735 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
736 | DWARFCompileUnit *U2 = |
737 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 1)); |
738 | |
739 | // Get the compile unit DIE is valid. |
740 | auto Unit1DieDG = U1->getUnitDIE(ExtractUnitDIEOnly: false); |
741 | EXPECT_TRUE(Unit1DieDG.isValid()); |
742 | |
743 | auto Unit2DieDG = U2->getUnitDIE(ExtractUnitDIEOnly: false); |
744 | EXPECT_TRUE(Unit2DieDG.isValid()); |
745 | |
746 | // Verify the first child of the compile unit 1 DIE is our int base type. |
747 | auto CU1TypeDieDG = Unit1DieDG.getFirstChild(); |
748 | EXPECT_TRUE(CU1TypeDieDG.isValid()); |
749 | EXPECT_EQ(CU1TypeDieDG.getTag(), DW_TAG_base_type); |
750 | EXPECT_EQ(DW_ATE_signed, toUnsigned(CU1TypeDieDG.find(DW_AT_encoding), 0)); |
751 | |
752 | // Verify the first child of the compile unit 2 DIE is our float base type. |
753 | auto CU2TypeDieDG = Unit2DieDG.getFirstChild(); |
754 | EXPECT_TRUE(CU2TypeDieDG.isValid()); |
755 | EXPECT_EQ(CU2TypeDieDG.getTag(), DW_TAG_base_type); |
756 | EXPECT_EQ(DW_ATE_float, toUnsigned(CU2TypeDieDG.find(DW_AT_encoding), 0)); |
757 | |
758 | // Verify the sibling of the base type DIE is our Ref1 DIE and that its |
759 | // DW_AT_type points to our base type DIE. |
760 | auto CU1Ref1DieDG = CU1TypeDieDG.getSibling(); |
761 | EXPECT_TRUE(CU1Ref1DieDG.isValid()); |
762 | EXPECT_EQ(CU1Ref1DieDG.getTag(), DW_TAG_variable); |
763 | EXPECT_EQ(CU1TypeDieDG.getOffset(), |
764 | toReference(CU1Ref1DieDG.find(DW_AT_type), -1ULL)); |
765 | // Verify the sibling is our Ref2 DIE and that its DW_AT_type points to our |
766 | // base type DIE in CU1. |
767 | auto CU1Ref2DieDG = CU1Ref1DieDG.getSibling(); |
768 | EXPECT_TRUE(CU1Ref2DieDG.isValid()); |
769 | EXPECT_EQ(CU1Ref2DieDG.getTag(), DW_TAG_variable); |
770 | EXPECT_EQ(CU1TypeDieDG.getOffset(), |
771 | toReference(CU1Ref2DieDG.find(DW_AT_type), -1ULL)); |
772 | |
773 | // Verify the sibling is our Ref4 DIE and that its DW_AT_type points to our |
774 | // base type DIE in CU1. |
775 | auto CU1Ref4DieDG = CU1Ref2DieDG.getSibling(); |
776 | EXPECT_TRUE(CU1Ref4DieDG.isValid()); |
777 | EXPECT_EQ(CU1Ref4DieDG.getTag(), DW_TAG_variable); |
778 | EXPECT_EQ(CU1TypeDieDG.getOffset(), |
779 | toReference(CU1Ref4DieDG.find(DW_AT_type), -1ULL)); |
780 | |
781 | // Verify the sibling is our Ref8 DIE and that its DW_AT_type points to our |
782 | // base type DIE in CU1. |
783 | auto CU1Ref8DieDG = CU1Ref4DieDG.getSibling(); |
784 | EXPECT_TRUE(CU1Ref8DieDG.isValid()); |
785 | EXPECT_EQ(CU1Ref8DieDG.getTag(), DW_TAG_variable); |
786 | EXPECT_EQ(CU1TypeDieDG.getOffset(), |
787 | toReference(CU1Ref8DieDG.find(DW_AT_type), -1ULL)); |
788 | |
789 | // Verify the sibling is our RefAddr DIE and that its DW_AT_type points to our |
790 | // base type DIE in CU1. |
791 | auto CU1RefAddrDieDG = CU1Ref8DieDG.getSibling(); |
792 | EXPECT_TRUE(CU1RefAddrDieDG.isValid()); |
793 | EXPECT_EQ(CU1RefAddrDieDG.getTag(), DW_TAG_variable); |
794 | EXPECT_EQ(CU1TypeDieDG.getOffset(), |
795 | toReference(CU1RefAddrDieDG.find(DW_AT_type), -1ULL)); |
796 | |
797 | // Verify the sibling of the Ref4 DIE is our RefAddr DIE and that its |
798 | // DW_AT_type points to our base type DIE. |
799 | auto CU1ToCU2RefAddrDieDG = CU1RefAddrDieDG.getSibling(); |
800 | EXPECT_TRUE(CU1ToCU2RefAddrDieDG.isValid()); |
801 | EXPECT_EQ(CU1ToCU2RefAddrDieDG.getTag(), DW_TAG_variable); |
802 | EXPECT_EQ(CU2TypeDieDG.getOffset(), |
803 | toReference(CU1ToCU2RefAddrDieDG.find(DW_AT_type), -1ULL)); |
804 | |
805 | // Verify the sibling of the base type DIE is our Ref1 DIE and that its |
806 | // DW_AT_type points to our base type DIE. |
807 | auto CU2Ref1DieDG = CU2TypeDieDG.getSibling(); |
808 | EXPECT_TRUE(CU2Ref1DieDG.isValid()); |
809 | EXPECT_EQ(CU2Ref1DieDG.getTag(), DW_TAG_variable); |
810 | EXPECT_EQ(CU2TypeDieDG.getOffset(), |
811 | toReference(CU2Ref1DieDG.find(DW_AT_type), -1ULL)); |
812 | // Verify the sibling is our Ref2 DIE and that its DW_AT_type points to our |
813 | // base type DIE in CU2. |
814 | auto CU2Ref2DieDG = CU2Ref1DieDG.getSibling(); |
815 | EXPECT_TRUE(CU2Ref2DieDG.isValid()); |
816 | EXPECT_EQ(CU2Ref2DieDG.getTag(), DW_TAG_variable); |
817 | EXPECT_EQ(CU2TypeDieDG.getOffset(), |
818 | toReference(CU2Ref2DieDG.find(DW_AT_type), -1ULL)); |
819 | |
820 | // Verify the sibling is our Ref4 DIE and that its DW_AT_type points to our |
821 | // base type DIE in CU2. |
822 | auto CU2Ref4DieDG = CU2Ref2DieDG.getSibling(); |
823 | EXPECT_TRUE(CU2Ref4DieDG.isValid()); |
824 | EXPECT_EQ(CU2Ref4DieDG.getTag(), DW_TAG_variable); |
825 | EXPECT_EQ(CU2TypeDieDG.getOffset(), |
826 | toReference(CU2Ref4DieDG.find(DW_AT_type), -1ULL)); |
827 | |
828 | // Verify the sibling is our Ref8 DIE and that its DW_AT_type points to our |
829 | // base type DIE in CU2. |
830 | auto CU2Ref8DieDG = CU2Ref4DieDG.getSibling(); |
831 | EXPECT_TRUE(CU2Ref8DieDG.isValid()); |
832 | EXPECT_EQ(CU2Ref8DieDG.getTag(), DW_TAG_variable); |
833 | EXPECT_EQ(CU2TypeDieDG.getOffset(), |
834 | toReference(CU2Ref8DieDG.find(DW_AT_type), -1ULL)); |
835 | |
836 | // Verify the sibling is our RefAddr DIE and that its DW_AT_type points to our |
837 | // base type DIE in CU2. |
838 | auto CU2RefAddrDieDG = CU2Ref8DieDG.getSibling(); |
839 | EXPECT_TRUE(CU2RefAddrDieDG.isValid()); |
840 | EXPECT_EQ(CU2RefAddrDieDG.getTag(), DW_TAG_variable); |
841 | EXPECT_EQ(CU2TypeDieDG.getOffset(), |
842 | toReference(CU2RefAddrDieDG.find(DW_AT_type), -1ULL)); |
843 | |
844 | // Verify the sibling of the Ref4 DIE is our RefAddr DIE and that its |
845 | // DW_AT_type points to our base type DIE. |
846 | auto CU2ToCU1RefAddrDieDG = CU2RefAddrDieDG.getSibling(); |
847 | EXPECT_TRUE(CU2ToCU1RefAddrDieDG.isValid()); |
848 | EXPECT_EQ(CU2ToCU1RefAddrDieDG.getTag(), DW_TAG_variable); |
849 | EXPECT_EQ(CU1TypeDieDG.getOffset(), |
850 | toReference(CU2ToCU1RefAddrDieDG.find(DW_AT_type), -1ULL)); |
851 | } |
852 | |
853 | TEST(DWARFDebugInfo, TestDWARF32Version2Addr4References) { |
854 | // Test that we can decode all forms for DWARF32, version 2, with 4 byte |
855 | // addresses. |
856 | typedef uint32_t AddrType; |
857 | TestReferences<2, AddrType>(); |
858 | } |
859 | |
860 | TEST(DWARFDebugInfo, TestDWARF32Version2Addr8References) { |
861 | // Test that we can decode all forms for DWARF32, version 2, with 8 byte |
862 | // addresses. |
863 | typedef uint64_t AddrType; |
864 | TestReferences<2, AddrType>(); |
865 | } |
866 | |
867 | TEST(DWARFDebugInfo, TestDWARF32Version3Addr4References) { |
868 | // Test that we can decode all forms for DWARF32, version 3, with 4 byte |
869 | // addresses. |
870 | typedef uint32_t AddrType; |
871 | TestReferences<3, AddrType>(); |
872 | } |
873 | |
874 | TEST(DWARFDebugInfo, TestDWARF32Version3Addr8References) { |
875 | // Test that we can decode all forms for DWARF32, version 3, with 8 byte |
876 | // addresses. |
877 | typedef uint64_t AddrType; |
878 | TestReferences<3, AddrType>(); |
879 | } |
880 | |
881 | TEST(DWARFDebugInfo, TestDWARF32Version4Addr4References) { |
882 | // Test that we can decode all forms for DWARF32, version 4, with 4 byte |
883 | // addresses. |
884 | typedef uint32_t AddrType; |
885 | TestReferences<4, AddrType>(); |
886 | } |
887 | |
888 | TEST(DWARFDebugInfo, TestDWARF32Version4Addr8References) { |
889 | // Test that we can decode all forms for DWARF32, version 4, with 8 byte |
890 | // addresses. |
891 | typedef uint64_t AddrType; |
892 | TestReferences<4, AddrType>(); |
893 | } |
894 | |
895 | template <uint16_t Version, class AddrType> void TestAddresses() { |
896 | Triple Triple = getDefaultTargetTripleForAddrSize(AddrSize: sizeof(AddrType)); |
897 | if (!isConfigurationSupported(T&: Triple)) |
898 | GTEST_SKIP(); |
899 | |
900 | // Test the DWARF APIs related to accessing the DW_AT_low_pc and |
901 | // DW_AT_high_pc. |
902 | const bool SupportsHighPCAsOffset = Version >= 4; |
903 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
904 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
905 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
906 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
907 | dwarfgen::DIE CUDie = CU.getUnitDIE(); |
908 | |
909 | CUDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "/tmp/main.c" ); |
910 | CUDie.addAttribute(Attr: DW_AT_language, Form: DW_FORM_data2, U: DW_LANG_C); |
911 | |
912 | // Create a subprogram DIE with no low or high PC. |
913 | dwarfgen::DIE SubprogramNoPC = CUDie.addChild(Tag: DW_TAG_subprogram); |
914 | SubprogramNoPC.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "no_pc" ); |
915 | |
916 | // Create a subprogram DIE with a low PC only. |
917 | dwarfgen::DIE SubprogramLowPC = CUDie.addChild(Tag: DW_TAG_subprogram); |
918 | SubprogramLowPC.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "low_pc" ); |
919 | const uint64_t ActualLowPC = 0x1000; |
920 | const uint64_t ActualHighPC = 0x2000; |
921 | const uint64_t ActualHighPCOffset = ActualHighPC - ActualLowPC; |
922 | SubprogramLowPC.addAttribute(Attr: DW_AT_low_pc, Form: DW_FORM_addr, U: ActualLowPC); |
923 | |
924 | // Create a subprogram DIE with a low and high PC. |
925 | dwarfgen::DIE SubprogramLowHighPC = CUDie.addChild(Tag: DW_TAG_subprogram); |
926 | SubprogramLowHighPC.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "low_high_pc" ); |
927 | SubprogramLowHighPC.addAttribute(Attr: DW_AT_low_pc, Form: DW_FORM_addr, U: ActualLowPC); |
928 | // Encode the high PC as an offset from the low PC if supported. |
929 | if (SupportsHighPCAsOffset) |
930 | SubprogramLowHighPC.addAttribute(Attr: DW_AT_high_pc, Form: DW_FORM_data4, |
931 | U: ActualHighPCOffset); |
932 | else |
933 | SubprogramLowHighPC.addAttribute(Attr: DW_AT_high_pc, Form: DW_FORM_addr, U: ActualHighPC); |
934 | |
935 | StringRef FileBytes = DG->generate(); |
936 | MemoryBufferRef FileBuffer(FileBytes, "dwarf" ); |
937 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
938 | EXPECT_TRUE((bool)Obj); |
939 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
940 | |
941 | // Verify the number of compile units is correct. |
942 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
943 | EXPECT_EQ(NumCUs, 1u); |
944 | DWARFCompileUnit *U = |
945 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
946 | |
947 | // Get the compile unit DIE is valid. |
948 | auto DieDG = U->getUnitDIE(ExtractUnitDIEOnly: false); |
949 | EXPECT_TRUE(DieDG.isValid()); |
950 | |
951 | uint64_t LowPC, HighPC, SectionIndex; |
952 | std::optional<uint64_t> OptU64; |
953 | // Verify the that our subprogram with no PC value fails appropriately when |
954 | // asked for any PC values. |
955 | auto SubprogramDieNoPC = DieDG.getFirstChild(); |
956 | EXPECT_TRUE(SubprogramDieNoPC.isValid()); |
957 | EXPECT_EQ(SubprogramDieNoPC.getTag(), DW_TAG_subprogram); |
958 | OptU64 = toAddress(V: SubprogramDieNoPC.find(Attr: DW_AT_low_pc)); |
959 | EXPECT_FALSE((bool)OptU64); |
960 | OptU64 = toAddress(V: SubprogramDieNoPC.find(Attr: DW_AT_high_pc)); |
961 | EXPECT_FALSE((bool)OptU64); |
962 | EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC, SectionIndex)); |
963 | OptU64 = toAddress(V: SubprogramDieNoPC.find(Attr: DW_AT_high_pc)); |
964 | EXPECT_FALSE((bool)OptU64); |
965 | OptU64 = toUnsigned(V: SubprogramDieNoPC.find(Attr: DW_AT_high_pc)); |
966 | EXPECT_FALSE((bool)OptU64); |
967 | OptU64 = SubprogramDieNoPC.getHighPC(LowPC: ActualLowPC); |
968 | EXPECT_FALSE((bool)OptU64); |
969 | EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC, SectionIndex)); |
970 | |
971 | // Verify the that our subprogram with only a low PC value succeeds when |
972 | // we ask for the Low PC, but fails appropriately when asked for the high PC |
973 | // or both low and high PC values. |
974 | auto SubprogramDieLowPC = SubprogramDieNoPC.getSibling(); |
975 | EXPECT_TRUE(SubprogramDieLowPC.isValid()); |
976 | EXPECT_EQ(SubprogramDieLowPC.getTag(), DW_TAG_subprogram); |
977 | OptU64 = toAddress(V: SubprogramDieLowPC.find(Attr: DW_AT_low_pc)); |
978 | EXPECT_TRUE((bool)OptU64); |
979 | EXPECT_EQ(*OptU64, ActualLowPC); |
980 | OptU64 = toAddress(V: SubprogramDieLowPC.find(Attr: DW_AT_high_pc)); |
981 | EXPECT_FALSE((bool)OptU64); |
982 | OptU64 = toUnsigned(V: SubprogramDieLowPC.find(Attr: DW_AT_high_pc)); |
983 | EXPECT_FALSE((bool)OptU64); |
984 | OptU64 = SubprogramDieLowPC.getHighPC(LowPC: ActualLowPC); |
985 | EXPECT_FALSE((bool)OptU64); |
986 | EXPECT_FALSE(SubprogramDieLowPC.getLowAndHighPC(LowPC, HighPC, SectionIndex)); |
987 | |
988 | // Verify the that our subprogram with only a low PC value succeeds when |
989 | // we ask for the Low PC, but fails appropriately when asked for the high PC |
990 | // or both low and high PC values. |
991 | auto SubprogramDieLowHighPC = SubprogramDieLowPC.getSibling(); |
992 | EXPECT_TRUE(SubprogramDieLowHighPC.isValid()); |
993 | EXPECT_EQ(SubprogramDieLowHighPC.getTag(), DW_TAG_subprogram); |
994 | OptU64 = toAddress(V: SubprogramDieLowHighPC.find(Attr: DW_AT_low_pc)); |
995 | EXPECT_TRUE((bool)OptU64); |
996 | EXPECT_EQ(*OptU64, ActualLowPC); |
997 | // Get the high PC as an address. This should succeed if the high PC was |
998 | // encoded as an address and fail if the high PC was encoded as an offset. |
999 | OptU64 = toAddress(V: SubprogramDieLowHighPC.find(Attr: DW_AT_high_pc)); |
1000 | if (SupportsHighPCAsOffset) { |
1001 | EXPECT_FALSE((bool)OptU64); |
1002 | } else { |
1003 | EXPECT_TRUE((bool)OptU64); |
1004 | EXPECT_EQ(*OptU64, ActualHighPC); |
1005 | } |
1006 | // Get the high PC as an unsigned constant. This should succeed if the high PC |
1007 | // was encoded as an offset and fail if the high PC was encoded as an address. |
1008 | OptU64 = toUnsigned(V: SubprogramDieLowHighPC.find(Attr: DW_AT_high_pc)); |
1009 | if (SupportsHighPCAsOffset) { |
1010 | EXPECT_TRUE((bool)OptU64); |
1011 | EXPECT_EQ(*OptU64, ActualHighPCOffset); |
1012 | } else { |
1013 | EXPECT_FALSE((bool)OptU64); |
1014 | } |
1015 | |
1016 | OptU64 = SubprogramDieLowHighPC.getHighPC(LowPC: ActualLowPC); |
1017 | EXPECT_TRUE((bool)OptU64); |
1018 | EXPECT_EQ(*OptU64, ActualHighPC); |
1019 | |
1020 | EXPECT_TRUE(SubprogramDieLowHighPC.getLowAndHighPC(LowPC, HighPC, SectionIndex)); |
1021 | EXPECT_EQ(LowPC, ActualLowPC); |
1022 | EXPECT_EQ(HighPC, ActualHighPC); |
1023 | } |
1024 | |
1025 | TEST(DWARFDebugInfo, TestDWARF32Version2Addr4Addresses) { |
1026 | // Test that we can decode address values in DWARF32, version 2, with 4 byte |
1027 | // addresses. |
1028 | typedef uint32_t AddrType; |
1029 | TestAddresses<2, AddrType>(); |
1030 | } |
1031 | |
1032 | TEST(DWARFDebugInfo, TestDWARF32Version2Addr8Addresses) { |
1033 | // Test that we can decode address values in DWARF32, version 2, with 8 byte |
1034 | // addresses. |
1035 | typedef uint64_t AddrType; |
1036 | TestAddresses<2, AddrType>(); |
1037 | } |
1038 | |
1039 | TEST(DWARFDebugInfo, TestDWARF32Version3Addr4Addresses) { |
1040 | // Test that we can decode address values in DWARF32, version 3, with 4 byte |
1041 | // addresses. |
1042 | typedef uint32_t AddrType; |
1043 | TestAddresses<3, AddrType>(); |
1044 | } |
1045 | |
1046 | TEST(DWARFDebugInfo, TestDWARF32Version3Addr8Addresses) { |
1047 | // Test that we can decode address values in DWARF32, version 3, with 8 byte |
1048 | // addresses. |
1049 | typedef uint64_t AddrType; |
1050 | TestAddresses<3, AddrType>(); |
1051 | } |
1052 | |
1053 | TEST(DWARFDebugInfo, TestDWARF32Version4Addr4Addresses) { |
1054 | // Test that we can decode address values in DWARF32, version 4, with 4 byte |
1055 | // addresses. |
1056 | typedef uint32_t AddrType; |
1057 | TestAddresses<4, AddrType>(); |
1058 | } |
1059 | |
1060 | TEST(DWARFDebugInfo, TestDWARF32Version4Addr8Addresses) { |
1061 | // Test that we can decode address values in DWARF32, version 4, with 8 byte |
1062 | // addresses. |
1063 | typedef uint64_t AddrType; |
1064 | TestAddresses<4, AddrType>(); |
1065 | } |
1066 | |
1067 | #ifdef NO_SUPPORT_DEBUG_STR_OFFSETS |
1068 | TEST(DWARFDebugInfo, DISABLED_TestStringOffsets) { |
1069 | #else |
1070 | TEST(DWARFDebugInfo, TestStringOffsets) { |
1071 | #endif |
1072 | Triple Triple = getNormalizedDefaultTargetTriple(); |
1073 | if (!isConfigurationSupported(T&: Triple)) |
1074 | GTEST_SKIP(); |
1075 | |
1076 | const char *String1 = "Hello" ; |
1077 | const char *String2 = "World" ; |
1078 | |
1079 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: 5); |
1080 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1081 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1082 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1083 | dwarfgen::DIE CUDie = CU.getUnitDIE(); |
1084 | |
1085 | CUDie.addStrOffsetsBaseAttribute(); |
1086 | |
1087 | uint16_t Attr = DW_AT_lo_user; |
1088 | |
1089 | // Create our strings. First we create a non-indexed reference to String1, |
1090 | // followed by an indexed String2. Finally, we add an indexed reference to |
1091 | // String1. |
1092 | const auto Attr1 = static_cast<dwarf::Attribute>(Attr++); |
1093 | CUDie.addAttribute(Attr: Attr1, Form: DW_FORM_strp, String: String1); |
1094 | |
1095 | const auto Attr2 = static_cast<dwarf::Attribute>(Attr++); |
1096 | CUDie.addAttribute(Attr: Attr2, Form: DW_FORM_strx, String: String2); |
1097 | |
1098 | const auto Attr3 = static_cast<dwarf::Attribute>(Attr++); |
1099 | CUDie.addAttribute(Attr: Attr3, Form: DW_FORM_strx, String: String1); |
1100 | |
1101 | // Generate the DWARF |
1102 | StringRef FileBytes = DG->generate(); |
1103 | MemoryBufferRef FileBuffer(FileBytes, "dwarf" ); |
1104 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1105 | ASSERT_TRUE((bool)Obj); |
1106 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1107 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
1108 | ASSERT_EQ(NumCUs, 1u); |
1109 | DWARFUnit *U = DwarfContext->getUnitAtIndex(index: 0); |
1110 | auto DieDG = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1111 | ASSERT_TRUE(DieDG.isValid()); |
1112 | ASSERT_TRUE(U->isLittleEndian() == Triple.isLittleEndian()); |
1113 | |
1114 | // Now make sure the string offsets came out properly. Attr2 should have index |
1115 | // 0 (because it was the first indexed string) even though the string itself |
1116 | // was added eariler. |
1117 | auto = toString(V: DieDG.find(Attr: Attr1)); |
1118 | ASSERT_TRUE((bool)Extracted1); |
1119 | EXPECT_STREQ(String1, *Extracted1); |
1120 | |
1121 | std::optional<DWARFFormValue> Form2 = DieDG.find(Attr: Attr2); |
1122 | ASSERT_TRUE((bool)Form2); |
1123 | EXPECT_EQ(0u, Form2->getRawUValue()); |
1124 | auto = toString(V: Form2); |
1125 | ASSERT_TRUE((bool)Extracted2); |
1126 | EXPECT_STREQ(String2, *Extracted2); |
1127 | |
1128 | std::optional<DWARFFormValue> Form3 = DieDG.find(Attr: Attr3); |
1129 | ASSERT_TRUE((bool)Form3); |
1130 | EXPECT_EQ(1u, Form3->getRawUValue()); |
1131 | auto = toString(V: Form3); |
1132 | ASSERT_TRUE((bool)Extracted3); |
1133 | EXPECT_STREQ(String1, *Extracted3); |
1134 | } |
1135 | |
1136 | #ifdef NO_SUPPORT_DEBUG_ADDR |
1137 | TEST(DWARFDebugInfo, DISABLED_TestEmptyStringOffsets) { |
1138 | #else |
1139 | TEST(DWARFDebugInfo, TestEmptyStringOffsets) { |
1140 | #endif |
1141 | |
1142 | Triple Triple = getNormalizedDefaultTargetTriple(); |
1143 | if (!isConfigurationSupported(T&: Triple)) |
1144 | GTEST_SKIP(); |
1145 | |
1146 | const char *String1 = "Hello" ; |
1147 | |
1148 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: 5); |
1149 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1150 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1151 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1152 | dwarfgen::DIE CUDie = CU.getUnitDIE(); |
1153 | |
1154 | uint16_t Attr = DW_AT_lo_user; |
1155 | |
1156 | // We shall insert only one string. It will be referenced directly. |
1157 | const auto Attr1 = static_cast<dwarf::Attribute>(Attr++); |
1158 | CUDie.addAttribute(Attr: Attr1, Form: DW_FORM_strp, String: String1); |
1159 | |
1160 | // Generate the DWARF |
1161 | StringRef FileBytes = DG->generate(); |
1162 | MemoryBufferRef FileBuffer(FileBytes, "dwarf" ); |
1163 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1164 | ASSERT_TRUE((bool)Obj); |
1165 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1166 | EXPECT_TRUE( |
1167 | DwarfContext->getDWARFObj().getStrOffsetsSection().Data.empty()); |
1168 | } |
1169 | |
1170 | TEST(DWARFDebugInfo, TestRelations) { |
1171 | Triple Triple = getNormalizedDefaultTargetTriple(); |
1172 | if (!isConfigurationSupported(T&: Triple)) |
1173 | GTEST_SKIP(); |
1174 | |
1175 | // Test the DWARF APIs related to accessing the DW_AT_low_pc and |
1176 | // DW_AT_high_pc. |
1177 | uint16_t Version = 4; |
1178 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
1179 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1180 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1181 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1182 | |
1183 | enum class Tag: uint16_t { |
1184 | A = dwarf::DW_TAG_lo_user, |
1185 | B, |
1186 | C, |
1187 | C1, |
1188 | C2, |
1189 | D, |
1190 | D1 |
1191 | }; |
1192 | |
1193 | // Scope to allow us to re-use the same DIE names |
1194 | { |
1195 | // Create DWARF tree that looks like: |
1196 | // |
1197 | // CU |
1198 | // A |
1199 | // B |
1200 | // C |
1201 | // C1 |
1202 | // C2 |
1203 | // D |
1204 | // D1 |
1205 | dwarfgen::DIE CUDie = CU.getUnitDIE(); |
1206 | dwarfgen::DIE A = CUDie.addChild(Tag: (dwarf::Tag)Tag::A); |
1207 | A.addChild(Tag: (dwarf::Tag)Tag::B); |
1208 | dwarfgen::DIE C = A.addChild(Tag: (dwarf::Tag)Tag::C); |
1209 | dwarfgen::DIE D = A.addChild(Tag: (dwarf::Tag)Tag::D); |
1210 | C.addChild(Tag: (dwarf::Tag)Tag::C1); |
1211 | C.addChild(Tag: (dwarf::Tag)Tag::C2); |
1212 | D.addChild(Tag: (dwarf::Tag)Tag::D1); |
1213 | } |
1214 | |
1215 | MemoryBufferRef FileBuffer(DG->generate(), "dwarf" ); |
1216 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1217 | EXPECT_TRUE((bool)Obj); |
1218 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1219 | |
1220 | // Verify the number of compile units is correct. |
1221 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
1222 | EXPECT_EQ(NumCUs, 1u); |
1223 | DWARFCompileUnit *U = |
1224 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
1225 | |
1226 | // Get the compile unit DIE is valid. |
1227 | auto CUDie = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1228 | EXPECT_TRUE(CUDie.isValid()); |
1229 | |
1230 | // The compile unit doesn't have a parent or a sibling. |
1231 | auto ParentDie = CUDie.getParent(); |
1232 | EXPECT_FALSE(ParentDie.isValid()); |
1233 | auto SiblingDie = CUDie.getSibling(); |
1234 | EXPECT_FALSE(SiblingDie.isValid()); |
1235 | |
1236 | // Get the children of the compile unit |
1237 | auto A = CUDie.getFirstChild(); |
1238 | auto B = A.getFirstChild(); |
1239 | auto C = B.getSibling(); |
1240 | auto D = C.getSibling(); |
1241 | auto Null = D.getSibling(); |
1242 | |
1243 | // Verify NULL Die is NULL and has no children or siblings |
1244 | EXPECT_TRUE(Null.isNULL()); |
1245 | EXPECT_FALSE(Null.getSibling().isValid()); |
1246 | EXPECT_FALSE(Null.getFirstChild().isValid()); |
1247 | |
1248 | // Verify all children of the compile unit DIE are correct. |
1249 | EXPECT_EQ(A.getTag(), (dwarf::Tag)Tag::A); |
1250 | EXPECT_EQ(B.getTag(), (dwarf::Tag)Tag::B); |
1251 | EXPECT_EQ(C.getTag(), (dwarf::Tag)Tag::C); |
1252 | EXPECT_EQ(D.getTag(), (dwarf::Tag)Tag::D); |
1253 | |
1254 | // Verify who has children |
1255 | EXPECT_TRUE(A.hasChildren()); |
1256 | EXPECT_FALSE(B.hasChildren()); |
1257 | EXPECT_TRUE(C.hasChildren()); |
1258 | EXPECT_TRUE(D.hasChildren()); |
1259 | |
1260 | // Make sure the parent of all the children of the compile unit are the |
1261 | // compile unit. |
1262 | EXPECT_EQ(A.getParent(), CUDie); |
1263 | |
1264 | // Make sure the parent of all the children of A are the A. |
1265 | // B is the first child in A, so we need to verify we can get the previous |
1266 | // DIE as the parent. |
1267 | EXPECT_EQ(B.getParent(), A); |
1268 | // C is the second child in A, so we need to make sure we can backup across |
1269 | // other DIE (B) at the same level to get the correct parent. |
1270 | EXPECT_EQ(C.getParent(), A); |
1271 | // D is the third child of A. We need to verify we can backup across other DIE |
1272 | // (B and C) including DIE that have children (D) to get the correct parent. |
1273 | EXPECT_EQ(D.getParent(), A); |
1274 | |
1275 | // Verify that a DIE with no children returns an invalid DWARFDie. |
1276 | EXPECT_FALSE(B.getFirstChild().isValid()); |
1277 | |
1278 | // Verify the children of the B DIE |
1279 | auto C1 = C.getFirstChild(); |
1280 | auto C2 = C1.getSibling(); |
1281 | EXPECT_TRUE(C2.getSibling().isNULL()); |
1282 | |
1283 | // Verify all children of the B DIE correctly valid or invalid. |
1284 | EXPECT_EQ(C1.getTag(), (dwarf::Tag)Tag::C1); |
1285 | EXPECT_EQ(C2.getTag(), (dwarf::Tag)Tag::C2); |
1286 | |
1287 | // Make sure the parent of all the children of the B are the B. |
1288 | EXPECT_EQ(C1.getParent(), C); |
1289 | EXPECT_EQ(C2.getParent(), C); |
1290 | |
1291 | // Make sure iterators work as expected. |
1292 | EXPECT_THAT(std::vector<DWARFDie>(A.begin(), A.end()), |
1293 | testing::ElementsAre(B, C, D)); |
1294 | EXPECT_THAT(std::vector<DWARFDie>(A.rbegin(), A.rend()), |
1295 | testing::ElementsAre(D, C, B)); |
1296 | |
1297 | // Make sure conversion from reverse iterator works as expected. |
1298 | EXPECT_EQ(A.rbegin().base(), A.end()); |
1299 | EXPECT_EQ(A.rend().base(), A.begin()); |
1300 | |
1301 | // Make sure iterator is bidirectional. |
1302 | { |
1303 | auto Begin = A.begin(); |
1304 | auto End = A.end(); |
1305 | auto It = A.begin(); |
1306 | |
1307 | EXPECT_EQ(It, Begin); |
1308 | EXPECT_EQ(*It, B); |
1309 | ++It; |
1310 | EXPECT_EQ(*It, C); |
1311 | ++It; |
1312 | EXPECT_EQ(*It, D); |
1313 | ++It; |
1314 | EXPECT_EQ(It, End); |
1315 | --It; |
1316 | EXPECT_EQ(*It, D); |
1317 | --It; |
1318 | EXPECT_EQ(*It, C); |
1319 | --It; |
1320 | EXPECT_EQ(*It, B); |
1321 | EXPECT_EQ(It, Begin); |
1322 | } |
1323 | |
1324 | // Make sure reverse iterator is bidirectional. |
1325 | { |
1326 | auto Begin = A.rbegin(); |
1327 | auto End = A.rend(); |
1328 | auto It = A.rbegin(); |
1329 | |
1330 | EXPECT_EQ(It, Begin); |
1331 | EXPECT_EQ(*It, D); |
1332 | ++It; |
1333 | EXPECT_EQ(*It, C); |
1334 | ++It; |
1335 | EXPECT_EQ(*It, B); |
1336 | ++It; |
1337 | EXPECT_EQ(It, End); |
1338 | --It; |
1339 | EXPECT_EQ(*It, B); |
1340 | --It; |
1341 | EXPECT_EQ(*It, C); |
1342 | --It; |
1343 | EXPECT_EQ(*It, D); |
1344 | EXPECT_EQ(It, Begin); |
1345 | } |
1346 | } |
1347 | |
1348 | TEST(DWARFDebugInfo, TestDWARFDie) { |
1349 | // Make sure a default constructed DWARFDie doesn't have any parent, sibling |
1350 | // or child; |
1351 | DWARFDie DefaultDie; |
1352 | EXPECT_FALSE(DefaultDie.getParent().isValid()); |
1353 | EXPECT_FALSE(DefaultDie.getFirstChild().isValid()); |
1354 | EXPECT_FALSE(DefaultDie.getSibling().isValid()); |
1355 | } |
1356 | |
1357 | TEST(DWARFDebugInfo, TestChildIterators) { |
1358 | Triple Triple = getNormalizedDefaultTargetTriple(); |
1359 | if (!isConfigurationSupported(T&: Triple)) |
1360 | GTEST_SKIP(); |
1361 | |
1362 | // Test the DWARF APIs related to iterating across the children of a DIE using |
1363 | // the DWARFDie::iterator class. |
1364 | uint16_t Version = 4; |
1365 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
1366 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1367 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1368 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1369 | |
1370 | enum class Tag: uint16_t { |
1371 | A = dwarf::DW_TAG_lo_user, |
1372 | B, |
1373 | }; |
1374 | |
1375 | // Scope to allow us to re-use the same DIE names |
1376 | { |
1377 | // Create DWARF tree that looks like: |
1378 | // |
1379 | // CU |
1380 | // A |
1381 | // B |
1382 | auto CUDie = CU.getUnitDIE(); |
1383 | CUDie.addChild(Tag: (dwarf::Tag)Tag::A); |
1384 | CUDie.addChild(Tag: (dwarf::Tag)Tag::B); |
1385 | } |
1386 | |
1387 | MemoryBufferRef FileBuffer(DG->generate(), "dwarf" ); |
1388 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1389 | EXPECT_TRUE((bool)Obj); |
1390 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1391 | |
1392 | // Verify the number of compile units is correct. |
1393 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
1394 | EXPECT_EQ(NumCUs, 1u); |
1395 | DWARFCompileUnit *U = |
1396 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
1397 | |
1398 | // Get the compile unit DIE is valid. |
1399 | auto CUDie = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1400 | EXPECT_TRUE(CUDie.isValid()); |
1401 | uint32_t Index; |
1402 | DWARFDie A; |
1403 | DWARFDie B; |
1404 | |
1405 | // Verify the compile unit DIE's children. |
1406 | Index = 0; |
1407 | for (auto Die : CUDie.children()) { |
1408 | switch (Index++) { |
1409 | case 0: A = Die; break; |
1410 | case 1: B = Die; break; |
1411 | } |
1412 | } |
1413 | |
1414 | EXPECT_EQ(A.getTag(), (dwarf::Tag)Tag::A); |
1415 | EXPECT_EQ(B.getTag(), (dwarf::Tag)Tag::B); |
1416 | |
1417 | // Verify that A has no children by verifying that the begin and end contain |
1418 | // invalid DIEs and also that the iterators are equal. |
1419 | EXPECT_EQ(A.begin(), A.end()); |
1420 | } |
1421 | |
1422 | TEST(DWARFDebugInfo, TestChildIteratorsOnInvalidDie) { |
1423 | // Verify that an invalid DIE has no children. |
1424 | DWARFDie Invalid; |
1425 | auto begin = Invalid.begin(); |
1426 | auto end = Invalid.end(); |
1427 | EXPECT_FALSE(begin->isValid()); |
1428 | EXPECT_FALSE(end->isValid()); |
1429 | EXPECT_EQ(begin, end); |
1430 | } |
1431 | |
1432 | TEST(DWARFDebugInfo, TestEmptyChildren) { |
1433 | const char *yamldata = "debug_abbrev:\n" |
1434 | " - Table:\n" |
1435 | " - Code: 0x00000001\n" |
1436 | " Tag: DW_TAG_compile_unit\n" |
1437 | " Children: DW_CHILDREN_yes\n" |
1438 | "debug_info:\n" |
1439 | " - Version: 4\n" |
1440 | " AddrSize: 8\n" |
1441 | " Entries:\n" |
1442 | " - AbbrCode: 0x00000001\n" |
1443 | " - AbbrCode: 0x00000000\n" ; |
1444 | |
1445 | auto ErrOrSections = DWARFYAML::emitDebugSections(YAMLString: StringRef(yamldata)); |
1446 | ASSERT_TRUE((bool)ErrOrSections); |
1447 | std::unique_ptr<DWARFContext> DwarfContext = |
1448 | DWARFContext::create(Sections: *ErrOrSections, AddrSize: 8); |
1449 | |
1450 | // Verify the number of compile units is correct. |
1451 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
1452 | EXPECT_EQ(NumCUs, 1u); |
1453 | DWARFCompileUnit *U = |
1454 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
1455 | |
1456 | // Get the compile unit DIE is valid. |
1457 | auto CUDie = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1458 | EXPECT_TRUE(CUDie.isValid()); |
1459 | |
1460 | // Verify that the CU Die that says it has children, but doesn't, actually |
1461 | // has begin and end iterators that are equal. We want to make sure we don't |
1462 | // see the Null DIEs during iteration. |
1463 | EXPECT_EQ(CUDie.begin(), CUDie.end()); |
1464 | } |
1465 | |
1466 | TEST(DWARFDebugInfo, TestAttributeIterators) { |
1467 | Triple Triple = getNormalizedDefaultTargetTriple(); |
1468 | if (!isConfigurationSupported(T&: Triple)) |
1469 | GTEST_SKIP(); |
1470 | |
1471 | // Test the DWARF APIs related to iterating across all attribute values in a |
1472 | // a DWARFDie. |
1473 | uint16_t Version = 4; |
1474 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
1475 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1476 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1477 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1478 | const uint64_t CULowPC = 0x1000; |
1479 | StringRef CUPath("/tmp/main.c" ); |
1480 | |
1481 | // Scope to allow us to re-use the same DIE names |
1482 | { |
1483 | auto CUDie = CU.getUnitDIE(); |
1484 | // Encode an attribute value before an attribute with no data. |
1485 | CUDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: CUPath.data()); |
1486 | // Encode an attribute value with no data in .debug_info/types to ensure |
1487 | // the iteration works correctly. |
1488 | CUDie.addAttribute(Attr: DW_AT_declaration, Form: DW_FORM_flag_present); |
1489 | // Encode an attribute value after an attribute with no data. |
1490 | CUDie.addAttribute(Attr: DW_AT_low_pc, Form: DW_FORM_addr, U: CULowPC); |
1491 | } |
1492 | |
1493 | MemoryBufferRef FileBuffer(DG->generate(), "dwarf" ); |
1494 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1495 | EXPECT_TRUE((bool)Obj); |
1496 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1497 | |
1498 | // Verify the number of compile units is correct. |
1499 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
1500 | EXPECT_EQ(NumCUs, 1u); |
1501 | DWARFCompileUnit *U = |
1502 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
1503 | |
1504 | // Get the compile unit DIE is valid. |
1505 | auto CUDie = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1506 | EXPECT_TRUE(CUDie.isValid()); |
1507 | |
1508 | auto R = CUDie.attributes(); |
1509 | auto I = R.begin(); |
1510 | auto E = R.end(); |
1511 | |
1512 | ASSERT_NE(E, I); |
1513 | EXPECT_EQ(I->Attr, DW_AT_name); |
1514 | auto ActualCUPath = toString(V: I->Value); |
1515 | EXPECT_EQ(CUPath, *ActualCUPath); |
1516 | |
1517 | ASSERT_NE(E, ++I); |
1518 | EXPECT_EQ(I->Attr, DW_AT_declaration); |
1519 | EXPECT_EQ(1ull, *I->Value.getAsUnsignedConstant()); |
1520 | |
1521 | ASSERT_NE(E, ++I); |
1522 | EXPECT_EQ(I->Attr, DW_AT_low_pc); |
1523 | EXPECT_EQ(CULowPC, *I->Value.getAsAddress()); |
1524 | |
1525 | EXPECT_EQ(E, ++I); |
1526 | } |
1527 | |
1528 | TEST(DWARFDebugInfo, TestFindRecurse) { |
1529 | Triple Triple = getNormalizedDefaultTargetTriple(); |
1530 | if (!isConfigurationSupported(T&: Triple)) |
1531 | GTEST_SKIP(); |
1532 | |
1533 | uint16_t Version = 4; |
1534 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
1535 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1536 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1537 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1538 | |
1539 | StringRef SpecDieName = "spec" ; |
1540 | StringRef SpecLinkageName = "spec_linkage" ; |
1541 | StringRef AbsDieName = "abs" ; |
1542 | // Scope to allow us to re-use the same DIE names |
1543 | { |
1544 | auto CUDie = CU.getUnitDIE(); |
1545 | auto FuncSpecDie = CUDie.addChild(Tag: DW_TAG_subprogram); |
1546 | auto FuncAbsDie = CUDie.addChild(Tag: DW_TAG_subprogram); |
1547 | // Put the linkage name in a second abstract origin DIE to ensure we |
1548 | // recurse through more than just one DIE when looking for attributes. |
1549 | auto FuncAbsDie2 = CUDie.addChild(Tag: DW_TAG_subprogram); |
1550 | auto FuncDie = CUDie.addChild(Tag: DW_TAG_subprogram); |
1551 | auto VarAbsDie = CUDie.addChild(Tag: DW_TAG_variable); |
1552 | auto VarDie = CUDie.addChild(Tag: DW_TAG_variable); |
1553 | FuncSpecDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: SpecDieName); |
1554 | FuncAbsDie2.addAttribute(Attr: DW_AT_linkage_name, Form: DW_FORM_strp, String: SpecLinkageName); |
1555 | FuncAbsDie.addAttribute(Attr: DW_AT_specification, Form: DW_FORM_ref4, RefDie&: FuncSpecDie); |
1556 | FuncAbsDie.addAttribute(Attr: DW_AT_abstract_origin, Form: DW_FORM_ref4, RefDie&: FuncAbsDie2); |
1557 | FuncDie.addAttribute(Attr: DW_AT_abstract_origin, Form: DW_FORM_ref4, RefDie&: FuncAbsDie); |
1558 | VarAbsDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: AbsDieName); |
1559 | VarDie.addAttribute(Attr: DW_AT_abstract_origin, Form: DW_FORM_ref4, RefDie&: VarAbsDie); |
1560 | } |
1561 | |
1562 | MemoryBufferRef FileBuffer(DG->generate(), "dwarf" ); |
1563 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1564 | EXPECT_TRUE((bool)Obj); |
1565 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1566 | |
1567 | // Verify the number of compile units is correct. |
1568 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
1569 | EXPECT_EQ(NumCUs, 1u); |
1570 | DWARFCompileUnit *U = |
1571 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
1572 | |
1573 | // Get the compile unit DIE is valid. |
1574 | auto CUDie = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1575 | EXPECT_TRUE(CUDie.isValid()); |
1576 | |
1577 | auto FuncSpecDie = CUDie.getFirstChild(); |
1578 | auto FuncAbsDie = FuncSpecDie.getSibling(); |
1579 | auto FuncAbsDie2 = FuncAbsDie.getSibling(); |
1580 | auto FuncDie = FuncAbsDie2.getSibling(); |
1581 | auto VarAbsDie = FuncDie.getSibling(); |
1582 | auto VarDie = VarAbsDie.getSibling(); |
1583 | |
1584 | // Make sure we can't extract the name from the specification die when using |
1585 | // DWARFDie::find() since it won't check the DW_AT_specification DIE. |
1586 | EXPECT_FALSE(FuncDie.find(DW_AT_name)); |
1587 | |
1588 | // Make sure we can extract the name from the specification die when using |
1589 | // DWARFDie::findRecursively() since it should recurse through the |
1590 | // DW_AT_specification DIE. |
1591 | auto NameOpt = FuncDie.findRecursively(Attrs: DW_AT_name); |
1592 | EXPECT_TRUE(NameOpt); |
1593 | // Test the dwarf::toString() helper function. |
1594 | auto StringOpt = toString(V: NameOpt); |
1595 | EXPECT_TRUE(StringOpt); |
1596 | EXPECT_EQ(SpecDieName, StringOpt.value_or(nullptr)); |
1597 | // Test the dwarf::toString() helper function with a default value specified. |
1598 | EXPECT_EQ(SpecDieName, toString(NameOpt, nullptr)); |
1599 | |
1600 | auto LinkageNameOpt = FuncDie.findRecursively(Attrs: DW_AT_linkage_name); |
1601 | EXPECT_EQ(SpecLinkageName, toString(LinkageNameOpt).value_or(nullptr)); |
1602 | |
1603 | // Make sure we can't extract the name from the abstract origin die when using |
1604 | // DWARFDie::find() since it won't check the DW_AT_abstract_origin DIE. |
1605 | EXPECT_FALSE(VarDie.find(DW_AT_name)); |
1606 | |
1607 | // Make sure we can extract the name from the abstract origin die when using |
1608 | // DWARFDie::findRecursively() since it should recurse through the |
1609 | // DW_AT_abstract_origin DIE. |
1610 | NameOpt = VarDie.findRecursively(Attrs: DW_AT_name); |
1611 | EXPECT_TRUE(NameOpt); |
1612 | // Test the dwarf::toString() helper function. |
1613 | StringOpt = toString(V: NameOpt); |
1614 | EXPECT_TRUE(StringOpt); |
1615 | EXPECT_EQ(AbsDieName, StringOpt.value_or(nullptr)); |
1616 | } |
1617 | |
1618 | TEST(DWARFDebugInfo, TestSelfRecursiveType) { |
1619 | typedef uint32_t AddrType; |
1620 | Triple Triple = getDefaultTargetTripleForAddrSize(AddrSize: sizeof(AddrType)); |
1621 | if (!isConfigurationSupported(T&: Triple)) |
1622 | GTEST_SKIP(); |
1623 | |
1624 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: 4); |
1625 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1626 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1627 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1628 | dwarfgen::DIE CUDie = CU.getUnitDIE(); |
1629 | |
1630 | // Create an invalid self-recursive typedef. |
1631 | dwarfgen::DIE TypedefDie = CUDie.addChild(Tag: DW_TAG_typedef); |
1632 | TypedefDie.addAttribute(Attr: DW_AT_name, Form: DW_FORM_strp, String: "illegal" ); |
1633 | TypedefDie.addAttribute(Attr: DW_AT_type, Form: DW_FORM_ref_addr, RefDie&: TypedefDie); |
1634 | |
1635 | MemoryBufferRef FileBuffer(DG->generate(), "dwarf" ); |
1636 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1637 | EXPECT_TRUE((bool)Obj); |
1638 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1639 | |
1640 | // Verify the number of compile units is correct. |
1641 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
1642 | EXPECT_EQ(NumCUs, 1u); |
1643 | DWARFCompileUnit *U = cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
1644 | { |
1645 | DWARFDie CUDie = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1646 | EXPECT_TRUE(CUDie.isValid()); |
1647 | DWARFDie TypedefDie = CUDie.getFirstChild(); |
1648 | |
1649 | // Test that getTypeSize doesn't get into an infinite loop. |
1650 | EXPECT_EQ(TypedefDie.getTypeSize(sizeof(AddrType)), std::nullopt); |
1651 | } |
1652 | } |
1653 | |
1654 | TEST(DWARFDebugInfo, TestDwarfToFunctions) { |
1655 | // Test all of the dwarf::toXXX functions that take a |
1656 | // std::optional<DWARFFormValue> and extract the values from it. |
1657 | uint64_t InvalidU64 = 0xBADBADBADBADBADB; |
1658 | int64_t InvalidS64 = 0xBADBADBADBADBADB; |
1659 | |
1660 | // First test that we don't get valid values back when using an optional with |
1661 | // no value. |
1662 | std::optional<DWARFFormValue> FormValOpt1 = DWARFFormValue(); |
1663 | EXPECT_FALSE(toString(FormValOpt1).has_value()); |
1664 | EXPECT_FALSE(toUnsigned(FormValOpt1).has_value()); |
1665 | EXPECT_FALSE(toReference(FormValOpt1).has_value()); |
1666 | EXPECT_FALSE(toSigned(FormValOpt1).has_value()); |
1667 | EXPECT_FALSE(toAddress(FormValOpt1).has_value()); |
1668 | EXPECT_FALSE(toSectionOffset(FormValOpt1).has_value()); |
1669 | EXPECT_FALSE(toBlock(FormValOpt1).has_value()); |
1670 | EXPECT_EQ(nullptr, toString(FormValOpt1, nullptr)); |
1671 | EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt1, InvalidU64)); |
1672 | EXPECT_EQ(InvalidU64, toReference(FormValOpt1, InvalidU64)); |
1673 | EXPECT_EQ(InvalidU64, toAddress(FormValOpt1, InvalidU64)); |
1674 | EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt1, InvalidU64)); |
1675 | EXPECT_EQ(InvalidS64, toSigned(FormValOpt1, InvalidS64)); |
1676 | |
1677 | // Test successful and unsuccessful address decoding. |
1678 | uint64_t Address = 0x100000000ULL; |
1679 | std::optional<DWARFFormValue> FormValOpt2 = |
1680 | DWARFFormValue::createFromUValue(F: DW_FORM_addr, V: Address); |
1681 | |
1682 | EXPECT_FALSE(toString(FormValOpt2).has_value()); |
1683 | EXPECT_FALSE(toUnsigned(FormValOpt2).has_value()); |
1684 | EXPECT_FALSE(toReference(FormValOpt2).has_value()); |
1685 | EXPECT_FALSE(toSigned(FormValOpt2).has_value()); |
1686 | EXPECT_TRUE(toAddress(FormValOpt2).has_value()); |
1687 | EXPECT_FALSE(toSectionOffset(FormValOpt2).has_value()); |
1688 | EXPECT_FALSE(toBlock(FormValOpt2).has_value()); |
1689 | EXPECT_EQ(nullptr, toString(FormValOpt2, nullptr)); |
1690 | EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt2, InvalidU64)); |
1691 | EXPECT_EQ(InvalidU64, toReference(FormValOpt2, InvalidU64)); |
1692 | EXPECT_EQ(Address, toAddress(FormValOpt2, InvalidU64)); |
1693 | EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt2, InvalidU64)); |
1694 | EXPECT_EQ(InvalidS64, toSigned(FormValOpt2, InvalidU64)); |
1695 | |
1696 | // Test successful and unsuccessful unsigned constant decoding. |
1697 | uint64_t UData8 = 0x1020304050607080ULL; |
1698 | std::optional<DWARFFormValue> FormValOpt3 = |
1699 | DWARFFormValue::createFromUValue(F: DW_FORM_udata, V: UData8); |
1700 | |
1701 | EXPECT_FALSE(toString(FormValOpt3).has_value()); |
1702 | EXPECT_TRUE(toUnsigned(FormValOpt3).has_value()); |
1703 | EXPECT_FALSE(toReference(FormValOpt3).has_value()); |
1704 | EXPECT_TRUE(toSigned(FormValOpt3).has_value()); |
1705 | EXPECT_FALSE(toAddress(FormValOpt3).has_value()); |
1706 | EXPECT_FALSE(toSectionOffset(FormValOpt3).has_value()); |
1707 | EXPECT_FALSE(toBlock(FormValOpt3).has_value()); |
1708 | EXPECT_EQ(nullptr, toString(FormValOpt3, nullptr)); |
1709 | EXPECT_EQ(UData8, toUnsigned(FormValOpt3, InvalidU64)); |
1710 | EXPECT_EQ(InvalidU64, toReference(FormValOpt3, InvalidU64)); |
1711 | EXPECT_EQ(InvalidU64, toAddress(FormValOpt3, InvalidU64)); |
1712 | EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt3, InvalidU64)); |
1713 | EXPECT_EQ((int64_t)UData8, toSigned(FormValOpt3, InvalidU64)); |
1714 | |
1715 | // Test successful and unsuccessful reference decoding. |
1716 | uint32_t RefData = 0x11223344U; |
1717 | std::optional<DWARFFormValue> FormValOpt4 = |
1718 | DWARFFormValue::createFromUValue(F: DW_FORM_ref_addr, V: RefData); |
1719 | |
1720 | EXPECT_FALSE(toString(FormValOpt4).has_value()); |
1721 | EXPECT_FALSE(toUnsigned(FormValOpt4).has_value()); |
1722 | EXPECT_TRUE(toReference(FormValOpt4).has_value()); |
1723 | EXPECT_FALSE(toSigned(FormValOpt4).has_value()); |
1724 | EXPECT_FALSE(toAddress(FormValOpt4).has_value()); |
1725 | EXPECT_FALSE(toSectionOffset(FormValOpt4).has_value()); |
1726 | EXPECT_FALSE(toBlock(FormValOpt4).has_value()); |
1727 | EXPECT_EQ(nullptr, toString(FormValOpt4, nullptr)); |
1728 | EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt4, InvalidU64)); |
1729 | EXPECT_EQ(RefData, toReference(FormValOpt4, InvalidU64)); |
1730 | EXPECT_EQ(InvalidU64, toAddress(FormValOpt4, InvalidU64)); |
1731 | EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt4, InvalidU64)); |
1732 | EXPECT_EQ(InvalidS64, toSigned(FormValOpt4, InvalidU64)); |
1733 | |
1734 | // Test successful and unsuccessful signed constant decoding. |
1735 | int64_t SData8 = 0x1020304050607080ULL; |
1736 | std::optional<DWARFFormValue> FormValOpt5 = |
1737 | DWARFFormValue::createFromSValue(F: DW_FORM_udata, V: SData8); |
1738 | |
1739 | EXPECT_FALSE(toString(FormValOpt5).has_value()); |
1740 | EXPECT_TRUE(toUnsigned(FormValOpt5).has_value()); |
1741 | EXPECT_FALSE(toReference(FormValOpt5).has_value()); |
1742 | EXPECT_TRUE(toSigned(FormValOpt5).has_value()); |
1743 | EXPECT_FALSE(toAddress(FormValOpt5).has_value()); |
1744 | EXPECT_FALSE(toSectionOffset(FormValOpt5).has_value()); |
1745 | EXPECT_FALSE(toBlock(FormValOpt5).has_value()); |
1746 | EXPECT_EQ(nullptr, toString(FormValOpt5, nullptr)); |
1747 | EXPECT_EQ((uint64_t)SData8, toUnsigned(FormValOpt5, InvalidU64)); |
1748 | EXPECT_EQ(InvalidU64, toReference(FormValOpt5, InvalidU64)); |
1749 | EXPECT_EQ(InvalidU64, toAddress(FormValOpt5, InvalidU64)); |
1750 | EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt5, InvalidU64)); |
1751 | EXPECT_EQ(SData8, toSigned(FormValOpt5, InvalidU64)); |
1752 | |
1753 | // Test successful and unsuccessful block decoding. |
1754 | uint8_t Data[] = { 2, 3, 4 }; |
1755 | ArrayRef<uint8_t> Array(Data); |
1756 | std::optional<DWARFFormValue> FormValOpt6 = |
1757 | DWARFFormValue::createFromBlockValue(F: DW_FORM_block1, D: Array); |
1758 | |
1759 | EXPECT_FALSE(toString(FormValOpt6).has_value()); |
1760 | EXPECT_FALSE(toUnsigned(FormValOpt6).has_value()); |
1761 | EXPECT_FALSE(toReference(FormValOpt6).has_value()); |
1762 | EXPECT_FALSE(toSigned(FormValOpt6).has_value()); |
1763 | EXPECT_FALSE(toAddress(FormValOpt6).has_value()); |
1764 | EXPECT_FALSE(toSectionOffset(FormValOpt6).has_value()); |
1765 | auto BlockOpt = toBlock(V: FormValOpt6); |
1766 | EXPECT_TRUE(BlockOpt.has_value()); |
1767 | EXPECT_EQ(*BlockOpt, Array); |
1768 | EXPECT_EQ(nullptr, toString(FormValOpt6, nullptr)); |
1769 | EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt6, InvalidU64)); |
1770 | EXPECT_EQ(InvalidU64, toReference(FormValOpt6, InvalidU64)); |
1771 | EXPECT_EQ(InvalidU64, toAddress(FormValOpt6, InvalidU64)); |
1772 | EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt6, InvalidU64)); |
1773 | EXPECT_EQ(InvalidS64, toSigned(FormValOpt6, InvalidU64)); |
1774 | |
1775 | // Test |
1776 | } |
1777 | |
1778 | TEST(DWARFDebugInfo, TestFindAttrs) { |
1779 | Triple Triple = getNormalizedDefaultTargetTriple(); |
1780 | if (!isConfigurationSupported(T&: Triple)) |
1781 | GTEST_SKIP(); |
1782 | |
1783 | // Test the DWARFDie::find() and DWARFDie::findRecursively() that take an |
1784 | // ArrayRef<dwarf::Attribute> value to make sure they work correctly. |
1785 | uint16_t Version = 4; |
1786 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
1787 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1788 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1789 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1790 | |
1791 | StringRef DieMangled("_Z3fooi" ); |
1792 | // Scope to allow us to re-use the same DIE names |
1793 | { |
1794 | auto CUDie = CU.getUnitDIE(); |
1795 | auto FuncSpecDie = CUDie.addChild(Tag: DW_TAG_subprogram); |
1796 | auto FuncDie = CUDie.addChild(Tag: DW_TAG_subprogram); |
1797 | FuncSpecDie.addAttribute(Attr: DW_AT_MIPS_linkage_name, Form: DW_FORM_strp, String: DieMangled); |
1798 | FuncDie.addAttribute(Attr: DW_AT_specification, Form: DW_FORM_ref4, RefDie&: FuncSpecDie); |
1799 | } |
1800 | |
1801 | MemoryBufferRef FileBuffer(DG->generate(), "dwarf" ); |
1802 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1803 | EXPECT_TRUE((bool)Obj); |
1804 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1805 | |
1806 | // Verify the number of compile units is correct. |
1807 | uint32_t NumCUs = DwarfContext->getNumCompileUnits(); |
1808 | EXPECT_EQ(NumCUs, 1u); |
1809 | DWARFCompileUnit *U = |
1810 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
1811 | |
1812 | // Get the compile unit DIE is valid. |
1813 | auto CUDie = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1814 | EXPECT_TRUE(CUDie.isValid()); |
1815 | |
1816 | auto FuncSpecDie = CUDie.getFirstChild(); |
1817 | auto FuncDie = FuncSpecDie.getSibling(); |
1818 | |
1819 | // Make sure that passing in an empty attribute list behave correctly. |
1820 | EXPECT_FALSE(FuncDie.find(ArrayRef<dwarf::Attribute>()).has_value()); |
1821 | |
1822 | // Make sure that passing in a list of attribute that are not contained |
1823 | // in the DIE returns nothing. |
1824 | EXPECT_FALSE(FuncDie.find({DW_AT_low_pc, DW_AT_entry_pc}).has_value()); |
1825 | |
1826 | const dwarf::Attribute Attrs[] = {DW_AT_linkage_name, |
1827 | DW_AT_MIPS_linkage_name}; |
1828 | |
1829 | // Make sure we can't extract the linkage name attributes when using |
1830 | // DWARFDie::find() since it won't check the DW_AT_specification DIE. |
1831 | EXPECT_FALSE(FuncDie.find(Attrs).has_value()); |
1832 | |
1833 | // Make sure we can extract the name from the specification die when using |
1834 | // DWARFDie::findRecursively() since it should recurse through the |
1835 | // DW_AT_specification DIE. |
1836 | auto NameOpt = FuncDie.findRecursively(Attrs); |
1837 | EXPECT_TRUE(NameOpt.has_value()); |
1838 | EXPECT_EQ(DieMangled, toString(NameOpt, "" )); |
1839 | } |
1840 | |
1841 | #ifdef NO_SUPPORT_DEBUG_ADDR |
1842 | TEST(DWARFDebugInfo, DISABLED_TestImplicitConstAbbrevs) { |
1843 | #else |
1844 | TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) { |
1845 | #endif |
1846 | Triple Triple = getNormalizedDefaultTargetTriple(); |
1847 | if (!isConfigurationSupported(T&: Triple)) |
1848 | GTEST_SKIP(); |
1849 | |
1850 | uint16_t Version = 5; |
1851 | auto ExpectedDG = dwarfgen::Generator::create(TheTriple: Triple, DwarfVersion: Version); |
1852 | ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); |
1853 | dwarfgen::Generator *DG = ExpectedDG.get().get(); |
1854 | dwarfgen::CompileUnit &CU = DG->addCompileUnit(); |
1855 | dwarfgen::DIE CUDie = CU.getUnitDIE(); |
1856 | const dwarf::Attribute Attr = DW_AT_lo_user; |
1857 | const int64_t Val1 = 42; |
1858 | const int64_t Val2 = 43; |
1859 | |
1860 | auto FirstVal1DIE = CUDie.addChild(Tag: DW_TAG_class_type); |
1861 | FirstVal1DIE.addAttribute(Attr, Form: DW_FORM_implicit_const, U: Val1); |
1862 | |
1863 | auto SecondVal1DIE = CUDie.addChild(Tag: DW_TAG_class_type); |
1864 | SecondVal1DIE.addAttribute(Attr, Form: DW_FORM_implicit_const, U: Val1); |
1865 | |
1866 | auto Val2DIE = CUDie.addChild(Tag: DW_TAG_class_type); |
1867 | Val2DIE.addAttribute(Attr, Form: DW_FORM_implicit_const, U: Val2); |
1868 | |
1869 | MemoryBufferRef FileBuffer(DG->generate(), "dwarf" ); |
1870 | auto Obj = object::ObjectFile::createObjectFile(Object: FileBuffer); |
1871 | EXPECT_TRUE((bool)Obj); |
1872 | std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(Obj: **Obj); |
1873 | DWARFCompileUnit *U = |
1874 | cast<DWARFCompileUnit>(Val: DwarfContext->getUnitAtIndex(index: 0)); |
1875 | EXPECT_TRUE((bool)U); |
1876 | |
1877 | const auto *Abbrevs = U->getAbbreviations(); |
1878 | EXPECT_TRUE((bool)Abbrevs); |
1879 | |
1880 | // Let's find implicit_const abbrevs and verify, |
1881 | // that there are exactly two of them and both of them |
1882 | // can be dumped correctly. |
1883 | typedef decltype(Abbrevs->begin()) AbbrevIt; |
1884 | AbbrevIt Val1Abbrev = Abbrevs->end(); |
1885 | AbbrevIt Val2Abbrev = Abbrevs->end(); |
1886 | for(auto it = Abbrevs->begin(); it != Abbrevs->end(); ++it) { |
1887 | if (it->getNumAttributes() == 0) |
1888 | continue; // root abbrev for DW_TAG_compile_unit |
1889 | |
1890 | auto A = it->getAttrByIndex(idx: 0); |
1891 | EXPECT_EQ(A, Attr); |
1892 | |
1893 | std::optional<uint32_t> AttrIndex = it->findAttributeIndex(attr: A); |
1894 | EXPECT_TRUE((bool)AttrIndex); |
1895 | EXPECT_EQ(*AttrIndex, 0u); |
1896 | uint64_t OffsetVal = |
1897 | it->getAttributeOffsetFromIndex(AttrIndex: *AttrIndex, /* offset */ DIEOffset: 0, U: *U); |
1898 | EXPECT_TRUE(it->getAttributeValueFromOffset(*AttrIndex, OffsetVal, *U)); |
1899 | |
1900 | auto FormValue = it->getAttributeValue(/* offset */ DIEOffset: 0, Attr: A, U: *U); |
1901 | EXPECT_TRUE((bool)FormValue); |
1902 | EXPECT_EQ(FormValue->getForm(), dwarf::DW_FORM_implicit_const); |
1903 | |
1904 | const auto V = FormValue->getAsSignedConstant(); |
1905 | EXPECT_TRUE((bool)V); |
1906 | |
1907 | auto VerifyAbbrevDump = [&V](AbbrevIt it) { |
1908 | std::string S; |
1909 | llvm::raw_string_ostream OS(S); |
1910 | it->dump(OS); |
1911 | auto FormPos = OS.str().find(s: "DW_FORM_implicit_const" ); |
1912 | EXPECT_NE(FormPos, std::string::npos); |
1913 | auto ValPos = S.find_first_of(s: "-0123456789" , pos: FormPos); |
1914 | EXPECT_NE(ValPos, std::string::npos); |
1915 | int64_t Val = std::atoll(nptr: S.substr(pos: ValPos).c_str()); |
1916 | EXPECT_EQ(Val, *V); |
1917 | }; |
1918 | |
1919 | switch(*V) { |
1920 | case Val1: |
1921 | EXPECT_EQ(Val1Abbrev, Abbrevs->end()); |
1922 | Val1Abbrev = it; |
1923 | VerifyAbbrevDump(it); |
1924 | break; |
1925 | case Val2: |
1926 | EXPECT_EQ(Val2Abbrev, Abbrevs->end()); |
1927 | Val2Abbrev = it; |
1928 | VerifyAbbrevDump(it); |
1929 | break; |
1930 | default: |
1931 | FAIL() << "Unexpected attribute value: " << *V; |
1932 | } |
1933 | } |
1934 | |
1935 | // Now let's make sure that two Val1-DIEs refer to the same abbrev, |
1936 | // and Val2-DIE refers to another one. |
1937 | auto DieDG = U->getUnitDIE(ExtractUnitDIEOnly: false); |
1938 | auto it = DieDG.begin(); |
1939 | std::multimap<int64_t, decltype(it->getAbbreviationDeclarationPtr())> DIEs; |
1940 | const DWARFAbbreviationDeclaration *AbbrevPtrVal1 = nullptr; |
1941 | const DWARFAbbreviationDeclaration *AbbrevPtrVal2 = nullptr; |
1942 | for (; it != DieDG.end(); ++it) { |
1943 | const auto *AbbrevPtr = it->getAbbreviationDeclarationPtr(); |
1944 | EXPECT_TRUE((bool)AbbrevPtr); |
1945 | auto FormValue = it->find(Attr); |
1946 | EXPECT_TRUE((bool)FormValue); |
1947 | const auto V = FormValue->getAsSignedConstant(); |
1948 | EXPECT_TRUE((bool)V); |
1949 | switch(*V) { |
1950 | case Val1: |
1951 | AbbrevPtrVal1 = AbbrevPtr; |
1952 | break; |
1953 | case Val2: |
1954 | AbbrevPtrVal2 = AbbrevPtr; |
1955 | break; |
1956 | default: |
1957 | FAIL() << "Unexpected attribute value: " << *V; |
1958 | } |
1959 | DIEs.insert(x: std::make_pair(x: *V, y&: AbbrevPtr)); |
1960 | } |
1961 | EXPECT_EQ(DIEs.count(Val1), 2u); |
1962 | EXPECT_EQ(DIEs.count(Val2), 1u); |
1963 | auto Val1Range = DIEs.equal_range(x: Val1); |
1964 | for (auto it = Val1Range.first; it != Val1Range.second; ++it) |
1965 | EXPECT_EQ(it->second, AbbrevPtrVal1); |
1966 | EXPECT_EQ(DIEs.find(Val2)->second, AbbrevPtrVal2); |
1967 | } |
1968 | |
1969 | TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) { |
1970 | DWARFVerifier::DieRangeInfo Empty; |
1971 | ASSERT_TRUE(Empty.contains(Empty)); |
1972 | |
1973 | DWARFVerifier::DieRangeInfo Ranges( |
1974 | {{0x10, 0x20}, {0x30, 0x40}, {0x40, 0x50}}); |
1975 | |
1976 | ASSERT_TRUE(Ranges.contains(Empty)); |
1977 | ASSERT_FALSE(Ranges.contains({{{0x0f, 0x10}}})); |
1978 | ASSERT_FALSE(Ranges.contains({{{0x0f, 0x20}}})); |
1979 | ASSERT_FALSE(Ranges.contains({{{0x0f, 0x21}}})); |
1980 | |
1981 | // Test ranges that start at R's start address |
1982 | ASSERT_TRUE(Ranges.contains({{{0x10, 0x10}}})); |
1983 | ASSERT_TRUE(Ranges.contains({{{0x10, 0x11}}})); |
1984 | ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}}})); |
1985 | ASSERT_FALSE(Ranges.contains({{{0x10, 0x21}}})); |
1986 | |
1987 | ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}}})); |
1988 | |
1989 | // Test ranges that start at last bytes of Range |
1990 | ASSERT_TRUE(Ranges.contains({{{0x1f, 0x20}}})); |
1991 | ASSERT_FALSE(Ranges.contains({{{0x1f, 0x21}}})); |
1992 | |
1993 | // Test ranges that start after Range |
1994 | ASSERT_TRUE(Ranges.contains({{{0x20, 0x20}}})); |
1995 | ASSERT_FALSE(Ranges.contains({{{0x20, 0x21}}})); |
1996 | |
1997 | ASSERT_TRUE(Ranges.contains({{{0x31, 0x32}}})); |
1998 | ASSERT_TRUE(Ranges.contains({{{0x3f, 0x40}}})); |
1999 | ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}, {0x30, 0x40}}})); |
2000 | ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x31, 0x32}}})); |
2001 | ASSERT_TRUE(Ranges.contains( |
2002 | {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x33}}})); |
2003 | ASSERT_FALSE(Ranges.contains({{{0x11, 0x12}, |
2004 | {0x12, 0x13}, |
2005 | {0x20, 0x21}, |
2006 | {0x31, 0x32}, |
2007 | {0x32, 0x33}}})); |
2008 | ASSERT_FALSE(Ranges.contains( |
2009 | {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x51}}})); |
2010 | ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x30, 0x50}}})); |
2011 | ASSERT_FALSE(Ranges.contains({{{0x30, 0x51}}})); |
2012 | ASSERT_FALSE(Ranges.contains({{{0x50, 0x51}}})); |
2013 | } |
2014 | |
2015 | namespace { |
2016 | |
2017 | void AssertRangesIntersect(const DWARFAddressRange &LHS, |
2018 | const DWARFAddressRange &RHS) { |
2019 | ASSERT_TRUE(LHS.intersects(RHS)); |
2020 | ASSERT_TRUE(RHS.intersects(LHS)); |
2021 | } |
2022 | void AssertRangesDontIntersect(const DWARFAddressRange &LHS, |
2023 | const DWARFAddressRange &RHS) { |
2024 | ASSERT_FALSE(LHS.intersects(RHS)); |
2025 | ASSERT_FALSE(RHS.intersects(LHS)); |
2026 | } |
2027 | |
2028 | void AssertRangesIntersect(const DWARFVerifier::DieRangeInfo &LHS, |
2029 | const DWARFAddressRangesVector &Ranges) { |
2030 | DWARFVerifier::DieRangeInfo RHS(Ranges); |
2031 | ASSERT_TRUE(LHS.intersects(RHS)); |
2032 | ASSERT_TRUE(RHS.intersects(LHS)); |
2033 | } |
2034 | |
2035 | void AssertRangesDontIntersect(const DWARFVerifier::DieRangeInfo &LHS, |
2036 | const DWARFAddressRangesVector &Ranges) { |
2037 | DWARFVerifier::DieRangeInfo RHS(Ranges); |
2038 | ASSERT_FALSE(LHS.intersects(RHS)); |
2039 | ASSERT_FALSE(RHS.intersects(LHS)); |
2040 | } |
2041 | |
2042 | } // namespace |
2043 | TEST(DWARFDebugInfo, TestDwarfRangesIntersect) { |
2044 | DWARFAddressRange R(0x10, 0x20); |
2045 | |
2046 | //---------------------------------------------------------------------- |
2047 | // Test ranges that start before R... |
2048 | //---------------------------------------------------------------------- |
2049 | // Other range ends before start of R |
2050 | AssertRangesDontIntersect(LHS: R, RHS: {0x00, 0x10}); |
2051 | // Other range end address is start of a R |
2052 | AssertRangesIntersect(LHS: R, RHS: {0x00, 0x11}); |
2053 | // Other range end address is in R |
2054 | AssertRangesIntersect(LHS: R, RHS: {0x00, 0x15}); |
2055 | // Other range end address is at and of R |
2056 | AssertRangesIntersect(LHS: R, RHS: {0x00, 0x20}); |
2057 | // Other range end address is past end of R |
2058 | AssertRangesIntersect(LHS: R, RHS: {0x00, 0x40}); |
2059 | |
2060 | //---------------------------------------------------------------------- |
2061 | // Test ranges that start at R's start address |
2062 | //---------------------------------------------------------------------- |
2063 | // Ensure empty ranges doesn't match |
2064 | AssertRangesDontIntersect(LHS: R, RHS: {0x10, 0x10}); |
2065 | // 1 byte of Range |
2066 | AssertRangesIntersect(LHS: R, RHS: {0x10, 0x11}); |
2067 | // same as Range |
2068 | AssertRangesIntersect(LHS: R, RHS: {0x10, 0x20}); |
2069 | // 1 byte past Range |
2070 | AssertRangesIntersect(LHS: R, RHS: {0x10, 0x21}); |
2071 | |
2072 | //---------------------------------------------------------------------- |
2073 | // Test ranges that start inside Range |
2074 | //---------------------------------------------------------------------- |
2075 | // empty in range |
2076 | AssertRangesDontIntersect(LHS: R, RHS: {0x11, 0x11}); |
2077 | // all in Range |
2078 | AssertRangesIntersect(LHS: R, RHS: {0x11, 0x1f}); |
2079 | // ends at end of Range |
2080 | AssertRangesIntersect(LHS: R, RHS: {0x11, 0x20}); |
2081 | // ends past Range |
2082 | AssertRangesIntersect(LHS: R, RHS: {0x11, 0x21}); |
2083 | |
2084 | //---------------------------------------------------------------------- |
2085 | // Test ranges that start at last bytes of Range |
2086 | //---------------------------------------------------------------------- |
2087 | // ends at end of Range |
2088 | AssertRangesIntersect(LHS: R, RHS: {0x1f, 0x20}); |
2089 | // ends past Range |
2090 | AssertRangesIntersect(LHS: R, RHS: {0x1f, 0x21}); |
2091 | |
2092 | //---------------------------------------------------------------------- |
2093 | // Test ranges that start after Range |
2094 | //---------------------------------------------------------------------- |
2095 | // empty just past in Range |
2096 | AssertRangesDontIntersect(LHS: R, RHS: {0x20, 0x20}); |
2097 | // valid past Range |
2098 | AssertRangesDontIntersect(LHS: R, RHS: {0x20, 0x21}); |
2099 | } |
2100 | |
2101 | TEST(DWARFDebugInfo, TestDWARFDieRangeInfoIntersects) { |
2102 | |
2103 | DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}}); |
2104 | |
2105 | // Test empty range |
2106 | AssertRangesDontIntersect(LHS: Ranges, Ranges: {}); |
2107 | // Test range that appears before all ranges in Ranges |
2108 | AssertRangesDontIntersect(LHS: Ranges, Ranges: {{0x00, 0x10}}); |
2109 | // Test range that appears between ranges in Ranges |
2110 | AssertRangesDontIntersect(LHS: Ranges, Ranges: {{0x20, 0x30}}); |
2111 | // Test range that appears after ranges in Ranges |
2112 | AssertRangesDontIntersect(LHS: Ranges, Ranges: {{0x40, 0x50}}); |
2113 | |
2114 | // Test range that start before first range |
2115 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x00, 0x11}}); |
2116 | // Test range that start at first range |
2117 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x10, 0x11}}); |
2118 | // Test range that start in first range |
2119 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x11, 0x12}}); |
2120 | // Test range that start at end of first range |
2121 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x1f, 0x20}}); |
2122 | // Test range that starts at end of first range |
2123 | AssertRangesDontIntersect(LHS: Ranges, Ranges: {{0x20, 0x21}}); |
2124 | // Test range that starts at end of first range |
2125 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x20, 0x31}}); |
2126 | |
2127 | // Test range that start before second range and ends before second |
2128 | AssertRangesDontIntersect(LHS: Ranges, Ranges: {{0x2f, 0x30}}); |
2129 | // Test range that start before second range and ends in second |
2130 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x2f, 0x31}}); |
2131 | // Test range that start at second range |
2132 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x30, 0x31}}); |
2133 | // Test range that start in second range |
2134 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x31, 0x32}}); |
2135 | // Test range that start at end of second range |
2136 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x3f, 0x40}}); |
2137 | // Test range that starts at end of second range |
2138 | AssertRangesDontIntersect(LHS: Ranges, Ranges: {{0x40, 0x41}}); |
2139 | |
2140 | AssertRangesDontIntersect(LHS: Ranges, Ranges: {{0x20, 0x21}, {0x2f, 0x30}}); |
2141 | AssertRangesIntersect(LHS: Ranges, Ranges: {{0x20, 0x21}, {0x2f, 0x31}}); |
2142 | } |
2143 | |
2144 | TEST(DWARFDebugInfo, TestDWARF64UnitLength) { |
2145 | static const char DebugInfoSecRaw[] = |
2146 | "\xff\xff\xff\xff" // DWARF64 mark |
2147 | "\x88\x77\x66\x55\x44\x33\x22\x11" // Length |
2148 | "\x05\x00" // Version |
2149 | "\x01" // DW_UT_compile |
2150 | "\x04" // Address size |
2151 | "\0\0\0\0\0\0\0\0" ; // Offset Into Abbrev. Sec. |
2152 | StringMap<std::unique_ptr<MemoryBuffer>> Sections; |
2153 | Sections.insert(KV: std::make_pair( |
2154 | x: "debug_info" , y: MemoryBuffer::getMemBuffer(InputData: StringRef( |
2155 | DebugInfoSecRaw, sizeof(DebugInfoSecRaw) - 1)))); |
2156 | auto Context = DWARFContext::create(Sections, /* AddrSize = */ 4, |
2157 | /* isLittleEndian = */ true); |
2158 | const auto &Obj = Context->getDWARFObj(); |
2159 | Obj.forEachInfoSections(F: [&](const DWARFSection &Sec) { |
2160 | DWARFUnitHeader ; |
2161 | DWARFDataExtractor Data(Obj, Sec, /* IsLittleEndian = */ true, |
2162 | /* AddressSize = */ 4); |
2163 | uint64_t Offset = 0; |
2164 | ASSERT_THAT_ERROR( |
2165 | Header.extract(*Context, Data, &Offset, DW_SECT_INFO), |
2166 | FailedWithMessage( |
2167 | "DWARF unit from offset 0x00000000 incl. to offset " |
2168 | "0x1122334455667794 excl. extends past section size 0x00000018" )); |
2169 | // Header.extract() returns false because there is not enough space |
2170 | // in the section for the declared length. Anyway, we can check that |
2171 | // the properties are read correctly. |
2172 | ASSERT_EQ(DwarfFormat::DWARF64, Header.getFormat()); |
2173 | ASSERT_EQ(0x1122334455667788ULL, Header.getLength()); |
2174 | ASSERT_EQ(5, Header.getVersion()); |
2175 | ASSERT_EQ(DW_UT_compile, Header.getUnitType()); |
2176 | ASSERT_EQ(4, Header.getAddressByteSize()); |
2177 | |
2178 | // Check that the length can be correctly read in the unit class. |
2179 | DWARFUnitVector DummyUnitVector; |
2180 | DWARFSection DummySec; |
2181 | DWARFCompileUnit CU(*Context, Sec, Header, /* DA = */ 0, /* RS = */ 0, |
2182 | /* LocSection = */ 0, /* SS = */ StringRef(), |
2183 | /* SOS = */ DummySec, /* AOS = */ 0, |
2184 | /* LS = */ DummySec, /* LE = */ true, |
2185 | /* isDWO= */ false, DummyUnitVector); |
2186 | ASSERT_EQ(0x1122334455667788ULL, CU.getLength()); |
2187 | }); |
2188 | } |
2189 | |
2190 | } // end anonymous namespace |
2191 | |