[flang] Fix length handling in character kind implicit conversion (#74586)
[llvm-project.git] / lldb / unittests / SymbolFile / DWARF / DWARFIndexCachingTest.cpp
blobc5f25780a18f33a90be94efa15ede5ffb4ace5fc
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;
24 using namespace lldb_private::plugin::dwarf;
26 static void EncodeDecode(const DIERef &object, ByteOrder byte_order) {
27 const uint8_t addr_size = 8;
28 DataEncoder encoder(byte_order, addr_size);
29 object.Encode(encoder);
30 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
31 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
32 offset_t data_offset = 0;
33 EXPECT_EQ(object, DIERef::Decode(data, &data_offset));
36 static void EncodeDecode(const DIERef &object) {
37 EncodeDecode(object, eByteOrderLittle);
38 EncodeDecode(object, eByteOrderBig);
41 TEST(DWARFIndexCachingTest, DIERefEncodeDecode) {
42 // Tests DIERef::Encode(...) and DIERef::Decode(...)
43 EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugInfo, 0x11223344));
44 EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugTypes, 0x11223344));
45 EncodeDecode(DIERef(100, DIERef::Section::DebugInfo, 0x11223344));
46 EncodeDecode(DIERef(200, DIERef::Section::DebugTypes, 0x11223344));
49 TEST(DWARFIndexCachingTest, DIERefEncodeDecodeMax) {
50 // Tests DIERef::Encode(...) and DIERef::Decode(...)
51 EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugInfo,
52 DIERef::k_die_offset_mask - 1));
53 EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugTypes,
54 DIERef::k_die_offset_mask - 1));
55 EncodeDecode(
56 DIERef(100, DIERef::Section::DebugInfo, DIERef::k_die_offset_mask - 1));
57 EncodeDecode(
58 DIERef(200, DIERef::Section::DebugTypes, DIERef::k_die_offset_mask - 1));
59 EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugInfo,
60 DIERef::k_file_index_mask));
61 EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugTypes,
62 DIERef::k_file_index_mask));
63 EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugInfo,
64 0x11223344));
65 EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugTypes,
66 0x11223344));
69 static void EncodeDecode(const NameToDIE &object, ByteOrder byte_order) {
70 const uint8_t addr_size = 8;
71 DataEncoder encoder(byte_order, addr_size);
72 DataEncoder strtab_encoder(byte_order, addr_size);
73 ConstStringTable const_strtab;
75 object.Encode(encoder, const_strtab);
77 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
78 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
80 const_strtab.Encode(strtab_encoder);
81 llvm::ArrayRef<uint8_t> strtab_bytes = strtab_encoder.GetData();
82 DataExtractor strtab_data(strtab_bytes.data(), strtab_bytes.size(),
83 byte_order, addr_size);
84 StringTableReader strtab_reader;
85 offset_t strtab_data_offset = 0;
86 ASSERT_EQ(strtab_reader.Decode(strtab_data, &strtab_data_offset), true);
88 NameToDIE decoded_object;
89 offset_t data_offset = 0;
90 decoded_object.Decode(data, &data_offset, strtab_reader);
91 EXPECT_EQ(object, decoded_object);
94 static void EncodeDecode(const NameToDIE &object) {
95 EncodeDecode(object, eByteOrderLittle);
96 EncodeDecode(object, eByteOrderBig);
99 TEST(DWARFIndexCachingTest, NameToDIEEncodeDecode) {
100 NameToDIE map;
101 // Make sure an empty NameToDIE map encodes and decodes correctly.
102 EncodeDecode(map);
103 map.Insert(ConstString("hello"),
104 DIERef(std::nullopt, DIERef::Section::DebugInfo, 0x11223344));
105 map.Insert(ConstString("workd"),
106 DIERef(100, DIERef::Section::DebugInfo, 0x11223344));
107 map.Finalize();
108 // Make sure a valid NameToDIE map encodes and decodes correctly.
109 EncodeDecode(map);
112 static void EncodeDecode(const ManualDWARFIndex::IndexSet &object,
113 ByteOrder byte_order) {
114 const uint8_t addr_size = 8;
115 DataEncoder encoder(byte_order, addr_size);
116 DataEncoder strtab_encoder(byte_order, addr_size);
117 object.Encode(encoder);
118 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
119 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
120 ManualDWARFIndex::IndexSet decoded_object;
121 offset_t data_offset = 0;
122 decoded_object.Decode(data, &data_offset);
123 EXPECT_TRUE(object == decoded_object);
126 static void EncodeDecode(const ManualDWARFIndex::IndexSet &object) {
127 EncodeDecode(object, eByteOrderLittle);
128 EncodeDecode(object, eByteOrderBig);
131 TEST(DWARFIndexCachingTest, ManualDWARFIndexIndexSetEncodeDecode) {
132 ManualDWARFIndex::IndexSet set;
133 // Make sure empty IndexSet can be encoded and decoded correctly
134 EncodeDecode(set);
136 dw_offset_t die_offset = 0;
137 // Make sure an IndexSet with only items in IndexSet::function_basenames can
138 // be encoded and decoded correctly.
139 set.function_basenames.Insert(
140 ConstString("a"),
141 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
142 EncodeDecode(set);
143 set.function_basenames.Clear();
144 // Make sure an IndexSet with only items in IndexSet::function_fullnames can
145 // be encoded and decoded correctly.
146 set.function_fullnames.Insert(
147 ConstString("a"),
148 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
149 EncodeDecode(set);
150 set.function_fullnames.Clear();
151 // Make sure an IndexSet with only items in IndexSet::function_methods can
152 // be encoded and decoded correctly.
153 set.function_methods.Insert(
154 ConstString("a"),
155 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
156 EncodeDecode(set);
157 set.function_methods.Clear();
158 // Make sure an IndexSet with only items in IndexSet::function_selectors can
159 // be encoded and decoded correctly.
160 set.function_selectors.Insert(
161 ConstString("a"),
162 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
163 EncodeDecode(set);
164 set.function_selectors.Clear();
165 // Make sure an IndexSet with only items in IndexSet::objc_class_selectors can
166 // be encoded and decoded correctly.
167 set.objc_class_selectors.Insert(
168 ConstString("a"),
169 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
170 EncodeDecode(set);
171 set.objc_class_selectors.Clear();
172 // Make sure an IndexSet with only items in IndexSet::globals can
173 // be encoded and decoded correctly.
174 set.globals.Insert(
175 ConstString("a"),
176 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
177 EncodeDecode(set);
178 set.globals.Clear();
179 // Make sure an IndexSet with only items in IndexSet::types can
180 // be encoded and decoded correctly.
181 set.types.Insert(
182 ConstString("a"),
183 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
184 EncodeDecode(set);
185 set.types.Clear();
186 // Make sure an IndexSet with only items in IndexSet::namespaces can
187 // be encoded and decoded correctly.
188 set.namespaces.Insert(
189 ConstString("a"),
190 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
191 EncodeDecode(set);
192 set.namespaces.Clear();
193 // Make sure that an IndexSet with item in all NameToDIE maps can be
194 // be encoded and decoded correctly.
195 set.function_basenames.Insert(
196 ConstString("a"),
197 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
198 set.function_fullnames.Insert(
199 ConstString("b"),
200 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
201 set.function_methods.Insert(
202 ConstString("c"),
203 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
204 set.function_selectors.Insert(
205 ConstString("d"),
206 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
207 set.objc_class_selectors.Insert(
208 ConstString("e"),
209 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
210 set.globals.Insert(
211 ConstString("f"),
212 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
213 set.types.Insert(
214 ConstString("g"),
215 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
216 set.namespaces.Insert(
217 ConstString("h"),
218 DIERef(std::nullopt, DIERef::Section::DebugInfo, ++die_offset));
219 EncodeDecode(set);
222 static void EncodeDecode(const CacheSignature &object, ByteOrder byte_order,
223 bool encode_result) {
224 const uint8_t addr_size = 8;
225 DataEncoder encoder(byte_order, addr_size);
226 EXPECT_EQ(encode_result, object.Encode(encoder));
227 if (!encode_result)
228 return;
229 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
230 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
231 offset_t data_offset = 0;
232 CacheSignature decoded_object;
233 EXPECT_TRUE(decoded_object.Decode(data, &data_offset));
234 EXPECT_EQ(object, decoded_object);
237 static void EncodeDecode(const CacheSignature &object, bool encode_result) {
238 EncodeDecode(object, eByteOrderLittle, encode_result);
239 EncodeDecode(object, eByteOrderBig, encode_result);
242 TEST(DWARFIndexCachingTest, CacheSignatureTests) {
243 CacheSignature sig;
244 // A cache signature is only considered valid if it has a UUID.
245 sig.m_mod_time = 0x12345678;
246 EXPECT_FALSE(sig.IsValid());
247 EncodeDecode(sig, /*encode_result=*/false);
248 sig.Clear();
250 sig.m_obj_mod_time = 0x12345678;
251 EXPECT_FALSE(sig.IsValid());
252 EncodeDecode(sig, /*encode_result=*/false);
253 sig.Clear();
255 sig.m_uuid = UUID("@\x00\x11\x22\x33\x44\x55\x66\x77", 8);
256 EXPECT_TRUE(sig.IsValid());
257 EncodeDecode(sig, /*encode_result=*/true);
258 sig.m_mod_time = 0x12345678;
259 EXPECT_TRUE(sig.IsValid());
260 EncodeDecode(sig, /*encode_result=*/true);
261 sig.m_obj_mod_time = 0x456789ab;
262 EXPECT_TRUE(sig.IsValid());
263 EncodeDecode(sig, /*encode_result=*/true);
264 sig.m_mod_time = std::nullopt;
265 EXPECT_TRUE(sig.IsValid());
266 EncodeDecode(sig, /*encode_result=*/true);
268 // Recent changes do not allow cache signatures with only a modification time
269 // or object modification time, so make sure if we try to decode such a cache
270 // file that we fail. This verifies that if we try to load an previously
271 // valid cache file where the signature is insufficient, that we will fail to
272 // decode and load these cache files.
273 DataEncoder encoder(eByteOrderLittle, /*addr_size=*/8);
274 encoder.AppendU8(2); // eSignatureModTime
275 encoder.AppendU32(0x12345678);
276 encoder.AppendU8(255); // eSignatureEnd
278 llvm::ArrayRef<uint8_t> bytes = encoder.GetData();
279 DataExtractor data(bytes.data(), bytes.size(), eByteOrderLittle,
280 /*addr_size=*/8);
281 offset_t data_offset = 0;
283 // Make sure we fail to decode a CacheSignature with only a mod time
284 EXPECT_FALSE(sig.Decode(data, &data_offset));
286 // Change the signature data to contain only a eSignatureObjectModTime and
287 // make sure decoding fails as well.
288 encoder.PutU8(/*offset=*/0, 3); // eSignatureObjectModTime
289 data_offset = 0;
290 EXPECT_FALSE(sig.Decode(data, &data_offset));