blob: 449442f36cf96618f6e0c73d68f77296d504053d [file] [log] [blame]
Pavel Labath3c36d8d2020-02-13 16:47:31 +01001//===- 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//===----------------------------------------------------------------------===//
8
9#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
Pavel Labath122c50d2020-04-14 17:06:04 +020010#include "llvm/DebugInfo/DWARF/DWARFContext.h"
11#include "llvm/Object/ObjectFile.h"
12#include "llvm/ObjectYAML/yaml2obj.h"
Pavel Labath3c36d8d2020-02-13 16:47:31 +010013#include "llvm/Testing/Support/Error.h"
14#include "gtest/gtest.h"
15
16using namespace llvm;
17
18namespace {
19
Pavel Labath122c50d2020-04-14 17:06:04 +020020TEST(DWARFDataExtractorTest, getRelocatedValue) {
21 StringRef Yaml = R"(
22!ELF
23FileHeader:
24 Class: ELFCLASS32
25 Data: ELFDATA2LSB
26 Type: ET_REL
27 Machine: EM_386
28Sections:
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
45Symbols:
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());
58
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));
Pavel Labath04aea762020-04-20 17:28:15 +020064 EXPECT_THAT_ERROR(
65 C.takeError(),
66 FailedWithMessage(
67 "unexpected end of data at offset 0x6 while reading [0x4, 0x8)"));
Pavel Labath122c50d2020-04-14 17:06:04 +020068}
69
Pavel Labath3c36d8d2020-02-13 16:47:31 +010070TEST(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());
80
81 EXPECT_EQ(Length, 0u);
82 EXPECT_EQ(Format, dwarf::DWARF32);
83 EXPECT_EQ(C.tell(), 0u);
84 return C.takeError();
85 };
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);
93 };
94 auto ErrorResult = std::make_tuple(0, dwarf::DWARF32, 0);
95
96 // Empty data.
Pavel Labath5754a612020-02-27 16:22:12 +010097 EXPECT_THAT_EXPECTED(
98 GetWithError({}),
Pavel Labath04aea762020-04-20 17:28:15 +020099 FailedWithMessage(
100 "unexpected end of data at offset 0x0 while reading [0x0, 0x4)"));
Pavel Labath3c36d8d2020-02-13 16:47:31 +0100101 EXPECT_EQ(GetWithoutError({}), ErrorResult);
102
103 // Not long enough for the U32 field.
Pavel Labath5754a612020-02-27 16:22:12 +0100104 EXPECT_THAT_EXPECTED(
105 GetWithError({0x00, 0x01, 0x02}),
Pavel Labath04aea762020-04-20 17:28:15 +0200106 FailedWithMessage(
107 "unexpected end of data at offset 0x3 while reading [0x0, 0x4)"));
Pavel Labath3c36d8d2020-02-13 16:47:31 +0100108 EXPECT_EQ(GetWithoutError({0x00, 0x01, 0x02}), ErrorResult);
109
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));
115
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));
123
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);
130
131 // DWARF64 marker without the subsequent length field.
Pavel Labath5754a612020-02-27 16:22:12 +0100132 EXPECT_THAT_EXPECTED(
133 GetWithError({0xff, 0xff, 0xff, 0xff}),
Pavel Labath04aea762020-04-20 17:28:15 +0200134 FailedWithMessage(
135 "unexpected end of data at offset 0x4 while reading [0x4, 0xc)"));
Pavel Labath3c36d8d2020-02-13 16:47:31 +0100136 EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff}), ErrorResult);
137
138 // Not enough data for the U64 length.
139 EXPECT_THAT_EXPECTED(
140 GetWithError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03}),
Pavel Labath04aea762020-04-20 17:28:15 +0200141 FailedWithMessage(
142 "unexpected end of data at offset 0x8 while reading [0x4, 0xc)"));
Pavel Labath3c36d8d2020-02-13 16:47:31 +0100143 EXPECT_EQ(GetWithoutError({0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03}),
144 ErrorResult);
145
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));
153}
154
Pavel Labathcc0acda2020-03-23 14:20:08 +0100155TEST(DWARFDataExtractorTest, Truncation) {
156 StringRef Yaml = R"(
157!ELF
158FileHeader:
159 Class: ELFCLASS32
160 Data: ELFDATA2LSB
161 Type: ET_REL
162 Machine: EM_386
163Sections:
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
177Symbols:
178 - Name: f
179 Type: STT_SECTION
180 Section: .text
181 Value: 0x42
182)";
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());
190
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());
198
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));
Pavel Labath04aea762020-04-20 17:28:15 +0200204 EXPECT_THAT_ERROR(
205 C.takeError(),
206 FailedWithMessage(
207 "unexpected end of data at offset 0x8 while reading [0x8, 0xc)"));
Pavel Labathcc0acda2020-03-23 14:20:08 +0100208
209 C = DataExtractor::Cursor{0};
210 DWARFDataExtractor Truncated6(Data, 6);
211 EXPECT_EQ(0x64636261u, Truncated6.getRelocatedAddress(C));
212 EXPECT_EQ(0x0u, Truncated6.getRelocatedAddress(C));
Pavel Labath04aea762020-04-20 17:28:15 +0200213 EXPECT_THAT_ERROR(
214 C.takeError(),
215 FailedWithMessage(
216 "unexpected end of data at offset 0x6 while reading [0x4, 0x8)"));
Pavel Labathcc0acda2020-03-23 14:20:08 +0100217
218 C = DataExtractor::Cursor{0};
219 DWARFDataExtractor Truncated2(Data, 2);
220 EXPECT_EQ(0x0u, Truncated2.getRelocatedAddress(C));
Pavel Labath04aea762020-04-20 17:28:15 +0200221 EXPECT_THAT_ERROR(
222 C.takeError(),
223 FailedWithMessage(
224 "unexpected end of data at offset 0x2 while reading [0x0, 0x4)"));
Pavel Labathcc0acda2020-03-23 14:20:08 +0100225}
226
Pavel Labath3c36d8d2020-02-13 16:47:31 +0100227} // namespace