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 <deque> 20 #include <ios> 21 #include <memory> 22 #include <string> 23 24 #include <gtest/gtest.h> 25 26 #include "ArmExidx.h" 27 #include "Regs.h" 28 #include "Log.h" 29 30 #include "LogFake.h" 31 #include "MemoryFake.h" 32 33 class ArmExidxDecodeTest : public ::testing::TestWithParam<std::string> { 34 protected: 35 void Init(Memory* process_memory = nullptr) { 36 TearDown(); 37 38 if (process_memory == nullptr) { 39 process_memory = &process_memory_; 40 } 41 42 regs_arm_.reset(new RegsArm()); 43 for (size_t i = 0; i < regs_arm_->total_regs(); i++) { 44 (*regs_arm_)[i] = 0; 45 } 46 regs_arm_->set_pc(0); 47 regs_arm_->set_sp(0); 48 49 exidx_.reset(new ArmExidx(regs_arm_.get(), &elf_memory_, process_memory)); 50 if (log_) { 51 exidx_->set_log(true); 52 exidx_->set_log_indent(0); 53 exidx_->set_log_skip_execution(false); 54 } 55 data_ = exidx_->data(); 56 exidx_->set_cfa(0x10000); 57 } 58 59 void SetUp() override { 60 if (GetParam() != "no_logging") { 61 log_ = false; 62 } else { 63 log_ = true; 64 } 65 ResetLogs(); 66 elf_memory_.Clear(); 67 process_memory_.Clear(); 68 Init(); 69 } 70 71 std::unique_ptr<ArmExidx> exidx_; 72 std::unique_ptr<RegsArm> regs_arm_; 73 std::deque<uint8_t>* data_; 74 75 MemoryFake elf_memory_; 76 MemoryFake process_memory_; 77 bool log_; 78 }; 79 80 TEST_P(ArmExidxDecodeTest, vsp_incr) { 81 // 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4 82 data_->push_back(0x00); 83 ASSERT_TRUE(exidx_->Decode()); 84 ASSERT_FALSE(exidx_->pc_set()); 85 ASSERT_EQ("", GetFakeLogBuf()); 86 if (log_) { 87 ASSERT_EQ("4 unwind vsp = vsp + 4\n", GetFakeLogPrint()); 88 } else { 89 ASSERT_EQ("", GetFakeLogPrint()); 90 } 91 ASSERT_EQ(0x10004U, exidx_->cfa()); 92 93 ResetLogs(); 94 data_->clear(); 95 data_->push_back(0x01); 96 ASSERT_TRUE(exidx_->Decode()); 97 ASSERT_FALSE(exidx_->pc_set()); 98 ASSERT_EQ("", GetFakeLogBuf()); 99 if (log_) { 100 ASSERT_EQ("4 unwind vsp = vsp + 8\n", GetFakeLogPrint()); 101 } else { 102 ASSERT_EQ("", GetFakeLogPrint()); 103 } 104 ASSERT_EQ(0x1000cU, exidx_->cfa()); 105 106 ResetLogs(); 107 data_->clear(); 108 data_->push_back(0x3f); 109 ASSERT_TRUE(exidx_->Decode()); 110 ASSERT_FALSE(exidx_->pc_set()); 111 ASSERT_EQ("", GetFakeLogBuf()); 112 if (log_) { 113 ASSERT_EQ("4 unwind vsp = vsp + 256\n", GetFakeLogPrint()); 114 } else { 115 ASSERT_EQ("", GetFakeLogPrint()); 116 } 117 ASSERT_EQ(0x1010cU, exidx_->cfa()); 118 } 119 120 TEST_P(ArmExidxDecodeTest, vsp_decr) { 121 // 01xxxxxx: vsp = vsp - (xxxxxx << 2) + 4 122 data_->push_back(0x40); 123 ASSERT_TRUE(exidx_->Decode()); 124 ASSERT_FALSE(exidx_->pc_set()); 125 ASSERT_EQ("", GetFakeLogBuf()); 126 if (log_) { 127 ASSERT_EQ("4 unwind vsp = vsp - 4\n", GetFakeLogPrint()); 128 } else { 129 ASSERT_EQ("", GetFakeLogPrint()); 130 } 131 ASSERT_EQ(0xfffcU, exidx_->cfa()); 132 133 ResetLogs(); 134 data_->clear(); 135 data_->push_back(0x41); 136 ASSERT_TRUE(exidx_->Decode()); 137 ASSERT_FALSE(exidx_->pc_set()); 138 ASSERT_EQ("", GetFakeLogBuf()); 139 if (log_) { 140 ASSERT_EQ("4 unwind vsp = vsp - 8\n", GetFakeLogPrint()); 141 } else { 142 ASSERT_EQ("", GetFakeLogPrint()); 143 } 144 ASSERT_EQ(0xfff4U, exidx_->cfa()); 145 146 ResetLogs(); 147 data_->clear(); 148 data_->push_back(0x7f); 149 ASSERT_TRUE(exidx_->Decode()); 150 ASSERT_FALSE(exidx_->pc_set()); 151 ASSERT_EQ("", GetFakeLogBuf()); 152 if (log_) { 153 ASSERT_EQ("4 unwind vsp = vsp - 256\n", GetFakeLogPrint()); 154 } else { 155 ASSERT_EQ("", GetFakeLogPrint()); 156 } 157 ASSERT_EQ(0xfef4U, exidx_->cfa()); 158 } 159 160 TEST_P(ArmExidxDecodeTest, refuse_unwind) { 161 // 10000000 00000000: Refuse to unwind 162 data_->push_back(0x80); 163 data_->push_back(0x00); 164 ASSERT_FALSE(exidx_->Decode()); 165 ASSERT_EQ("", GetFakeLogBuf()); 166 if (log_) { 167 ASSERT_EQ("4 unwind Refuse to unwind\n", GetFakeLogPrint()); 168 } else { 169 ASSERT_EQ("", GetFakeLogPrint()); 170 } 171 ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status()); 172 } 173 174 TEST_P(ArmExidxDecodeTest, pop_up_to_12) { 175 // 1000iiii iiiiiiii: Pop up to 12 integer registers 176 data_->push_back(0x88); 177 data_->push_back(0x00); 178 process_memory_.SetData32(0x10000, 0x10); 179 ASSERT_TRUE(exidx_->Decode()); 180 ASSERT_TRUE(exidx_->pc_set()); 181 ASSERT_EQ("", GetFakeLogBuf()); 182 if (log_) { 183 ASSERT_EQ("4 unwind pop {r15}\n", GetFakeLogPrint()); 184 } else { 185 ASSERT_EQ("", GetFakeLogPrint()); 186 } 187 ASSERT_EQ(0x10004U, exidx_->cfa()); 188 ASSERT_EQ(0x10U, (*exidx_->regs())[15]); 189 190 ResetLogs(); 191 data_->push_back(0x8f); 192 data_->push_back(0xff); 193 for (size_t i = 0; i < 12; i++) { 194 process_memory_.SetData32(0x10004 + i * 4, i + 0x20); 195 } 196 exidx_->set_pc_set(false); 197 ASSERT_TRUE(exidx_->Decode()); 198 ASSERT_TRUE(exidx_->pc_set()); 199 ASSERT_EQ("", GetFakeLogBuf()); 200 if (log_) { 201 ASSERT_EQ("4 unwind pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}\n", 202 GetFakeLogPrint()); 203 } else { 204 ASSERT_EQ("", GetFakeLogPrint()); 205 } 206 // Popping r13 results in a modified cfa. 207 ASSERT_EQ(0x29U, exidx_->cfa()); 208 209 ASSERT_EQ(0x20U, (*exidx_->regs())[4]); 210 ASSERT_EQ(0x21U, (*exidx_->regs())[5]); 211 ASSERT_EQ(0x22U, (*exidx_->regs())[6]); 212 ASSERT_EQ(0x23U, (*exidx_->regs())[7]); 213 ASSERT_EQ(0x24U, (*exidx_->regs())[8]); 214 ASSERT_EQ(0x25U, (*exidx_->regs())[9]); 215 ASSERT_EQ(0x26U, (*exidx_->regs())[10]); 216 ASSERT_EQ(0x27U, (*exidx_->regs())[11]); 217 ASSERT_EQ(0x28U, (*exidx_->regs())[12]); 218 ASSERT_EQ(0x29U, (*exidx_->regs())[13]); 219 ASSERT_EQ(0x2aU, (*exidx_->regs())[14]); 220 ASSERT_EQ(0x2bU, (*exidx_->regs())[15]); 221 222 ResetLogs(); 223 exidx_->set_cfa(0x10034); 224 data_->push_back(0x81); 225 data_->push_back(0x28); 226 process_memory_.SetData32(0x10034, 0x11); 227 process_memory_.SetData32(0x10038, 0x22); 228 process_memory_.SetData32(0x1003c, 0x33); 229 exidx_->set_pc_set(false); 230 ASSERT_TRUE(exidx_->Decode()); 231 ASSERT_FALSE(exidx_->pc_set()); 232 ASSERT_EQ("", GetFakeLogBuf()); 233 if (log_) { 234 ASSERT_EQ("4 unwind pop {r7, r9, r12}\n", GetFakeLogPrint()); 235 } else { 236 ASSERT_EQ("", GetFakeLogPrint()); 237 } 238 ASSERT_EQ(0x10040U, exidx_->cfa()); 239 ASSERT_EQ(0x11U, (*exidx_->regs())[7]); 240 ASSERT_EQ(0x22U, (*exidx_->regs())[9]); 241 ASSERT_EQ(0x33U, (*exidx_->regs())[12]); 242 } 243 244 TEST_P(ArmExidxDecodeTest, set_vsp_from_register) { 245 // 1001nnnn: Set vsp = r[nnnn] (nnnn != 13, 15) 246 exidx_->set_cfa(0x100); 247 for (size_t i = 0; i < 15; i++) { 248 (*regs_arm_)[i] = i + 1; 249 } 250 251 data_->push_back(0x90); 252 ASSERT_TRUE(exidx_->Decode()); 253 ASSERT_FALSE(exidx_->pc_set()); 254 ASSERT_EQ("", GetFakeLogBuf()); 255 if (log_) { 256 ASSERT_EQ("4 unwind vsp = r0\n", GetFakeLogPrint()); 257 } else { 258 ASSERT_EQ("", GetFakeLogPrint()); 259 } 260 ASSERT_EQ(1U, exidx_->cfa()); 261 262 ResetLogs(); 263 data_->push_back(0x93); 264 ASSERT_TRUE(exidx_->Decode()); 265 ASSERT_FALSE(exidx_->pc_set()); 266 ASSERT_EQ("", GetFakeLogBuf()); 267 if (log_) { 268 ASSERT_EQ("4 unwind vsp = r3\n", GetFakeLogPrint()); 269 } else { 270 ASSERT_EQ("", GetFakeLogPrint()); 271 } 272 ASSERT_EQ(4U, exidx_->cfa()); 273 274 ResetLogs(); 275 data_->push_back(0x9e); 276 ASSERT_TRUE(exidx_->Decode()); 277 ASSERT_FALSE(exidx_->pc_set()); 278 ASSERT_EQ("", GetFakeLogBuf()); 279 if (log_) { 280 ASSERT_EQ("4 unwind vsp = r14\n", GetFakeLogPrint()); 281 } else { 282 ASSERT_EQ("", GetFakeLogPrint()); 283 } 284 ASSERT_EQ(15U, exidx_->cfa()); 285 } 286 287 TEST_P(ArmExidxDecodeTest, reserved_prefix) { 288 // 10011101: Reserved as prefix for ARM register to register moves 289 data_->push_back(0x9d); 290 ASSERT_FALSE(exidx_->Decode()); 291 ASSERT_EQ("", GetFakeLogBuf()); 292 if (log_) { 293 ASSERT_EQ("4 unwind [Reserved]\n", GetFakeLogPrint()); 294 } else { 295 ASSERT_EQ("", GetFakeLogPrint()); 296 } 297 ASSERT_EQ(ARM_STATUS_RESERVED, exidx_->status()); 298 299 // 10011111: Reserved as prefix for Intel Wireless MMX register to register moves 300 ResetLogs(); 301 data_->push_back(0x9f); 302 ASSERT_FALSE(exidx_->Decode()); 303 ASSERT_EQ("", GetFakeLogBuf()); 304 if (log_) { 305 ASSERT_EQ("4 unwind [Reserved]\n", GetFakeLogPrint()); 306 } else { 307 ASSERT_EQ("", GetFakeLogPrint()); 308 } 309 ASSERT_EQ(ARM_STATUS_RESERVED, exidx_->status()); 310 } 311 312 TEST_P(ArmExidxDecodeTest, pop_registers) { 313 // 10100nnn: Pop r4-r[4+nnn] 314 data_->push_back(0xa0); 315 process_memory_.SetData32(0x10000, 0x14); 316 ASSERT_TRUE(exidx_->Decode()); 317 ASSERT_FALSE(exidx_->pc_set()); 318 ASSERT_EQ("", GetFakeLogBuf()); 319 if (log_) { 320 ASSERT_EQ("4 unwind pop {r4}\n", GetFakeLogPrint()); 321 } else { 322 ASSERT_EQ("", GetFakeLogPrint()); 323 } 324 ASSERT_EQ(0x10004U, exidx_->cfa()); 325 ASSERT_EQ(0x14U, (*exidx_->regs())[4]); 326 327 ResetLogs(); 328 data_->push_back(0xa3); 329 process_memory_.SetData32(0x10004, 0x20); 330 process_memory_.SetData32(0x10008, 0x30); 331 process_memory_.SetData32(0x1000c, 0x40); 332 process_memory_.SetData32(0x10010, 0x50); 333 ASSERT_TRUE(exidx_->Decode()); 334 ASSERT_FALSE(exidx_->pc_set()); 335 ASSERT_EQ("", GetFakeLogBuf()); 336 if (log_) { 337 ASSERT_EQ("4 unwind pop {r4-r7}\n", GetFakeLogPrint()); 338 } else { 339 ASSERT_EQ("", GetFakeLogPrint()); 340 } 341 ASSERT_EQ(0x10014U, exidx_->cfa()); 342 ASSERT_EQ(0x20U, (*exidx_->regs())[4]); 343 ASSERT_EQ(0x30U, (*exidx_->regs())[5]); 344 ASSERT_EQ(0x40U, (*exidx_->regs())[6]); 345 ASSERT_EQ(0x50U, (*exidx_->regs())[7]); 346 347 ResetLogs(); 348 data_->push_back(0xa7); 349 process_memory_.SetData32(0x10014, 0x41); 350 process_memory_.SetData32(0x10018, 0x51); 351 process_memory_.SetData32(0x1001c, 0x61); 352 process_memory_.SetData32(0x10020, 0x71); 353 process_memory_.SetData32(0x10024, 0x81); 354 process_memory_.SetData32(0x10028, 0x91); 355 process_memory_.SetData32(0x1002c, 0xa1); 356 process_memory_.SetData32(0x10030, 0xb1); 357 ASSERT_TRUE(exidx_->Decode()); 358 ASSERT_FALSE(exidx_->pc_set()); 359 ASSERT_EQ("", GetFakeLogBuf()); 360 if (log_) { 361 ASSERT_EQ("4 unwind pop {r4-r11}\n", GetFakeLogPrint()); 362 } else { 363 ASSERT_EQ("", GetFakeLogPrint()); 364 } 365 ASSERT_EQ(0x10034U, exidx_->cfa()); 366 ASSERT_EQ(0x41U, (*exidx_->regs())[4]); 367 ASSERT_EQ(0x51U, (*exidx_->regs())[5]); 368 ASSERT_EQ(0x61U, (*exidx_->regs())[6]); 369 ASSERT_EQ(0x71U, (*exidx_->regs())[7]); 370 ASSERT_EQ(0x81U, (*exidx_->regs())[8]); 371 ASSERT_EQ(0x91U, (*exidx_->regs())[9]); 372 ASSERT_EQ(0xa1U, (*exidx_->regs())[10]); 373 ASSERT_EQ(0xb1U, (*exidx_->regs())[11]); 374 } 375 376 TEST_P(ArmExidxDecodeTest, pop_registers_with_r14) { 377 // 10101nnn: Pop r4-r[4+nnn], r14 378 data_->push_back(0xa8); 379 process_memory_.SetData32(0x10000, 0x12); 380 process_memory_.SetData32(0x10004, 0x22); 381 ASSERT_TRUE(exidx_->Decode()); 382 ASSERT_FALSE(exidx_->pc_set()); 383 ASSERT_EQ("", GetFakeLogBuf()); 384 if (log_) { 385 ASSERT_EQ("4 unwind pop {r4, r14}\n", GetFakeLogPrint()); 386 } else { 387 ASSERT_EQ("", GetFakeLogPrint()); 388 } 389 ASSERT_EQ(0x10008U, exidx_->cfa()); 390 ASSERT_EQ(0x12U, (*exidx_->regs())[4]); 391 ASSERT_EQ(0x22U, (*exidx_->regs())[14]); 392 393 ResetLogs(); 394 data_->push_back(0xab); 395 process_memory_.SetData32(0x10008, 0x1); 396 process_memory_.SetData32(0x1000c, 0x2); 397 process_memory_.SetData32(0x10010, 0x3); 398 process_memory_.SetData32(0x10014, 0x4); 399 process_memory_.SetData32(0x10018, 0x5); 400 ASSERT_TRUE(exidx_->Decode()); 401 ASSERT_FALSE(exidx_->pc_set()); 402 ASSERT_EQ("", GetFakeLogBuf()); 403 if (log_) { 404 ASSERT_EQ("4 unwind pop {r4-r7, r14}\n", GetFakeLogPrint()); 405 } else { 406 ASSERT_EQ("", GetFakeLogPrint()); 407 } 408 ASSERT_EQ(0x1001cU, exidx_->cfa()); 409 ASSERT_EQ(0x1U, (*exidx_->regs())[4]); 410 ASSERT_EQ(0x2U, (*exidx_->regs())[5]); 411 ASSERT_EQ(0x3U, (*exidx_->regs())[6]); 412 ASSERT_EQ(0x4U, (*exidx_->regs())[7]); 413 ASSERT_EQ(0x5U, (*exidx_->regs())[14]); 414 415 ResetLogs(); 416 data_->push_back(0xaf); 417 process_memory_.SetData32(0x1001c, 0x1a); 418 process_memory_.SetData32(0x10020, 0x2a); 419 process_memory_.SetData32(0x10024, 0x3a); 420 process_memory_.SetData32(0x10028, 0x4a); 421 process_memory_.SetData32(0x1002c, 0x5a); 422 process_memory_.SetData32(0x10030, 0x6a); 423 process_memory_.SetData32(0x10034, 0x7a); 424 process_memory_.SetData32(0x10038, 0x8a); 425 process_memory_.SetData32(0x1003c, 0x9a); 426 ASSERT_TRUE(exidx_->Decode()); 427 ASSERT_FALSE(exidx_->pc_set()); 428 ASSERT_EQ("", GetFakeLogBuf()); 429 if (log_) { 430 ASSERT_EQ("4 unwind pop {r4-r11, r14}\n", GetFakeLogPrint()); 431 } else { 432 ASSERT_EQ("", GetFakeLogPrint()); 433 } 434 ASSERT_EQ(0x10040U, exidx_->cfa()); 435 ASSERT_EQ(0x1aU, (*exidx_->regs())[4]); 436 ASSERT_EQ(0x2aU, (*exidx_->regs())[5]); 437 ASSERT_EQ(0x3aU, (*exidx_->regs())[6]); 438 ASSERT_EQ(0x4aU, (*exidx_->regs())[7]); 439 ASSERT_EQ(0x5aU, (*exidx_->regs())[8]); 440 ASSERT_EQ(0x6aU, (*exidx_->regs())[9]); 441 ASSERT_EQ(0x7aU, (*exidx_->regs())[10]); 442 ASSERT_EQ(0x8aU, (*exidx_->regs())[11]); 443 ASSERT_EQ(0x9aU, (*exidx_->regs())[14]); 444 } 445 446 TEST_P(ArmExidxDecodeTest, finish) { 447 // 10110000: Finish 448 data_->push_back(0xb0); 449 ASSERT_FALSE(exidx_->Decode()); 450 ASSERT_EQ("", GetFakeLogBuf()); 451 if (log_) { 452 ASSERT_EQ("4 unwind finish\n", GetFakeLogPrint()); 453 } else { 454 ASSERT_EQ("", GetFakeLogPrint()); 455 } 456 ASSERT_EQ(0x10000U, exidx_->cfa()); 457 ASSERT_EQ(ARM_STATUS_FINISH, exidx_->status()); 458 } 459 460 TEST_P(ArmExidxDecodeTest, spare) { 461 // 10110001 00000000: Spare 462 data_->push_back(0xb1); 463 data_->push_back(0x00); 464 ASSERT_FALSE(exidx_->Decode()); 465 ASSERT_EQ("", GetFakeLogBuf()); 466 if (log_) { 467 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()); 468 } else { 469 ASSERT_EQ("", GetFakeLogPrint()); 470 } 471 ASSERT_EQ(0x10000U, exidx_->cfa()); 472 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status()); 473 474 // 10110001 xxxxyyyy: Spare (xxxx != 0000) 475 for (size_t x = 1; x < 16; x++) { 476 for (size_t y = 0; y < 16; y++) { 477 ResetLogs(); 478 data_->push_back(0xb1); 479 data_->push_back((x << 4) | y); 480 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y; 481 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y; 482 if (log_) { 483 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y; 484 } else { 485 ASSERT_EQ("", GetFakeLogPrint()); 486 } 487 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y; 488 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status()); 489 } 490 } 491 492 // 101101nn: Spare 493 for (size_t n = 0; n < 4; n++) { 494 ResetLogs(); 495 data_->push_back(0xb4 | n); 496 ASSERT_FALSE(exidx_->Decode()) << "n = " << n; 497 ASSERT_EQ("", GetFakeLogBuf()) << "n = " << n; 498 if (log_) { 499 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "n = " << n; 500 } else { 501 ASSERT_EQ("", GetFakeLogPrint()); 502 } 503 ASSERT_EQ(0x10000U, exidx_->cfa()) << "n = " << n; 504 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status()); 505 } 506 507 // 11000111 00000000: Spare 508 ResetLogs(); 509 data_->push_back(0xc7); 510 data_->push_back(0x00); 511 ASSERT_FALSE(exidx_->Decode()); 512 ASSERT_EQ("", GetFakeLogBuf()); 513 if (log_) { 514 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()); 515 } else { 516 ASSERT_EQ("", GetFakeLogPrint()); 517 } 518 ASSERT_EQ(0x10000U, exidx_->cfa()); 519 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status()); 520 521 // 11000111 xxxxyyyy: Spare (xxxx != 0000) 522 for (size_t x = 1; x < 16; x++) { 523 for (size_t y = 0; y < 16; y++) { 524 ResetLogs(); 525 data_->push_back(0xc7); 526 data_->push_back(0x10); 527 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y; 528 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y; 529 if (log_) { 530 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y; 531 } else { 532 ASSERT_EQ("", GetFakeLogPrint()); 533 } 534 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y; 535 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status()); 536 } 537 } 538 539 // 11001yyy: Spare (yyy != 000, 001) 540 for (size_t y = 2; y < 8; y++) { 541 ResetLogs(); 542 data_->push_back(0xc8 | y); 543 ASSERT_FALSE(exidx_->Decode()) << "y = " << y; 544 ASSERT_EQ("", GetFakeLogBuf()) << "y = " << y; 545 if (log_) { 546 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "y = " << y; 547 } else { 548 ASSERT_EQ("", GetFakeLogPrint()); 549 } 550 ASSERT_EQ(0x10000U, exidx_->cfa()) << "y = " << y; 551 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status()); 552 } 553 554 // 11xxxyyy: Spare (xxx != 000, 001, 010) 555 for (size_t x = 3; x < 8; x++) { 556 for (size_t y = 0; y < 8; y++) { 557 ResetLogs(); 558 data_->push_back(0xc0 | (x << 3) | y); 559 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y; 560 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y; 561 if (log_) { 562 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y; 563 } else { 564 ASSERT_EQ("", GetFakeLogPrint()); 565 } 566 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y; 567 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status()); 568 } 569 } 570 } 571 572 TEST_P(ArmExidxDecodeTest, pop_registers_under_mask) { 573 // 10110001 0000iiii: Pop integer registers {r0, r1, r2, r3} 574 data_->push_back(0xb1); 575 data_->push_back(0x01); 576 process_memory_.SetData32(0x10000, 0x45); 577 ASSERT_TRUE(exidx_->Decode()); 578 ASSERT_FALSE(exidx_->pc_set()); 579 ASSERT_EQ("", GetFakeLogBuf()); 580 if (log_) { 581 ASSERT_EQ("4 unwind pop {r0}\n", GetFakeLogPrint()); 582 } else { 583 ASSERT_EQ("", GetFakeLogPrint()); 584 } 585 ASSERT_EQ(0x10004U, exidx_->cfa()); 586 ASSERT_EQ(0x45U, (*exidx_->regs())[0]); 587 588 ResetLogs(); 589 data_->push_back(0xb1); 590 data_->push_back(0x0a); 591 process_memory_.SetData32(0x10004, 0x23); 592 process_memory_.SetData32(0x10008, 0x24); 593 ASSERT_TRUE(exidx_->Decode()); 594 ASSERT_FALSE(exidx_->pc_set()); 595 ASSERT_EQ("", GetFakeLogBuf()); 596 if (log_) { 597 ASSERT_EQ("4 unwind pop {r1, r3}\n", GetFakeLogPrint()); 598 } else { 599 ASSERT_EQ("", GetFakeLogPrint()); 600 } 601 ASSERT_EQ(0x1000cU, exidx_->cfa()); 602 ASSERT_EQ(0x23U, (*exidx_->regs())[1]); 603 ASSERT_EQ(0x24U, (*exidx_->regs())[3]); 604 605 ResetLogs(); 606 data_->push_back(0xb1); 607 data_->push_back(0x0f); 608 process_memory_.SetData32(0x1000c, 0x65); 609 process_memory_.SetData32(0x10010, 0x54); 610 process_memory_.SetData32(0x10014, 0x43); 611 process_memory_.SetData32(0x10018, 0x32); 612 ASSERT_TRUE(exidx_->Decode()); 613 ASSERT_FALSE(exidx_->pc_set()); 614 ASSERT_EQ("", GetFakeLogBuf()); 615 if (log_) { 616 ASSERT_EQ("4 unwind pop {r0, r1, r2, r3}\n", GetFakeLogPrint()); 617 } else { 618 ASSERT_EQ("", GetFakeLogPrint()); 619 } 620 ASSERT_EQ(0x1001cU, exidx_->cfa()); 621 ASSERT_EQ(0x65U, (*exidx_->regs())[0]); 622 ASSERT_EQ(0x54U, (*exidx_->regs())[1]); 623 ASSERT_EQ(0x43U, (*exidx_->regs())[2]); 624 ASSERT_EQ(0x32U, (*exidx_->regs())[3]); 625 } 626 627 TEST_P(ArmExidxDecodeTest, vsp_large_incr) { 628 // 10110010 uleb128: vsp = vsp + 0x204 + (uleb128 << 2) 629 data_->push_back(0xb2); 630 data_->push_back(0x7f); 631 ASSERT_TRUE(exidx_->Decode()); 632 ASSERT_FALSE(exidx_->pc_set()); 633 ASSERT_EQ("", GetFakeLogBuf()); 634 if (log_) { 635 ASSERT_EQ("4 unwind vsp = vsp + 1024\n", GetFakeLogPrint()); 636 } else { 637 ASSERT_EQ("", GetFakeLogPrint()); 638 } 639 ASSERT_EQ(0x10400U, exidx_->cfa()); 640 641 ResetLogs(); 642 data_->push_back(0xb2); 643 data_->push_back(0xff); 644 data_->push_back(0x02); 645 ASSERT_TRUE(exidx_->Decode()); 646 ASSERT_FALSE(exidx_->pc_set()); 647 ASSERT_EQ("", GetFakeLogBuf()); 648 if (log_) { 649 ASSERT_EQ("4 unwind vsp = vsp + 2048\n", GetFakeLogPrint()); 650 } else { 651 ASSERT_EQ("", GetFakeLogPrint()); 652 } 653 ASSERT_EQ(0x10c00U, exidx_->cfa()); 654 655 ResetLogs(); 656 data_->push_back(0xb2); 657 data_->push_back(0xff); 658 data_->push_back(0x82); 659 data_->push_back(0x30); 660 ASSERT_TRUE(exidx_->Decode()); 661 ASSERT_FALSE(exidx_->pc_set()); 662 ASSERT_EQ("", GetFakeLogBuf()); 663 if (log_) { 664 ASSERT_EQ("4 unwind vsp = vsp + 3147776\n", GetFakeLogPrint()); 665 } else { 666 ASSERT_EQ("", GetFakeLogPrint()); 667 } 668 ASSERT_EQ(0x311400U, exidx_->cfa()); 669 } 670 671 TEST_P(ArmExidxDecodeTest, pop_vfp_fstmfdx) { 672 // 10110011 sssscccc: Pop VFP double precision registers D[ssss]-D[ssss+cccc] by FSTMFDX 673 data_->push_back(0xb3); 674 data_->push_back(0x00); 675 ASSERT_TRUE(exidx_->Decode()); 676 ASSERT_FALSE(exidx_->pc_set()); 677 ASSERT_EQ("", GetFakeLogBuf()); 678 if (log_) { 679 ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint()); 680 } else { 681 ASSERT_EQ("", GetFakeLogPrint()); 682 } 683 ASSERT_EQ(0x1000cU, exidx_->cfa()); 684 685 ResetLogs(); 686 data_->push_back(0xb3); 687 data_->push_back(0x48); 688 ASSERT_TRUE(exidx_->Decode()); 689 ASSERT_FALSE(exidx_->pc_set()); 690 ASSERT_EQ("", GetFakeLogBuf()); 691 if (log_) { 692 ASSERT_EQ("4 unwind pop {d4-d12}\n", GetFakeLogPrint()); 693 } else { 694 ASSERT_EQ("", GetFakeLogPrint()); 695 } 696 ASSERT_EQ(0x10058U, exidx_->cfa()); 697 } 698 699 TEST_P(ArmExidxDecodeTest, pop_vfp8_fstmfdx) { 700 // 10111nnn: Pop VFP double precision registers D[8]-D[8+nnn] by FSTMFDX 701 data_->push_back(0xb8); 702 ASSERT_TRUE(exidx_->Decode()); 703 ASSERT_FALSE(exidx_->pc_set()); 704 ASSERT_EQ("", GetFakeLogBuf()); 705 if (log_) { 706 ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint()); 707 } else { 708 ASSERT_EQ("", GetFakeLogPrint()); 709 } 710 ASSERT_EQ(0x1000cU, exidx_->cfa()); 711 712 ResetLogs(); 713 data_->push_back(0xbb); 714 ASSERT_TRUE(exidx_->Decode()); 715 ASSERT_FALSE(exidx_->pc_set()); 716 ASSERT_EQ("", GetFakeLogBuf()); 717 if (log_) { 718 ASSERT_EQ("4 unwind pop {d8-d11}\n", GetFakeLogPrint()); 719 } else { 720 ASSERT_EQ("", GetFakeLogPrint()); 721 } 722 ASSERT_EQ(0x10030U, exidx_->cfa()); 723 724 ResetLogs(); 725 data_->push_back(0xbf); 726 ASSERT_TRUE(exidx_->Decode()); 727 ASSERT_FALSE(exidx_->pc_set()); 728 ASSERT_EQ("", GetFakeLogBuf()); 729 if (log_) { 730 ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint()); 731 } else { 732 ASSERT_EQ("", GetFakeLogPrint()); 733 } 734 ASSERT_EQ(0x10074U, exidx_->cfa()); 735 } 736 737 TEST_P(ArmExidxDecodeTest, pop_mmx_wr10) { 738 // 11000nnn: Intel Wireless MMX pop wR[10]-wR[10+nnn] (nnn != 6, 7) 739 data_->push_back(0xc0); 740 ASSERT_TRUE(exidx_->Decode()); 741 ASSERT_FALSE(exidx_->pc_set()); 742 ASSERT_EQ("", GetFakeLogBuf()); 743 if (log_) { 744 ASSERT_EQ("4 unwind pop {wR10}\n", GetFakeLogPrint()); 745 } else { 746 ASSERT_EQ("", GetFakeLogPrint()); 747 } 748 ASSERT_EQ(0x10008U, exidx_->cfa()); 749 750 ResetLogs(); 751 data_->push_back(0xc2); 752 ASSERT_TRUE(exidx_->Decode()); 753 ASSERT_FALSE(exidx_->pc_set()); 754 ASSERT_EQ("", GetFakeLogBuf()); 755 if (log_) { 756 ASSERT_EQ("4 unwind pop {wR10-wR12}\n", GetFakeLogPrint()); 757 } else { 758 ASSERT_EQ("", GetFakeLogPrint()); 759 } 760 ASSERT_EQ(0x10020U, exidx_->cfa()); 761 762 ResetLogs(); 763 data_->push_back(0xc5); 764 ASSERT_TRUE(exidx_->Decode()); 765 ASSERT_FALSE(exidx_->pc_set()); 766 ASSERT_EQ("", GetFakeLogBuf()); 767 if (log_) { 768 ASSERT_EQ("4 unwind pop {wR10-wR15}\n", GetFakeLogPrint()); 769 } else { 770 ASSERT_EQ("", GetFakeLogPrint()); 771 } 772 ASSERT_EQ(0x10050U, exidx_->cfa()); 773 } 774 775 TEST_P(ArmExidxDecodeTest, pop_mmx_wr) { 776 // 11000110 sssscccc: Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc] 777 data_->push_back(0xc6); 778 data_->push_back(0x00); 779 ASSERT_TRUE(exidx_->Decode()); 780 ASSERT_FALSE(exidx_->pc_set()); 781 ASSERT_EQ("", GetFakeLogBuf()); 782 if (log_) { 783 ASSERT_EQ("4 unwind pop {wR0}\n", GetFakeLogPrint()); 784 } else { 785 ASSERT_EQ("", GetFakeLogPrint()); 786 } 787 ASSERT_EQ(0x10008U, exidx_->cfa()); 788 789 ResetLogs(); 790 data_->push_back(0xc6); 791 data_->push_back(0x25); 792 ASSERT_TRUE(exidx_->Decode()); 793 ASSERT_FALSE(exidx_->pc_set()); 794 ASSERT_EQ("", GetFakeLogBuf()); 795 if (log_) { 796 ASSERT_EQ("4 unwind pop {wR2-wR7}\n", GetFakeLogPrint()); 797 } else { 798 ASSERT_EQ("", GetFakeLogPrint()); 799 } 800 ASSERT_EQ(0x10038U, exidx_->cfa()); 801 802 ResetLogs(); 803 data_->push_back(0xc6); 804 data_->push_back(0xff); 805 ASSERT_TRUE(exidx_->Decode()); 806 ASSERT_FALSE(exidx_->pc_set()); 807 ASSERT_EQ("", GetFakeLogBuf()); 808 if (log_) { 809 ASSERT_EQ("4 unwind pop {wR15-wR30}\n", GetFakeLogPrint()); 810 } else { 811 ASSERT_EQ("", GetFakeLogPrint()); 812 } 813 ASSERT_EQ(0x100b8U, exidx_->cfa()); 814 } 815 816 TEST_P(ArmExidxDecodeTest, pop_mmx_wcgr) { 817 // 11000111 0000iiii: Intel Wireless MMX pop wCGR registes {wCGR0,1,2,3} 818 data_->push_back(0xc7); 819 data_->push_back(0x01); 820 ASSERT_TRUE(exidx_->Decode()); 821 ASSERT_FALSE(exidx_->pc_set()); 822 ASSERT_EQ("", GetFakeLogBuf()); 823 if (log_) { 824 ASSERT_EQ("4 unwind pop {wCGR0}\n", GetFakeLogPrint()); 825 } else { 826 ASSERT_EQ("", GetFakeLogPrint()); 827 } 828 ASSERT_EQ(0x10004U, exidx_->cfa()); 829 830 ResetLogs(); 831 data_->push_back(0xc7); 832 data_->push_back(0x0a); 833 ASSERT_TRUE(exidx_->Decode()); 834 ASSERT_FALSE(exidx_->pc_set()); 835 ASSERT_EQ("", GetFakeLogBuf()); 836 if (log_) { 837 ASSERT_EQ("4 unwind pop {wCGR1, wCGR3}\n", GetFakeLogPrint()); 838 } else { 839 ASSERT_EQ("", GetFakeLogPrint()); 840 } 841 ASSERT_EQ(0x1000cU, exidx_->cfa()); 842 843 ResetLogs(); 844 data_->push_back(0xc7); 845 data_->push_back(0x0f); 846 ASSERT_TRUE(exidx_->Decode()); 847 ASSERT_FALSE(exidx_->pc_set()); 848 ASSERT_EQ("", GetFakeLogBuf()); 849 if (log_) { 850 ASSERT_EQ("4 unwind pop {wCGR0, wCGR1, wCGR2, wCGR3}\n", GetFakeLogPrint()); 851 } else { 852 ASSERT_EQ("", GetFakeLogPrint()); 853 } 854 ASSERT_EQ(0x1001cU, exidx_->cfa()); 855 } 856 857 TEST_P(ArmExidxDecodeTest, pop_vfp16_vpush) { 858 // 11001000 sssscccc: Pop VFP double precision registers d[16+ssss]-D[16+ssss+cccc] by VPUSH 859 data_->push_back(0xc8); 860 data_->push_back(0x00); 861 ASSERT_TRUE(exidx_->Decode()); 862 ASSERT_FALSE(exidx_->pc_set()); 863 ASSERT_EQ("", GetFakeLogBuf()); 864 if (log_) { 865 ASSERT_EQ("4 unwind pop {d16}\n", GetFakeLogPrint()); 866 } else { 867 ASSERT_EQ("", GetFakeLogPrint()); 868 } 869 ASSERT_EQ(0x10008U, exidx_->cfa()); 870 871 ResetLogs(); 872 data_->push_back(0xc8); 873 data_->push_back(0x14); 874 ASSERT_TRUE(exidx_->Decode()); 875 ASSERT_FALSE(exidx_->pc_set()); 876 ASSERT_EQ("", GetFakeLogBuf()); 877 if (log_) { 878 ASSERT_EQ("4 unwind pop {d17-d21}\n", GetFakeLogPrint()); 879 } else { 880 ASSERT_EQ("", GetFakeLogPrint()); 881 } 882 ASSERT_EQ(0x10030U, exidx_->cfa()); 883 884 ResetLogs(); 885 data_->push_back(0xc8); 886 data_->push_back(0xff); 887 ASSERT_TRUE(exidx_->Decode()); 888 ASSERT_FALSE(exidx_->pc_set()); 889 ASSERT_EQ("", GetFakeLogBuf()); 890 if (log_) { 891 ASSERT_EQ("4 unwind pop {d31-d46}\n", GetFakeLogPrint()); 892 } else { 893 ASSERT_EQ("", GetFakeLogPrint()); 894 } 895 ASSERT_EQ(0x100b0U, exidx_->cfa()); 896 } 897 898 TEST_P(ArmExidxDecodeTest, pop_vfp_vpush) { 899 // 11001001 sssscccc: Pop VFP double precision registers d[ssss]-D[ssss+cccc] by VPUSH 900 data_->push_back(0xc9); 901 data_->push_back(0x00); 902 ASSERT_TRUE(exidx_->Decode()); 903 ASSERT_FALSE(exidx_->pc_set()); 904 ASSERT_EQ("", GetFakeLogBuf()); 905 if (log_) { 906 ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint()); 907 } else { 908 ASSERT_EQ("", GetFakeLogPrint()); 909 } 910 ASSERT_EQ(0x10008U, exidx_->cfa()); 911 912 ResetLogs(); 913 data_->push_back(0xc9); 914 data_->push_back(0x23); 915 ASSERT_TRUE(exidx_->Decode()); 916 ASSERT_FALSE(exidx_->pc_set()); 917 ASSERT_EQ("", GetFakeLogBuf()); 918 if (log_) { 919 ASSERT_EQ("4 unwind pop {d2-d5}\n", GetFakeLogPrint()); 920 } else { 921 ASSERT_EQ("", GetFakeLogPrint()); 922 } 923 ASSERT_EQ(0x10028U, exidx_->cfa()); 924 925 ResetLogs(); 926 data_->push_back(0xc9); 927 data_->push_back(0xff); 928 ASSERT_TRUE(exidx_->Decode()); 929 ASSERT_FALSE(exidx_->pc_set()); 930 ASSERT_EQ("", GetFakeLogBuf()); 931 if (log_) { 932 ASSERT_EQ("4 unwind pop {d15-d30}\n", GetFakeLogPrint()); 933 } else { 934 ASSERT_EQ("", GetFakeLogPrint()); 935 } 936 ASSERT_EQ(0x100a8U, exidx_->cfa()); 937 } 938 939 TEST_P(ArmExidxDecodeTest, pop_vfp8_vpush) { 940 // 11010nnn: Pop VFP double precision registers D[8]-D[8+nnn] by VPUSH 941 data_->push_back(0xd0); 942 ASSERT_TRUE(exidx_->Decode()); 943 ASSERT_FALSE(exidx_->pc_set()); 944 ASSERT_EQ("", GetFakeLogBuf()); 945 if (log_) { 946 ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint()); 947 } else { 948 ASSERT_EQ("", GetFakeLogPrint()); 949 } 950 ASSERT_EQ(0x10008U, exidx_->cfa()); 951 952 ResetLogs(); 953 data_->push_back(0xd2); 954 ASSERT_TRUE(exidx_->Decode()); 955 ASSERT_FALSE(exidx_->pc_set()); 956 ASSERT_EQ("", GetFakeLogBuf()); 957 if (log_) { 958 ASSERT_EQ("4 unwind pop {d8-d10}\n", GetFakeLogPrint()); 959 } else { 960 ASSERT_EQ("", GetFakeLogPrint()); 961 } 962 ASSERT_EQ(0x10020U, exidx_->cfa()); 963 964 ResetLogs(); 965 data_->push_back(0xd7); 966 ASSERT_TRUE(exidx_->Decode()); 967 ASSERT_FALSE(exidx_->pc_set()); 968 ASSERT_EQ("", GetFakeLogBuf()); 969 if (log_) { 970 ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint()); 971 } else { 972 ASSERT_EQ("", GetFakeLogPrint()); 973 } 974 ASSERT_EQ(0x10060U, exidx_->cfa()); 975 } 976 977 TEST_P(ArmExidxDecodeTest, expect_truncated) { 978 // This test verifies that any op that requires extra ops will 979 // fail if the data is not present. 980 data_->push_back(0x80); 981 ASSERT_FALSE(exidx_->Decode()); 982 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status()); 983 984 data_->clear(); 985 data_->push_back(0xb1); 986 ASSERT_FALSE(exidx_->Decode()); 987 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status()); 988 989 data_->clear(); 990 data_->push_back(0xb2); 991 ASSERT_FALSE(exidx_->Decode()); 992 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status()); 993 994 data_->clear(); 995 data_->push_back(0xb3); 996 ASSERT_FALSE(exidx_->Decode()); 997 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status()); 998 999 data_->clear(); 1000 data_->push_back(0xc6); 1001 ASSERT_FALSE(exidx_->Decode()); 1002 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status()); 1003 1004 data_->clear(); 1005 data_->push_back(0xc7); 1006 ASSERT_FALSE(exidx_->Decode()); 1007 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status()); 1008 1009 data_->clear(); 1010 data_->push_back(0xc8); 1011 ASSERT_FALSE(exidx_->Decode()); 1012 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status()); 1013 1014 data_->clear(); 1015 data_->push_back(0xc9); 1016 ASSERT_FALSE(exidx_->Decode()); 1017 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status()); 1018 } 1019 1020 TEST_P(ArmExidxDecodeTest, verify_no_truncated) { 1021 // This test verifies that no pattern results in a crash or truncation. 1022 MemoryFakeAlwaysReadZero memory_zero; 1023 Init(&memory_zero); 1024 1025 for (size_t x = 0; x < 256; x++) { 1026 if (x == 0xb2) { 1027 // This opcode is followed by an uleb128, so just skip this one. 1028 continue; 1029 } 1030 for (size_t y = 0; y < 256; y++) { 1031 data_->clear(); 1032 data_->push_back(x); 1033 data_->push_back(y); 1034 if (!exidx_->Decode()) { 1035 ASSERT_NE(ARM_STATUS_TRUNCATED, exidx_->status()) 1036 << "x y = 0x" << std::hex << x << " 0x" << y; 1037 ASSERT_NE(ARM_STATUS_READ_FAILED, exidx_->status()) 1038 << "x y = 0x" << std::hex << x << " 0x" << y; 1039 } 1040 } 1041 } 1042 } 1043 1044 TEST_P(ArmExidxDecodeTest, eval_multiple_decodes) { 1045 // vsp = vsp + 4 1046 data_->push_back(0x00); 1047 // vsp = vsp + 8 1048 data_->push_back(0x02); 1049 // Finish 1050 data_->push_back(0xb0); 1051 1052 ASSERT_TRUE(exidx_->Eval()); 1053 if (log_) { 1054 ASSERT_EQ("4 unwind vsp = vsp + 4\n" 1055 "4 unwind vsp = vsp + 12\n" 1056 "4 unwind finish\n", GetFakeLogPrint()); 1057 } else { 1058 ASSERT_EQ("", GetFakeLogPrint()); 1059 } 1060 ASSERT_EQ(0x10010U, exidx_->cfa()); 1061 ASSERT_FALSE(exidx_->pc_set()); 1062 } 1063 1064 TEST_P(ArmExidxDecodeTest, eval_pc_set) { 1065 // vsp = vsp + 4 1066 data_->push_back(0x00); 1067 // vsp = vsp + 8 1068 data_->push_back(0x02); 1069 // Pop {r15} 1070 data_->push_back(0x88); 1071 data_->push_back(0x00); 1072 // vsp = vsp + 8 1073 data_->push_back(0x02); 1074 // Finish 1075 data_->push_back(0xb0); 1076 1077 process_memory_.SetData32(0x10010, 0x10); 1078 1079 ASSERT_TRUE(exidx_->Eval()); 1080 if (log_) { 1081 ASSERT_EQ("4 unwind vsp = vsp + 4\n" 1082 "4 unwind vsp = vsp + 12\n" 1083 "4 unwind pop {r15}\n" 1084 "4 unwind vsp = vsp + 12\n" 1085 "4 unwind finish\n", GetFakeLogPrint()); 1086 } else { 1087 ASSERT_EQ("", GetFakeLogPrint()); 1088 } 1089 ASSERT_EQ(0x10020U, exidx_->cfa()); 1090 ASSERT_TRUE(exidx_->pc_set()); 1091 ASSERT_EQ(0x10U, (*exidx_->regs())[15]); 1092 } 1093 1094 INSTANTIATE_TEST_CASE_P(, ArmExidxDecodeTest, ::testing::Values("logging", "no_logging")); 1095