1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18
19 #include <vector>
20
21 #include <gtest/gtest.h>
22
23 #include <unwindstack/DwarfError.h>
24 #include <unwindstack/Elf.h>
25 #include <unwindstack/ElfInterface.h>
26
27 #include "DwarfDebugFrame.h"
28 #include "DwarfEncoding.h"
29
30 #include "LogFake.h"
31 #include "utils/MemoryFake.h"
32
33 namespace unwindstack {
34
35 template <typename TypeParam>
36 class DwarfDebugFrameTest : public ::testing::Test {
37 protected:
SetUp()38 void SetUp() override {
39 fake_memory_ = new MemoryFake;
40 std::shared_ptr<Memory> memory(fake_memory_);
41 debug_frame_ = new DwarfDebugFrame<TypeParam>(memory);
42 ResetLogs();
43 }
44
TearDown()45 void TearDown() override { delete debug_frame_; }
46
47 MemoryFake* fake_memory_;
48 DwarfDebugFrame<TypeParam>* debug_frame_ = nullptr;
49 };
50 TYPED_TEST_SUITE_P(DwarfDebugFrameTest);
51
52 // NOTE: All test class variables need to be referenced as this->.
53
SetCie32(MemoryFake * memory,uint64_t offset,uint32_t length,std::vector<uint8_t> data)54 static void SetCie32(MemoryFake* memory, uint64_t offset, uint32_t length,
55 std::vector<uint8_t> data) {
56 memory->SetData32(offset, length);
57 offset += 4;
58 // Indicates this is a cie.
59 memory->SetData32(offset, 0xffffffff);
60 offset += 4;
61 memory->SetMemory(offset, data);
62 }
63
SetCie64(MemoryFake * memory,uint64_t offset,uint64_t length,std::vector<uint8_t> data)64 static void SetCie64(MemoryFake* memory, uint64_t offset, uint64_t length,
65 std::vector<uint8_t> data) {
66 memory->SetData32(offset, 0xffffffff);
67 offset += 4;
68 memory->SetData64(offset, length);
69 offset += 8;
70 // Indicates this is a cie.
71 memory->SetData64(offset, 0xffffffffffffffffUL);
72 offset += 8;
73 memory->SetMemory(offset, data);
74 }
75
SetFde32(MemoryFake * memory,uint64_t offset,uint32_t length,uint64_t cie_offset,uint32_t pc_start,uint32_t pc_length,uint64_t segment_length=0,std::vector<uint8_t> * data=nullptr)76 static void SetFde32(MemoryFake* memory, uint64_t offset, uint32_t length, uint64_t cie_offset,
77 uint32_t pc_start, uint32_t pc_length, uint64_t segment_length = 0,
78 std::vector<uint8_t>* data = nullptr) {
79 memory->SetData32(offset, length);
80 offset += 4;
81 memory->SetData32(offset, cie_offset);
82 offset += 4 + segment_length;
83 memory->SetData32(offset, pc_start);
84 offset += 4;
85 memory->SetData32(offset, pc_length);
86 if (data != nullptr) {
87 offset += 4;
88 memory->SetMemory(offset, *data);
89 }
90 }
91
SetFde64(MemoryFake * memory,uint64_t offset,uint64_t length,uint64_t cie_offset,uint64_t pc_start,uint64_t pc_length,uint64_t segment_length=0,std::vector<uint8_t> * data=nullptr)92 static void SetFde64(MemoryFake* memory, uint64_t offset, uint64_t length, uint64_t cie_offset,
93 uint64_t pc_start, uint64_t pc_length, uint64_t segment_length = 0,
94 std::vector<uint8_t>* data = nullptr) {
95 memory->SetData32(offset, 0xffffffff);
96 offset += 4;
97 memory->SetData64(offset, length);
98 offset += 8;
99 memory->SetData64(offset, cie_offset);
100 offset += 8 + segment_length;
101 memory->SetData64(offset, pc_start);
102 offset += 8;
103 memory->SetData64(offset, pc_length);
104 if (data != nullptr) {
105 offset += 8;
106 memory->SetMemory(offset, *data);
107 }
108 }
109
SetFourFdes32(MemoryFake * memory)110 static void SetFourFdes32(MemoryFake* memory) {
111 SetCie32(memory, 0x5000, 0xfc, std::vector<uint8_t>{1, '\0', 0, 0, 1});
112
113 // FDE 32 information.
114 SetFde32(memory, 0x5100, 0xfc, 0, 0x1500, 0x200);
115 SetFde32(memory, 0x5200, 0xfc, 0, 0x2500, 0x300);
116
117 // CIE 32 information.
118 SetCie32(memory, 0x5300, 0xfc, std::vector<uint8_t>{1, '\0', 0, 0, 1});
119
120 // FDE 32 information.
121 SetFde32(memory, 0x5400, 0xfc, 0x300, 0x3500, 0x400);
122 SetFde32(memory, 0x5500, 0xfc, 0x300, 0x4500, 0x500);
123 }
124
TYPED_TEST_P(DwarfDebugFrameTest,Init_compressed)125 TYPED_TEST_P(DwarfDebugFrameTest, Init_compressed) {
126 SetFourFdes32(this->fake_memory_);
127 ASSERT_FALSE(this->debug_frame_->Init(
128 SectionInfo{.offset = 0x5000, .size = 0x600, .flags = SHF_COMPRESSED}));
129 }
130
TYPED_TEST_P(DwarfDebugFrameTest,GetFdes32)131 TYPED_TEST_P(DwarfDebugFrameTest, GetFdes32) {
132 SetFourFdes32(this->fake_memory_);
133 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x600}));
134
135 std::vector<const DwarfFde*> fdes;
136 this->debug_frame_->GetFdes(&fdes);
137
138 ASSERT_EQ(4U, fdes.size());
139
140 EXPECT_EQ(0x5000U, fdes[0]->cie_offset);
141 EXPECT_EQ(0x5110U, fdes[0]->cfa_instructions_offset);
142 EXPECT_EQ(0x5200U, fdes[0]->cfa_instructions_end);
143 EXPECT_EQ(0x1500U, fdes[0]->pc_start);
144 EXPECT_EQ(0x1700U, fdes[0]->pc_end);
145 EXPECT_EQ(0U, fdes[0]->lsda_address);
146 EXPECT_TRUE(fdes[0]->cie != nullptr);
147
148 EXPECT_EQ(0x5000U, fdes[1]->cie_offset);
149 EXPECT_EQ(0x5210U, fdes[1]->cfa_instructions_offset);
150 EXPECT_EQ(0x5300U, fdes[1]->cfa_instructions_end);
151 EXPECT_EQ(0x2500U, fdes[1]->pc_start);
152 EXPECT_EQ(0x2800U, fdes[1]->pc_end);
153 EXPECT_EQ(0U, fdes[1]->lsda_address);
154 EXPECT_TRUE(fdes[1]->cie != nullptr);
155
156 EXPECT_EQ(0x5300U, fdes[2]->cie_offset);
157 EXPECT_EQ(0x5410U, fdes[2]->cfa_instructions_offset);
158 EXPECT_EQ(0x5500U, fdes[2]->cfa_instructions_end);
159 EXPECT_EQ(0x3500U, fdes[2]->pc_start);
160 EXPECT_EQ(0x3900U, fdes[2]->pc_end);
161 EXPECT_EQ(0U, fdes[2]->lsda_address);
162 EXPECT_TRUE(fdes[2]->cie != nullptr);
163
164 EXPECT_EQ(0x5300U, fdes[3]->cie_offset);
165 EXPECT_EQ(0x5510U, fdes[3]->cfa_instructions_offset);
166 EXPECT_EQ(0x5600U, fdes[3]->cfa_instructions_end);
167 EXPECT_EQ(0x4500U, fdes[3]->pc_start);
168 EXPECT_EQ(0x4a00U, fdes[3]->pc_end);
169 EXPECT_EQ(0U, fdes[3]->lsda_address);
170 EXPECT_TRUE(fdes[3]->cie != nullptr);
171 }
172
TYPED_TEST_P(DwarfDebugFrameTest,GetFdes32_after_GetFdeFromPc)173 TYPED_TEST_P(DwarfDebugFrameTest, GetFdes32_after_GetFdeFromPc) {
174 SetFourFdes32(this->fake_memory_);
175 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x600}));
176
177 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x3600);
178 ASSERT_TRUE(fde != nullptr);
179 EXPECT_EQ(0x3500U, fde->pc_start);
180 EXPECT_EQ(0x3900U, fde->pc_end);
181
182 std::vector<const DwarfFde*> fdes;
183 this->debug_frame_->GetFdes(&fdes);
184 ASSERT_EQ(4U, fdes.size());
185
186 // Verify that they got added in the correct order.
187 EXPECT_EQ(0x1500U, fdes[0]->pc_start);
188 EXPECT_EQ(0x1700U, fdes[0]->pc_end);
189 EXPECT_EQ(0x2500U, fdes[1]->pc_start);
190 EXPECT_EQ(0x2800U, fdes[1]->pc_end);
191 EXPECT_EQ(0x3500U, fdes[2]->pc_start);
192 EXPECT_EQ(0x3900U, fdes[2]->pc_end);
193 EXPECT_EQ(0x4500U, fdes[3]->pc_start);
194 EXPECT_EQ(0x4a00U, fdes[3]->pc_end);
195 }
196
TYPED_TEST_P(DwarfDebugFrameTest,GetFdes32_not_in_section)197 TYPED_TEST_P(DwarfDebugFrameTest, GetFdes32_not_in_section) {
198 SetFourFdes32(this->fake_memory_);
199 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x500}));
200
201 std::vector<const DwarfFde*> fdes;
202 this->debug_frame_->GetFdes(&fdes);
203
204 ASSERT_EQ(3U, fdes.size());
205 }
206
TYPED_TEST_P(DwarfDebugFrameTest,GetFdes32_big_function_address)207 TYPED_TEST_P(DwarfDebugFrameTest, GetFdes32_big_function_address) {
208 SetCie32(this->fake_memory_, 0x5000, 0xfc, std::vector<uint8_t>{1, '\0', 0, 0, 1});
209 SetFde32(this->fake_memory_, 0x5100, 0xfc, 0, 0xe9ad9b1f, 0x200);
210 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x200}));
211
212 std::vector<const DwarfFde*> fdes;
213 this->debug_frame_->GetFdes(&fdes);
214
215 ASSERT_EQ(1U, fdes.size());
216
217 EXPECT_EQ(0x5000U, fdes[0]->cie_offset);
218 EXPECT_EQ(0x5110U, fdes[0]->cfa_instructions_offset);
219 EXPECT_EQ(0x5200U, fdes[0]->cfa_instructions_end);
220 EXPECT_EQ(0xe9ad9b1fU, fdes[0]->pc_start);
221 EXPECT_EQ(0xe9ad9d1fU, fdes[0]->pc_end);
222 EXPECT_EQ(0U, fdes[0]->lsda_address);
223 EXPECT_TRUE(fdes[0]->cie != nullptr);
224 }
225
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromPc32)226 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc32) {
227 SetFourFdes32(this->fake_memory_);
228 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x600}));
229
230 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x1600);
231 ASSERT_TRUE(fde != nullptr);
232 EXPECT_EQ(0x1500U, fde->pc_start);
233
234 fde = this->debug_frame_->GetFdeFromPc(0x2600);
235 ASSERT_TRUE(fde != nullptr);
236 EXPECT_EQ(0x2500U, fde->pc_start);
237
238 fde = this->debug_frame_->GetFdeFromPc(0x3600);
239 ASSERT_TRUE(fde != nullptr);
240 EXPECT_EQ(0x3500U, fde->pc_start);
241
242 fde = this->debug_frame_->GetFdeFromPc(0x4600);
243 ASSERT_TRUE(fde != nullptr);
244 EXPECT_EQ(0x4500U, fde->pc_start);
245
246 fde = this->debug_frame_->GetFdeFromPc(0);
247 ASSERT_TRUE(fde == nullptr);
248 }
249
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromPc32_reverse)250 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc32_reverse) {
251 SetFourFdes32(this->fake_memory_);
252 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x600}));
253
254 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x4600);
255 ASSERT_TRUE(fde != nullptr);
256 EXPECT_EQ(0x4500U, fde->pc_start);
257
258 fde = this->debug_frame_->GetFdeFromPc(0x3600);
259 ASSERT_TRUE(fde != nullptr);
260 EXPECT_EQ(0x3500U, fde->pc_start);
261
262 fde = this->debug_frame_->GetFdeFromPc(0x2600);
263 ASSERT_TRUE(fde != nullptr);
264 EXPECT_EQ(0x2500U, fde->pc_start);
265
266 fde = this->debug_frame_->GetFdeFromPc(0x1600);
267 ASSERT_TRUE(fde != nullptr);
268 EXPECT_EQ(0x1500U, fde->pc_start);
269
270 fde = this->debug_frame_->GetFdeFromPc(0);
271 ASSERT_TRUE(fde == nullptr);
272 }
273
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromPc32_not_in_section)274 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc32_not_in_section) {
275 SetFourFdes32(this->fake_memory_);
276 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x500}));
277
278 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x4600);
279 ASSERT_TRUE(fde == nullptr);
280 }
281
SetFourFdes64(MemoryFake * memory)282 static void SetFourFdes64(MemoryFake* memory) {
283 // CIE 64 information.
284 SetCie64(memory, 0x5000, 0xf4, std::vector<uint8_t>{1, '\0', 0, 0, 1});
285
286 // FDE 64 information.
287 SetFde64(memory, 0x5100, 0xf4, 0, 0x1500, 0x200);
288 SetFde64(memory, 0x5200, 0xf4, 0, 0x2500, 0x300);
289
290 // CIE 64 information.
291 SetCie64(memory, 0x5300, 0xf4, std::vector<uint8_t>{1, '\0', 0, 0, 1});
292
293 // FDE 64 information.
294 SetFde64(memory, 0x5400, 0xf4, 0x300, 0x3500, 0x400);
295 SetFde64(memory, 0x5500, 0xf4, 0x300, 0x4500, 0x500);
296 }
297
TYPED_TEST_P(DwarfDebugFrameTest,GetFdes64)298 TYPED_TEST_P(DwarfDebugFrameTest, GetFdes64) {
299 SetFourFdes64(this->fake_memory_);
300 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x600}));
301
302 std::vector<const DwarfFde*> fdes;
303 this->debug_frame_->GetFdes(&fdes);
304
305 ASSERT_EQ(4U, fdes.size());
306
307 EXPECT_EQ(0x5000U, fdes[0]->cie_offset);
308 EXPECT_EQ(0x5124U, fdes[0]->cfa_instructions_offset);
309 EXPECT_EQ(0x5200U, fdes[0]->cfa_instructions_end);
310 EXPECT_EQ(0x1500U, fdes[0]->pc_start);
311 EXPECT_EQ(0x1700U, fdes[0]->pc_end);
312 EXPECT_EQ(0U, fdes[0]->lsda_address);
313 EXPECT_TRUE(fdes[0]->cie != nullptr);
314
315 EXPECT_EQ(0x5000U, fdes[1]->cie_offset);
316 EXPECT_EQ(0x5224U, fdes[1]->cfa_instructions_offset);
317 EXPECT_EQ(0x5300U, fdes[1]->cfa_instructions_end);
318 EXPECT_EQ(0x2500U, fdes[1]->pc_start);
319 EXPECT_EQ(0x2800U, fdes[1]->pc_end);
320 EXPECT_EQ(0U, fdes[1]->lsda_address);
321 EXPECT_TRUE(fdes[1]->cie != nullptr);
322
323 EXPECT_EQ(0x5300U, fdes[2]->cie_offset);
324 EXPECT_EQ(0x5424U, fdes[2]->cfa_instructions_offset);
325 EXPECT_EQ(0x5500U, fdes[2]->cfa_instructions_end);
326 EXPECT_EQ(0x3500U, fdes[2]->pc_start);
327 EXPECT_EQ(0x3900U, fdes[2]->pc_end);
328 EXPECT_EQ(0U, fdes[2]->lsda_address);
329 EXPECT_TRUE(fdes[2]->cie != nullptr);
330
331 EXPECT_EQ(0x5300U, fdes[3]->cie_offset);
332 EXPECT_EQ(0x5524U, fdes[3]->cfa_instructions_offset);
333 EXPECT_EQ(0x5600U, fdes[3]->cfa_instructions_end);
334 EXPECT_EQ(0x4500U, fdes[3]->pc_start);
335 EXPECT_EQ(0x4a00U, fdes[3]->pc_end);
336 EXPECT_EQ(0U, fdes[3]->lsda_address);
337 EXPECT_TRUE(fdes[3]->cie != nullptr);
338 }
339
TYPED_TEST_P(DwarfDebugFrameTest,GetFdes64_after_GetFdeFromPc)340 TYPED_TEST_P(DwarfDebugFrameTest, GetFdes64_after_GetFdeFromPc) {
341 SetFourFdes64(this->fake_memory_);
342 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x600}));
343
344 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x2600);
345 ASSERT_TRUE(fde != nullptr);
346 EXPECT_EQ(0x2500U, fde->pc_start);
347 EXPECT_EQ(0x2800U, fde->pc_end);
348
349 std::vector<const DwarfFde*> fdes;
350 this->debug_frame_->GetFdes(&fdes);
351 ASSERT_EQ(4U, fdes.size());
352
353 // Verify that they got added in the correct order.
354 EXPECT_EQ(0x1500U, fdes[0]->pc_start);
355 EXPECT_EQ(0x1700U, fdes[0]->pc_end);
356 EXPECT_EQ(0x2500U, fdes[1]->pc_start);
357 EXPECT_EQ(0x2800U, fdes[1]->pc_end);
358 EXPECT_EQ(0x3500U, fdes[2]->pc_start);
359 EXPECT_EQ(0x3900U, fdes[2]->pc_end);
360 EXPECT_EQ(0x4500U, fdes[3]->pc_start);
361 EXPECT_EQ(0x4a00U, fdes[3]->pc_end);
362 }
363
TYPED_TEST_P(DwarfDebugFrameTest,GetFdes64_not_in_section)364 TYPED_TEST_P(DwarfDebugFrameTest, GetFdes64_not_in_section) {
365 SetFourFdes64(this->fake_memory_);
366 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x500}));
367
368 std::vector<const DwarfFde*> fdes;
369 this->debug_frame_->GetFdes(&fdes);
370
371 ASSERT_EQ(3U, fdes.size());
372 }
373
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromPc64)374 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc64) {
375 SetFourFdes64(this->fake_memory_);
376 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x600}));
377
378 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x1600);
379 ASSERT_TRUE(fde != nullptr);
380 EXPECT_EQ(0x1500U, fde->pc_start);
381
382 fde = this->debug_frame_->GetFdeFromPc(0x2600);
383 ASSERT_TRUE(fde != nullptr);
384 EXPECT_EQ(0x2500U, fde->pc_start);
385
386 fde = this->debug_frame_->GetFdeFromPc(0x3600);
387 ASSERT_TRUE(fde != nullptr);
388 EXPECT_EQ(0x3500U, fde->pc_start);
389
390 fde = this->debug_frame_->GetFdeFromPc(0x4600);
391 ASSERT_TRUE(fde != nullptr);
392 EXPECT_EQ(0x4500U, fde->pc_start);
393
394 fde = this->debug_frame_->GetFdeFromPc(0);
395 ASSERT_TRUE(fde == nullptr);
396 }
397
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromPc64_reverse)398 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc64_reverse) {
399 SetFourFdes64(this->fake_memory_);
400 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x600}));
401
402 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x4600);
403 ASSERT_TRUE(fde != nullptr);
404 EXPECT_EQ(0x4500U, fde->pc_start);
405
406 fde = this->debug_frame_->GetFdeFromPc(0x3600);
407 ASSERT_TRUE(fde != nullptr);
408 EXPECT_EQ(0x3500U, fde->pc_start);
409
410 fde = this->debug_frame_->GetFdeFromPc(0x2600);
411 ASSERT_TRUE(fde != nullptr);
412 EXPECT_EQ(0x2500U, fde->pc_start);
413
414 fde = this->debug_frame_->GetFdeFromPc(0x1600);
415 ASSERT_TRUE(fde != nullptr);
416 EXPECT_EQ(0x1500U, fde->pc_start);
417
418 fde = this->debug_frame_->GetFdeFromPc(0);
419 ASSERT_TRUE(fde == nullptr);
420 }
421
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromPc64_not_in_section)422 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc64_not_in_section) {
423 SetFourFdes64(this->fake_memory_);
424 ASSERT_TRUE(this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x500}));
425
426 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x4600);
427 ASSERT_TRUE(fde == nullptr);
428 }
429
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFde32)430 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFde32) {
431 SetCie32(this->fake_memory_, 0xf000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
432 SetFde32(this->fake_memory_, 0x14000, 0x20, 0xf000, 0x9000, 0x100);
433
434 const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x14000);
435 ASSERT_TRUE(fde != nullptr);
436 EXPECT_EQ(0x14010U, fde->cfa_instructions_offset);
437 EXPECT_EQ(0x14024U, fde->cfa_instructions_end);
438 EXPECT_EQ(0x9000U, fde->pc_start);
439 EXPECT_EQ(0x9100U, fde->pc_end);
440 EXPECT_EQ(0xf000U, fde->cie_offset);
441 EXPECT_EQ(0U, fde->lsda_address);
442
443 ASSERT_TRUE(fde->cie != nullptr);
444 EXPECT_EQ(1U, fde->cie->version);
445 EXPECT_EQ(DW_EH_PE_udata4, fde->cie->fde_address_encoding);
446 EXPECT_EQ(DW_EH_PE_omit, fde->cie->lsda_encoding);
447 EXPECT_EQ(0U, fde->cie->segment_size);
448 EXPECT_EQ(1U, fde->cie->augmentation_string.size());
449 EXPECT_EQ('\0', fde->cie->augmentation_string[0]);
450 EXPECT_EQ(0U, fde->cie->personality_handler);
451 EXPECT_EQ(0xf00dU, fde->cie->cfa_instructions_offset);
452 EXPECT_EQ(0xf104U, fde->cie->cfa_instructions_end);
453 EXPECT_EQ(4U, fde->cie->code_alignment_factor);
454 EXPECT_EQ(8, fde->cie->data_alignment_factor);
455 EXPECT_EQ(0x20U, fde->cie->return_address_register);
456 }
457
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFde64)458 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFde64) {
459 SetCie64(this->fake_memory_, 0x6000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
460 SetFde64(this->fake_memory_, 0x8000, 0x200, 0x6000, 0x5000, 0x300);
461
462 const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x8000);
463 ASSERT_TRUE(fde != nullptr);
464 EXPECT_EQ(0x8024U, fde->cfa_instructions_offset);
465 EXPECT_EQ(0x820cU, fde->cfa_instructions_end);
466 EXPECT_EQ(0x5000U, fde->pc_start);
467 EXPECT_EQ(0x5300U, fde->pc_end);
468 EXPECT_EQ(0x6000U, fde->cie_offset);
469 EXPECT_EQ(0U, fde->lsda_address);
470
471 ASSERT_TRUE(fde->cie != nullptr);
472 EXPECT_EQ(1U, fde->cie->version);
473 EXPECT_EQ(DW_EH_PE_udata8, fde->cie->fde_address_encoding);
474 EXPECT_EQ(DW_EH_PE_omit, fde->cie->lsda_encoding);
475 EXPECT_EQ(0U, fde->cie->segment_size);
476 EXPECT_EQ(1U, fde->cie->augmentation_string.size());
477 EXPECT_EQ('\0', fde->cie->augmentation_string[0]);
478 EXPECT_EQ(0U, fde->cie->personality_handler);
479 EXPECT_EQ(0x6019U, fde->cie->cfa_instructions_offset);
480 EXPECT_EQ(0x610cU, fde->cie->cfa_instructions_end);
481 EXPECT_EQ(4U, fde->cie->code_alignment_factor);
482 EXPECT_EQ(8, fde->cie->data_alignment_factor);
483 EXPECT_EQ(0x20U, fde->cie->return_address_register);
484 }
485
VerifyCieVersion(const DwarfCie * cie,uint8_t version,uint8_t segment_size,uint8_t fde_encoding,uint64_t return_address,uint64_t start_offset,uint64_t end_offset)486 static void VerifyCieVersion(const DwarfCie* cie, uint8_t version, uint8_t segment_size,
487 uint8_t fde_encoding, uint64_t return_address, uint64_t start_offset,
488 uint64_t end_offset) {
489 EXPECT_EQ(version, cie->version);
490 EXPECT_EQ(fde_encoding, cie->fde_address_encoding);
491 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
492 EXPECT_EQ(segment_size, cie->segment_size);
493 EXPECT_EQ(1U, cie->augmentation_string.size());
494 EXPECT_EQ('\0', cie->augmentation_string[0]);
495 EXPECT_EQ(0U, cie->personality_handler);
496 EXPECT_EQ(4U, cie->code_alignment_factor);
497 EXPECT_EQ(8, cie->data_alignment_factor);
498 EXPECT_EQ(return_address, cie->return_address_register);
499 EXPECT_EQ(0x5000U + start_offset, cie->cfa_instructions_offset);
500 EXPECT_EQ(0x5000U + end_offset, cie->cfa_instructions_end);
501 }
502
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset32_cie_cached)503 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_cie_cached) {
504 SetCie32(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
505 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
506 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
507 ASSERT_TRUE(cie != nullptr);
508 VerifyCieVersion(cie, 1, 0, DW_EH_PE_udata4, 0x20, 0xd, 0x104);
509
510 std::vector<uint8_t> zero(0x100, 0);
511 this->fake_memory_->SetMemory(0x5000, zero);
512 cie = this->debug_frame_->GetCieFromOffset(0x5000);
513 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
514 ASSERT_TRUE(cie != nullptr);
515 VerifyCieVersion(cie, 1, 0, DW_EH_PE_udata4, 0x20, 0xd, 0x104);
516 }
517
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset64_cie_cached)518 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_cie_cached) {
519 SetCie64(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
520 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
521 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
522 ASSERT_TRUE(cie != nullptr);
523 VerifyCieVersion(cie, 1, 0, DW_EH_PE_udata8, 0x20, 0x19, 0x10c);
524
525 std::vector<uint8_t> zero(0x100, 0);
526 this->fake_memory_->SetMemory(0x5000, zero);
527 cie = this->debug_frame_->GetCieFromOffset(0x5000);
528 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
529 ASSERT_TRUE(cie != nullptr);
530 VerifyCieVersion(cie, 1, 0, DW_EH_PE_udata8, 0x20, 0x19, 0x10c);
531 }
532
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset32_version1)533 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_version1) {
534 SetCie32(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
535 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
536 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
537 ASSERT_TRUE(cie != nullptr);
538 VerifyCieVersion(cie, 1, 0, DW_EH_PE_udata4, 0x20, 0xd, 0x104);
539 }
540
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset64_version1)541 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_version1) {
542 SetCie64(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
543 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
544 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
545 ASSERT_TRUE(cie != nullptr);
546 VerifyCieVersion(cie, 1, 0, DW_EH_PE_udata8, 0x20, 0x19, 0x10c);
547 }
548
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset32_version3)549 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_version3) {
550 SetCie32(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{3, '\0', 4, 8, 0x81, 3});
551 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
552 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
553 ASSERT_TRUE(cie != nullptr);
554 VerifyCieVersion(cie, 3, 0, DW_EH_PE_udata4, 0x181, 0xe, 0x104);
555 }
556
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset64_version3)557 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_version3) {
558 SetCie64(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{3, '\0', 4, 8, 0x81, 3});
559 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
560 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
561 ASSERT_TRUE(cie != nullptr);
562 VerifyCieVersion(cie, 3, 0, DW_EH_PE_udata8, 0x181, 0x1a, 0x10c);
563 }
564
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset32_version4_32bit_address)565 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_version4_32bit_address) {
566 SetCie32(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{4, '\0', 4, 10, 4, 8, 0x81, 3});
567 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
568 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
569 ASSERT_TRUE(cie != nullptr);
570 VerifyCieVersion(cie, 4, 10, DW_EH_PE_udata4, 0x181, 0x10, 0x104);
571 }
572
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset32_version4_64bit_address)573 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_version4_64bit_address) {
574 SetCie32(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{4, '\0', 8, 10, 4, 8, 0x81, 3});
575 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
576 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
577 ASSERT_TRUE(cie != nullptr);
578 VerifyCieVersion(cie, 4, 10, DW_EH_PE_udata8, 0x181, 0x10, 0x104);
579 }
580
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset64_version4_32bit_address)581 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_version4_32bit_address) {
582 SetCie64(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{4, '\0', 4, 10, 4, 8, 0x81, 3});
583 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
584 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
585 ASSERT_TRUE(cie != nullptr);
586 VerifyCieVersion(cie, 4, 10, DW_EH_PE_udata4, 0x181, 0x1c, 0x10c);
587 }
588
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset64_version4_64bit_address)589 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_version4_64bit_address) {
590 SetCie64(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{4, '\0', 8, 10, 4, 8, 0x81, 3});
591 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
592 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
593 ASSERT_TRUE(cie != nullptr);
594 VerifyCieVersion(cie, 4, 10, DW_EH_PE_udata8, 0x181, 0x1c, 0x10c);
595 }
596
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset32_version5)597 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_version5) {
598 SetCie32(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{5, '\0', 4, 10, 4, 8, 0x81, 3});
599 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
600 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
601 ASSERT_TRUE(cie != nullptr);
602 VerifyCieVersion(cie, 5, 10, DW_EH_PE_udata4, 0x181, 0x10, 0x104);
603 }
604
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset64_version5)605 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_version5) {
606 SetCie64(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{5, '\0', 8, 10, 4, 8, 0x81, 3});
607 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
608 EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
609 ASSERT_TRUE(cie != nullptr);
610 VerifyCieVersion(cie, 5, 10, DW_EH_PE_udata8, 0x181, 0x1c, 0x10c);
611 }
612
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset_version_invalid)613 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset_version_invalid) {
614 SetCie32(this->fake_memory_, 0x5000, 0x100, std::vector<uint8_t>{0, '\0', 1, 2, 3, 4, 5, 6, 7});
615 ASSERT_TRUE(this->debug_frame_->GetCieFromOffset(0x5000) == nullptr);
616 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->debug_frame_->LastErrorCode());
617 SetCie64(this->fake_memory_, 0x6000, 0x100, std::vector<uint8_t>{0, '\0', 1, 2, 3, 4, 5, 6, 7});
618 ASSERT_TRUE(this->debug_frame_->GetCieFromOffset(0x6000) == nullptr);
619 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->debug_frame_->LastErrorCode());
620
621 SetCie32(this->fake_memory_, 0x7000, 0x100, std::vector<uint8_t>{6, '\0', 1, 2, 3, 4, 5, 6, 7});
622 ASSERT_TRUE(this->debug_frame_->GetCieFromOffset(0x7000) == nullptr);
623 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->debug_frame_->LastErrorCode());
624 SetCie64(this->fake_memory_, 0x8000, 0x100, std::vector<uint8_t>{6, '\0', 1, 2, 3, 4, 5, 6, 7});
625 ASSERT_TRUE(this->debug_frame_->GetCieFromOffset(0x8000) == nullptr);
626 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->debug_frame_->LastErrorCode());
627 }
628
VerifyCieAugment(const DwarfCie * cie,uint64_t inst_offset,uint64_t inst_end)629 static void VerifyCieAugment(const DwarfCie* cie, uint64_t inst_offset, uint64_t inst_end) {
630 EXPECT_EQ(1U, cie->version);
631 EXPECT_EQ(DW_EH_PE_udata2, cie->fde_address_encoding);
632 EXPECT_EQ(DW_EH_PE_textrel | DW_EH_PE_udata2, cie->lsda_encoding);
633 EXPECT_EQ(0U, cie->segment_size);
634 EXPECT_EQ(5U, cie->augmentation_string.size());
635 EXPECT_EQ('z', cie->augmentation_string[0]);
636 EXPECT_EQ('L', cie->augmentation_string[1]);
637 EXPECT_EQ('P', cie->augmentation_string[2]);
638 EXPECT_EQ('R', cie->augmentation_string[3]);
639 EXPECT_EQ('\0', cie->augmentation_string[4]);
640 EXPECT_EQ(0x12345678U, cie->personality_handler);
641 EXPECT_EQ(4U, cie->code_alignment_factor);
642 EXPECT_EQ(8, cie->data_alignment_factor);
643 EXPECT_EQ(0x10U, cie->return_address_register);
644 EXPECT_EQ(inst_offset, cie->cfa_instructions_offset);
645 EXPECT_EQ(inst_end, cie->cfa_instructions_end);
646 }
647
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset32_augment)648 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_augment) {
649 SetCie32(this->fake_memory_, 0x5000, 0x100,
650 std::vector<uint8_t>{/* version */ 1,
651 /* augment string */ 'z', 'L', 'P', 'R', '\0',
652 /* code alignment factor */ 4,
653 /* data alignment factor */ 8,
654 /* return address register */ 0x10,
655 /* augment length */ 0xf,
656 /* L data */ DW_EH_PE_textrel | DW_EH_PE_udata2,
657 /* P data */ DW_EH_PE_udata4, 0x78, 0x56, 0x34, 0x12,
658 /* R data */ DW_EH_PE_udata2});
659
660 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
661 ASSERT_TRUE(cie != nullptr);
662 VerifyCieAugment(cie, 0x5021, 0x5104);
663 }
664
TYPED_TEST_P(DwarfDebugFrameTest,GetCieFromOffset64_augment)665 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_augment) {
666 SetCie64(this->fake_memory_, 0x5000, 0x100,
667 std::vector<uint8_t>{/* version */ 1,
668 /* augment string */ 'z', 'L', 'P', 'R', '\0',
669 /* code alignment factor */ 4,
670 /* data alignment factor */ 8,
671 /* return address register */ 0x10,
672 /* augment length */ 0xf,
673 /* L data */ DW_EH_PE_textrel | DW_EH_PE_udata2,
674 /* P data */ DW_EH_PE_udata4, 0x78, 0x56, 0x34, 0x12,
675 /* R data */ DW_EH_PE_udata2});
676
677 const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
678 ASSERT_TRUE(cie != nullptr);
679 VerifyCieAugment(cie, 0x502d, 0x510c);
680 }
681
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromOffset32_augment)682 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromOffset32_augment) {
683 SetCie32(this->fake_memory_, 0x5000, 0xfc,
684 std::vector<uint8_t>{/* version */ 4,
685 /* augment string */ 'z', '\0',
686 /* address size */ 4,
687 /* segment size */ 0x10,
688 /* code alignment factor */ 16,
689 /* data alignment factor */ 32,
690 /* return address register */ 10,
691 /* augment length */ 0x0});
692
693 std::vector<uint8_t> data{/* augment length */ 0x80, 0x3};
694 SetFde32(this->fake_memory_, 0x5200, 0x300, 0x5000, 0x4300, 0x300, 0x10, &data);
695
696 const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x5200);
697 ASSERT_TRUE(fde != nullptr);
698 ASSERT_TRUE(fde->cie != nullptr);
699 EXPECT_EQ(4U, fde->cie->version);
700 EXPECT_EQ(0x5000U, fde->cie_offset);
701 EXPECT_EQ(0x53a2U, fde->cfa_instructions_offset);
702 EXPECT_EQ(0x5504U, fde->cfa_instructions_end);
703 EXPECT_EQ(0x4300U, fde->pc_start);
704 EXPECT_EQ(0x4600U, fde->pc_end);
705 EXPECT_EQ(0U, fde->lsda_address);
706 }
707
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromOffset64_augment)708 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromOffset64_augment) {
709 SetCie64(this->fake_memory_, 0x5000, 0xfc,
710 std::vector<uint8_t>{/* version */ 4,
711 /* augment string */ 'z', '\0',
712 /* address size */ 8,
713 /* segment size */ 0x10,
714 /* code alignment factor */ 16,
715 /* data alignment factor */ 32,
716 /* return address register */ 10,
717 /* augment length */ 0x0});
718
719 std::vector<uint8_t> data{/* augment length */ 0x80, 0x3};
720 SetFde64(this->fake_memory_, 0x5200, 0x300, 0x5000, 0x4300, 0x300, 0x10, &data);
721
722 const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x5200);
723 ASSERT_TRUE(fde != nullptr);
724 ASSERT_TRUE(fde->cie != nullptr);
725 EXPECT_EQ(4U, fde->cie->version);
726 EXPECT_EQ(0x5000U, fde->cie_offset);
727 EXPECT_EQ(0x53b6U, fde->cfa_instructions_offset);
728 EXPECT_EQ(0x550cU, fde->cfa_instructions_end);
729 EXPECT_EQ(0x4300U, fde->pc_start);
730 EXPECT_EQ(0x4600U, fde->pc_end);
731 EXPECT_EQ(0U, fde->lsda_address);
732 }
733
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromOffset32_lsda_address)734 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromOffset32_lsda_address) {
735 SetCie32(this->fake_memory_, 0x5000, 0xfc,
736 std::vector<uint8_t>{/* version */ 1,
737 /* augment string */ 'z', 'L', '\0',
738 /* address size */ 8,
739 /* code alignment factor */ 16,
740 /* data alignment factor */ 32,
741 /* return address register */ 10,
742 /* augment length */ 0x2,
743 /* L data */ DW_EH_PE_udata2});
744
745 std::vector<uint8_t> data{/* augment length */ 0x80, 0x3,
746 /* lsda address */ 0x20, 0x45};
747 SetFde32(this->fake_memory_, 0x5200, 0x300, 0x5000, 0x4300, 0x300, 0, &data);
748
749 const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x5200);
750 ASSERT_TRUE(fde != nullptr);
751 ASSERT_TRUE(fde->cie != nullptr);
752 EXPECT_EQ(1U, fde->cie->version);
753 EXPECT_EQ(0x5000U, fde->cie_offset);
754 EXPECT_EQ(0x5392U, fde->cfa_instructions_offset);
755 EXPECT_EQ(0x5504U, fde->cfa_instructions_end);
756 EXPECT_EQ(0x4300U, fde->pc_start);
757 EXPECT_EQ(0x4600U, fde->pc_end);
758 EXPECT_EQ(0x4520U, fde->lsda_address);
759 }
760
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromOffset64_lsda_address)761 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromOffset64_lsda_address) {
762 SetCie64(this->fake_memory_, 0x5000, 0xfc,
763 std::vector<uint8_t>{/* version */ 1,
764 /* augment string */ 'z', 'L', '\0',
765 /* address size */ 8,
766 /* code alignment factor */ 16,
767 /* data alignment factor */ 32,
768 /* return address register */ 10,
769 /* augment length */ 0x2,
770 /* L data */ DW_EH_PE_udata2});
771
772 std::vector<uint8_t> data{/* augment length */ 0x80, 0x3,
773 /* lsda address */ 0x20, 0x45};
774 SetFde64(this->fake_memory_, 0x5200, 0x300, 0x5000, 0x4300, 0x300, 0, &data);
775
776 const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x5200);
777 ASSERT_TRUE(fde != nullptr);
778 ASSERT_TRUE(fde->cie != nullptr);
779 EXPECT_EQ(1U, fde->cie->version);
780 EXPECT_EQ(0x5000U, fde->cie_offset);
781 EXPECT_EQ(0x53a6U, fde->cfa_instructions_offset);
782 EXPECT_EQ(0x550cU, fde->cfa_instructions_end);
783 EXPECT_EQ(0x4300U, fde->pc_start);
784 EXPECT_EQ(0x4600U, fde->pc_end);
785 EXPECT_EQ(0x4520U, fde->lsda_address);
786 }
787
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromPc_interleaved)788 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc_interleaved) {
789 SetCie32(this->fake_memory_, 0x5000, 0xfc, std::vector<uint8_t>{1, '\0', 0, 0, 1});
790
791 // FDE 0 (0x100 - 0x200)
792 SetFde32(this->fake_memory_, 0x5100, 0xfc, 0, 0x100, 0x100);
793 // FDE 1 (0x300 - 0x500)
794 SetFde32(this->fake_memory_, 0x5200, 0xfc, 0, 0x300, 0x200);
795 // FDE 2 (0x700 - 0x800)
796 SetFde32(this->fake_memory_, 0x5300, 0xfc, 0, 0x700, 0x100);
797 // FDE 3 (0xa00 - 0xb00)
798 SetFde32(this->fake_memory_, 0x5400, 0xfc, 0, 0xa00, 0x100);
799 // FDE 4 (0x100 - 0xb00)
800 SetFde32(this->fake_memory_, 0x5500, 0xfc, 0, 0x150, 0xa00);
801 // FDE 5 (0x50 - 0xa0)
802 SetFde32(this->fake_memory_, 0x5600, 0xfc, 0, 0x50, 0x50);
803 // FDE 6 (0x0 - 0x50)
804 SetFde32(this->fake_memory_, 0x5700, 0xfc, 0, 0, 0x50);
805
806 this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x800});
807
808 // Force reading all entries so no entries are found.
809 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0xfffff);
810 ASSERT_TRUE(fde == nullptr);
811
812 // 0x50 - 0xa0 FDE 5
813 fde = this->debug_frame_->GetFdeFromPc(0x60);
814 ASSERT_TRUE(fde != nullptr);
815 EXPECT_EQ(0x50U, fde->pc_start);
816 EXPECT_EQ(0xa0U, fde->pc_end);
817
818 // 0x0 - 0x50 FDE 6
819 fde = this->debug_frame_->GetFdeFromPc(0x10);
820 ASSERT_TRUE(fde != nullptr);
821 EXPECT_EQ(0U, fde->pc_start);
822 EXPECT_EQ(0x50U, fde->pc_end);
823
824 // 0x100 - 0x200 FDE 0
825 fde = this->debug_frame_->GetFdeFromPc(0x170);
826 ASSERT_TRUE(fde != nullptr);
827 EXPECT_EQ(0x100U, fde->pc_start);
828 EXPECT_EQ(0x200U, fde->pc_end);
829
830 // 0x200 - 0x300 FDE 4
831 fde = this->debug_frame_->GetFdeFromPc(0x210);
832 ASSERT_TRUE(fde != nullptr);
833 EXPECT_EQ(0x150U, fde->pc_start);
834 EXPECT_EQ(0xb50U, fde->pc_end);
835
836 // 0x300 - 0x500 FDE 1
837 fde = this->debug_frame_->GetFdeFromPc(0x310);
838 ASSERT_TRUE(fde != nullptr);
839 EXPECT_EQ(0x300U, fde->pc_start);
840 EXPECT_EQ(0x500U, fde->pc_end);
841
842 // 0x700 - 0x800 FDE 2
843 fde = this->debug_frame_->GetFdeFromPc(0x790);
844 ASSERT_TRUE(fde != nullptr);
845 EXPECT_EQ(0x700U, fde->pc_start);
846 EXPECT_EQ(0x800U, fde->pc_end);
847
848 // 0x800 - 0x900 FDE 4
849 fde = this->debug_frame_->GetFdeFromPc(0x850);
850 ASSERT_TRUE(fde != nullptr);
851 EXPECT_EQ(0x150U, fde->pc_start);
852 EXPECT_EQ(0xb50U, fde->pc_end);
853
854 // 0xa00 - 0xb00 FDE 3
855 fde = this->debug_frame_->GetFdeFromPc(0xa35);
856 ASSERT_TRUE(fde != nullptr);
857 EXPECT_EQ(0xa00U, fde->pc_start);
858 EXPECT_EQ(0xb00U, fde->pc_end);
859
860 // 0xb00 - 0xb50 FDE 4
861 fde = this->debug_frame_->GetFdeFromPc(0xb20);
862 ASSERT_TRUE(fde != nullptr);
863 EXPECT_EQ(0x150U, fde->pc_start);
864 EXPECT_EQ(0xb50U, fde->pc_end);
865 }
866
TYPED_TEST_P(DwarfDebugFrameTest,GetFdeFromPc_overlap)867 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc_overlap) {
868 SetCie32(this->fake_memory_, 0x5000, 0xfc, std::vector<uint8_t>{1, '\0', 0, 0, 1});
869
870 // FDE 0 (0x100 - 0x200)
871 SetFde32(this->fake_memory_, 0x5100, 0xfc, 0, 0x100, 0x100);
872 // FDE 1 (0x50 - 0x550)
873 SetFde32(this->fake_memory_, 0x5200, 0xfc, 0, 0x50, 0x500);
874 // FDE 2 (0x00 - 0x800)
875 SetFde32(this->fake_memory_, 0x5300, 0xfc, 0, 0x0, 0x800);
876
877 this->debug_frame_->Init(SectionInfo{.offset = 0x5000, .size = 0x400});
878
879 // Force reading all entries so no entries are found.
880 const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0xfffff);
881 ASSERT_TRUE(fde == nullptr);
882
883 // 0x0 - 0x50 FDE 2
884 fde = this->debug_frame_->GetFdeFromPc(0x10);
885 ASSERT_TRUE(fde != nullptr);
886 EXPECT_EQ(0x0U, fde->pc_start);
887 EXPECT_EQ(0x800U, fde->pc_end);
888
889 // 0x50 - 0x100 FDE 1 or FDE 2
890 fde = this->debug_frame_->GetFdeFromPc(0x60);
891 ASSERT_TRUE(fde != nullptr);
892 EXPECT_EQ(0x00U, fde->pc_start);
893 EXPECT_EQ(0x800U, fde->pc_end);
894
895 // 0x100 - 0x200 FDE 0, FDE 1, or FDE 2
896 fde = this->debug_frame_->GetFdeFromPc(0x170);
897 ASSERT_TRUE(fde != nullptr);
898 EXPECT_EQ(0x100U, fde->pc_start);
899 EXPECT_EQ(0x200U, fde->pc_end);
900
901 // 0x200 - 0x550 FDE 1, or FDE 2
902 fde = this->debug_frame_->GetFdeFromPc(0x210);
903 ASSERT_TRUE(fde != nullptr);
904 EXPECT_EQ(0x50U, fde->pc_start);
905 EXPECT_EQ(0x550U, fde->pc_end);
906
907 // 0x550 - 0x800 FDE 2
908 fde = this->debug_frame_->GetFdeFromPc(0x580);
909 ASSERT_TRUE(fde != nullptr);
910 EXPECT_EQ(0x0U, fde->pc_start);
911 EXPECT_EQ(0x800U, fde->pc_end);
912
913 fde = this->debug_frame_->GetFdeFromPc(0x810);
914 ASSERT_TRUE(fde == nullptr);
915 }
916
917 REGISTER_TYPED_TEST_SUITE_P(
918 DwarfDebugFrameTest, Init_compressed, GetFdes32, GetFdes32_after_GetFdeFromPc,
919 GetFdes32_not_in_section, GetFdes32_big_function_address, GetFdeFromPc32,
920 GetFdeFromPc32_reverse, GetFdeFromPc32_not_in_section, GetFdes64, GetFdes64_after_GetFdeFromPc,
921 GetFdes64_not_in_section, GetFdeFromPc64, GetFdeFromPc64_reverse, GetFdeFromPc64_not_in_section,
922 GetCieFde32, GetCieFde64, GetCieFromOffset32_cie_cached, GetCieFromOffset64_cie_cached,
923 GetCieFromOffset32_version1, GetCieFromOffset64_version1, GetCieFromOffset32_version3,
924 GetCieFromOffset64_version3, GetCieFromOffset32_version4_32bit_address,
925 GetCieFromOffset32_version4_64bit_address, GetCieFromOffset64_version4_32bit_address,
926 GetCieFromOffset64_version4_64bit_address, GetCieFromOffset32_version5,
927 GetCieFromOffset64_version5, GetCieFromOffset_version_invalid, GetCieFromOffset32_augment,
928 GetCieFromOffset64_augment, GetFdeFromOffset32_augment, GetFdeFromOffset64_augment,
929 GetFdeFromOffset32_lsda_address, GetFdeFromOffset64_lsda_address, GetFdeFromPc_interleaved,
930 GetFdeFromPc_overlap);
931
932 typedef ::testing::Types<uint32_t, uint64_t> DwarfDebugFrameTestTypes;
933 INSTANTIATE_TYPED_TEST_SUITE_P(Libunwindstack, DwarfDebugFrameTest, DwarfDebugFrameTestTypes);
934
935 } // namespace unwindstack
936