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 //===----------------------------------------------------------------------===// 8 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" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 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)); 33 } 34 35 static void EncodeDecode(const DIERef &object) { 36 EncodeDecode(object, eByteOrderLittle); 37 EncodeDecode(object, eByteOrderBig); 38 } 39 40 TEST(DWARFIndexCachingTest, DIERefEncodeDecode) { 41 // Tests DIERef::Encode(...) and DIERef::Decode(...) 42 EncodeDecode(DIERef(llvm::None, DIERef::Section::DebugInfo, 0x11223344)); 43 EncodeDecode(DIERef(llvm::None, DIERef::Section::DebugTypes, 0x11223344)); 44 EncodeDecode(DIERef(100, DIERef::Section::DebugInfo, 0x11223344)); 45 EncodeDecode(DIERef(200, DIERef::Section::DebugTypes, 0x11223344)); 46 } 47 48 static void EncodeDecode(const NameToDIE &object, ByteOrder byte_order) { 49 const uint8_t addr_size = 8; 50 DataEncoder encoder(byte_order, addr_size); 51 DataEncoder strtab_encoder(byte_order, addr_size); 52 ConstStringTable const_strtab; 53 54 object.Encode(encoder, const_strtab); 55 56 llvm::ArrayRef<uint8_t> bytes = encoder.GetData(); 57 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size); 58 59 const_strtab.Encode(strtab_encoder); 60 llvm::ArrayRef<uint8_t> strtab_bytes = strtab_encoder.GetData(); 61 DataExtractor strtab_data(strtab_bytes.data(), strtab_bytes.size(), 62 byte_order, addr_size); 63 StringTableReader strtab_reader; 64 offset_t strtab_data_offset = 0; 65 ASSERT_EQ(strtab_reader.Decode(strtab_data, &strtab_data_offset), true); 66 67 NameToDIE decoded_object; 68 offset_t data_offset = 0; 69 decoded_object.Decode(data, &data_offset, strtab_reader); 70 EXPECT_TRUE(object == decoded_object); 71 } 72 73 static void EncodeDecode(const NameToDIE &object) { 74 EncodeDecode(object, eByteOrderLittle); 75 EncodeDecode(object, eByteOrderBig); 76 } 77 78 TEST(DWARFIndexCachingTest, NameToDIEEncodeDecode) { 79 NameToDIE map; 80 // Make sure an empty NameToDIE map encodes and decodes correctly. 81 EncodeDecode(map); 82 map.Insert(ConstString("hello"), 83 DIERef(llvm::None, DIERef::Section::DebugInfo, 0x11223344)); 84 map.Insert(ConstString("workd"), 85 DIERef(100, DIERef::Section::DebugInfo, 0x11223344)); 86 // Make sure a valid NameToDIE map encodes and decodes correctly. 87 EncodeDecode(map); 88 } 89 90 static void EncodeDecode(const ManualDWARFIndex::IndexSet &object, 91 ByteOrder byte_order) { 92 const uint8_t addr_size = 8; 93 DataEncoder encoder(byte_order, addr_size); 94 DataEncoder strtab_encoder(byte_order, addr_size); 95 object.Encode(encoder); 96 llvm::ArrayRef<uint8_t> bytes = encoder.GetData(); 97 DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size); 98 ManualDWARFIndex::IndexSet decoded_object; 99 offset_t data_offset = 0; 100 decoded_object.Decode(data, &data_offset); 101 EXPECT_TRUE(object == decoded_object); 102 } 103 104 static void EncodeDecode(const ManualDWARFIndex::IndexSet &object) { 105 EncodeDecode(object, eByteOrderLittle); 106 EncodeDecode(object, eByteOrderBig); 107 } 108 109 TEST(DWARFIndexCachingTest, ManualDWARFIndexIndexSetEncodeDecode) { 110 ManualDWARFIndex::IndexSet set; 111 // Make sure empty IndexSet can be encoded and decoded correctly 112 EncodeDecode(set); 113 114 dw_offset_t die_offset = 0; 115 // Make sure an IndexSet with only items in IndexSet::function_basenames can 116 // be encoded and decoded correctly. 117 set.function_basenames.Insert( 118 ConstString("a"), 119 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 120 EncodeDecode(set); 121 set.function_basenames.Clear(); 122 // Make sure an IndexSet with only items in IndexSet::function_fullnames can 123 // be encoded and decoded correctly. 124 set.function_fullnames.Insert( 125 ConstString("a"), 126 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 127 EncodeDecode(set); 128 set.function_fullnames.Clear(); 129 // Make sure an IndexSet with only items in IndexSet::function_methods can 130 // be encoded and decoded correctly. 131 set.function_methods.Insert( 132 ConstString("a"), 133 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 134 EncodeDecode(set); 135 set.function_methods.Clear(); 136 // Make sure an IndexSet with only items in IndexSet::function_selectors can 137 // be encoded and decoded correctly. 138 set.function_selectors.Insert( 139 ConstString("a"), 140 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 141 EncodeDecode(set); 142 set.function_selectors.Clear(); 143 // Make sure an IndexSet with only items in IndexSet::objc_class_selectors can 144 // be encoded and decoded correctly. 145 set.objc_class_selectors.Insert( 146 ConstString("a"), 147 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 148 EncodeDecode(set); 149 set.objc_class_selectors.Clear(); 150 // Make sure an IndexSet with only items in IndexSet::globals can 151 // be encoded and decoded correctly. 152 set.globals.Insert( 153 ConstString("a"), 154 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 155 EncodeDecode(set); 156 set.globals.Clear(); 157 // Make sure an IndexSet with only items in IndexSet::types can 158 // be encoded and decoded correctly. 159 set.types.Insert( 160 ConstString("a"), 161 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 162 EncodeDecode(set); 163 set.types.Clear(); 164 // Make sure an IndexSet with only items in IndexSet::namespaces can 165 // be encoded and decoded correctly. 166 set.namespaces.Insert( 167 ConstString("a"), 168 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 169 EncodeDecode(set); 170 set.namespaces.Clear(); 171 // Make sure that an IndexSet with item in all NameToDIE maps can be 172 // be encoded and decoded correctly. 173 set.function_basenames.Insert( 174 ConstString("a"), 175 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 176 set.function_fullnames.Insert( 177 ConstString("b"), 178 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 179 set.function_methods.Insert( 180 ConstString("c"), 181 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 182 set.function_selectors.Insert( 183 ConstString("d"), 184 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 185 set.objc_class_selectors.Insert( 186 ConstString("e"), 187 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 188 set.globals.Insert( 189 ConstString("f"), 190 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 191 set.types.Insert( 192 ConstString("g"), 193 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 194 set.namespaces.Insert( 195 ConstString("h"), 196 DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); 197 EncodeDecode(set); 198 } 199