[AMDGPU][AsmParser][NFC] Translate parsed MIMG instructions to MCInsts automatically.
[llvm-project.git] / lldb / unittests / SymbolFile / DWARF / DWARFIndexCachingTest.cpp
blobe5d2b8eda0e7a8c79e8b6c440d8e1ddcaaadaad4
1 //===-- DWARFIndexCachingTest.cpp -------------------------------------=---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "Plugins/SymbolFile/DWARF/DIERef.h"
10 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
11 #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h"
12 #include "Plugins/SymbolFile/DWARF/NameToDIE.h"
13 #include "TestingSupport/Symbol/YAMLModuleTester.h"
14 #include "lldb/Core/DataFileCache.h"
15 #include "lldb/Core/ModuleList.h"
16 #include "lldb/Utility/DataEncoder.h"
17 #include "lldb/Utility/DataExtractor.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
22 using namespace lldb;
23 using namespace lldb_private;
25 static void EncodeDecode(const DIERef &object, ByteOrder byte_order) {
26 const uint8_t addr_size = 8;
27 DataEncoder encoder(byte_order, addr_size);
28 object.Encode(encoder);
29 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
30 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
31 offset_t data_offset = 0;
32 EXPECT_EQ(object, DIERef::Decode(data, &data_offset));
35 static void EncodeDecode(const DIERef &object) {
36 EncodeDecode(object, eByteOrderLittle);
37 EncodeDecode(object, eByteOrderBig);
40 TEST(DWARFIndexCachingTest, DIERefEncodeDecode) {
41 // Tests DIERef::Encode(...) and DIERef::Decode(...)
42 EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugInfo, 0x11223344));
43 EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugTypes, 0x11223344));
44 EncodeDecode(DIERef(100, DIERef::Section::DebugInfo, 0x11223344));
45 EncodeDecode(DIERef(200, DIERef::Section::DebugTypes, 0x11223344));
48 TEST(DWARFIndexCachingTest, DIERefEncodeDecodeMax) {
49 // Tests DIERef::Encode(...) and DIERef::Decode(...)
50 EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugInfo,
51 DIERef::k_die_offset_mask - 1));
52 EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugTypes,
53 DIERef::k_die_offset_mask - 1));
54 EncodeDecode(
55 DIERef(100, DIERef::Section::DebugInfo, DIERef::k_die_offset_mask - 1));
56 EncodeDecode(
57 DIERef(200, DIERef::Section::DebugTypes, DIERef::k_die_offset_mask - 1));
58 EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugInfo,
59 DIERef::k_file_index_mask));
60 EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugTypes,
61 DIERef::k_file_index_mask));
62 EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugInfo,
63 0x11223344));
64 EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugTypes,
65 0x11223344));
68 static void EncodeDecode(const NameToDIE &object, ByteOrder byte_order) {
69 const uint8_t addr_size = 8;
70 DataEncoder encoder(byte_order, addr_size);
71 DataEncoder strtab_encoder(byte_order, addr_size);
72 ConstStringTable const_strtab;
74 object.Encode(encoder, const_strtab);
76 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
77 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
79 const_strtab.Encode(strtab_encoder);
80 llvm::ArrayRef<uint8_t> strtab_bytes = strtab_encoder.GetData();
81 DataExtractor strtab_data(strtab_bytes.data(), strtab_bytes.size(),
82 byte_order, addr_size);
83 StringTableReader strtab_reader;
84 offset_t strtab_data_offset = 0;
85 ASSERT_EQ(strtab_reader.Decode(strtab_data, &strtab_data_offset), true);
87 NameToDIE decoded_object;
88 offset_t data_offset = 0;
89 decoded_object.Decode(data, &data_offset, strtab_reader);
90 EXPECT_EQ(object, decoded_object);
93 static void EncodeDecode(const NameToDIE &object) {
94 EncodeDecode(object, eByteOrderLittle);
95 EncodeDecode(object, eByteOrderBig);
98 TEST(DWARFIndexCachingTest, NameToDIEEncodeDecode) {
99 NameToDIE map;
100 // Make sure an empty NameToDIE map encodes and decodes correctly.
101 EncodeDecode(map);
102 map.Insert(ConstString("hello"),
103 DIERef(std::nullopt, DIERef::Section::DebugInfo, 0x11223344));
104 map.Insert(ConstString("workd"),
105 DIERef(100, DIERef::Section::DebugInfo, 0x11223344));
106 map.Finalize();
107 // Make sure a valid NameToDIE map encodes and decodes correctly.
108 EncodeDecode(map);
111 static void EncodeDecode(const ManualDWARFIndex::IndexSet &object,
112 ByteOrder byte_order) {
113 const uint8_t addr_size = 8;
114 DataEncoder encoder(byte_order, addr_size);
115 DataEncoder strtab_encoder(byte_order, addr_size);
116 object.Encode(encoder);
117 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
118 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
119 ManualDWARFIndex::IndexSet decoded_object;
120 offset_t data_offset = 0;
121 decoded_object.Decode(data, &data_offset);
122 EXPECT_TRUE(object == decoded_object);
125 static void EncodeDecode(const ManualDWARFIndex::IndexSet &object) {
126 EncodeDecode(object, eByteOrderLittle);
127 EncodeDecode(object, eByteOrderBig);
130 TEST(DWARFIndexCachingTest, ManualDWARFIndexIndexSetEncodeDecode) {
131 ManualDWARFIndex::IndexSet set;
132 // Make sure empty IndexSet can be encoded and decoded correctly
133 EncodeDecode(set);
135 dw_offset_t die_offset = 0;
136 // Make sure an IndexSet with only items in IndexSet::function_basenames can
137 // be encoded and decoded correctly.
138 set.function_basenames.Insert(
139 ConstString("a"),
140 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
141 EncodeDecode(set);
142 set.function_basenames.Clear();
143 // Make sure an IndexSet with only items in IndexSet::function_fullnames can
144 // be encoded and decoded correctly.
145 set.function_fullnames.Insert(
146 ConstString("a"),
147 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
148 EncodeDecode(set);
149 set.function_fullnames.Clear();
150 // Make sure an IndexSet with only items in IndexSet::function_methods can
151 // be encoded and decoded correctly.
152 set.function_methods.Insert(
153 ConstString("a"),
154 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
155 EncodeDecode(set);
156 set.function_methods.Clear();
157 // Make sure an IndexSet with only items in IndexSet::function_selectors can
158 // be encoded and decoded correctly.
159 set.function_selectors.Insert(
160 ConstString("a"),
161 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
162 EncodeDecode(set);
163 set.function_selectors.Clear();
164 // Make sure an IndexSet with only items in IndexSet::objc_class_selectors can
165 // be encoded and decoded correctly.
166 set.objc_class_selectors.Insert(
167 ConstString("a"),
168 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
169 EncodeDecode(set);
170 set.objc_class_selectors.Clear();
171 // Make sure an IndexSet with only items in IndexSet::globals can
172 // be encoded and decoded correctly.
173 set.globals.Insert(
174 ConstString("a"),
175 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
176 EncodeDecode(set);
177 set.globals.Clear();
178 // Make sure an IndexSet with only items in IndexSet::types can
179 // be encoded and decoded correctly.
180 set.types.Insert(
181 ConstString("a"),
182 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
183 EncodeDecode(set);
184 set.types.Clear();
185 // Make sure an IndexSet with only items in IndexSet::namespaces can
186 // be encoded and decoded correctly.
187 set.namespaces.Insert(
188 ConstString("a"),
189 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
190 EncodeDecode(set);
191 set.namespaces.Clear();
192 // Make sure that an IndexSet with item in all NameToDIE maps can be
193 // be encoded and decoded correctly.
194 set.function_basenames.Insert(
195 ConstString("a"),
196 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
197 set.function_fullnames.Insert(
198 ConstString("b"),
199 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
200 set.function_methods.Insert(
201 ConstString("c"),
202 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
203 set.function_selectors.Insert(
204 ConstString("d"),
205 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
206 set.objc_class_selectors.Insert(
207 ConstString("e"),
208 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
209 set.globals.Insert(
210 ConstString("f"),
211 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
212 set.types.Insert(
213 ConstString("g"),
214 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
215 set.namespaces.Insert(
216 ConstString("h"),
217 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
218 EncodeDecode(set);
221 static void EncodeDecode(const CacheSignature &object, ByteOrder byte_order,
222 bool encode_result) {
223 const uint8_t addr_size = 8;
224 DataEncoder encoder(byte_order, addr_size);
225 EXPECT_EQ(encode_result, object.Encode(encoder));
226 if (!encode_result)
227 return;
228 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
229 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
230 offset_t data_offset = 0;
231 CacheSignature decoded_object;
232 EXPECT_TRUE(decoded_object.Decode(data, &data_offset));
233 EXPECT_EQ(object, decoded_object);
236 static void EncodeDecode(const CacheSignature &object, bool encode_result) {
237 EncodeDecode(object, eByteOrderLittle, encode_result);
238 EncodeDecode(object, eByteOrderBig, encode_result);
241 TEST(DWARFIndexCachingTest, CacheSignatureTests) {
242 CacheSignature sig;
243 // A cache signature is only considered valid if it has a UUID.
244 sig.m_mod_time = 0x12345678;
245 EXPECT_FALSE(sig.IsValid());
246 EncodeDecode(sig, /*encode_result=*/false);
247 sig.Clear();
249 sig.m_obj_mod_time = 0x12345678;
250 EXPECT_FALSE(sig.IsValid());
251 EncodeDecode(sig, /*encode_result=*/false);
252 sig.Clear();
254 sig.m_uuid = UUID("@\x00\x11\x22\x33\x44\x55\x66\x77", 8);
255 EXPECT_TRUE(sig.IsValid());
256 EncodeDecode(sig, /*encode_result=*/true);
257 sig.m_mod_time = 0x12345678;
258 EXPECT_TRUE(sig.IsValid());
259 EncodeDecode(sig, /*encode_result=*/true);
260 sig.m_obj_mod_time = 0x456789ab;
261 EXPECT_TRUE(sig.IsValid());
262 EncodeDecode(sig, /*encode_result=*/true);
263 sig.m_mod_time = std::nullopt;
264 EXPECT_TRUE(sig.IsValid());
265 EncodeDecode(sig, /*encode_result=*/true);
267 // Recent changes do not allow cache signatures with only a modification time
268 // or object modification time, so make sure if we try to decode such a cache
269 // file that we fail. This verifies that if we try to load an previously
270 // valid cache file where the signature is insufficient, that we will fail to
271 // decode and load these cache files.
272 DataEncoder encoder(eByteOrderLittle, /*addr_size=*/8);
273 encoder.AppendU8(2); // eSignatureModTime
274 encoder.AppendU32(0x12345678);
275 encoder.AppendU8(255); // eSignatureEnd
277 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
278 DataExtractor data(bytes.data(), bytes.size(), eByteOrderLittle,
279 /*addr_size=*/8);
280 offset_t data_offset = 0;
282 // Make sure we fail to decode a CacheSignature with only a mod time
283 EXPECT_FALSE(sig.Decode(data, &data_offset));
285 // Change the signature data to contain only a eSignatureObjectModTime and
286 // make sure decoding fails as well.
287 encoder.PutU8(/*offset=*/0, 3); // eSignatureObjectModTime
288 data_offset = 0;
289 EXPECT_FALSE(sig.Decode(data, &data_offset));