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#include <unwindstack/DwarfSection.h> 24 25#include "DwarfEncoding.h" 26 27#include "LogFake.h" 28#include "MemoryFake.h" 29#include "RegsFake.h" 30 31namespace unwindstack { 32 33template <typename TypeParam> 34class MockDwarfSectionImpl : public DwarfSectionImpl<TypeParam> { 35 public: 36 MockDwarfSectionImpl(Memory* memory) : DwarfSectionImpl<TypeParam>(memory) {} 37 virtual ~MockDwarfSectionImpl() = default; 38 39 MOCK_METHOD2(Init, bool(uint64_t, uint64_t)); 40 41 MOCK_METHOD2(GetFdeOffsetFromPc, bool(uint64_t, uint64_t*)); 42 43 MOCK_METHOD1(GetFdeFromIndex, const DwarfFde*(size_t)); 44 45 MOCK_METHOD1(GetCieOffsetFromFde32, uint64_t(uint32_t)); 46 47 MOCK_METHOD1(GetCieOffsetFromFde64, uint64_t(uint64_t)); 48 49 MOCK_METHOD1(AdjustPcFromFde, uint64_t(uint64_t)); 50 51 void TestSetCie32Value(uint32_t value32) { this->cie32_value_ = value32; } 52 53 void TestSetCie64Value(uint64_t value64) { this->cie64_value_ = value64; } 54 55 void TestSetCachedCieEntry(uint64_t offset, const DwarfCie& cie) { 56 this->cie_entries_[offset] = cie; 57 } 58 void TestClearCachedCieEntry() { this->cie_entries_.clear(); } 59 60 void TestSetCachedFdeEntry(uint64_t offset, const DwarfFde& fde) { 61 this->fde_entries_[offset] = fde; 62 } 63 void TestClearCachedFdeEntry() { this->fde_entries_.clear(); } 64 65 void TestSetCachedCieLocRegs(uint64_t offset, const dwarf_loc_regs_t& loc_regs) { 66 this->cie_loc_regs_[offset] = loc_regs; 67 } 68 void TestClearCachedCieLocRegs() { this->cie_loc_regs_.clear(); } 69 70 void TestClearError() { this->last_error_.code = DWARF_ERROR_NONE; } 71}; 72 73template <typename TypeParam> 74class DwarfSectionImplTest : public ::testing::Test { 75 protected: 76 void SetUp() override { 77 memory_.Clear(); 78 section_ = new MockDwarfSectionImpl<TypeParam>(&memory_); 79 ResetLogs(); 80 section_->TestSetCie32Value(static_cast<uint32_t>(-1)); 81 section_->TestSetCie64Value(static_cast<uint64_t>(-1)); 82 } 83 84 void TearDown() override { delete section_; } 85 86 MemoryFake memory_; 87 MockDwarfSectionImpl<TypeParam>* section_ = nullptr; 88}; 89TYPED_TEST_CASE_P(DwarfSectionImplTest); 90 91// NOTE: All test class variables need to be referenced as this->. 92 93TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { 94 DwarfCie cie{.version = 3, .return_address_register = 5}; 95 RegsImplFake<TypeParam> regs(10); 96 dwarf_loc_regs_t loc_regs; 97 98 regs.set_pc(0x100); 99 regs.set_sp(0x2000); 100 regs[5] = 0x20; 101 regs[9] = 0x3000; 102 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; 103 bool finished; 104 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 105 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); 106 EXPECT_EQ(0x5000U, this->section_->LastErrorAddress()); 107} 108 109TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { 110 DwarfCie cie{.version = 3, .return_address_register = 5}; 111 RegsImplFake<TypeParam> regs(10); 112 dwarf_loc_regs_t loc_regs; 113 114 regs.set_pc(0x100); 115 regs.set_sp(0x2000); 116 regs[5] = 0x20; 117 regs[9] = 0x3000; 118 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96}); 119 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; 120 bool finished; 121 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 122 EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode()); 123} 124 125TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { 126 DwarfCie cie{.version = 3, .return_address_register = 5}; 127 RegsImplFake<TypeParam> regs(10); 128 dwarf_loc_regs_t loc_regs; 129 130 regs.set_pc(0x100); 131 regs.set_sp(0x2000); 132 regs[5] = 0x20; 133 regs[9] = 0x3000; 134 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80}); 135 TypeParam cfa_value = 0x12345; 136 this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value)); 137 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}}; 138 bool finished; 139 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 140 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); 141} 142 143TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { 144 DwarfCie cie{.version = 3, .return_address_register = 5}; 145 RegsImplFake<TypeParam> regs(10); 146 dwarf_loc_regs_t loc_regs; 147 148 regs.set_pc(0x100); 149 regs.set_sp(0x2000); 150 regs[5] = 0x20; 151 regs[9] = 0x3000; 152 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80}); 153 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5004}}; 154 bool finished; 155 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 156 ASSERT_FALSE(finished); 157 EXPECT_EQ(0x80000000U, regs.sp()); 158 EXPECT_EQ(0x20U, regs.pc()); 159} 160 161TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { 162 DwarfCie cie{.version = 3, .return_address_register = 5}; 163 RegsImplFake<TypeParam> regs(10); 164 dwarf_loc_regs_t loc_regs; 165 166 regs.set_pc(0x100); 167 regs.set_sp(0x2000); 168 regs[5] = 0x20; 169 regs[9] = 0x3000; 170 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96}); 171 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; 172 bool finished; 173 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 174 EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode()); 175} 176 177TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) { 178 DwarfCie cie{.return_address_register = 60}; 179 RegsImplFake<TypeParam> regs(10); 180 dwarf_loc_regs_t loc_regs; 181 182 bool finished; 183 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 184 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); 185} 186 187TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) { 188 DwarfCie cie{.return_address_register = 5}; 189 RegsImplFake<TypeParam> regs(10); 190 dwarf_loc_regs_t loc_regs; 191 192 bool finished; 193 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 194 EXPECT_EQ(DWARF_ERROR_CFA_NOT_DEFINED, this->section_->LastErrorCode()); 195} 196 197TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) { 198 DwarfCie cie{.return_address_register = 5}; 199 RegsImplFake<TypeParam> regs(10); 200 dwarf_loc_regs_t loc_regs; 201 202 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}}; 203 bool finished; 204 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 205 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); 206 207 this->section_->TestClearError(); 208 loc_regs.erase(CFA_REG); 209 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_INVALID, {0, 0}}; 210 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 211 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); 212 213 this->section_->TestClearError(); 214 loc_regs.erase(CFA_REG); 215 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_OFFSET, {0, 0}}; 216 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 217 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); 218 219 this->section_->TestClearError(); 220 loc_regs.erase(CFA_REG); 221 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0, 0}}; 222 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 223 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); 224} 225 226TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) { 227 DwarfCie cie{.return_address_register = 5}; 228 RegsImplFake<TypeParam> regs(10); 229 dwarf_loc_regs_t loc_regs; 230 231 regs.set_pc(0x100); 232 regs.set_sp(0x2000); 233 regs[5] = 0x20; 234 regs[9] = 0x3000; 235 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {9, 0}}; 236 bool finished; 237 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 238 EXPECT_FALSE(finished); 239 EXPECT_EQ(0x20U, regs.pc()); 240 EXPECT_EQ(0x3000U, regs.sp()); 241} 242 243TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) { 244 DwarfCie cie{.return_address_register = 5}; 245 RegsImplFake<TypeParam> regs(10); 246 dwarf_loc_regs_t loc_regs; 247 248 regs.set_pc(0x100); 249 regs.set_sp(0x2000); 250 regs[5] = 0x20; 251 regs[6] = 0x4000; 252 regs[9] = 0x3000; 253 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {6, 0}}; 254 bool finished; 255 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 256 EXPECT_FALSE(finished); 257 EXPECT_EQ(0x20U, regs.pc()); 258 EXPECT_EQ(0x4000U, regs.sp()); 259} 260 261TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) { 262 DwarfCie cie{.return_address_register = 5}; 263 RegsImplFake<TypeParam> regs(10); 264 dwarf_loc_regs_t loc_regs; 265 266 regs.set_pc(0x100); 267 regs.set_sp(0x2000); 268 regs[1] = 0x100; 269 regs[3] = 0x300; 270 regs[8] = 0x10; 271 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 272 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 1}}; 273 loc_regs[9] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 2}}; 274 bool finished; 275 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 276 EXPECT_EQ(0x301U, regs[1]); 277 EXPECT_EQ(0x300U, regs[3]); 278 EXPECT_EQ(0x10U, regs[8]); 279 EXPECT_EQ(0x102U, regs[9]); 280} 281 282TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) { 283 DwarfCie cie{.return_address_register = 5}; 284 RegsImplFake<TypeParam> regs(10); 285 dwarf_loc_regs_t loc_regs; 286 287 regs.set_pc(0x100); 288 regs.set_sp(0x2000); 289 regs[0] = 0x10; 290 regs[1] = 0x20; 291 regs[2] = 0x30; 292 regs[3] = 0x40; 293 regs[4] = 0x50; 294 regs[5] = 0x60; 295 regs[8] = 0x20; 296 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 297 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {0, 1}}; 298 loc_regs[2] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 2}}; 299 loc_regs[3] = DwarfLocation{DWARF_LOCATION_REGISTER, {2, 3}}; 300 loc_regs[4] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 4}}; 301 loc_regs[5] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 5}}; 302 bool finished; 303 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 304 EXPECT_EQ(0x10U, regs[0]); 305 EXPECT_EQ(0x11U, regs[1]); 306 EXPECT_EQ(0x22U, regs[2]); 307 EXPECT_EQ(0x33U, regs[3]); 308 EXPECT_EQ(0x44U, regs[4]); 309 EXPECT_EQ(0x55U, regs[5]); 310 EXPECT_EQ(0x20U, regs[8]); 311} 312 313TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) { 314 DwarfCie cie{.return_address_register = 5}; 315 RegsImplFake<TypeParam> regs(10); 316 dwarf_loc_regs_t loc_regs; 317 318 regs.set_pc(0x100); 319 regs.set_sp(0x2000); 320 regs[0] = 0x10; 321 regs[8] = 0x20; 322 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 323 loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x8, 0x5008}}; 324 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '1', 0x13, 0x08, 0x11}); 325 bool finished; 326 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 327 EXPECT_EQ(0x10U, regs[0]); 328 EXPECT_EQ(0x20U, regs[8]); 329 EXPECT_EQ(0x11U, regs.dex_pc()); 330} 331 332TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) { 333 DwarfCie cie{.return_address_register = 5}; 334 RegsImplFake<TypeParam> regs(10); 335 dwarf_loc_regs_t loc_regs; 336 337 regs.set_pc(0x100); 338 regs.set_sp(0x2000); 339 regs[8] = 0x10; 340 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 341 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {10, 0}}; 342 bool finished; 343 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 344 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); 345} 346 347TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) { 348 DwarfCie cie{.return_address_register = 5}; 349 RegsImplFake<TypeParam> regs(10); 350 dwarf_loc_regs_t loc_regs; 351 352 if (sizeof(TypeParam) == sizeof(uint64_t)) { 353 this->memory_.SetData64(0x2150, 0x12345678abcdef00ULL); 354 } else { 355 this->memory_.SetData32(0x2150, 0x12345678); 356 } 357 358 regs.set_pc(0x100); 359 regs.set_sp(0x2000); 360 regs[3] = 0x234; 361 regs[5] = 0x10; 362 regs[8] = 0x2100; 363 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 364 loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0x100, 0}}; 365 loc_regs[2] = DwarfLocation{DWARF_LOCATION_OFFSET, {0x50, 0}}; 366 loc_regs[3] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}}; 367 bool finished; 368 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 369 EXPECT_FALSE(finished); 370 EXPECT_EQ(0x10U, regs.pc()); 371 EXPECT_EQ(0x2100U, regs.sp()); 372 EXPECT_EQ(0x2200U, regs[1]); 373 EXPECT_EQ(0x234U, regs[3]); 374 if (sizeof(TypeParam) == sizeof(uint64_t)) { 375 EXPECT_EQ(0x12345678abcdef00ULL, regs[2]); 376 } else { 377 EXPECT_EQ(0x12345678U, regs[2]); 378 } 379} 380 381TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) { 382 DwarfCie cie{.return_address_register = 5}; 383 RegsImplFake<TypeParam> regs(10); 384 dwarf_loc_regs_t loc_regs; 385 386 regs.set_pc(0x100); 387 regs.set_sp(0x2000); 388 regs[5] = 0x20; 389 regs[8] = 0x10; 390 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 391 loc_regs[5] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}}; 392 bool finished; 393 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 394 EXPECT_TRUE(finished); 395 EXPECT_EQ(0U, regs.pc()); 396 EXPECT_EQ(0x10U, regs.sp()); 397} 398 399TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) { 400 DwarfCie cie{.return_address_register = 5}; 401 RegsImplFake<TypeParam> regs(10); 402 dwarf_loc_regs_t loc_regs; 403 404 regs.set_pc(0x100); 405 regs.set_sp(0x2000); 406 regs[5] = 0; 407 regs[8] = 0x10; 408 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 409 bool finished; 410 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 411 EXPECT_TRUE(finished); 412 EXPECT_EQ(0U, regs.pc()); 413 EXPECT_EQ(0x10U, regs.sp()); 414} 415 416TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) { 417 DwarfCie cie{.return_address_register = 5}; 418 RegsImplFake<TypeParam> regs(10); 419 dwarf_loc_regs_t loc_regs; 420 421 regs.set_pc(0x100); 422 regs.set_sp(0x2000); 423 regs[5] = 0x20; 424 regs[8] = 0x10; 425 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 426 bool finished; 427 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 428 EXPECT_FALSE(finished); 429 EXPECT_EQ(0x20U, regs.pc()); 430 EXPECT_EQ(0x10U, regs.sp()); 431} 432 433TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) { 434 DwarfCie cie{.return_address_register = 5}; 435 RegsImplFake<TypeParam> regs(10); 436 dwarf_loc_regs_t loc_regs; 437 438 regs.set_pc(0x100); 439 regs.set_sp(0x2000); 440 regs[5] = 0x20; 441 regs[8] = 0x10; 442 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 443 // This should not result in any errors. 444 loc_regs[20] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 445 bool finished; 446 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 447 EXPECT_FALSE(finished); 448 EXPECT_EQ(0x20U, regs.pc()); 449 EXPECT_EQ(0x10U, regs.sp()); 450} 451 452TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) { 453 DwarfCie cie{.version = 3, .return_address_register = 5}; 454 RegsImplFake<TypeParam> regs(10); 455 dwarf_loc_regs_t loc_regs; 456 457 regs.set_pc(0x100); 458 regs.set_sp(0x2000); 459 regs[8] = 0x3000; 460 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80}); 461 TypeParam cfa_value = 0x12345; 462 this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value)); 463 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 464 loc_regs[5] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}}; 465 bool finished; 466 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 467 EXPECT_FALSE(finished); 468 EXPECT_EQ(0x3000U, regs.sp()); 469 EXPECT_EQ(0x12345U, regs.pc()); 470} 471 472TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) { 473 DwarfCie cie{.version = 3, .return_address_register = 5}; 474 RegsImplFake<TypeParam> regs(10); 475 dwarf_loc_regs_t loc_regs; 476 477 regs.set_pc(0x100); 478 regs.set_sp(0x2000); 479 regs[8] = 0x3000; 480 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80}); 481 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; 482 loc_regs[5] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5004}}; 483 bool finished; 484 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); 485 EXPECT_FALSE(finished); 486 EXPECT_EQ(0x3000U, regs.sp()); 487 EXPECT_EQ(0x80000000U, regs.pc()); 488} 489 490TYPED_TEST_P(DwarfSectionImplTest, GetCie_fail_should_not_cache) { 491 ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr); 492 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); 493 EXPECT_EQ(0x4000U, this->section_->LastErrorAddress()); 494 this->section_->TestClearError(); 495 ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr); 496 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); 497 EXPECT_EQ(0x4000U, this->section_->LastErrorAddress()); 498} 499 500TYPED_TEST_P(DwarfSectionImplTest, GetCie_32_version_check) { 501 this->memory_.SetData32(0x5000, 0x100); 502 this->memory_.SetData32(0x5004, 0xffffffff); 503 this->memory_.SetData8(0x5008, 0x1); 504 this->memory_.SetData8(0x5009, '\0'); 505 this->memory_.SetData8(0x500a, 4); 506 this->memory_.SetData8(0x500b, 8); 507 this->memory_.SetData8(0x500c, 0x20); 508 509 const DwarfCie* cie = this->section_->GetCie(0x5000); 510 ASSERT_TRUE(cie != nullptr); 511 EXPECT_EQ(1U, cie->version); 512 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding); 513 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding); 514 EXPECT_EQ(0U, cie->segment_size); 515 EXPECT_EQ(1U, cie->augmentation_string.size()); 516 EXPECT_EQ('\0', cie->augmentation_string[0]); 517 EXPECT_EQ(0U, cie->personality_handler); 518 EXPECT_EQ(0x500dU, cie->cfa_instructions_offset); 519 EXPECT_EQ(0x5104U, cie->cfa_instructions_end); 520 EXPECT_EQ(4U, cie->code_alignment_factor); 521 EXPECT_EQ(8, cie->data_alignment_factor); 522 EXPECT_EQ(0x20U, cie->return_address_register); 523 EXPECT_EQ(DWARF_ERROR_NONE, this->section_->LastErrorCode()); 524 525 this->section_->TestClearCachedCieEntry(); 526 // Set version to 0, 2, 5 and verify we fail. 527 this->memory_.SetData8(0x5008, 0x0); 528 this->section_->TestClearError(); 529 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr); 530 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode()); 531 532 this->memory_.SetData8(0x5008, 0x2); 533 this->section_->TestClearError(); 534 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr); 535 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode()); 536 537 this->memory_.SetData8(0x5008, 0x5); 538 this->section_->TestClearError(); 539 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr); 540 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode()); 541} 542 543TYPED_TEST_P(DwarfSectionImplTest, GetCie_negative_data_alignment_factor) { 544 this->memory_.SetData32(0x5000, 0x100); 545 this->memory_.SetData32(0x5004, 0xffffffff); 546 this->memory_.SetData8(0x5008, 0x1); 547 this->memory_.SetData8(0x5009, '\0'); 548 this->memory_.SetData8(0x500a, 4); 549 this->memory_.SetMemory(0x500b, std::vector<uint8_t>{0xfc, 0xff, 0xff, 0xff, 0x7f}); 550 this->memory_.SetData8(0x5010, 0x20); 551 552 const DwarfCie* cie = this->section_->GetCie(0x5000); 553 ASSERT_TRUE(cie != nullptr); 554 EXPECT_EQ(1U, cie->version); 555 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding); 556 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding); 557 EXPECT_EQ(0U, cie->segment_size); 558 EXPECT_EQ(1U, cie->augmentation_string.size()); 559 EXPECT_EQ('\0', cie->augmentation_string[0]); 560 EXPECT_EQ(0U, cie->personality_handler); 561 EXPECT_EQ(0x5011U, cie->cfa_instructions_offset); 562 EXPECT_EQ(0x5104U, cie->cfa_instructions_end); 563 EXPECT_EQ(4U, cie->code_alignment_factor); 564 EXPECT_EQ(-4, cie->data_alignment_factor); 565 EXPECT_EQ(0x20U, cie->return_address_register); 566} 567 568TYPED_TEST_P(DwarfSectionImplTest, GetCie_64_no_augment) { 569 this->memory_.SetData32(0x8000, 0xffffffff); 570 this->memory_.SetData64(0x8004, 0x200); 571 this->memory_.SetData64(0x800c, 0xffffffffffffffffULL); 572 this->memory_.SetData8(0x8014, 0x1); 573 this->memory_.SetData8(0x8015, '\0'); 574 this->memory_.SetData8(0x8016, 4); 575 this->memory_.SetData8(0x8017, 8); 576 this->memory_.SetData8(0x8018, 0x20); 577 578 const DwarfCie* cie = this->section_->GetCie(0x8000); 579 ASSERT_TRUE(cie != nullptr); 580 EXPECT_EQ(1U, cie->version); 581 EXPECT_EQ(DW_EH_PE_sdata8, cie->fde_address_encoding); 582 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding); 583 EXPECT_EQ(0U, cie->segment_size); 584 EXPECT_EQ(1U, cie->augmentation_string.size()); 585 EXPECT_EQ('\0', cie->augmentation_string[0]); 586 EXPECT_EQ(0U, cie->personality_handler); 587 EXPECT_EQ(0x8019U, cie->cfa_instructions_offset); 588 EXPECT_EQ(0x820cU, cie->cfa_instructions_end); 589 EXPECT_EQ(4U, cie->code_alignment_factor); 590 EXPECT_EQ(8, cie->data_alignment_factor); 591 EXPECT_EQ(0x20U, cie->return_address_register); 592} 593 594TYPED_TEST_P(DwarfSectionImplTest, GetCie_augment) { 595 this->memory_.SetData32(0x5000, 0x100); 596 this->memory_.SetData32(0x5004, 0xffffffff); 597 this->memory_.SetData8(0x5008, 0x1); 598 this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'}); 599 this->memory_.SetData8(0x500e, 4); 600 this->memory_.SetData8(0x500f, 8); 601 this->memory_.SetData8(0x5010, 0x10); 602 // Augment length. 603 this->memory_.SetData8(0x5011, 0xf); 604 // L data. 605 this->memory_.SetData8(0x5012, DW_EH_PE_textrel | DW_EH_PE_udata2); 606 // P data. 607 this->memory_.SetData8(0x5013, DW_EH_PE_udata4); 608 this->memory_.SetData32(0x5014, 0x12345678); 609 // R data. 610 this->memory_.SetData8(0x5018, DW_EH_PE_udata2); 611 612 const DwarfCie* cie = this->section_->GetCie(0x5000); 613 ASSERT_TRUE(cie != nullptr); 614 EXPECT_EQ(1U, cie->version); 615 EXPECT_EQ(DW_EH_PE_udata2, cie->fde_address_encoding); 616 EXPECT_EQ(DW_EH_PE_textrel | DW_EH_PE_udata2, cie->lsda_encoding); 617 EXPECT_EQ(0U, cie->segment_size); 618 EXPECT_EQ(5U, cie->augmentation_string.size()); 619 EXPECT_EQ('z', cie->augmentation_string[0]); 620 EXPECT_EQ('L', cie->augmentation_string[1]); 621 EXPECT_EQ('P', cie->augmentation_string[2]); 622 EXPECT_EQ('R', cie->augmentation_string[3]); 623 EXPECT_EQ('\0', cie->augmentation_string[4]); 624 EXPECT_EQ(0x12345678U, cie->personality_handler); 625 EXPECT_EQ(0x5021U, cie->cfa_instructions_offset); 626 EXPECT_EQ(0x5104U, cie->cfa_instructions_end); 627 EXPECT_EQ(4U, cie->code_alignment_factor); 628 EXPECT_EQ(8, cie->data_alignment_factor); 629 EXPECT_EQ(0x10U, cie->return_address_register); 630} 631 632TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_3) { 633 this->memory_.SetData32(0x5000, 0x100); 634 this->memory_.SetData32(0x5004, 0xffffffff); 635 this->memory_.SetData8(0x5008, 0x3); 636 this->memory_.SetData8(0x5009, '\0'); 637 this->memory_.SetData8(0x500a, 4); 638 this->memory_.SetData8(0x500b, 8); 639 this->memory_.SetMemory(0x500c, std::vector<uint8_t>{0x81, 0x03}); 640 641 const DwarfCie* cie = this->section_->GetCie(0x5000); 642 ASSERT_TRUE(cie != nullptr); 643 EXPECT_EQ(3U, cie->version); 644 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding); 645 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding); 646 EXPECT_EQ(0U, cie->segment_size); 647 EXPECT_EQ(1U, cie->augmentation_string.size()); 648 EXPECT_EQ('\0', cie->augmentation_string[0]); 649 EXPECT_EQ(0U, cie->personality_handler); 650 EXPECT_EQ(0x500eU, cie->cfa_instructions_offset); 651 EXPECT_EQ(0x5104U, cie->cfa_instructions_end); 652 EXPECT_EQ(4U, cie->code_alignment_factor); 653 EXPECT_EQ(8, cie->data_alignment_factor); 654 EXPECT_EQ(0x181U, cie->return_address_register); 655} 656 657TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_4) { 658 this->memory_.SetData32(0x5000, 0x100); 659 this->memory_.SetData32(0x5004, 0xffffffff); 660 this->memory_.SetData8(0x5008, 0x4); 661 this->memory_.SetData8(0x5009, '\0'); 662 this->memory_.SetData8(0x500a, 4); 663 this->memory_.SetData8(0x500b, 0x13); 664 this->memory_.SetData8(0x500c, 4); 665 this->memory_.SetData8(0x500d, 8); 666 this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x81, 0x03}); 667 668 const DwarfCie* cie = this->section_->GetCie(0x5000); 669 ASSERT_TRUE(cie != nullptr); 670 EXPECT_EQ(4U, cie->version); 671 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding); 672 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding); 673 EXPECT_EQ(0x13U, cie->segment_size); 674 EXPECT_EQ(1U, cie->augmentation_string.size()); 675 EXPECT_EQ('\0', cie->augmentation_string[0]); 676 EXPECT_EQ(0U, cie->personality_handler); 677 EXPECT_EQ(0x5010U, cie->cfa_instructions_offset); 678 EXPECT_EQ(0x5104U, cie->cfa_instructions_end); 679 EXPECT_EQ(4U, cie->code_alignment_factor); 680 EXPECT_EQ(8, cie->data_alignment_factor); 681 EXPECT_EQ(0x181U, cie->return_address_register); 682} 683 684TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_fail_should_not_cache) { 685 ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr); 686 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); 687 EXPECT_EQ(0x4000U, this->section_->LastErrorAddress()); 688 this->section_->TestClearError(); 689 ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr); 690 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); 691 EXPECT_EQ(0x4000U, this->section_->LastErrorAddress()); 692} 693 694TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment) { 695 this->memory_.SetData32(0x4000, 0x20); 696 this->memory_.SetData32(0x4004, 0x8000); 697 this->memory_.SetData32(0x4008, 0x5000); 698 this->memory_.SetData32(0x400c, 0x100); 699 700 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000)); 701 DwarfCie cie{}; 702 cie.fde_address_encoding = DW_EH_PE_udata4; 703 this->section_->TestSetCachedCieEntry(0x8000, cie); 704 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000)); 705 706 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000); 707 ASSERT_TRUE(fde != nullptr); 708 ASSERT_TRUE(fde->cie != nullptr); 709 EXPECT_EQ(0x4010U, fde->cfa_instructions_offset); 710 EXPECT_EQ(0x4024U, fde->cfa_instructions_end); 711 EXPECT_EQ(0x5000U, fde->pc_start); 712 EXPECT_EQ(0x5100U, fde->pc_end); 713 EXPECT_EQ(0x8000U, fde->cie_offset); 714 EXPECT_EQ(0U, fde->lsda_address); 715} 716 717TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment_non_zero_segment_size) { 718 this->memory_.SetData32(0x4000, 0x30); 719 this->memory_.SetData32(0x4004, 0x8000); 720 this->memory_.SetData32(0x4018, 0x5000); 721 this->memory_.SetData32(0x401c, 0x100); 722 723 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000)); 724 DwarfCie cie{}; 725 cie.fde_address_encoding = DW_EH_PE_udata4; 726 cie.segment_size = 0x10; 727 this->section_->TestSetCachedCieEntry(0x8000, cie); 728 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000)); 729 730 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000); 731 ASSERT_TRUE(fde != nullptr); 732 ASSERT_TRUE(fde->cie != nullptr); 733 EXPECT_EQ(0x4020U, fde->cfa_instructions_offset); 734 EXPECT_EQ(0x4034U, fde->cfa_instructions_end); 735 EXPECT_EQ(0x5000U, fde->pc_start); 736 EXPECT_EQ(0x5100U, fde->pc_end); 737 EXPECT_EQ(0x8000U, fde->cie_offset); 738 EXPECT_EQ(0U, fde->lsda_address); 739} 740 741TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_augment) { 742 this->memory_.SetData32(0x4000, 0x100); 743 this->memory_.SetData32(0x4004, 0x8000); 744 this->memory_.SetData32(0x4008, 0x5000); 745 this->memory_.SetData32(0x400c, 0x100); 746 this->memory_.SetMemory(0x4010, std::vector<uint8_t>{0x82, 0x01}); 747 this->memory_.SetData16(0x4012, 0x1234); 748 749 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000)); 750 DwarfCie cie{}; 751 cie.fde_address_encoding = DW_EH_PE_udata4; 752 cie.augmentation_string.push_back('z'); 753 cie.lsda_encoding = DW_EH_PE_udata2; 754 this->section_->TestSetCachedCieEntry(0x8000, cie); 755 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000)); 756 757 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000); 758 ASSERT_TRUE(fde != nullptr); 759 ASSERT_TRUE(fde->cie != nullptr); 760 EXPECT_EQ(0x4094U, fde->cfa_instructions_offset); 761 EXPECT_EQ(0x4104U, fde->cfa_instructions_end); 762 EXPECT_EQ(0x5000U, fde->pc_start); 763 EXPECT_EQ(0x5100U, fde->pc_end); 764 EXPECT_EQ(0x8000U, fde->cie_offset); 765 EXPECT_EQ(0x1234U, fde->lsda_address); 766} 767 768TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_64_no_augment) { 769 this->memory_.SetData32(0x4000, 0xffffffff); 770 this->memory_.SetData64(0x4004, 0x100); 771 this->memory_.SetData64(0x400c, 0x12345678); 772 this->memory_.SetData32(0x4014, 0x5000); 773 this->memory_.SetData32(0x4018, 0x100); 774 775 EXPECT_CALL(*this->section_, GetCieOffsetFromFde64(0x12345678)) 776 .WillOnce(::testing::Return(0x12345678)); 777 DwarfCie cie{}; 778 cie.fde_address_encoding = DW_EH_PE_udata4; 779 this->section_->TestSetCachedCieEntry(0x12345678, cie); 780 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000)); 781 782 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000); 783 ASSERT_TRUE(fde != nullptr); 784 ASSERT_TRUE(fde->cie != nullptr); 785 EXPECT_EQ(0x401cU, fde->cfa_instructions_offset); 786 EXPECT_EQ(0x410cU, fde->cfa_instructions_end); 787 EXPECT_EQ(0x5000U, fde->pc_start); 788 EXPECT_EQ(0x5100U, fde->pc_end); 789 EXPECT_EQ(0x12345678U, fde->cie_offset); 790 EXPECT_EQ(0U, fde->lsda_address); 791} 792 793TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_cached) { 794 DwarfCie cie{}; 795 cie.fde_address_encoding = DW_EH_PE_udata4; 796 cie.augmentation_string.push_back('z'); 797 cie.lsda_encoding = DW_EH_PE_udata2; 798 799 DwarfFde fde_cached{}; 800 fde_cached.cfa_instructions_offset = 0x1000; 801 fde_cached.cfa_instructions_end = 0x1100; 802 fde_cached.pc_start = 0x9000; 803 fde_cached.pc_end = 0x9400; 804 fde_cached.cie_offset = 0x30000; 805 fde_cached.cie = &cie; 806 this->section_->TestSetCachedFdeEntry(0x6000, fde_cached); 807 808 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x6000); 809 ASSERT_TRUE(fde != nullptr); 810 ASSERT_EQ(&cie, fde->cie); 811 EXPECT_EQ(0x1000U, fde->cfa_instructions_offset); 812 EXPECT_EQ(0x1100U, fde->cfa_instructions_end); 813 EXPECT_EQ(0x9000U, fde->pc_start); 814 EXPECT_EQ(0x9400U, fde->pc_end); 815 EXPECT_EQ(0x30000U, fde->cie_offset); 816} 817 818TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_not_cached) { 819 DwarfCie cie{}; 820 cie.cfa_instructions_offset = 0x3000; 821 cie.cfa_instructions_end = 0x3002; 822 DwarfFde fde{}; 823 fde.cie = &cie; 824 fde.cie_offset = 0x8000; 825 fde.cfa_instructions_offset = 0x6000; 826 fde.cfa_instructions_end = 0x6002; 827 828 this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x09, 0x02, 0x01}); 829 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03}); 830 831 dwarf_loc_regs_t loc_regs; 832 ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs)); 833 ASSERT_EQ(2U, loc_regs.size()); 834 835 auto entry = loc_regs.find(2); 836 ASSERT_NE(entry, loc_regs.end()); 837 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type); 838 ASSERT_EQ(1U, entry->second.values[0]); 839 840 entry = loc_regs.find(4); 841 ASSERT_NE(entry, loc_regs.end()); 842 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type); 843 ASSERT_EQ(3U, entry->second.values[0]); 844} 845 846TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) { 847 DwarfCie cie{}; 848 cie.cfa_instructions_offset = 0x3000; 849 cie.cfa_instructions_end = 0x3002; 850 DwarfFde fde{}; 851 fde.cie = &cie; 852 fde.cie_offset = 0x8000; 853 fde.cfa_instructions_offset = 0x6000; 854 fde.cfa_instructions_end = 0x6002; 855 856 dwarf_loc_regs_t cie_loc_regs; 857 cie_loc_regs[6] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 0}}; 858 this->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs); 859 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03}); 860 861 dwarf_loc_regs_t loc_regs; 862 ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs)); 863 ASSERT_EQ(2U, loc_regs.size()); 864 865 auto entry = loc_regs.find(6); 866 ASSERT_NE(entry, loc_regs.end()); 867 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type); 868 ASSERT_EQ(4U, entry->second.values[0]); 869 870 entry = loc_regs.find(4); 871 ASSERT_NE(entry, loc_regs.end()); 872 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type); 873 ASSERT_EQ(3U, entry->second.values[0]); 874} 875 876TYPED_TEST_P(DwarfSectionImplTest, Log) { 877 DwarfCie cie{}; 878 cie.cfa_instructions_offset = 0x5000; 879 cie.cfa_instructions_end = 0x5001; 880 DwarfFde fde{}; 881 fde.cie = &cie; 882 fde.cfa_instructions_offset = 0x6000; 883 fde.cfa_instructions_end = 0x6001; 884 885 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x00}); 886 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0xc2}); 887 ASSERT_TRUE(this->section_->Log(2, 0x1000, 0x1000, &fde)); 888 889 ASSERT_EQ( 890 "4 unwind DW_CFA_nop\n" 891 "4 unwind Raw Data: 0x00\n" 892 "4 unwind DW_CFA_restore register(2)\n" 893 "4 unwind Raw Data: 0xc2\n", 894 GetFakeLogPrint()); 895 ASSERT_EQ("", GetFakeLogBuf()); 896} 897 898REGISTER_TYPED_TEST_CASE_P( 899 DwarfSectionImplTest, Eval_cfa_expr_eval_fail, Eval_cfa_expr_no_stack, 900 Eval_cfa_expr_is_register, Eval_cfa_expr, Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa, 901 Eval_cfa_bad, Eval_cfa_register_prev, Eval_cfa_register_from_value, Eval_double_indirection, 902 Eval_register_reference_chain, Eval_dex_pc, Eval_invalid_register, Eval_different_reg_locations, 903 Eval_return_address_undefined, Eval_pc_zero, Eval_return_address, Eval_ignore_large_reg_loc, 904 Eval_reg_expr, Eval_reg_val_expr, GetCie_fail_should_not_cache, GetCie_32_version_check, 905 GetCie_negative_data_alignment_factor, GetCie_64_no_augment, GetCie_augment, GetCie_version_3, 906 GetCie_version_4, GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment, 907 GetFdeFromOffset_32_no_augment_non_zero_segment_size, GetFdeFromOffset_32_augment, 908 GetFdeFromOffset_64_no_augment, GetFdeFromOffset_cached, GetCfaLocationInfo_cie_not_cached, 909 GetCfaLocationInfo_cie_cached, Log); 910 911typedef ::testing::Types<uint32_t, uint64_t> DwarfSectionImplTestTypes; 912INSTANTIATE_TYPED_TEST_CASE_P(, DwarfSectionImplTest, DwarfSectionImplTestTypes); 913 914} // namespace unwindstack 915