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 <gmock/gmock.h> 20 #include <gtest/gtest.h> 21 22 #include <unwindstack/DwarfError.h> 23 24 #include "DwarfDebugFrame.h" 25 #include "DwarfEncoding.h" 26 27 #include "LogFake.h" 28 #include "MemoryFake.h" 29 30 namespace unwindstack { 31 32 template <typename TypeParam> 33 class MockDwarfDebugFrame : public DwarfDebugFrame<TypeParam> { 34 public: MockDwarfDebugFrame(Memory * memory)35 MockDwarfDebugFrame(Memory* memory) : DwarfDebugFrame<TypeParam>(memory) {} 36 ~MockDwarfDebugFrame() = default; 37 TestSetFdeCount(uint64_t count)38 void TestSetFdeCount(uint64_t count) { this->fde_count_ = count; } TestSetOffset(uint64_t offset)39 void TestSetOffset(uint64_t offset) { this->entries_offset_ = offset; } TestSetEndOffset(uint64_t offset)40 void TestSetEndOffset(uint64_t offset) { this->entries_end_ = offset; } TestPushFdeInfo(const typename DwarfDebugFrame<TypeParam>::FdeInfo & info)41 void TestPushFdeInfo(const typename DwarfDebugFrame<TypeParam>::FdeInfo& info) { 42 this->fdes_.push_back(info); 43 } 44 TestGetFdeCount()45 uint64_t TestGetFdeCount() { return this->fde_count_; } TestGetOffset()46 uint8_t TestGetOffset() { return this->offset_; } TestGetEndOffset()47 uint8_t TestGetEndOffset() { return this->end_offset_; } TestGetFdeInfo(size_t index,typename DwarfDebugFrame<TypeParam>::FdeInfo * info)48 void TestGetFdeInfo(size_t index, typename DwarfDebugFrame<TypeParam>::FdeInfo* info) { 49 *info = this->fdes_[index]; 50 } 51 }; 52 53 template <typename TypeParam> 54 class DwarfDebugFrameTest : public ::testing::Test { 55 protected: SetUp()56 void SetUp() override { 57 memory_.Clear(); 58 debug_frame_ = new MockDwarfDebugFrame<TypeParam>(&memory_); 59 ResetLogs(); 60 } 61 TearDown()62 void TearDown() override { delete debug_frame_; } 63 64 MemoryFake memory_; 65 MockDwarfDebugFrame<TypeParam>* debug_frame_ = nullptr; 66 }; 67 TYPED_TEST_CASE_P(DwarfDebugFrameTest); 68 69 // NOTE: All test class variables need to be referenced as this->. 70 TYPED_TEST_P(DwarfDebugFrameTest,Init32)71 TYPED_TEST_P(DwarfDebugFrameTest, Init32) { 72 // CIE 32 information. 73 this->memory_.SetData32(0x5000, 0xfc); 74 this->memory_.SetData32(0x5004, 0xffffffff); 75 this->memory_.SetData8(0x5008, 1); 76 this->memory_.SetData8(0x5009, '\0'); 77 78 // FDE 32 information. 79 this->memory_.SetData32(0x5100, 0xfc); 80 this->memory_.SetData32(0x5104, 0); 81 this->memory_.SetData32(0x5108, 0x1500); 82 this->memory_.SetData32(0x510c, 0x200); 83 84 this->memory_.SetData32(0x5200, 0xfc); 85 this->memory_.SetData32(0x5204, 0); 86 this->memory_.SetData32(0x5208, 0x2500); 87 this->memory_.SetData32(0x520c, 0x300); 88 89 // CIE 32 information. 90 this->memory_.SetData32(0x5300, 0xfc); 91 this->memory_.SetData32(0x5304, 0xffffffff); 92 this->memory_.SetData8(0x5308, 1); 93 this->memory_.SetData8(0x5309, '\0'); 94 95 // FDE 32 information. 96 this->memory_.SetData32(0x5400, 0xfc); 97 this->memory_.SetData32(0x5404, 0x300); 98 this->memory_.SetData32(0x5408, 0x3500); 99 this->memory_.SetData32(0x540c, 0x400); 100 101 this->memory_.SetData32(0x5500, 0xfc); 102 this->memory_.SetData32(0x5504, 0x300); 103 this->memory_.SetData32(0x5508, 0x4500); 104 this->memory_.SetData32(0x550c, 0x500); 105 106 ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600)); 107 ASSERT_EQ(4U, this->debug_frame_->TestGetFdeCount()); 108 109 typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0); 110 111 this->debug_frame_->TestGetFdeInfo(0, &info); 112 EXPECT_EQ(0x5100U, info.offset); 113 EXPECT_EQ(0x1500U, info.start); 114 EXPECT_EQ(0x1700U, info.end); 115 116 this->debug_frame_->TestGetFdeInfo(1, &info); 117 EXPECT_EQ(0x5200U, info.offset); 118 EXPECT_EQ(0x2500U, info.start); 119 EXPECT_EQ(0x2800U, info.end); 120 121 this->debug_frame_->TestGetFdeInfo(2, &info); 122 EXPECT_EQ(0x5400U, info.offset); 123 EXPECT_EQ(0x3500U, info.start); 124 EXPECT_EQ(0x3900U, info.end); 125 126 this->debug_frame_->TestGetFdeInfo(3, &info); 127 EXPECT_EQ(0x5500U, info.offset); 128 EXPECT_EQ(0x4500U, info.start); 129 EXPECT_EQ(0x4a00U, info.end); 130 } 131 TYPED_TEST_P(DwarfDebugFrameTest,Init32_fde_not_following_cie)132 TYPED_TEST_P(DwarfDebugFrameTest, Init32_fde_not_following_cie) { 133 // CIE 32 information. 134 this->memory_.SetData32(0x5000, 0xfc); 135 this->memory_.SetData32(0x5004, 0xffffffff); 136 this->memory_.SetData8(0x5008, 1); 137 this->memory_.SetData8(0x5009, '\0'); 138 139 // FDE 32 information. 140 this->memory_.SetData32(0x5100, 0xfc); 141 this->memory_.SetData32(0x5104, 0x1000); 142 this->memory_.SetData32(0x5108, 0x1500); 143 this->memory_.SetData32(0x510c, 0x200); 144 145 ASSERT_FALSE(this->debug_frame_->Init(0x5000, 0x600)); 146 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->debug_frame_->LastErrorCode()); 147 } 148 TYPED_TEST_P(DwarfDebugFrameTest,Init32_do_not_fail_on_bad_next_entry)149 TYPED_TEST_P(DwarfDebugFrameTest, Init32_do_not_fail_on_bad_next_entry) { 150 // CIE 32 information. 151 this->memory_.SetData32(0x5000, 0xfc); 152 this->memory_.SetData32(0x5004, 0xffffffff); 153 this->memory_.SetData8(0x5008, 1); 154 this->memory_.SetData8(0x5009, '\0'); 155 156 // FDE 32 information. 157 this->memory_.SetData32(0x5100, 0xfc); 158 this->memory_.SetData32(0x5104, 0); 159 this->memory_.SetData32(0x5108, 0x1500); 160 this->memory_.SetData32(0x510c, 0x200); 161 162 this->memory_.SetData32(0x5200, 0xfc); 163 this->memory_.SetData32(0x5204, 0); 164 this->memory_.SetData32(0x5208, 0x2500); 165 this->memory_.SetData32(0x520c, 0x300); 166 167 // CIE 32 information. 168 this->memory_.SetData32(0x5300, 0); 169 this->memory_.SetData32(0x5304, 0xffffffff); 170 this->memory_.SetData8(0x5308, 1); 171 this->memory_.SetData8(0x5309, '\0'); 172 173 // FDE 32 information. 174 this->memory_.SetData32(0x5400, 0xfc); 175 this->memory_.SetData32(0x5404, 0x300); 176 this->memory_.SetData32(0x5408, 0x3500); 177 this->memory_.SetData32(0x540c, 0x400); 178 179 this->memory_.SetData32(0x5500, 0xfc); 180 this->memory_.SetData32(0x5504, 0x300); 181 this->memory_.SetData32(0x5508, 0x4500); 182 this->memory_.SetData32(0x550c, 0x500); 183 184 ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600)); 185 ASSERT_EQ(2U, this->debug_frame_->TestGetFdeCount()); 186 } 187 TYPED_TEST_P(DwarfDebugFrameTest,Init64)188 TYPED_TEST_P(DwarfDebugFrameTest, Init64) { 189 // CIE 64 information. 190 this->memory_.SetData32(0x5000, 0xffffffff); 191 this->memory_.SetData64(0x5004, 0xf4); 192 this->memory_.SetData64(0x500c, 0xffffffffffffffffULL); 193 this->memory_.SetData8(0x5014, 1); 194 this->memory_.SetData8(0x5015, '\0'); 195 196 // FDE 64 information. 197 this->memory_.SetData32(0x5100, 0xffffffff); 198 this->memory_.SetData64(0x5104, 0xf4); 199 this->memory_.SetData64(0x510c, 0); 200 this->memory_.SetData64(0x5114, 0x1500); 201 this->memory_.SetData64(0x511c, 0x200); 202 203 this->memory_.SetData32(0x5200, 0xffffffff); 204 this->memory_.SetData64(0x5204, 0xf4); 205 this->memory_.SetData64(0x520c, 0); 206 this->memory_.SetData64(0x5214, 0x2500); 207 this->memory_.SetData64(0x521c, 0x300); 208 209 // CIE 64 information. 210 this->memory_.SetData32(0x5300, 0xffffffff); 211 this->memory_.SetData64(0x5304, 0xf4); 212 this->memory_.SetData64(0x530c, 0xffffffffffffffffULL); 213 this->memory_.SetData8(0x5314, 1); 214 this->memory_.SetData8(0x5315, '\0'); 215 216 // FDE 64 information. 217 this->memory_.SetData32(0x5400, 0xffffffff); 218 this->memory_.SetData64(0x5404, 0xf4); 219 this->memory_.SetData64(0x540c, 0x300); 220 this->memory_.SetData64(0x5414, 0x3500); 221 this->memory_.SetData64(0x541c, 0x400); 222 223 this->memory_.SetData32(0x5500, 0xffffffff); 224 this->memory_.SetData64(0x5504, 0xf4); 225 this->memory_.SetData64(0x550c, 0x300); 226 this->memory_.SetData64(0x5514, 0x4500); 227 this->memory_.SetData64(0x551c, 0x500); 228 229 ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600)); 230 ASSERT_EQ(4U, this->debug_frame_->TestGetFdeCount()); 231 232 typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0); 233 234 this->debug_frame_->TestGetFdeInfo(0, &info); 235 EXPECT_EQ(0x5100U, info.offset); 236 EXPECT_EQ(0x1500U, info.start); 237 EXPECT_EQ(0x1700U, info.end); 238 239 this->debug_frame_->TestGetFdeInfo(1, &info); 240 EXPECT_EQ(0x5200U, info.offset); 241 EXPECT_EQ(0x2500U, info.start); 242 EXPECT_EQ(0x2800U, info.end); 243 244 this->debug_frame_->TestGetFdeInfo(2, &info); 245 EXPECT_EQ(0x5400U, info.offset); 246 EXPECT_EQ(0x3500U, info.start); 247 EXPECT_EQ(0x3900U, info.end); 248 249 this->debug_frame_->TestGetFdeInfo(3, &info); 250 EXPECT_EQ(0x5500U, info.offset); 251 EXPECT_EQ(0x4500U, info.start); 252 EXPECT_EQ(0x4a00U, info.end); 253 } 254 TYPED_TEST_P(DwarfDebugFrameTest,Init64_fde_not_following_cie)255 TYPED_TEST_P(DwarfDebugFrameTest, Init64_fde_not_following_cie) { 256 // CIE 64 information. 257 this->memory_.SetData32(0x5000, 0xffffffff); 258 this->memory_.SetData64(0x5004, 0xf4); 259 this->memory_.SetData64(0x500c, 0xffffffffffffffffULL); 260 this->memory_.SetData8(0x5014, 1); 261 this->memory_.SetData8(0x5015, '\0'); 262 263 // FDE 64 information. 264 this->memory_.SetData32(0x5100, 0xffffffff); 265 this->memory_.SetData64(0x5104, 0xf4); 266 this->memory_.SetData64(0x510c, 0x1000); 267 this->memory_.SetData64(0x5114, 0x1500); 268 this->memory_.SetData64(0x511c, 0x200); 269 270 ASSERT_FALSE(this->debug_frame_->Init(0x5000, 0x600)); 271 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->debug_frame_->LastErrorCode()); 272 } 273 TYPED_TEST_P(DwarfDebugFrameTest,Init64_do_not_fail_on_bad_next_entry)274 TYPED_TEST_P(DwarfDebugFrameTest, Init64_do_not_fail_on_bad_next_entry) { 275 // CIE 64 information. 276 this->memory_.SetData32(0x5000, 0xffffffff); 277 this->memory_.SetData64(0x5004, 0xf4); 278 this->memory_.SetData64(0x500c, 0xffffffffffffffffULL); 279 this->memory_.SetData8(0x5014, 1); 280 this->memory_.SetData8(0x5015, '\0'); 281 282 // FDE 64 information. 283 this->memory_.SetData32(0x5100, 0xffffffff); 284 this->memory_.SetData64(0x5104, 0xf4); 285 this->memory_.SetData64(0x510c, 0); 286 this->memory_.SetData64(0x5114, 0x1500); 287 this->memory_.SetData64(0x511c, 0x200); 288 289 this->memory_.SetData32(0x5200, 0xffffffff); 290 this->memory_.SetData64(0x5204, 0xf4); 291 this->memory_.SetData64(0x520c, 0); 292 this->memory_.SetData64(0x5214, 0x2500); 293 this->memory_.SetData64(0x521c, 0x300); 294 295 // CIE 64 information. 296 this->memory_.SetData32(0x5300, 0xffffffff); 297 this->memory_.SetData64(0x5304, 0); 298 this->memory_.SetData64(0x530c, 0xffffffffffffffffULL); 299 this->memory_.SetData8(0x5314, 1); 300 this->memory_.SetData8(0x5315, '\0'); 301 302 // FDE 64 information. 303 this->memory_.SetData32(0x5400, 0xffffffff); 304 this->memory_.SetData64(0x5404, 0xf4); 305 this->memory_.SetData64(0x540c, 0x300); 306 this->memory_.SetData64(0x5414, 0x3500); 307 this->memory_.SetData64(0x541c, 0x400); 308 309 this->memory_.SetData32(0x5500, 0xffffffff); 310 this->memory_.SetData64(0x5504, 0xf4); 311 this->memory_.SetData64(0x550c, 0x300); 312 this->memory_.SetData64(0x5514, 0x4500); 313 this->memory_.SetData64(0x551c, 0x500); 314 315 ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600)); 316 ASSERT_EQ(2U, this->debug_frame_->TestGetFdeCount()); 317 } 318 TYPED_TEST_P(DwarfDebugFrameTest,Init_version1)319 TYPED_TEST_P(DwarfDebugFrameTest, Init_version1) { 320 // CIE 32 information. 321 this->memory_.SetData32(0x5000, 0xfc); 322 this->memory_.SetData32(0x5004, 0xffffffff); 323 this->memory_.SetData8(0x5008, 1); 324 // Augment string. 325 this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'R', 'P', 'L', '\0'}); 326 // Code alignment factor. 327 this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x80, 0x00}); 328 // Data alignment factor. 329 this->memory_.SetMemory(0x5010, std::vector<uint8_t>{0x81, 0x80, 0x80, 0x00}); 330 // Return address register 331 this->memory_.SetData8(0x5014, 0x84); 332 // Augmentation length 333 this->memory_.SetMemory(0x5015, std::vector<uint8_t>{0x84, 0x00}); 334 // R data. 335 this->memory_.SetData8(0x5017, DW_EH_PE_pcrel | DW_EH_PE_udata2); 336 337 // FDE 32 information. 338 this->memory_.SetData32(0x5100, 0xfc); 339 this->memory_.SetData32(0x5104, 0); 340 this->memory_.SetData16(0x5108, 0x1500); 341 this->memory_.SetData16(0x510a, 0x200); 342 343 ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x200)); 344 ASSERT_EQ(1U, this->debug_frame_->TestGetFdeCount()); 345 346 typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0); 347 this->debug_frame_->TestGetFdeInfo(0, &info); 348 EXPECT_EQ(0x5100U, info.offset); 349 EXPECT_EQ(0x1500U, info.start); 350 EXPECT_EQ(0x1700U, info.end); 351 } 352 TYPED_TEST_P(DwarfDebugFrameTest,Init_version4)353 TYPED_TEST_P(DwarfDebugFrameTest, Init_version4) { 354 // CIE 32 information. 355 this->memory_.SetData32(0x5000, 0xfc); 356 this->memory_.SetData32(0x5004, 0xffffffff); 357 this->memory_.SetData8(0x5008, 4); 358 // Augment string. 359 this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'}); 360 // Address size. 361 this->memory_.SetData8(0x500e, 4); 362 // Segment size. 363 this->memory_.SetData8(0x500f, 0); 364 // Code alignment factor. 365 this->memory_.SetMemory(0x5010, std::vector<uint8_t>{0x80, 0x00}); 366 // Data alignment factor. 367 this->memory_.SetMemory(0x5012, std::vector<uint8_t>{0x81, 0x80, 0x80, 0x00}); 368 // Return address register 369 this->memory_.SetMemory(0x5016, std::vector<uint8_t>{0x85, 0x10}); 370 // Augmentation length 371 this->memory_.SetMemory(0x5018, std::vector<uint8_t>{0x84, 0x00}); 372 // L data. 373 this->memory_.SetData8(0x501a, 0x10); 374 // P data. 375 this->memory_.SetData8(0x501b, DW_EH_PE_udata4); 376 this->memory_.SetData32(0x501c, 0x100); 377 // R data. 378 this->memory_.SetData8(0x5020, DW_EH_PE_pcrel | DW_EH_PE_udata2); 379 380 // FDE 32 information. 381 this->memory_.SetData32(0x5100, 0xfc); 382 this->memory_.SetData32(0x5104, 0); 383 this->memory_.SetData16(0x5108, 0x1500); 384 this->memory_.SetData16(0x510a, 0x200); 385 386 ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x200)); 387 ASSERT_EQ(1U, this->debug_frame_->TestGetFdeCount()); 388 389 typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0); 390 this->debug_frame_->TestGetFdeInfo(0, &info); 391 EXPECT_EQ(0x5100U, info.offset); 392 EXPECT_EQ(0x1500U, info.start); 393 EXPECT_EQ(0x1700U, info.end); 394 } 395 TYPED_TEST_P(DwarfDebugFrameTest,GetFdeOffsetFromPc)396 TYPED_TEST_P(DwarfDebugFrameTest, GetFdeOffsetFromPc) { 397 typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0); 398 for (size_t i = 0; i < 9; i++) { 399 info.start = 0x1000 * (i + 1); 400 info.end = 0x1000 * (i + 2) - 0x10; 401 info.offset = 0x5000 + i * 0x20; 402 this->debug_frame_->TestPushFdeInfo(info); 403 } 404 405 this->debug_frame_->TestSetFdeCount(0); 406 uint64_t fde_offset; 407 ASSERT_FALSE(this->debug_frame_->GetFdeOffsetFromPc(0x1000, &fde_offset)); 408 ASSERT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode()); 409 410 this->debug_frame_->TestSetFdeCount(9); 411 ASSERT_FALSE(this->debug_frame_->GetFdeOffsetFromPc(0x100, &fde_offset)); 412 ASSERT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode()); 413 // Odd number of elements. 414 for (size_t i = 0; i < 9; i++) { 415 TypeParam pc = 0x1000 * (i + 1); 416 ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc, &fde_offset)) << "Failed at index " << i; 417 EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; 418 ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc + 1, &fde_offset)) << "Failed at index " 419 << i; 420 EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; 421 ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc + 0xeff, &fde_offset)) 422 << "Failed at index " << i; 423 EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; 424 ASSERT_FALSE(this->debug_frame_->GetFdeOffsetFromPc(pc + 0xfff, &fde_offset)) 425 << "Failed at index " << i; 426 ASSERT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode()); 427 } 428 429 // Even number of elements. 430 this->debug_frame_->TestSetFdeCount(10); 431 info.start = 0xa000; 432 info.end = 0xaff0; 433 info.offset = 0x5120; 434 this->debug_frame_->TestPushFdeInfo(info); 435 436 for (size_t i = 0; i < 10; i++) { 437 TypeParam pc = 0x1000 * (i + 1); 438 ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc, &fde_offset)) << "Failed at index " << i; 439 EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; 440 ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc + 1, &fde_offset)) << "Failed at index " 441 << i; 442 EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; 443 ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc + 0xeff, &fde_offset)) 444 << "Failed at index " << i; 445 EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; 446 ASSERT_FALSE(this->debug_frame_->GetFdeOffsetFromPc(pc + 0xfff, &fde_offset)) 447 << "Failed at index " << i; 448 ASSERT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode()); 449 } 450 } 451 TYPED_TEST_P(DwarfDebugFrameTest,GetCieFde32)452 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFde32) { 453 this->debug_frame_->TestSetOffset(0x4000); 454 455 // CIE 32 information. 456 this->memory_.SetData32(0xf000, 0x100); 457 this->memory_.SetData32(0xf004, 0xffffffff); 458 this->memory_.SetData8(0xf008, 0x1); 459 this->memory_.SetData8(0xf009, '\0'); 460 this->memory_.SetData8(0xf00a, 4); 461 this->memory_.SetData8(0xf00b, 8); 462 this->memory_.SetData8(0xf00c, 0x20); 463 464 // FDE 32 information. 465 this->memory_.SetData32(0x14000, 0x20); 466 this->memory_.SetData32(0x14004, 0xb000); 467 this->memory_.SetData32(0x14008, 0x9000); 468 this->memory_.SetData32(0x1400c, 0x100); 469 470 const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x14000); 471 ASSERT_TRUE(fde != nullptr); 472 EXPECT_EQ(0x14010U, fde->cfa_instructions_offset); 473 EXPECT_EQ(0x14024U, fde->cfa_instructions_end); 474 EXPECT_EQ(0x9000U, fde->pc_start); 475 EXPECT_EQ(0x9100U, fde->pc_end); 476 EXPECT_EQ(0xf000U, fde->cie_offset); 477 EXPECT_EQ(0U, fde->lsda_address); 478 479 ASSERT_TRUE(fde->cie != nullptr); 480 EXPECT_EQ(1U, fde->cie->version); 481 EXPECT_EQ(DW_EH_PE_sdata4, fde->cie->fde_address_encoding); 482 EXPECT_EQ(DW_EH_PE_omit, fde->cie->lsda_encoding); 483 EXPECT_EQ(0U, fde->cie->segment_size); 484 EXPECT_EQ(1U, fde->cie->augmentation_string.size()); 485 EXPECT_EQ('\0', fde->cie->augmentation_string[0]); 486 EXPECT_EQ(0U, fde->cie->personality_handler); 487 EXPECT_EQ(0xf00dU, fde->cie->cfa_instructions_offset); 488 EXPECT_EQ(0xf104U, fde->cie->cfa_instructions_end); 489 EXPECT_EQ(4U, fde->cie->code_alignment_factor); 490 EXPECT_EQ(8, fde->cie->data_alignment_factor); 491 EXPECT_EQ(0x20U, fde->cie->return_address_register); 492 } 493 TYPED_TEST_P(DwarfDebugFrameTest,GetCieFde64)494 TYPED_TEST_P(DwarfDebugFrameTest, GetCieFde64) { 495 this->debug_frame_->TestSetOffset(0x2000); 496 497 // CIE 64 information. 498 this->memory_.SetData32(0x6000, 0xffffffff); 499 this->memory_.SetData64(0x6004, 0x100); 500 this->memory_.SetData64(0x600c, 0xffffffffffffffffULL); 501 this->memory_.SetData8(0x6014, 0x1); 502 this->memory_.SetData8(0x6015, '\0'); 503 this->memory_.SetData8(0x6016, 4); 504 this->memory_.SetData8(0x6017, 8); 505 this->memory_.SetData8(0x6018, 0x20); 506 507 // FDE 64 information. 508 this->memory_.SetData32(0x8000, 0xffffffff); 509 this->memory_.SetData64(0x8004, 0x200); 510 this->memory_.SetData64(0x800c, 0x4000); 511 this->memory_.SetData64(0x8014, 0x5000); 512 this->memory_.SetData64(0x801c, 0x300); 513 514 const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x8000); 515 ASSERT_TRUE(fde != nullptr); 516 EXPECT_EQ(0x8024U, fde->cfa_instructions_offset); 517 EXPECT_EQ(0x820cU, fde->cfa_instructions_end); 518 EXPECT_EQ(0x5000U, fde->pc_start); 519 EXPECT_EQ(0x5300U, fde->pc_end); 520 EXPECT_EQ(0x6000U, fde->cie_offset); 521 EXPECT_EQ(0U, fde->lsda_address); 522 523 ASSERT_TRUE(fde->cie != nullptr); 524 EXPECT_EQ(1U, fde->cie->version); 525 EXPECT_EQ(DW_EH_PE_sdata8, fde->cie->fde_address_encoding); 526 EXPECT_EQ(DW_EH_PE_omit, fde->cie->lsda_encoding); 527 EXPECT_EQ(0U, fde->cie->segment_size); 528 EXPECT_EQ(1U, fde->cie->augmentation_string.size()); 529 EXPECT_EQ('\0', fde->cie->augmentation_string[0]); 530 EXPECT_EQ(0U, fde->cie->personality_handler); 531 EXPECT_EQ(0x6019U, fde->cie->cfa_instructions_offset); 532 EXPECT_EQ(0x610cU, fde->cie->cfa_instructions_end); 533 EXPECT_EQ(4U, fde->cie->code_alignment_factor); 534 EXPECT_EQ(8, fde->cie->data_alignment_factor); 535 EXPECT_EQ(0x20U, fde->cie->return_address_register); 536 } 537 538 REGISTER_TYPED_TEST_CASE_P(DwarfDebugFrameTest, Init32, Init32_fde_not_following_cie, 539 Init32_do_not_fail_on_bad_next_entry, Init64, 540 Init64_do_not_fail_on_bad_next_entry, Init64_fde_not_following_cie, 541 Init_version1, Init_version4, GetFdeOffsetFromPc, GetCieFde32, 542 GetCieFde64); 543 544 typedef ::testing::Types<uint32_t, uint64_t> DwarfDebugFrameTestTypes; 545 INSTANTIATE_TYPED_TEST_CASE_P(, DwarfDebugFrameTest, DwarfDebugFrameTestTypes); 546 547 } // namespace unwindstack 548