lldb/unittests/SymbolFile/DWARF/DWARFIndexCachingTest.cpp (153 lines of code) (raw):

//===-- DWARFIndexCachingTest.cpp -------------------------------------=---===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "Plugins/SymbolFile/DWARF/DIERef.h" #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" #include "Plugins/SymbolFile/DWARF/NameToDIE.h" #include "TestingSupport/Symbol/YAMLModuleTester.h" #include "lldb/Core/DataFileCache.h" #include "lldb/Core/ModuleList.h" #include "lldb/Utility/DataEncoder.h" #include "lldb/Utility/DataExtractor.h" #include "llvm/ADT/STLExtras.h" #include "gmock/gmock.h" #include "gtest/gtest.h" using namespace lldb; using namespace lldb_private; static void EncodeDecode(const DIERef &object, ByteOrder byte_order) { const uint8_t addr_size = 8; DataEncoder encoder(byte_order, addr_size); object.Encode(encoder); llvm::ArrayRef<uint8_t> bytes = encoder.GetData(); DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size); offset_t data_offset = 0; EXPECT_EQ(object, DIERef::Decode(data, &data_offset)); } static void EncodeDecode(const DIERef &object) { EncodeDecode(object, eByteOrderLittle); EncodeDecode(object, eByteOrderBig); } TEST(DWARFIndexCachingTest, DIERefEncodeDecode) { // Tests DIERef::Encode(...) and DIERef::Decode(...) EncodeDecode(DIERef(llvm::None, DIERef::Section::DebugInfo, 0x11223344)); EncodeDecode(DIERef(llvm::None, DIERef::Section::DebugTypes, 0x11223344)); EncodeDecode(DIERef(100, DIERef::Section::DebugInfo, 0x11223344)); EncodeDecode(DIERef(200, DIERef::Section::DebugTypes, 0x11223344)); } static void EncodeDecode(const NameToDIE &object, ByteOrder byte_order) { const uint8_t addr_size = 8; DataEncoder encoder(byte_order, addr_size); DataEncoder strtab_encoder(byte_order, addr_size); ConstStringTable const_strtab; object.Encode(encoder, const_strtab); llvm::ArrayRef<uint8_t> bytes = encoder.GetData(); DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size); const_strtab.Encode(strtab_encoder); llvm::ArrayRef<uint8_t> strtab_bytes = strtab_encoder.GetData(); DataExtractor strtab_data(strtab_bytes.data(), strtab_bytes.size(), byte_order, addr_size); StringTableReader strtab_reader; offset_t strtab_data_offset = 0; ASSERT_EQ(strtab_reader.Decode(strtab_data, &strtab_data_offset), true); NameToDIE decoded_object; offset_t data_offset = 0; decoded_object.Decode(data, &data_offset, strtab_reader); EXPECT_TRUE(object == decoded_object); } static void EncodeDecode(const NameToDIE &object) { EncodeDecode(object, eByteOrderLittle); EncodeDecode(object, eByteOrderBig); } TEST(DWARFIndexCachingTest, NameToDIEEncodeDecode) { NameToDIE map; // Make sure an empty NameToDIE map encodes and decodes correctly. EncodeDecode(map); map.Insert(ConstString("hello"), DIERef(llvm::None, DIERef::Section::DebugInfo, 0x11223344)); map.Insert(ConstString("workd"), DIERef(100, DIERef::Section::DebugInfo, 0x11223344)); // Make sure a valid NameToDIE map encodes and decodes correctly. EncodeDecode(map); } static void EncodeDecode(const ManualDWARFIndex::IndexSet &object, ByteOrder byte_order) { const uint8_t addr_size = 8; DataEncoder encoder(byte_order, addr_size); DataEncoder strtab_encoder(byte_order, addr_size); object.Encode(encoder); llvm::ArrayRef<uint8_t> bytes = encoder.GetData(); DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size); ManualDWARFIndex::IndexSet decoded_object; offset_t data_offset = 0; decoded_object.Decode(data, &data_offset); EXPECT_TRUE(object == decoded_object); } static void EncodeDecode(const ManualDWARFIndex::IndexSet &object) { EncodeDecode(object, eByteOrderLittle); EncodeDecode(object, eByteOrderBig); } TEST(DWARFIndexCachingTest, ManualDWARFIndexIndexSetEncodeDecode) { ManualDWARFIndex::IndexSet set; // Make sure empty IndexSet can be encoded and decoded correctly EncodeDecode(set); dw_offset_t die_offset = 0; // Make sure an IndexSet with only items in IndexSet::function_basenames can // be encoded and decoded correctly. set.function_basenames.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); set.function_basenames.Clear(); // Make sure an IndexSet with only items in IndexSet::function_fullnames can // be encoded and decoded correctly. set.function_fullnames.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); set.function_fullnames.Clear(); // Make sure an IndexSet with only items in IndexSet::function_methods can // be encoded and decoded correctly. set.function_methods.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); set.function_methods.Clear(); // Make sure an IndexSet with only items in IndexSet::function_selectors can // be encoded and decoded correctly. set.function_selectors.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); set.function_selectors.Clear(); // Make sure an IndexSet with only items in IndexSet::objc_class_selectors can // be encoded and decoded correctly. set.objc_class_selectors.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); set.objc_class_selectors.Clear(); // Make sure an IndexSet with only items in IndexSet::globals can // be encoded and decoded correctly. set.globals.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); set.globals.Clear(); // Make sure an IndexSet with only items in IndexSet::types can // be encoded and decoded correctly. set.types.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); set.types.Clear(); // Make sure an IndexSet with only items in IndexSet::namespaces can // be encoded and decoded correctly. set.namespaces.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); set.namespaces.Clear(); // Make sure that an IndexSet with item in all NameToDIE maps can be // be encoded and decoded correctly. set.function_basenames.Insert( ConstString("a"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); set.function_fullnames.Insert( ConstString("b"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); set.function_methods.Insert( ConstString("c"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); set.function_selectors.Insert( ConstString("d"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); set.objc_class_selectors.Insert( ConstString("e"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); set.globals.Insert( ConstString("f"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); set.types.Insert( ConstString("g"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); set.namespaces.Insert( ConstString("h"), DIERef(llvm::None, DIERef::Section::DebugInfo, ++die_offset)); EncodeDecode(set); }