brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.1 KiB · e285ef2 Raw
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