//===-- DWARFDIETest.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/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h" #include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h" #include "TestingSupport/Symbol/YAMLModuleTester.h" #include "llvm/ADT/STLExtras.h" #include "gmock/gmock.h" #include "gtest/gtest.h" using namespace lldb; using namespace lldb_private; using namespace lldb_private::plugin::dwarf; using StringRef = llvm::StringRef; static void check_num_matches(DebugNamesDWARFIndex &index, int expected_num_matches, llvm::ArrayRef ctx_entries) { DWARFDeclContext ctx(ctx_entries); int num_matches = 0; index.GetFullyQualifiedType(ctx, [&](DWARFDIE die) { num_matches++; return true; }); ASSERT_EQ(num_matches, expected_num_matches); } static DWARFDeclContext::Entry make_entry(const char *c) { return DWARFDeclContext::Entry(llvm::dwarf::DW_TAG_class_type, c); } TEST(DWARFDebugNamesIndexTest, FullyQualifiedQueryWithIDXParent) { const char *yamldata = R"( --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_EXEC Machine: EM_386 DWARF: debug_str: - '1' - '2' - '3' debug_abbrev: - Table: # We intentionally don't nest types in debug_info: if the nesting is not # inferred from debug_names, we want the test to fail. - Code: 0x1 Tag: DW_TAG_compile_unit Children: DW_CHILDREN_yes - Code: 0x2 Tag: DW_TAG_class_type Children: DW_CHILDREN_no Attributes: - Attribute: DW_AT_name Form: DW_FORM_strp debug_info: - Version: 4 AddrSize: 8 Entries: - AbbrCode: 0x1 - AbbrCode: 0x2 Values: - Value: 0x0 # Name "1" - AbbrCode: 0x2 Values: - Value: 0x2 # Name "2" - AbbrCode: 0x2 Values: - Value: 0x4 # Name "3" - AbbrCode: 0x0 debug_names: Abbreviations: - Code: 0x11 Tag: DW_TAG_class_type Indices: - Idx: DW_IDX_parent Form: DW_FORM_flag_present - Idx: DW_IDX_die_offset Form: DW_FORM_ref4 - Code: 0x22 Tag: DW_TAG_class_type Indices: - Idx: DW_IDX_parent Form: DW_FORM_ref4 - Idx: DW_IDX_die_offset Form: DW_FORM_ref4 Entries: - Name: 0x0 # strp to Name1 Code: 0x11 Values: - 0xc # Die offset to entry named "1" - Name: 0x2 # strp to Name2 Code: 0x22 Values: - 0x0 # Parent = First entry ("1") - 0x11 # Die offset to entry named "1:2" - Name: 0x4 # strp to Name3 Code: 0x22 Values: - 0x6 # Parent = Second entry ("1::2") - 0x16 # Die offset to entry named "1::2::3" - Name: 0x4 # strp to Name3 Code: 0x11 Values: - 0x16 # Die offset to entry named "3" )"; YAMLModuleTester t(yamldata); auto *symbol_file = llvm::cast(t.GetModule()->GetSymbolFile()); auto *index = static_cast(symbol_file->getIndex()); ASSERT_NE(index, nullptr); check_num_matches(*index, 1, {make_entry("1")}); check_num_matches(*index, 1, {make_entry("2"), make_entry("1")}); check_num_matches(*index, 1, {make_entry("3"), make_entry("2"), make_entry("1")}); check_num_matches(*index, 0, {make_entry("2")}); check_num_matches(*index, 1, {make_entry("3")}); } TEST(DWARFDebugNamesIndexTest, FullyQualifiedQueryWithoutIDXParent) { const char *yamldata = R"( --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_EXEC Machine: EM_386 DWARF: debug_str: - '1' - '2' debug_abbrev: - Table: - Code: 0x1 Tag: DW_TAG_compile_unit Children: DW_CHILDREN_yes - Code: 0x2 Tag: DW_TAG_class_type Children: DW_CHILDREN_yes Attributes: - Attribute: DW_AT_name Form: DW_FORM_strp - Code: 0x3 Tag: DW_TAG_class_type Children: DW_CHILDREN_no Attributes: - Attribute: DW_AT_name Form: DW_FORM_strp debug_info: - Version: 4 AddrSize: 8 Entries: - AbbrCode: 0x1 - AbbrCode: 0x2 Values: - Value: 0x0 # Name "1" - AbbrCode: 0x3 Values: - Value: 0x2 # Name "2" - AbbrCode: 0x0 - AbbrCode: 0x3 Values: - Value: 0x2 # Name "2" - AbbrCode: 0x0 debug_names: Abbreviations: - Code: 0x1 Tag: DW_TAG_class_type Indices: - Idx: DW_IDX_die_offset Form: DW_FORM_ref4 Entries: - Name: 0x0 # strp to Name1 Code: 0x1 Values: - 0xc # Die offset to entry named "1" - Name: 0x2 # strp to Name2 Code: 0x1 Values: - 0x11 # Die offset to entry named "1::2" - Name: 0x2 # strp to Name2 Code: 0x1 Values: - 0x17 # Die offset to entry named "2" )"; YAMLModuleTester t(yamldata); auto *symbol_file = llvm::cast(t.GetModule()->GetSymbolFile()); auto *index = static_cast(symbol_file->getIndex()); ASSERT_NE(index, nullptr); check_num_matches(*index, 1, {make_entry("1")}); check_num_matches(*index, 1, {make_entry("2"), make_entry("1")}); check_num_matches(*index, 1, {make_entry("2")}); }