[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / DebugInfo / DWARF / DWARFDataExtractorTest.cpp
blob449442f36cf96618f6e0c73d68f77296d504053d
1 //===- DWARFDataExtractorTest.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 //===----------------------------------------------------------------------===//
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"
16 using namespace llvm;
18 namespace {
20 TEST(DWARFDataExtractorTest, getRelocatedValue) {
21 StringRef Yaml = R"(
22 !ELF
23 FileHeader:
24 Class: ELFCLASS32
25 Data: ELFDATA2LSB
26 Type: ET_REL
27 Machine: EM_386
28 Sections:
29 - Name: .text
30 Type: SHT_PROGBITS
31 Size: 0x80
32 - Name: .debug_line
33 Type: SHT_PROGBITS
34 Content: '000000000000'
35 - Name: .rel.debug_line
36 Type: SHT_REL
37 Info: .debug_line
38 Relocations:
39 - Offset: 0
40 Symbol: f
41 Type: R_386_32
42 - Offset: 4
43 Symbol: f
44 Type: R_386_32
45 Symbols:
46 - Name: f
47 Type: STT_SECTION
48 Section: .text
49 Value: 0x42
50 )";
51 SmallString<0> Storage;
52 std::unique_ptr<object::ObjectFile> Obj = yaml::yaml2ObjectFile(
53 Storage, Yaml, [](const Twine &Err) { errs() << Err; });
54 ASSERT_TRUE(Obj);
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));
64 EXPECT_THAT_ERROR(
65 C.takeError(),
66 FailedWithMessage(
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);
75 uint64_t Length;
76 dwarf::DwarfFormat Format;
77 std::tie(Length, Format) = Data.getInitialLength(C);
78 if (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);
84 return C.takeError();
86 auto GetWithoutError = [](ArrayRef<uint8_t> Bytes) {
87 DWARFDataExtractor Data(Bytes, /*IsLittleEndian=*/false, /*AddressSize=*/8);
88 uint64_t Offset = 0;
89 uint64_t Length;
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);
96 // Empty data.
97 EXPECT_THAT_EXPECTED(
98 GetWithError({}),
99 FailedWithMessage(
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}),
106 FailedWithMessage(
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}),
127 FailedWithMessage(
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}),
134 FailedWithMessage(
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}),
141 FailedWithMessage(
142 "unexpected end of data at offset 0x8 while reading [0x4, 0xc)"));
143 EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03}),
144 ErrorResult);
146 EXPECT_THAT_EXPECTED(
147 GetWithError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
148 0x06, 0x07}),
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) {
156 StringRef Yaml = R"(
157 !ELF
158 FileHeader:
159 Class: ELFCLASS32
160 Data: ELFDATA2LSB
161 Type: ET_REL
162 Machine: EM_386
163 Sections:
164 - Name: .text
165 Type: SHT_PROGBITS
166 Size: 0x80
167 - Name: .debug_line
168 Type: SHT_PROGBITS
169 Content: '616263640000000065666768'
170 - Name: .rel.debug_line
171 Type: SHT_REL
172 Info: .debug_line
173 Relocations:
174 - Offset: 4
175 Symbol: f
176 Type: R_386_32
177 Symbols:
178 - Name: f
179 Type: STT_SECTION
180 Section: .text
181 Value: 0x42
183 SmallString<0> Storage;
184 std::unique_ptr<object::ObjectFile> Obj = yaml::yaml2ObjectFile(
185 Storage, Yaml, [](const Twine &Err) { errs() << Err; });
186 ASSERT_TRUE(Obj);
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));
204 EXPECT_THAT_ERROR(
205 C.takeError(),
206 FailedWithMessage(
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));
213 EXPECT_THAT_ERROR(
214 C.takeError(),
215 FailedWithMessage(
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));
221 EXPECT_THAT_ERROR(
222 C.takeError(),
223 FailedWithMessage(
224 "unexpected end of data at offset 0x2 while reading [0x0, 0x4)"));
227 } // namespace