1095 lines · cpp
1//===-- DWARFDIETest.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"10#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"11#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"12#include "TestingSupport/Symbol/YAMLModuleTester.h"13#include "lldb/Core/dwarf.h"14#include "lldb/Symbol/Type.h"15#include "lldb/lldb-private-enumerations.h"16#include "llvm/ADT/STLExtras.h"17#include "gmock/gmock.h"18#include "gtest/gtest.h"19 20using namespace lldb;21using namespace lldb_private;22using namespace lldb_private::plugin::dwarf;23using namespace llvm::dwarf;24 25TEST(DWARFDIETest, ChildIteration) {26 // Tests DWARFDIE::child_iterator.27 28 const char *yamldata = R"(29--- !ELF30FileHeader:31 Class: ELFCLASS6432 Data: ELFDATA2LSB33 Type: ET_EXEC34 Machine: EM_38635DWARF:36 debug_abbrev:37 - Table:38 - Code: 0x0000000139 Tag: DW_TAG_compile_unit40 Children: DW_CHILDREN_yes41 Attributes:42 - Attribute: DW_AT_language43 Form: DW_FORM_data244 - Code: 0x0000000245 Tag: DW_TAG_base_type46 Children: DW_CHILDREN_no47 Attributes:48 - Attribute: DW_AT_encoding49 Form: DW_FORM_data150 - Attribute: DW_AT_byte_size51 Form: DW_FORM_data152 debug_info:53 - Version: 454 AddrSize: 855 Entries:56 - AbbrCode: 0x0000000157 Values:58 - Value: 0x000000000000000C59 - AbbrCode: 0x0000000260 Values:61 - Value: 0x0000000000000007 # DW_ATE_unsigned62 - Value: 0x000000000000000463 - AbbrCode: 0x0000000264 Values:65 - Value: 0x0000000000000007 # DW_ATE_unsigned66 - Value: 0x000000000000000867 - AbbrCode: 0x0000000268 Values:69 - Value: 0x0000000000000005 # DW_ATE_signed70 - Value: 0x000000000000000871 - AbbrCode: 0x0000000072)";73 74 YAMLModuleTester t(yamldata);75 ASSERT_TRUE((bool)t.GetDwarfUnit());76 77 DWARFUnit *unit = t.GetDwarfUnit();78 const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE();79 80 // Create a DWARFDIE that has three DW_TAG_base_type children.81 DWARFDIE top_die(unit, die_first);82 83 // Create the iterator range that has the three tags as elements.84 llvm::iterator_range<DWARFDIE::child_iterator> children = top_die.children();85 86 // Compare begin() to the first child DIE.87 DWARFDIE::child_iterator child_iter = children.begin();88 ASSERT_NE(child_iter, children.end());89 const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild();90 EXPECT_EQ((*child_iter).GetDIE(), die_child0);91 92 // Step to the second child DIE.93 ++child_iter;94 ASSERT_NE(child_iter, children.end());95 const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling();96 EXPECT_EQ((*child_iter).GetDIE(), die_child1);97 98 // Step to the third child DIE.99 ++child_iter;100 ASSERT_NE(child_iter, children.end());101 const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling();102 EXPECT_EQ((*child_iter).GetDIE(), die_child2);103 104 // Step to the end of the range.105 ++child_iter;106 EXPECT_EQ(child_iter, children.end());107 108 // Take one of the DW_TAG_base_type DIEs (which has no children) and make109 // sure the children range is now empty.110 DWARFDIE no_children_die(unit, die_child0);111 EXPECT_TRUE(no_children_die.children().empty());112}113 114TEST(DWARFDIETest, PeekName) {115 const char *yamldata = R"(116--- !ELF117FileHeader:118 Class: ELFCLASS64119 Data: ELFDATA2LSB120 Type: ET_EXEC121 Machine: EM_386122DWARF:123 debug_str:124 - 'NameType1'125 - 'NameType2'126 debug_abbrev:127 - Table:128 - Code: 0x00000001129 Tag: DW_TAG_compile_unit130 Children: DW_CHILDREN_yes131 Attributes:132 - Attribute: DW_AT_language133 Form: DW_FORM_data2134 - Code: 0x00000002135 Tag: DW_TAG_base_type136 Children: DW_CHILDREN_no137 Attributes:138 - Attribute: DW_AT_name139 Form: DW_FORM_strp140 - Code: 0x00000003141 Tag: DW_TAG_base_type142 Children: DW_CHILDREN_no143 Attributes:144 - Attribute: DW_AT_abstract_origin145 Form: DW_FORM_ref1146 - Code: 0x00000004147 Tag: DW_TAG_base_type148 Children: DW_CHILDREN_no149 Attributes:150 - Attribute: DW_AT_specification151 Form: DW_FORM_ref1152 debug_info:153 - Version: 4154 AddrSize: 8155 Entries:156 - AbbrCode: 0x00000001157 Values:158 - Value: 0x000000000000000C159 - AbbrCode: 0x00000002160 Values:161 - Value: 0x0000000000000000 # Name = NameType1162 - AbbrCode: 0x00000002163 Values:164 - Value: 0x000000000000000a # Name = NameType2165 - AbbrCode: 0x00000003166 Values:167 - Value: 0x000000000000000e # Ref abstract origin to NameType1 DIE.168 - AbbrCode: 0x00000004169 Values:170 - Value: 0x0000000000000013 # Ref specification to NameType2 DIE.171 - AbbrCode: 0x00000000172)";173 174 YAMLModuleTester t(yamldata);175 auto *symbol_file =176 llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());177 DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0);178 179 dw_offset_t first_die_offset = 11;180 EXPECT_EQ(unit->PeekDIEName(first_die_offset), "");181 182 dw_offset_t second_die_offset = 14;183 EXPECT_EQ(unit->PeekDIEName(second_die_offset), "NameType1");184 185 dw_offset_t third_die_offset = 19;186 EXPECT_EQ(unit->PeekDIEName(third_die_offset), "NameType2");187 188 dw_offset_t fourth_die_offset = 24;189 EXPECT_EQ(unit->PeekDIEName(fourth_die_offset), "NameType1");190 191 dw_offset_t fifth_die_offset = 26;192 EXPECT_EQ(unit->PeekDIEName(fifth_die_offset), "NameType2");193}194 195TEST(DWARFDIETest, GetContext) {196 const char *yamldata = R"(197--- !ELF198FileHeader:199 Class: ELFCLASS64200 Data: ELFDATA2LSB201 Type: ET_EXEC202 Machine: EM_386203DWARF:204 debug_abbrev:205 - ID: 0206 Table:207 - Code: 0x1208 Tag: DW_TAG_compile_unit209 Children: DW_CHILDREN_yes210 Attributes:211 - Attribute: DW_AT_language212 Form: DW_FORM_data2213 - Code: 0x2214 Tag: DW_TAG_namespace215 Children: DW_CHILDREN_yes216 Attributes:217 - Attribute: DW_AT_name218 Form: DW_FORM_string219 - Code: 0x3220 Tag: DW_TAG_structure_type221 Children: DW_CHILDREN_no222 Attributes:223 - Attribute: DW_AT_name224 Form: DW_FORM_string225 - Code: 0x4226 Tag: DW_TAG_namespace227 Children: DW_CHILDREN_yes228 debug_info:229 - Version: 4230 AddrSize: 8231 Entries:232 - AbbrCode: 0x1233 Values:234 - Value: 0x000000000000000C235 - AbbrCode: 0x2236 Values:237 - CStr: NAMESPACE238 - AbbrCode: 0x3239 Values:240 - CStr: STRUCT241 - AbbrCode: 0x4242 - AbbrCode: 0x3243 Values:244 - CStr: STRUCT245 - AbbrCode: 0x0246 - AbbrCode: 0x0247 - AbbrCode: 0x0248)";249 250 YAMLModuleTester t(yamldata);251 auto *symbol_file =252 llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());253 DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0);254 ASSERT_TRUE(unit);255 256 auto make_namespace = [](const char *name) {257 return CompilerContext(CompilerContextKind::Namespace, ConstString(name));258 };259 auto make_struct = [](const char *name) {260 return CompilerContext(CompilerContextKind::ClassOrStruct,261 ConstString(name));262 };263 DWARFDIE struct_die = unit->DIE().GetFirstChild().GetFirstChild();264 ASSERT_TRUE(struct_die);265 DWARFDIE anon_struct_die = struct_die.GetSibling().GetFirstChild();266 ASSERT_TRUE(anon_struct_die);267 EXPECT_THAT(268 struct_die.GetDeclContext(),269 testing::ElementsAre(make_namespace("NAMESPACE"), make_struct("STRUCT")));270 EXPECT_THAT(271 struct_die.GetTypeLookupContext(),272 testing::ElementsAre(make_namespace("NAMESPACE"), make_struct("STRUCT")));273 EXPECT_THAT(struct_die.GetDWARFDeclContext(),274 DWARFDeclContext({{DW_TAG_structure_type, "STRUCT"},275 {DW_TAG_namespace, "NAMESPACE"}}));276 EXPECT_THAT(anon_struct_die.GetDeclContext(),277 testing::ElementsAre(make_namespace("NAMESPACE"),278 make_namespace(nullptr),279 make_struct("STRUCT")));280 EXPECT_THAT(anon_struct_die.GetTypeLookupContext(),281 testing::ElementsAre(make_namespace("NAMESPACE"),282 make_namespace(nullptr),283 make_struct("STRUCT")));284 EXPECT_THAT(anon_struct_die.GetDWARFDeclContext(),285 DWARFDeclContext({{DW_TAG_structure_type, "STRUCT"},286 {DW_TAG_namespace, nullptr},287 {DW_TAG_namespace, "NAMESPACE"}}));288}289 290TEST(DWARFDIETest, GetContextInFunction) {291 // Make sure we get the right context fo each "struct_t" type. The first292 // should be "a::struct_t" and the one defined in the "foo" function should be293 // "struct_t". Previous DWARFDIE::GetTypeLookupContext() function calls would294 // have the "struct_t" in "foo" be "a::struct_t" because it would traverse the295 // entire die parent tree and ignore DW_TAG_subprogram and keep traversing the296 // parents.297 //298 // 0x0000000b: DW_TAG_compile_unit299 // 0x0000000c: DW_TAG_namespace300 // DW_AT_name("a")301 // 0x0000000f: DW_TAG_structure_type302 // DW_AT_name("struct_t")303 // 0x00000019: DW_TAG_subprogram304 // DW_AT_name("foo")305 // 0x0000001e: DW_TAG_structure_type306 // DW_AT_name("struct_t")307 // 0x00000028: NULL308 // 0x00000029: NULL309 // 0x0000002a: NULL310 const char *yamldata = R"(311--- !ELF312FileHeader:313 Class: ELFCLASS64314 Data: ELFDATA2LSB315 Type: ET_EXEC316 Machine: EM_386317DWARF:318 debug_str:319 - ''320 debug_abbrev:321 - ID: 0322 Table:323 - Code: 0x1324 Tag: DW_TAG_compile_unit325 Children: DW_CHILDREN_yes326 - Code: 0x2327 Tag: DW_TAG_namespace328 Children: DW_CHILDREN_yes329 Attributes:330 - Attribute: DW_AT_name331 Form: DW_FORM_string332 - Code: 0x3333 Tag: DW_TAG_structure_type334 Children: DW_CHILDREN_no335 Attributes:336 - Attribute: DW_AT_name337 Form: DW_FORM_string338 - Code: 0x4339 Tag: DW_TAG_subprogram340 Children: DW_CHILDREN_yes341 Attributes:342 - Attribute: DW_AT_name343 Form: DW_FORM_string344 debug_info:345 - Length: 0x27346 Version: 4347 AbbrevTableID: 0348 AbbrOffset: 0x0349 AddrSize: 8350 Entries:351 - AbbrCode: 0x1352 - AbbrCode: 0x2353 Values:354 - Value: 0xDEADBEEFDEADBEEF355 CStr: a356 - AbbrCode: 0x3357 Values:358 - Value: 0xDEADBEEFDEADBEEF359 CStr: struct_t360 - AbbrCode: 0x4361 Values:362 - Value: 0xDEADBEEFDEADBEEF363 CStr: foo364 - AbbrCode: 0x3365 Values:366 - Value: 0xDEADBEEFDEADBEEF367 CStr: struct_t368 - AbbrCode: 0x0369 - AbbrCode: 0x0370 - AbbrCode: 0x0)";371 372 YAMLModuleTester t(yamldata);373 auto *symbol_file =374 llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());375 DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0);376 ASSERT_TRUE(unit);377 378 auto make_namespace = [](llvm::StringRef name) {379 return CompilerContext(CompilerContextKind::Namespace, ConstString(name));380 };381 auto make_struct = [](llvm::StringRef name) {382 return CompilerContext(CompilerContextKind::ClassOrStruct,383 ConstString(name));384 };385 // Grab the "a::struct_t" type from the "a" namespace386 DWARFDIE a_struct_die = unit->DIE().GetFirstChild().GetFirstChild();387 ASSERT_TRUE(a_struct_die);388 EXPECT_THAT(389 a_struct_die.GetDeclContext(),390 testing::ElementsAre(make_namespace("a"), make_struct("struct_t")));391 // Grab the "struct_t" defined in the "foo" function.392 DWARFDIE foo_struct_die =393 unit->DIE().GetFirstChild().GetFirstChild().GetSibling().GetFirstChild();394 EXPECT_THAT(foo_struct_die.GetTypeLookupContext(),395 testing::ElementsAre(make_struct("struct_t")));396}397 398TEST(DWARFDIETest, GetAttributeValue_ImplicitConst) {399 // Make sure we can correctly retrieve the value of an attribute400 // that has a DW_FORM_implicit_const form.401 402 const char *yamldata = R"(403--- !ELF404FileHeader:405 Class: ELFCLASS64406 Data: ELFDATA2LSB407 Type: ET_EXEC408 Machine: EM_386409DWARF:410 debug_str:411 - ''412 debug_abbrev:413 - ID: 0414 Table:415 - Code: 0x1416 Tag: DW_TAG_compile_unit417 Children: DW_CHILDREN_yes418 - Code: 0x2419 Tag: DW_TAG_subprogram420 Children: DW_CHILDREN_no421 Attributes:422 - Attribute: DW_AT_name423 Form: DW_FORM_string424 - Attribute: DW_AT_object_pointer425 Form: DW_FORM_implicit_const426 Value: 5427 debug_info:428 - Version: 5429 UnitType: DW_UT_compile430 AddrSize: 8431 Entries:432 - AbbrCode: 0x1433 - AbbrCode: 0x2434 Values:435 - Value: 0xDEADBEEFDEADBEEF436 CStr: func437 - AbbrCode: 0x0)";438 439 YAMLModuleTester t(yamldata);440 auto *symbol_file =441 llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());442 DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0);443 ASSERT_TRUE(unit);444 445 DWARFDIE subprogram = unit->DIE().GetFirstChild();446 ASSERT_TRUE(subprogram);447 dw_offset_t end_attr_offset;448 DWARFFormValue form_value;449 dw_offset_t offset = subprogram.GetDIE()->GetAttributeValue(450 unit, DW_AT_object_pointer, form_value, &end_attr_offset);451 EXPECT_EQ(form_value.Unsigned(), 5U);452 EXPECT_GT(offset, 0U);453 EXPECT_GT(end_attr_offset, 0U);454}455 456struct GetAttributesTestFixture : public testing::TestWithParam<dw_attr_t> {};457 458TEST_P(GetAttributesTestFixture, TestGetAttributes_IterationOrder) {459 // Tests that we accumulate all current DIE's attributes first460 // before checking the attributes of the specification.461 462 const char *yamldata = R"(463--- !ELF464FileHeader:465 Class: ELFCLASS64466 Data: ELFDATA2LSB467 Type: ET_EXEC468 Machine: EM_AARCH64469DWARF:470 debug_str:471 - func472 debug_abbrev:473 - ID: 0474 Table:475 - Code: 0x1476 Tag: DW_TAG_compile_unit477 Children: DW_CHILDREN_yes478 Attributes:479 - Attribute: DW_AT_language480 Form: DW_FORM_data2481 - Code: 0x2482 Tag: DW_TAG_subprogram483 Children: DW_CHILDREN_no484 Attributes:485 - Attribute: DW_AT_high_pc486 Form: DW_FORM_data4487 - Attribute: DW_AT_name488 Form: DW_FORM_strp489 - Attribute: DW_AT_declaration490 Form: DW_FORM_flag_present491 - Attribute: DW_AT_external492 Form: DW_FORM_flag_present493 - Attribute: DW_AT_low_pc494 Form: DW_FORM_data4495 - Code: 0x3496 Tag: DW_TAG_subprogram497 Children: DW_CHILDREN_no498 Attributes:499 - Attribute: DW_AT_high_pc500 Form: DW_FORM_data4501 - Attribute: {0}502 Form: DW_FORM_ref4503 - Attribute: DW_AT_low_pc504 Form: DW_FORM_data4505 debug_info:506 - Version: 5507 UnitType: DW_UT_compile508 AddrSize: 8509 Entries:510 511# DW_TAG_compile_unit512# DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)513 514 - AbbrCode: 0x1515 Values:516 - Value: 0x04517 518# DW_TAG_subprogram519# DW_AT_high_pc [DW_FORM_data4]520# DW_AT_name [DW_FORM_strp] ("func")521# DW_AT_low_pc [DW_FORM_data4]522 - AbbrCode: 0x2523 Values:524 - Value: 0xdeadbeef525 - Value: 0x0526 - Value: 0x1527 - Value: 0x1528 - Value: 0xdeadbeef529 530# DW_TAG_subprogram531# DW_AT_high_pc [DW_FORM_data4]532# DW_AT_specification [DW_FORM_ref4] ("func")533# DW_AT_low_pc [DW_FORM_data4]534 - AbbrCode: 0x3535 Values:536 - Value: 0xf00dcafe537 - Value: 0xf538 - Value: 0xf00dcafe539 540 - AbbrCode: 0x0541...542)";543 YAMLModuleTester t(llvm::formatv(yamldata, GetParam()).str());544 545 DWARFUnit *unit = t.GetDwarfUnit();546 ASSERT_NE(unit, nullptr);547 const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();548 ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);549 ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);550 DWARFDIE cu_die(unit, cu_entry);551 552 auto declaration = cu_die.GetFirstChild();553 ASSERT_TRUE(declaration.IsValid());554 ASSERT_EQ(declaration.Tag(), DW_TAG_subprogram);555 556 auto definition = declaration.GetSibling();557 ASSERT_TRUE(definition.IsValid());558 ASSERT_EQ(definition.Tag(), DW_TAG_subprogram);559 ASSERT_FALSE(definition.GetAttributeValueAsOptionalUnsigned(DW_AT_external));560 561 auto attrs = definition.GetAttributes(DWARFDebugInfoEntry::Recurse::yes);562 EXPECT_EQ(attrs.Size(), 7U);563 564 // Check that the attributes on the definition (that are also present565 // on the declaration) take precedence.566 for (auto attr : {DW_AT_low_pc, DW_AT_high_pc}) {567 auto idx = attrs.FindAttributeIndex(attr);568 EXPECT_NE(idx, UINT32_MAX);569 570 DWARFFormValue form_value;571 auto success = attrs.ExtractFormValueAtIndex(idx, form_value);572 EXPECT_TRUE(success);573 574 EXPECT_EQ(form_value.Unsigned(), 0xf00dcafe);575 }576}577 578TEST_P(GetAttributesTestFixture, TestGetAttributes_Cycle) {579 // Tests that GetAttributes can deal with cycles in580 // specifications/abstract origins.581 //582 // Contrived example:583 //584 // func1 -> func3585 // ^ |586 // | v587 // +------func2588 589 const char *yamldata = R"(590--- !ELF591FileHeader:592 Class: ELFCLASS64593 Data: ELFDATA2LSB594 Type: ET_EXEC595 Machine: EM_AARCH64596DWARF:597 debug_abbrev:598 - ID: 0599 Table:600 - Code: 0x1601 Tag: DW_TAG_compile_unit602 Children: DW_CHILDREN_yes603 Attributes:604 - Attribute: DW_AT_language605 Form: DW_FORM_data2606 - Code: 0x2607 Tag: DW_TAG_subprogram608 Children: DW_CHILDREN_no609 Attributes:610 - Attribute: {0}611 Form: DW_FORM_ref4612 debug_info:613 - Version: 5614 UnitType: DW_UT_compile615 AddrSize: 8616 Entries:617 618 - AbbrCode: 0x1619 Values:620 - Value: 0x04621 622 - AbbrCode: 0x2623 Values:624 - Value: 0x19625 626 - AbbrCode: 0x2627 Values:628 - Value: 0xf629 630 - AbbrCode: 0x2631 Values:632 - Value: 0x14633 634 - AbbrCode: 0x0635...636)";637 YAMLModuleTester t(llvm::formatv(yamldata, GetParam()).str());638 639 DWARFUnit *unit = t.GetDwarfUnit();640 ASSERT_NE(unit, nullptr);641 const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();642 ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);643 ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);644 DWARFDIE cu_die(unit, cu_entry);645 646 auto func1 = cu_die.GetFirstChild();647 ASSERT_TRUE(func1.IsValid());648 ASSERT_EQ(func1.Tag(), DW_TAG_subprogram);649 650 auto func2 = func1.GetSibling();651 ASSERT_TRUE(func2.IsValid());652 ASSERT_EQ(func2.Tag(), DW_TAG_subprogram);653 654 auto func3 = func2.GetSibling();655 ASSERT_TRUE(func3.IsValid());656 ASSERT_EQ(func3.Tag(), DW_TAG_subprogram);657 658 auto attrs = func1.GetAttributes(DWARFDebugInfoEntry::Recurse::yes);659 EXPECT_EQ(attrs.Size(), 3U);660 661 // Confirm that the specifications do form a cycle.662 {663 DWARFFormValue form_value;664 auto success = attrs.ExtractFormValueAtIndex(0, form_value);665 ASSERT_TRUE(success);666 667 EXPECT_EQ(form_value.Reference(), func3);668 }669 670 {671 DWARFFormValue form_value;672 auto success = attrs.ExtractFormValueAtIndex(1, form_value);673 ASSERT_TRUE(success);674 675 EXPECT_EQ(form_value.Reference(), func2);676 }677 678 {679 DWARFFormValue form_value;680 auto success = attrs.ExtractFormValueAtIndex(2, form_value);681 ASSERT_TRUE(success);682 683 EXPECT_EQ(form_value.Reference(), func1);684 }685}686 687TEST_P(GetAttributesTestFixture,688 TestGetAttributes_SkipNonApplicableAttributes) {689 // Tests that GetAttributes will omit attributes found through690 // specifications/abstract origins which are not applicable.691 692 const char *yamldata = R"(693--- !ELF694FileHeader:695 Class: ELFCLASS64696 Data: ELFDATA2LSB697 Type: ET_EXEC698 Machine: EM_AARCH64699DWARF:700 debug_str:701 - func702 debug_abbrev:703 - ID: 0704 Table:705 - Code: 0x1706 Tag: DW_TAG_compile_unit707 Children: DW_CHILDREN_yes708 Attributes:709 - Attribute: DW_AT_language710 Form: DW_FORM_data2711 - Code: 0x2712 Tag: DW_TAG_subprogram713 Children: DW_CHILDREN_no714 Attributes:715 - Attribute: DW_AT_declaration716 Form: DW_FORM_flag_present717 - Attribute: DW_AT_name718 Form: DW_FORM_strp719 - Attribute: DW_AT_sibling720 Form: DW_FORM_ref4721 - Code: 0x3722 Tag: DW_TAG_subprogram723 Children: DW_CHILDREN_no724 Attributes:725 - Attribute: DW_AT_declaration726 Form: DW_FORM_flag_present727 - Attribute: {0}728 Form: DW_FORM_ref4729 - Attribute: DW_AT_sibling730 Form: DW_FORM_ref4731 debug_info:732 - Version: 5733 UnitType: DW_UT_compile734 AddrSize: 8735 Entries:736 737# DW_TAG_compile_unit738# DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)739 740 - AbbrCode: 0x1741 Values:742 - Value: 0x04743 744# DW_TAG_subprogram745# DW_AT_declaration746# DW_AT_name [DW_FORM_strp] ("func")747# DW_AT_sibling748 - AbbrCode: 0x2749 Values:750 - Value: 0x1751 - Value: 0x0752 - Value: 0x18753 754# DW_TAG_subprogram755# DW_AT_declaration756# DW_AT_specification [DW_FORM_ref4] ("func")757# DW_AT_sibling758 - AbbrCode: 0x3759 Values:760 - Value: 0x1761 - Value: 0xf762 - Value: 0xdeadbeef763 764 - AbbrCode: 0x0765...766)";767 YAMLModuleTester t(llvm::formatv(yamldata, GetParam()).str());768 769 DWARFUnit *unit = t.GetDwarfUnit();770 ASSERT_NE(unit, nullptr);771 const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();772 ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);773 ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);774 DWARFDIE cu_die(unit, cu_entry);775 776 auto declaration = cu_die.GetFirstChild();777 ASSERT_TRUE(declaration.IsValid());778 ASSERT_EQ(declaration.Tag(), DW_TAG_subprogram);779 780 auto definition = declaration.GetSibling();781 ASSERT_TRUE(definition.IsValid());782 ASSERT_EQ(definition.Tag(), DW_TAG_subprogram);783 784 auto attrs = definition.GetAttributes(DWARFDebugInfoEntry::Recurse::yes);785 EXPECT_EQ(attrs.Size(), 4U);786 EXPECT_NE(attrs.FindAttributeIndex(DW_AT_name), UINT32_MAX);787 EXPECT_NE(attrs.FindAttributeIndex(GetParam()), UINT32_MAX);788 789 auto sibling_idx = attrs.FindAttributeIndex(DW_AT_sibling);790 EXPECT_NE(sibling_idx, UINT32_MAX);791 792 DWARFFormValue form_value;793 auto success = attrs.ExtractFormValueAtIndex(sibling_idx, form_value);794 ASSERT_TRUE(success);795 796 EXPECT_EQ(form_value.Unsigned(), 0xdeadbeef);797}798 799TEST_P(GetAttributesTestFixture, TestGetAttributes_NoRecurse) {800 // Tests that GetAttributes will not recurse if Recurse::No is passed to it.801 802 const char *yamldata = R"(803--- !ELF804FileHeader:805 Class: ELFCLASS64806 Data: ELFDATA2LSB807 Type: ET_EXEC808 Machine: EM_AARCH64809DWARF:810 debug_str:811 - func812 debug_abbrev:813 - ID: 0814 Table:815 - Code: 0x1816 Tag: DW_TAG_compile_unit817 Children: DW_CHILDREN_yes818 Attributes:819 - Attribute: DW_AT_language820 Form: DW_FORM_data2821 - Code: 0x2822 Tag: DW_TAG_subprogram823 Children: DW_CHILDREN_no824 Attributes:825 - Attribute: DW_AT_name826 Form: DW_FORM_strp827 - Code: 0x3828 Tag: DW_TAG_subprogram829 Children: DW_CHILDREN_no830 Attributes:831 - Attribute: DW_AT_low_pc832 Form: DW_FORM_data4833 - Attribute: {0}834 Form: DW_FORM_ref4835 debug_info:836 - Version: 5837 UnitType: DW_UT_compile838 AddrSize: 8839 Entries:840 841# DW_TAG_compile_unit842# DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)843 844 - AbbrCode: 0x1845 Values:846 - Value: 0x04847 848# DW_TAG_subprogram849# DW_AT_name [DW_FORM_strp] ("func")850 - AbbrCode: 0x2851 Values:852 - Value: 0x0853 854# DW_TAG_subprogram855# DW_AT_low_pc [DW_FORM_data4]856# DW_AT_specification [DW_FORM_ref4]857 - AbbrCode: 0x3858 Values:859 - Value: 0xdeadbeef860 - Value: 0xf861 862 - AbbrCode: 0x0863...864)";865 YAMLModuleTester t(llvm::formatv(yamldata, GetParam()).str());866 867 DWARFUnit *unit = t.GetDwarfUnit();868 ASSERT_NE(unit, nullptr);869 const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();870 ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);871 ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);872 DWARFDIE cu_die(unit, cu_entry);873 874 auto declaration = cu_die.GetFirstChild();875 ASSERT_TRUE(declaration.IsValid());876 ASSERT_EQ(declaration.Tag(), DW_TAG_subprogram);877 878 auto definition = declaration.GetSibling();879 ASSERT_TRUE(definition.IsValid());880 ASSERT_EQ(definition.Tag(), DW_TAG_subprogram);881 882 auto attrs = definition.GetAttributes(DWARFDebugInfoEntry::Recurse::no);883 EXPECT_EQ(attrs.Size(), 2U);884 EXPECT_EQ(attrs.FindAttributeIndex(DW_AT_name), UINT32_MAX);885 EXPECT_NE(attrs.FindAttributeIndex(GetParam()), UINT32_MAX);886 EXPECT_NE(attrs.FindAttributeIndex(DW_AT_low_pc), UINT32_MAX);887}888 889TEST_P(GetAttributesTestFixture, TestGetAttributes_InvalidSpec) {890 // Test that GetAttributes doesn't try following invalid891 // specifications (but still add it to the list of attributes).892 893 const char *yamldata = R"(894--- !ELF895FileHeader:896 Class: ELFCLASS64897 Data: ELFDATA2LSB898 Type: ET_EXEC899 Machine: EM_AARCH64900DWARF:901 debug_str:902 - func903 debug_abbrev:904 - ID: 0905 Table:906 - Code: 0x1907 Tag: DW_TAG_compile_unit908 Children: DW_CHILDREN_yes909 Attributes:910 - Attribute: DW_AT_language911 Form: DW_FORM_data2912 - Code: 0x2913 Tag: DW_TAG_subprogram914 Children: DW_CHILDREN_no915 Attributes:916 - Attribute: DW_AT_name917 Form: DW_FORM_strp918 - Code: 0x3919 Tag: DW_TAG_subprogram920 Children: DW_CHILDREN_no921 Attributes:922 - Attribute: {0}923 Form: DW_FORM_ref4924 debug_info:925 - Version: 5926 UnitType: DW_UT_compile927 AddrSize: 8928 Entries:929 930# DW_TAG_compile_unit931# DW_AT_language [DW_FORM_data2] (DW_LANG_C_plus_plus)932 933 - AbbrCode: 0x1934 Values:935 - Value: 0x04936 937# DW_TAG_subprogram938# DW_AT_name [DW_FORM_strp] ("func")939 - AbbrCode: 0x2940 Values:941 - Value: 0x0942 943# DW_TAG_subprogram944# DW_AT_specification [DW_FORM_ref4]945 - AbbrCode: 0x3946 Values:947 - Value: 0xdeadbeef948 949 - AbbrCode: 0x0950...951)";952 YAMLModuleTester t(llvm::formatv(yamldata, GetParam()).str());953 954 DWARFUnit *unit = t.GetDwarfUnit();955 ASSERT_NE(unit, nullptr);956 const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();957 ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);958 ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);959 DWARFDIE cu_die(unit, cu_entry);960 961 auto declaration = cu_die.GetFirstChild();962 ASSERT_TRUE(declaration.IsValid());963 ASSERT_EQ(declaration.Tag(), DW_TAG_subprogram);964 965 auto definition = declaration.GetSibling();966 ASSERT_TRUE(definition.IsValid());967 ASSERT_EQ(definition.Tag(), DW_TAG_subprogram);968 969 auto attrs = definition.GetAttributes(DWARFDebugInfoEntry::Recurse::yes);970 EXPECT_EQ(attrs.Size(), 1U);971 EXPECT_EQ(attrs.FindAttributeIndex(DW_AT_name), UINT32_MAX);972 EXPECT_NE(attrs.FindAttributeIndex(GetParam()), UINT32_MAX);973}974 975TEST(DWARFDIETest, TestGetAttributes_Worklist) {976 // Test that GetAttributes will follow both the abstract origin977 // and specification on a single DIE correctly (omitting non-applicable978 // attributes in the process).979 980 // Contrived example where981 // f1---> f2 --> f4982 // `-> f3 `-> f5983 //984 const char *yamldata = R"(985--- !ELF986FileHeader:987 Class: ELFCLASS64988 Data: ELFDATA2LSB989 Type: ET_EXEC990 Machine: EM_AARCH64991DWARF:992 debug_str:993 - foo994 - bar995 debug_abbrev:996 - ID: 0997 Table:998 - Code: 0x1999 Tag: DW_TAG_compile_unit1000 Children: DW_CHILDREN_yes1001 Attributes:1002 - Attribute: DW_AT_language1003 Form: DW_FORM_data21004 - Code: 0x21005 Tag: DW_TAG_subprogram1006 Children: DW_CHILDREN_no1007 Attributes:1008 - Attribute: DW_AT_specification1009 Form: DW_FORM_ref41010 - Attribute: DW_AT_abstract_origin1011 Form: DW_FORM_ref41012 - Code: 0x31013 Tag: DW_TAG_subprogram1014 Children: DW_CHILDREN_no1015 Attributes:1016 - Attribute: DW_AT_declaration1017 Form: DW_FORM_flag_present1018 - Attribute: DW_AT_artificial1019 Form: DW_FORM_flag_present1020 1021 debug_info:1022 - Version: 51023 UnitType: DW_UT_compile1024 AddrSize: 81025 Entries:1026 1027 - AbbrCode: 0x11028 Values:1029 - Value: 0x041030 1031# DW_TAG_subprogram ("f1")1032# DW_AT_specification [DW_FORM_ref4] ("f2")1033# DW_AT_abstract_origin [DW_FORM_ref4] ("f3")1034 - AbbrCode: 0x21035 Values:1036 - Value: 0x181037 - Value: 0x211038 1039# DW_TAG_subprogram ("f2")1040# DW_AT_specification [DW_FORM_ref4] ("f4")1041# DW_AT_abstract_origin [DW_FORM_ref4] ("f5")1042 - AbbrCode: 0x21043 Values:1044 - Value: 0x221045 - Value: 0x231046 1047# DW_TAG_subprogram ("f3")1048# DW_AT_declaration [DW_FORM_flag_present]1049# DW_AT_artificial [DW_FORM_flag_present]1050 - AbbrCode: 0x31051 Values:1052 - Value: 0x11053 - Value: 0x11054 1055# DW_TAG_subprogram ("f4")1056# DW_AT_declaration [DW_FORM_flag_present]1057# DW_AT_artificial [DW_FORM_flag_present]1058 - AbbrCode: 0x31059 Values:1060 - Value: 0x11061 - Value: 0x11062 1063# DW_TAG_subprogram ("f5")1064# DW_AT_declaration [DW_FORM_flag_present]1065# DW_AT_artificial [DW_FORM_flag_present]1066 - AbbrCode: 0x31067 Values:1068 - Value: 0x11069 - Value: 0x11070 1071 - AbbrCode: 0x01072...1073)";1074 YAMLModuleTester t(yamldata);1075 1076 DWARFUnit *unit = t.GetDwarfUnit();1077 ASSERT_NE(unit, nullptr);1078 const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();1079 ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);1080 ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);1081 DWARFDIE cu_die(unit, cu_entry);1082 1083 auto f1 = cu_die.GetFirstChild();1084 ASSERT_TRUE(f1.IsValid());1085 ASSERT_EQ(f1.Tag(), DW_TAG_subprogram);1086 1087 auto attrs = f1.GetAttributes(DWARFDebugInfoEntry::Recurse::yes);1088 EXPECT_EQ(attrs.Size(), 7U);1089 EXPECT_EQ(attrs.FindAttributeIndex(DW_AT_declaration), UINT32_MAX);1090}1091 1092INSTANTIATE_TEST_SUITE_P(GetAttributeTests, GetAttributesTestFixture,1093 testing::Values(DW_AT_specification,1094 DW_AT_abstract_origin));1095