//===-- 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 "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; TEST(DWARFDIETest, ChildIteration) { // Tests DWARFDIE::child_iterator. const char *yamldata = R"( --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_EXEC Machine: EM_386 DWARF: debug_abbrev: - Table: - Code: 0x00000001 Tag: DW_TAG_compile_unit Children: DW_CHILDREN_yes Attributes: - Attribute: DW_AT_language Form: DW_FORM_data2 - Code: 0x00000002 Tag: DW_TAG_base_type Children: DW_CHILDREN_no Attributes: - Attribute: DW_AT_encoding Form: DW_FORM_data1 - Attribute: DW_AT_byte_size Form: DW_FORM_data1 debug_info: - Version: 4 AddrSize: 8 Entries: - AbbrCode: 0x00000001 Values: - Value: 0x000000000000000C - AbbrCode: 0x00000002 Values: - Value: 0x0000000000000007 # DW_ATE_unsigned - Value: 0x0000000000000004 - AbbrCode: 0x00000002 Values: - Value: 0x0000000000000007 # DW_ATE_unsigned - Value: 0x0000000000000008 - AbbrCode: 0x00000002 Values: - Value: 0x0000000000000005 # DW_ATE_signed - Value: 0x0000000000000008 - AbbrCode: 0x00000000 )"; YAMLModuleTester t(yamldata); ASSERT_TRUE((bool)t.GetDwarfUnit()); DWARFUnit *unit = t.GetDwarfUnit(); const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); // Create a DWARFDIE that has three DW_TAG_base_type children. DWARFDIE top_die(unit, die_first); // Create the iterator range that has the three tags as elements. llvm::iterator_range children = top_die.children(); // Compare begin() to the first child DIE. DWARFDIE::child_iterator child_iter = children.begin(); ASSERT_NE(child_iter, children.end()); const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild(); EXPECT_EQ((*child_iter).GetDIE(), die_child0); // Step to the second child DIE. ++child_iter; ASSERT_NE(child_iter, children.end()); const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling(); EXPECT_EQ((*child_iter).GetDIE(), die_child1); // Step to the third child DIE. ++child_iter; ASSERT_NE(child_iter, children.end()); const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling(); EXPECT_EQ((*child_iter).GetDIE(), die_child2); // Step to the end of the range. ++child_iter; EXPECT_EQ(child_iter, children.end()); // Take one of the DW_TAG_base_type DIEs (which has no children) and make // sure the children range is now empty. DWARFDIE no_children_die(unit, die_child0); EXPECT_TRUE(no_children_die.children().empty()); } TEST(DWARFDIETest, PeekName) { const char *yamldata = R"( --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_EXEC Machine: EM_386 DWARF: debug_str: - 'NameType1' - 'NameType2' debug_abbrev: - Table: - Code: 0x00000001 Tag: DW_TAG_compile_unit Children: DW_CHILDREN_yes Attributes: - Attribute: DW_AT_language Form: DW_FORM_data2 - Code: 0x00000002 Tag: DW_TAG_base_type Children: DW_CHILDREN_no Attributes: - Attribute: DW_AT_name Form: DW_FORM_strp - Code: 0x00000003 Tag: DW_TAG_base_type Children: DW_CHILDREN_no Attributes: - Attribute: DW_AT_abstract_origin Form: DW_FORM_ref1 - Code: 0x00000004 Tag: DW_TAG_base_type Children: DW_CHILDREN_no Attributes: - Attribute: DW_AT_specification Form: DW_FORM_ref1 debug_info: - Version: 4 AddrSize: 8 Entries: - AbbrCode: 0x00000001 Values: - Value: 0x000000000000000C - AbbrCode: 0x00000002 Values: - Value: 0x0000000000000000 # Name = NameType1 - AbbrCode: 0x00000002 Values: - Value: 0x000000000000000a # Name = NameType2 - AbbrCode: 0x00000003 Values: - Value: 0x000000000000000e # Ref abstract origin to NameType1 DIE. - AbbrCode: 0x00000004 Values: - Value: 0x0000000000000013 # Ref specification to NameType2 DIE. - AbbrCode: 0x00000000 )"; YAMLModuleTester t(yamldata); auto *symbol_file = llvm::cast(t.GetModule()->GetSymbolFile()); auto &debug_info = symbol_file->DebugInfo(); DIERef first_die(std::nullopt, DIERef::Section::DebugInfo, 11 /*FirstDIEOffset*/); EXPECT_EQ(debug_info.PeekDIEName(first_die), ""); DIERef second_die(std::nullopt, DIERef::Section::DebugInfo, 14); EXPECT_EQ(debug_info.PeekDIEName(second_die), "NameType1"); DIERef third_die(std::nullopt, DIERef::Section::DebugInfo, 19); EXPECT_EQ(debug_info.PeekDIEName(third_die), "NameType2"); DIERef fourth_die(std::nullopt, DIERef::Section::DebugInfo, 24); EXPECT_EQ(debug_info.PeekDIEName(fourth_die), "NameType1"); DIERef fifth_die(std::nullopt, DIERef::Section::DebugInfo, 26); EXPECT_EQ(debug_info.PeekDIEName(fifth_die), "NameType2"); }