Elf interface for new unwinder.
This cl includes the code to read arm unwind information from a shared
library.
Bug: 23762183
Test: Passes all unit tests. I can dump the arm unwind information
Test: for an arm shared library.
Change-Id: I43501ea2eab843b81de8bd5128401dd1971af8d3
diff --git a/libunwindstack/tests/ArmExidxDecodeTest.cpp b/libunwindstack/tests/ArmExidxDecodeTest.cpp
index 9ea917a..4fff48e 100644
--- a/libunwindstack/tests/ArmExidxDecodeTest.cpp
+++ b/libunwindstack/tests/ArmExidxDecodeTest.cpp
@@ -24,6 +24,7 @@
#include <gtest/gtest.h>
#include "ArmExidx.h"
+#include "Regs.h"
#include "Log.h"
#include "LogFake.h"
@@ -38,12 +39,14 @@
process_memory = &process_memory_;
}
- regs32_.reset(new Regs32(0, 1, 32));
- for (size_t i = 0; i < 32; i++) {
- (*regs32_)[i] = 0;
+ regs_arm_.reset(new RegsArm());
+ for (size_t i = 0; i < regs_arm_->total_regs(); i++) {
+ (*regs_arm_)[i] = 0;
}
+ regs_arm_->set_pc(0);
+ regs_arm_->set_sp(0);
- exidx_.reset(new ArmExidx(regs32_.get(), &elf_memory_, process_memory));
+ exidx_.reset(new ArmExidx(regs_arm_.get(), &elf_memory_, process_memory));
if (log_) {
exidx_->set_log(true);
exidx_->set_log_indent(0);
@@ -66,7 +69,7 @@
}
std::unique_ptr<ArmExidx> exidx_;
- std::unique_ptr<Regs32> regs32_;
+ std::unique_ptr<RegsArm> regs_arm_;
std::deque<uint8_t>* data_;
MemoryFake elf_memory_;
@@ -78,6 +81,7 @@
// 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4
data_->push_back(0x00);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp + 4\n", GetFakeLogPrint());
@@ -90,6 +94,7 @@
data_->clear();
data_->push_back(0x01);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp + 8\n", GetFakeLogPrint());
@@ -102,6 +107,7 @@
data_->clear();
data_->push_back(0x3f);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp + 256\n", GetFakeLogPrint());
@@ -115,6 +121,7 @@
// 01xxxxxx: vsp = vsp - (xxxxxx << 2) + 4
data_->push_back(0x40);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp - 4\n", GetFakeLogPrint());
@@ -127,6 +134,7 @@
data_->clear();
data_->push_back(0x41);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp - 8\n", GetFakeLogPrint());
@@ -139,6 +147,7 @@
data_->clear();
data_->push_back(0x7f);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp - 256\n", GetFakeLogPrint());
@@ -164,26 +173,29 @@
TEST_P(ArmExidxDecodeTest, pop_up_to_12) {
// 1000iiii iiiiiiii: Pop up to 12 integer registers
- data_->push_back(0x80);
- data_->push_back(0x01);
- process_memory_.SetData(0x10000, 0x10);
+ data_->push_back(0x88);
+ data_->push_back(0x00);
+ process_memory_.SetData32(0x10000, 0x10);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_TRUE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
- ASSERT_EQ("4 unwind pop {r4}\n", GetFakeLogPrint());
+ ASSERT_EQ("4 unwind pop {r15}\n", GetFakeLogPrint());
} else {
ASSERT_EQ("", GetFakeLogPrint());
}
ASSERT_EQ(0x10004U, exidx_->cfa());
- ASSERT_EQ(0x10U, (*exidx_->regs())[4]);
+ ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
ResetLogs();
data_->push_back(0x8f);
data_->push_back(0xff);
for (size_t i = 0; i < 12; i++) {
- process_memory_.SetData(0x10004 + i * 4, i + 0x20);
+ process_memory_.SetData32(0x10004 + i * 4, i + 0x20);
}
+ exidx_->set_pc_set(false);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_TRUE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}\n",
@@ -211,10 +223,12 @@
exidx_->set_cfa(0x10034);
data_->push_back(0x81);
data_->push_back(0x28);
- process_memory_.SetData(0x10034, 0x11);
- process_memory_.SetData(0x10038, 0x22);
- process_memory_.SetData(0x1003c, 0x33);
+ process_memory_.SetData32(0x10034, 0x11);
+ process_memory_.SetData32(0x10038, 0x22);
+ process_memory_.SetData32(0x1003c, 0x33);
+ exidx_->set_pc_set(false);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r7, r9, r12}\n", GetFakeLogPrint());
@@ -231,11 +245,12 @@
// 1001nnnn: Set vsp = r[nnnn] (nnnn != 13, 15)
exidx_->set_cfa(0x100);
for (size_t i = 0; i < 15; i++) {
- (*regs32_)[i] = i + 1;
+ (*regs_arm_)[i] = i + 1;
}
data_->push_back(0x90);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = r0\n", GetFakeLogPrint());
@@ -247,6 +262,7 @@
ResetLogs();
data_->push_back(0x93);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = r3\n", GetFakeLogPrint());
@@ -258,6 +274,7 @@
ResetLogs();
data_->push_back(0x9e);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = r14\n", GetFakeLogPrint());
@@ -295,8 +312,9 @@
TEST_P(ArmExidxDecodeTest, pop_registers) {
// 10100nnn: Pop r4-r[4+nnn]
data_->push_back(0xa0);
- process_memory_.SetData(0x10000, 0x14);
+ process_memory_.SetData32(0x10000, 0x14);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r4}\n", GetFakeLogPrint());
@@ -308,11 +326,12 @@
ResetLogs();
data_->push_back(0xa3);
- process_memory_.SetData(0x10004, 0x20);
- process_memory_.SetData(0x10008, 0x30);
- process_memory_.SetData(0x1000c, 0x40);
- process_memory_.SetData(0x10010, 0x50);
+ process_memory_.SetData32(0x10004, 0x20);
+ process_memory_.SetData32(0x10008, 0x30);
+ process_memory_.SetData32(0x1000c, 0x40);
+ process_memory_.SetData32(0x10010, 0x50);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r4-r7}\n", GetFakeLogPrint());
@@ -327,15 +346,16 @@
ResetLogs();
data_->push_back(0xa7);
- process_memory_.SetData(0x10014, 0x41);
- process_memory_.SetData(0x10018, 0x51);
- process_memory_.SetData(0x1001c, 0x61);
- process_memory_.SetData(0x10020, 0x71);
- process_memory_.SetData(0x10024, 0x81);
- process_memory_.SetData(0x10028, 0x91);
- process_memory_.SetData(0x1002c, 0xa1);
- process_memory_.SetData(0x10030, 0xb1);
+ process_memory_.SetData32(0x10014, 0x41);
+ process_memory_.SetData32(0x10018, 0x51);
+ process_memory_.SetData32(0x1001c, 0x61);
+ process_memory_.SetData32(0x10020, 0x71);
+ process_memory_.SetData32(0x10024, 0x81);
+ process_memory_.SetData32(0x10028, 0x91);
+ process_memory_.SetData32(0x1002c, 0xa1);
+ process_memory_.SetData32(0x10030, 0xb1);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r4-r11}\n", GetFakeLogPrint());
@@ -356,9 +376,10 @@
TEST_P(ArmExidxDecodeTest, pop_registers_with_r14) {
// 10101nnn: Pop r4-r[4+nnn], r14
data_->push_back(0xa8);
- process_memory_.SetData(0x10000, 0x12);
- process_memory_.SetData(0x10004, 0x22);
+ process_memory_.SetData32(0x10000, 0x12);
+ process_memory_.SetData32(0x10004, 0x22);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r4, r14}\n", GetFakeLogPrint());
@@ -371,12 +392,13 @@
ResetLogs();
data_->push_back(0xab);
- process_memory_.SetData(0x10008, 0x1);
- process_memory_.SetData(0x1000c, 0x2);
- process_memory_.SetData(0x10010, 0x3);
- process_memory_.SetData(0x10014, 0x4);
- process_memory_.SetData(0x10018, 0x5);
+ process_memory_.SetData32(0x10008, 0x1);
+ process_memory_.SetData32(0x1000c, 0x2);
+ process_memory_.SetData32(0x10010, 0x3);
+ process_memory_.SetData32(0x10014, 0x4);
+ process_memory_.SetData32(0x10018, 0x5);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r4-r7, r14}\n", GetFakeLogPrint());
@@ -392,16 +414,17 @@
ResetLogs();
data_->push_back(0xaf);
- process_memory_.SetData(0x1001c, 0x1a);
- process_memory_.SetData(0x10020, 0x2a);
- process_memory_.SetData(0x10024, 0x3a);
- process_memory_.SetData(0x10028, 0x4a);
- process_memory_.SetData(0x1002c, 0x5a);
- process_memory_.SetData(0x10030, 0x6a);
- process_memory_.SetData(0x10034, 0x7a);
- process_memory_.SetData(0x10038, 0x8a);
- process_memory_.SetData(0x1003c, 0x9a);
+ process_memory_.SetData32(0x1001c, 0x1a);
+ process_memory_.SetData32(0x10020, 0x2a);
+ process_memory_.SetData32(0x10024, 0x3a);
+ process_memory_.SetData32(0x10028, 0x4a);
+ process_memory_.SetData32(0x1002c, 0x5a);
+ process_memory_.SetData32(0x10030, 0x6a);
+ process_memory_.SetData32(0x10034, 0x7a);
+ process_memory_.SetData32(0x10038, 0x8a);
+ process_memory_.SetData32(0x1003c, 0x9a);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r4-r11, r14}\n", GetFakeLogPrint());
@@ -550,8 +573,9 @@
// 10110001 0000iiii: Pop integer registers {r0, r1, r2, r3}
data_->push_back(0xb1);
data_->push_back(0x01);
- process_memory_.SetData(0x10000, 0x45);
+ process_memory_.SetData32(0x10000, 0x45);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r0}\n", GetFakeLogPrint());
@@ -564,9 +588,10 @@
ResetLogs();
data_->push_back(0xb1);
data_->push_back(0x0a);
- process_memory_.SetData(0x10004, 0x23);
- process_memory_.SetData(0x10008, 0x24);
+ process_memory_.SetData32(0x10004, 0x23);
+ process_memory_.SetData32(0x10008, 0x24);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r1, r3}\n", GetFakeLogPrint());
@@ -580,11 +605,12 @@
ResetLogs();
data_->push_back(0xb1);
data_->push_back(0x0f);
- process_memory_.SetData(0x1000c, 0x65);
- process_memory_.SetData(0x10010, 0x54);
- process_memory_.SetData(0x10014, 0x43);
- process_memory_.SetData(0x10018, 0x32);
+ process_memory_.SetData32(0x1000c, 0x65);
+ process_memory_.SetData32(0x10010, 0x54);
+ process_memory_.SetData32(0x10014, 0x43);
+ process_memory_.SetData32(0x10018, 0x32);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {r0, r1, r2, r3}\n", GetFakeLogPrint());
@@ -603,6 +629,7 @@
data_->push_back(0xb2);
data_->push_back(0x7f);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp + 1024\n", GetFakeLogPrint());
@@ -616,6 +643,7 @@
data_->push_back(0xff);
data_->push_back(0x02);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp + 2048\n", GetFakeLogPrint());
@@ -630,6 +658,7 @@
data_->push_back(0x82);
data_->push_back(0x30);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind vsp = vsp + 3147776\n", GetFakeLogPrint());
@@ -644,6 +673,7 @@
data_->push_back(0xb3);
data_->push_back(0x00);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint());
@@ -656,6 +686,7 @@
data_->push_back(0xb3);
data_->push_back(0x48);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d4-d12}\n", GetFakeLogPrint());
@@ -669,6 +700,7 @@
// 10111nnn: Pop VFP double precision registers D[8]-D[8+nnn] by FSTMFDX
data_->push_back(0xb8);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint());
@@ -680,6 +712,7 @@
ResetLogs();
data_->push_back(0xbb);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d8-d11}\n", GetFakeLogPrint());
@@ -691,6 +724,7 @@
ResetLogs();
data_->push_back(0xbf);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint());
@@ -704,6 +738,7 @@
// 11000nnn: Intel Wireless MMX pop wR[10]-wR[10+nnn] (nnn != 6, 7)
data_->push_back(0xc0);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wR10}\n", GetFakeLogPrint());
@@ -715,6 +750,7 @@
ResetLogs();
data_->push_back(0xc2);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wR10-wR12}\n", GetFakeLogPrint());
@@ -726,6 +762,7 @@
ResetLogs();
data_->push_back(0xc5);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wR10-wR15}\n", GetFakeLogPrint());
@@ -740,6 +777,7 @@
data_->push_back(0xc6);
data_->push_back(0x00);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wR0}\n", GetFakeLogPrint());
@@ -752,6 +790,7 @@
data_->push_back(0xc6);
data_->push_back(0x25);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wR2-wR7}\n", GetFakeLogPrint());
@@ -764,6 +803,7 @@
data_->push_back(0xc6);
data_->push_back(0xff);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wR15-wR30}\n", GetFakeLogPrint());
@@ -778,6 +818,7 @@
data_->push_back(0xc7);
data_->push_back(0x01);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wCGR0}\n", GetFakeLogPrint());
@@ -790,6 +831,7 @@
data_->push_back(0xc7);
data_->push_back(0x0a);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wCGR1, wCGR3}\n", GetFakeLogPrint());
@@ -802,6 +844,7 @@
data_->push_back(0xc7);
data_->push_back(0x0f);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {wCGR0, wCGR1, wCGR2, wCGR3}\n", GetFakeLogPrint());
@@ -816,6 +859,7 @@
data_->push_back(0xc8);
data_->push_back(0x00);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d16}\n", GetFakeLogPrint());
@@ -828,6 +872,7 @@
data_->push_back(0xc8);
data_->push_back(0x14);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d17-d21}\n", GetFakeLogPrint());
@@ -840,6 +885,7 @@
data_->push_back(0xc8);
data_->push_back(0xff);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d31-d46}\n", GetFakeLogPrint());
@@ -854,6 +900,7 @@
data_->push_back(0xc9);
data_->push_back(0x00);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint());
@@ -866,6 +913,7 @@
data_->push_back(0xc9);
data_->push_back(0x23);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d2-d5}\n", GetFakeLogPrint());
@@ -878,6 +926,7 @@
data_->push_back(0xc9);
data_->push_back(0xff);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d15-d30}\n", GetFakeLogPrint());
@@ -891,6 +940,7 @@
// 11010nnn: Pop VFP double precision registers D[8]-D[8+nnn] by VPUSH
data_->push_back(0xd0);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint());
@@ -902,6 +952,7 @@
ResetLogs();
data_->push_back(0xd2);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d8-d10}\n", GetFakeLogPrint());
@@ -913,6 +964,7 @@
ResetLogs();
data_->push_back(0xd7);
ASSERT_TRUE(exidx_->Decode());
+ ASSERT_FALSE(exidx_->pc_set());
ASSERT_EQ("", GetFakeLogBuf());
if (log_) {
ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint());
@@ -989,4 +1041,54 @@
}
}
+TEST_P(ArmExidxDecodeTest, eval_multiple_decodes) {
+ // vsp = vsp + 4
+ data_->push_back(0x00);
+ // vsp = vsp + 8
+ data_->push_back(0x02);
+ // Finish
+ data_->push_back(0xb0);
+
+ ASSERT_TRUE(exidx_->Eval());
+ if (log_) {
+ ASSERT_EQ("4 unwind vsp = vsp + 4\n"
+ "4 unwind vsp = vsp + 12\n"
+ "4 unwind finish\n", GetFakeLogPrint());
+ } else {
+ ASSERT_EQ("", GetFakeLogPrint());
+ }
+ ASSERT_EQ(0x10010U, exidx_->cfa());
+ ASSERT_FALSE(exidx_->pc_set());
+}
+
+TEST_P(ArmExidxDecodeTest, eval_pc_set) {
+ // vsp = vsp + 4
+ data_->push_back(0x00);
+ // vsp = vsp + 8
+ data_->push_back(0x02);
+ // Pop {r15}
+ data_->push_back(0x88);
+ data_->push_back(0x00);
+ // vsp = vsp + 8
+ data_->push_back(0x02);
+ // Finish
+ data_->push_back(0xb0);
+
+ process_memory_.SetData32(0x10010, 0x10);
+
+ ASSERT_TRUE(exidx_->Eval());
+ if (log_) {
+ ASSERT_EQ("4 unwind vsp = vsp + 4\n"
+ "4 unwind vsp = vsp + 12\n"
+ "4 unwind pop {r15}\n"
+ "4 unwind vsp = vsp + 12\n"
+ "4 unwind finish\n", GetFakeLogPrint());
+ } else {
+ ASSERT_EQ("", GetFakeLogPrint());
+ }
+ ASSERT_EQ(0x10020U, exidx_->cfa());
+ ASSERT_TRUE(exidx_->pc_set());
+ ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
+}
+
INSTANTIATE_TEST_CASE_P(, ArmExidxDecodeTest, ::testing::Values("logging", "no_logging"));