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