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