1 //===- DWARFDataExtractorTest.cpp -----------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
10 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
11 #include "llvm/Object/ObjectFile.h"
12 #include "llvm/ObjectYAML/yaml2obj.h"
13 #include "llvm/Testing/Support/Error.h"
14 #include "gtest/gtest.h"
20 TEST(DWARFDataExtractorTest
, getRelocatedValue
) {
34 Content: '000000000000'
35 - Name: .rel.debug_line
51 SmallString
<0> Storage
;
52 std::unique_ptr
<object::ObjectFile
> Obj
= yaml::yaml2ObjectFile(
53 Storage
, Yaml
, [](const Twine
&Err
) { errs() << Err
; });
55 std::unique_ptr
<DWARFContext
> Ctx
= DWARFContext::create(*Obj
);
56 const DWARFObject
&DObj
= Ctx
->getDWARFObj();
57 ASSERT_EQ(6u, DObj
.getLineSection().Data
.size());
59 DWARFDataExtractor
Data(DObj
, DObj
.getLineSection(), Obj
->isLittleEndian(),
60 Obj
->getBytesInAddress());
61 DataExtractor::Cursor
C(0);
62 EXPECT_EQ(0x42u
, Data
.getRelocatedAddress(C
));
63 EXPECT_EQ(0u, Data
.getRelocatedAddress(C
));
67 "unexpected end of data at offset 0x6 while reading [0x4, 0x8)"));
70 TEST(DWARFDataExtractorTest
, getInitialLength
) {
71 auto GetWithError
= [](ArrayRef
<uint8_t> Bytes
)
72 -> Expected
<std::tuple
<uint64_t, dwarf::DwarfFormat
, uint64_t>> {
73 DWARFDataExtractor
Data(Bytes
, /*IsLittleEndian=*/false, /*AddressSize=*/8);
74 DWARFDataExtractor::Cursor
C(0);
76 dwarf::DwarfFormat Format
;
77 std::tie(Length
, Format
) = Data
.getInitialLength(C
);
79 return std::make_tuple(Length
, Format
, C
.tell());
81 EXPECT_EQ(Length
, 0u);
82 EXPECT_EQ(Format
, dwarf::DWARF32
);
83 EXPECT_EQ(C
.tell(), 0u);
86 auto GetWithoutError
= [](ArrayRef
<uint8_t> Bytes
) {
87 DWARFDataExtractor
Data(Bytes
, /*IsLittleEndian=*/false, /*AddressSize=*/8);
90 dwarf::DwarfFormat Format
;
91 std::tie(Length
, Format
) = Data
.getInitialLength(&Offset
);
92 return std::make_tuple(Length
, Format
, Offset
);
94 auto ErrorResult
= std::make_tuple(0, dwarf::DWARF32
, 0);
100 "unexpected end of data at offset 0x0 while reading [0x0, 0x4)"));
101 EXPECT_EQ(GetWithoutError({}), ErrorResult
);
103 // Not long enough for the U32 field.
104 EXPECT_THAT_EXPECTED(
105 GetWithError({0x00, 0x01, 0x02}),
107 "unexpected end of data at offset 0x3 while reading [0x0, 0x4)"));
108 EXPECT_EQ(GetWithoutError({0x00, 0x01, 0x02}), ErrorResult
);
110 EXPECT_THAT_EXPECTED(
111 GetWithError({0x00, 0x01, 0x02, 0x03}),
112 HasValue(std::make_tuple(0x00010203, dwarf::DWARF32
, 4)));
113 EXPECT_EQ(GetWithoutError({0x00, 0x01, 0x02, 0x03}),
114 std::make_tuple(0x00010203, dwarf::DWARF32
, 4));
116 // Zeroes are not an error, but without the Error object it is hard to tell
117 // them apart from a failed read.
118 EXPECT_THAT_EXPECTED(
119 GetWithError({0x00, 0x00, 0x00, 0x00}),
120 HasValue(std::make_tuple(0x00000000, dwarf::DWARF32
, 4)));
121 EXPECT_EQ(GetWithoutError({0x00, 0x00, 0x00, 0x00}),
122 std::make_tuple(0x00000000, dwarf::DWARF32
, 4));
124 // Smallest invalid value.
125 EXPECT_THAT_EXPECTED(
126 GetWithError({0xff, 0xff, 0xff, 0xf0}),
128 "unsupported reserved unit length of value 0xfffffff0"));
129 EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xf0}), ErrorResult
);
131 // DWARF64 marker without the subsequent length field.
132 EXPECT_THAT_EXPECTED(
133 GetWithError({0xff, 0xff, 0xff, 0xff}),
135 "unexpected end of data at offset 0x4 while reading [0x4, 0xc)"));
136 EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff}), ErrorResult
);
138 // Not enough data for the U64 length.
139 EXPECT_THAT_EXPECTED(
140 GetWithError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03}),
142 "unexpected end of data at offset 0x8 while reading [0x4, 0xc)"));
143 EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03}),
146 EXPECT_THAT_EXPECTED(
147 GetWithError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
149 HasValue(std::make_tuple(0x0001020304050607, dwarf::DWARF64
, 12)));
150 EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03,
151 0x04, 0x05, 0x06, 0x07}),
152 std::make_tuple(0x0001020304050607, dwarf::DWARF64
, 12));
155 TEST(DWARFDataExtractorTest
, Truncation
) {
169 Content: '616263640000000065666768'
170 - Name: .rel.debug_line
183 SmallString
<0> Storage
;
184 std::unique_ptr
<object::ObjectFile
> Obj
= yaml::yaml2ObjectFile(
185 Storage
, Yaml
, [](const Twine
&Err
) { errs() << Err
; });
187 std::unique_ptr
<DWARFContext
> Ctx
= DWARFContext::create(*Obj
);
188 const DWARFObject
&DObj
= Ctx
->getDWARFObj();
189 ASSERT_EQ(12u, DObj
.getLineSection().Data
.size());
191 DWARFDataExtractor
Data(DObj
, DObj
.getLineSection(), Obj
->isLittleEndian(),
192 Obj
->getBytesInAddress());
193 DataExtractor::Cursor
C(0);
194 EXPECT_EQ(0x64636261u
, Data
.getRelocatedAddress(C
));
195 EXPECT_EQ(0x42u
, Data
.getRelocatedAddress(C
));
196 EXPECT_EQ(0x68676665u
, Data
.getRelocatedAddress(C
));
197 EXPECT_THAT_ERROR(C
.takeError(), Succeeded());
199 C
= DataExtractor::Cursor
{0};
200 DWARFDataExtractor
Truncated8(Data
, 8);
201 EXPECT_EQ(0x64636261u
, Truncated8
.getRelocatedAddress(C
));
202 EXPECT_EQ(0x42u
, Truncated8
.getRelocatedAddress(C
));
203 EXPECT_EQ(0x0u
, Truncated8
.getRelocatedAddress(C
));
207 "unexpected end of data at offset 0x8 while reading [0x8, 0xc)"));
209 C
= DataExtractor::Cursor
{0};
210 DWARFDataExtractor
Truncated6(Data
, 6);
211 EXPECT_EQ(0x64636261u
, Truncated6
.getRelocatedAddress(C
));
212 EXPECT_EQ(0x0u
, Truncated6
.getRelocatedAddress(C
));
216 "unexpected end of data at offset 0x6 while reading [0x4, 0x8)"));
218 C
= DataExtractor::Cursor
{0};
219 DWARFDataExtractor
Truncated2(Data
, 2);
220 EXPECT_EQ(0x0u
, Truncated2
.getRelocatedAddress(C
));
224 "unexpected end of data at offset 0x2 while reading [0x0, 0x4)"));