1 //===- llvm/unittest/DebugInfo/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-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/BinaryFormat/Dwarf.h"
10 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
11 #include "llvm/ObjectYAML/DWARFEmitter.h"
12 #include "llvm/Testing/Support/Error.h"
13 #include "gtest/gtest.h"
14
15 using namespace llvm;
16 using namespace llvm::dwarf;
17 using object::SectionedAddress;
18
19 namespace {
20
TEST(DWARFDie,getLocations)21 TEST(DWARFDie, getLocations) {
22 const char *yamldata = R"(
23 debug_abbrev:
24 - Table:
25 - Code: 0x00000001
26 Tag: DW_TAG_compile_unit
27 Children: DW_CHILDREN_no
28 Attributes:
29 - Attribute: DW_AT_location
30 Form: DW_FORM_sec_offset
31 - Attribute: DW_AT_data_member_location
32 Form: DW_FORM_exprloc
33 - Attribute: DW_AT_vtable_elem_location
34 Form: DW_FORM_sec_offset
35 - Attribute: DW_AT_call_data_location
36 Form: DW_FORM_sec_offset
37 debug_info:
38 - Version: 5
39 UnitType: DW_UT_compile
40 AddrSize: 4
41 Entries:
42 - AbbrCode: 0x00000001
43 Values:
44 - Value: 12
45 - Value: 0x0000000000000001
46 BlockData: [ 0x47 ]
47 - Value: 20
48 - Value: 25
49 debug_loclists:
50 - AddressSize: 4
51 OffsetEntryCount: 0
52 Lists:
53 - Entries:
54 - Operator: DW_LLE_start_length
55 Values: [ 0x01, 0x02 ]
56 - Operator: DW_LLE_end_of_list
57 - Entries:
58 - Operator: DW_LLE_startx_length
59 Values: [ 0x01, 0x02 ]
60 - Operator: DW_LLE_end_of_list
61 - Entries:
62 - Operator: DW_LLE_start_length
63 Values: [ 0x01, 0x02 ]
64 ## end_of_list intentionally missing.
65 )";
66 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =
67 DWARFYAML::emitDebugSections(StringRef(yamldata),
68 /*IsLittleEndian=*/true,
69 /*Is64BitAddrSize=*/false);
70 ASSERT_THAT_EXPECTED(Sections, Succeeded());
71 std::unique_ptr<DWARFContext> Ctx =
72 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);
73 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);
74 ASSERT_NE(nullptr, CU);
75 DWARFDie Die = CU->getUnitDIE();
76 ASSERT_TRUE(Die.isValid());
77
78 EXPECT_THAT_EXPECTED(Die.getLocations(DW_AT_location),
79 HasValue(testing::ElementsAre(DWARFLocationExpression{
80 DWARFAddressRange{1, 3}, {}})));
81
82 EXPECT_THAT_EXPECTED(
83 Die.getLocations(DW_AT_data_member_location),
84 HasValue(testing::ElementsAre(DWARFLocationExpression{None, {0x47}})));
85
86 EXPECT_THAT_EXPECTED(
87 Die.getLocations(DW_AT_vtable_elem_location),
88 Failed<ErrorInfoBase>(testing::Property(
89 &ErrorInfoBase::message,
90 "Unable to resolve indirect address 1 for: DW_LLE_startx_length")));
91
92 EXPECT_THAT_EXPECTED(
93 Die.getLocations(DW_AT_call_data_location),
94 FailedWithMessage(
95 "unexpected end of data at offset 0x20 while reading [0x20, 0x21)"));
96
97 EXPECT_THAT_EXPECTED(
98 Die.getLocations(DW_AT_call_data_value),
99 Failed<ErrorInfoBase>(testing::Property(&ErrorInfoBase::message,
100 "No DW_AT_call_data_value")));
101 }
102
103 } // end anonymous namespace
104