xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/ArmExidxDecodeTest.cpp (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker  *
4*eb293b8fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker  *
8*eb293b8fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker  *
10*eb293b8fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker  * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker  */
16*eb293b8fSAndroid Build Coastguard Worker 
17*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h>
18*eb293b8fSAndroid Build Coastguard Worker 
19*eb293b8fSAndroid Build Coastguard Worker #include <deque>
20*eb293b8fSAndroid Build Coastguard Worker #include <ios>
21*eb293b8fSAndroid Build Coastguard Worker #include <memory>
22*eb293b8fSAndroid Build Coastguard Worker #include <string>
23*eb293b8fSAndroid Build Coastguard Worker 
24*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
25*eb293b8fSAndroid Build Coastguard Worker 
26*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Log.h>
27*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/RegsArm.h>
28*eb293b8fSAndroid Build Coastguard Worker 
29*eb293b8fSAndroid Build Coastguard Worker #include "ArmExidx.h"
30*eb293b8fSAndroid Build Coastguard Worker 
31*eb293b8fSAndroid Build Coastguard Worker #include "LogFake.h"
32*eb293b8fSAndroid Build Coastguard Worker #include "utils/MemoryFake.h"
33*eb293b8fSAndroid Build Coastguard Worker 
34*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
35*eb293b8fSAndroid Build Coastguard Worker 
36*eb293b8fSAndroid Build Coastguard Worker class ArmExidxDecodeTest : public ::testing::TestWithParam<std::string> {
37*eb293b8fSAndroid Build Coastguard Worker  protected:
Init(Memory * process_memory=nullptr)38*eb293b8fSAndroid Build Coastguard Worker   void Init(Memory* process_memory = nullptr) {
39*eb293b8fSAndroid Build Coastguard Worker     if (process_memory == nullptr) {
40*eb293b8fSAndroid Build Coastguard Worker       process_memory = &process_memory_;
41*eb293b8fSAndroid Build Coastguard Worker     }
42*eb293b8fSAndroid Build Coastguard Worker 
43*eb293b8fSAndroid Build Coastguard Worker     regs_arm_.reset(new RegsArm());
44*eb293b8fSAndroid Build Coastguard Worker     for (size_t i = 0; i < regs_arm_->total_regs(); i++) {
45*eb293b8fSAndroid Build Coastguard Worker       (*regs_arm_)[i] = 0;
46*eb293b8fSAndroid Build Coastguard Worker     }
47*eb293b8fSAndroid Build Coastguard Worker     regs_arm_->set_pc(0);
48*eb293b8fSAndroid Build Coastguard Worker     regs_arm_->set_sp(0);
49*eb293b8fSAndroid Build Coastguard Worker 
50*eb293b8fSAndroid Build Coastguard Worker     exidx_.reset(new ArmExidx(regs_arm_.get(), &elf_memory_, process_memory));
51*eb293b8fSAndroid Build Coastguard Worker     if (log_ != ARM_LOG_NONE) {
52*eb293b8fSAndroid Build Coastguard Worker       exidx_->set_log(log_);
53*eb293b8fSAndroid Build Coastguard Worker       exidx_->set_log_indent(0);
54*eb293b8fSAndroid Build Coastguard Worker       exidx_->set_log_skip_execution(false);
55*eb293b8fSAndroid Build Coastguard Worker     }
56*eb293b8fSAndroid Build Coastguard Worker     data_ = exidx_->data();
57*eb293b8fSAndroid Build Coastguard Worker     exidx_->set_cfa(0x10000);
58*eb293b8fSAndroid Build Coastguard Worker   }
59*eb293b8fSAndroid Build Coastguard Worker 
SetUp()60*eb293b8fSAndroid Build Coastguard Worker   void SetUp() override {
61*eb293b8fSAndroid Build Coastguard Worker     if (GetParam() == "no_logging") {
62*eb293b8fSAndroid Build Coastguard Worker       log_ = ARM_LOG_NONE;
63*eb293b8fSAndroid Build Coastguard Worker     } else if (GetParam() == "register_logging") {
64*eb293b8fSAndroid Build Coastguard Worker       log_ = ARM_LOG_BY_REG;
65*eb293b8fSAndroid Build Coastguard Worker     } else {
66*eb293b8fSAndroid Build Coastguard Worker       log_ = ARM_LOG_FULL;
67*eb293b8fSAndroid Build Coastguard Worker     }
68*eb293b8fSAndroid Build Coastguard Worker     elf_memory_.Clear();
69*eb293b8fSAndroid Build Coastguard Worker     process_memory_.Clear();
70*eb293b8fSAndroid Build Coastguard Worker     ResetExidx();
71*eb293b8fSAndroid Build Coastguard Worker   }
72*eb293b8fSAndroid Build Coastguard Worker 
ResetExidx()73*eb293b8fSAndroid Build Coastguard Worker   void ResetExidx() {
74*eb293b8fSAndroid Build Coastguard Worker     ResetLogs();
75*eb293b8fSAndroid Build Coastguard Worker     Init();
76*eb293b8fSAndroid Build Coastguard Worker   }
77*eb293b8fSAndroid Build Coastguard Worker 
78*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<ArmExidx> exidx_;
79*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<RegsArm> regs_arm_;
80*eb293b8fSAndroid Build Coastguard Worker   std::deque<uint8_t>* data_;
81*eb293b8fSAndroid Build Coastguard Worker 
82*eb293b8fSAndroid Build Coastguard Worker   MemoryFake elf_memory_;
83*eb293b8fSAndroid Build Coastguard Worker   MemoryFake process_memory_;
84*eb293b8fSAndroid Build Coastguard Worker   ArmLogType log_;
85*eb293b8fSAndroid Build Coastguard Worker };
86*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,vsp_incr)87*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, vsp_incr) {
88*eb293b8fSAndroid Build Coastguard Worker   // 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4
89*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
90*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
91*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
92*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
93*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
94*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
95*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
96*eb293b8fSAndroid Build Coastguard Worker       break;
97*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
98*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp + 4\n", GetFakeLogPrint());
99*eb293b8fSAndroid Build Coastguard Worker       break;
100*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
101*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
102*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 + 4\n", GetFakeLogPrint());
103*eb293b8fSAndroid Build Coastguard Worker       break;
104*eb293b8fSAndroid Build Coastguard Worker   }
105*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10004U, exidx_->cfa());
106*eb293b8fSAndroid Build Coastguard Worker 
107*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
108*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
109*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x01);
110*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
111*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
112*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
113*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
114*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
115*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
116*eb293b8fSAndroid Build Coastguard Worker       break;
117*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
118*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp + 8\n", GetFakeLogPrint());
119*eb293b8fSAndroid Build Coastguard Worker       break;
120*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
121*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
122*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 + 8\n", GetFakeLogPrint());
123*eb293b8fSAndroid Build Coastguard Worker       break;
124*eb293b8fSAndroid Build Coastguard Worker   }
125*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
126*eb293b8fSAndroid Build Coastguard Worker 
127*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
128*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
129*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x3f);
130*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
131*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
132*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
133*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
134*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
135*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
136*eb293b8fSAndroid Build Coastguard Worker       break;
137*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
138*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp + 256\n", GetFakeLogPrint());
139*eb293b8fSAndroid Build Coastguard Worker       break;
140*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
141*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
142*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 + 256\n", GetFakeLogPrint());
143*eb293b8fSAndroid Build Coastguard Worker       break;
144*eb293b8fSAndroid Build Coastguard Worker   }
145*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10100U, exidx_->cfa());
146*eb293b8fSAndroid Build Coastguard Worker }
147*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,vsp_decr)148*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, vsp_decr) {
149*eb293b8fSAndroid Build Coastguard Worker   // 01xxxxxx: vsp = vsp - (xxxxxx << 2) + 4
150*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x40);
151*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
152*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
153*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
154*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
155*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
156*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
157*eb293b8fSAndroid Build Coastguard Worker       break;
158*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
159*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp - 4\n", GetFakeLogPrint());
160*eb293b8fSAndroid Build Coastguard Worker       break;
161*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
162*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
163*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 - 4\n", GetFakeLogPrint());
164*eb293b8fSAndroid Build Coastguard Worker       break;
165*eb293b8fSAndroid Build Coastguard Worker   }
166*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xfffcU, exidx_->cfa());
167*eb293b8fSAndroid Build Coastguard Worker 
168*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
169*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
170*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x41);
171*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
172*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
173*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
174*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
175*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
176*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
177*eb293b8fSAndroid Build Coastguard Worker       break;
178*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
179*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp - 8\n", GetFakeLogPrint());
180*eb293b8fSAndroid Build Coastguard Worker       break;
181*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
182*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
183*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 - 8\n", GetFakeLogPrint());
184*eb293b8fSAndroid Build Coastguard Worker       break;
185*eb293b8fSAndroid Build Coastguard Worker   }
186*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xfff8U, exidx_->cfa());
187*eb293b8fSAndroid Build Coastguard Worker 
188*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
189*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
190*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x7f);
191*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
192*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
193*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
194*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
195*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
196*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
197*eb293b8fSAndroid Build Coastguard Worker       break;
198*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
199*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp - 256\n", GetFakeLogPrint());
200*eb293b8fSAndroid Build Coastguard Worker       break;
201*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
202*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
203*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 - 256\n", GetFakeLogPrint());
204*eb293b8fSAndroid Build Coastguard Worker       break;
205*eb293b8fSAndroid Build Coastguard Worker   }
206*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xff00U, exidx_->cfa());
207*eb293b8fSAndroid Build Coastguard Worker }
208*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,refuse_unwind)209*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, refuse_unwind) {
210*eb293b8fSAndroid Build Coastguard Worker   // 10000000 00000000: Refuse to unwind
211*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x80);
212*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
213*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
214*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
215*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
216*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
217*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
218*eb293b8fSAndroid Build Coastguard Worker       break;
219*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
220*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
221*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Refuse to unwind\n", GetFakeLogPrint());
222*eb293b8fSAndroid Build Coastguard Worker       break;
223*eb293b8fSAndroid Build Coastguard Worker   }
224*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status());
225*eb293b8fSAndroid Build Coastguard Worker }
226*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_up_to_12)227*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_up_to_12) {
228*eb293b8fSAndroid Build Coastguard Worker   // 1000iiii iiiiiiii: Pop up to 12 integer registers
229*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x88);
230*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
231*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x10);
232*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
233*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->pc_set());
234*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
235*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
236*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
237*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
238*eb293b8fSAndroid Build Coastguard Worker       break;
239*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
240*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r15}\n", GetFakeLogPrint());
241*eb293b8fSAndroid Build Coastguard Worker       break;
242*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
243*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
244*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
245*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 4\n"
246*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r15 = [cfa - 4]\n",
247*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
248*eb293b8fSAndroid Build Coastguard Worker       break;
249*eb293b8fSAndroid Build Coastguard Worker   }
250*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10004U, exidx_->cfa());
251*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
252*eb293b8fSAndroid Build Coastguard Worker 
253*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
254*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x8f);
255*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xff);
256*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 12; i++) {
257*eb293b8fSAndroid Build Coastguard Worker     process_memory_.SetData32(0x10000 + i * 4, i + 0x20);
258*eb293b8fSAndroid Build Coastguard Worker   }
259*eb293b8fSAndroid Build Coastguard Worker   exidx_->set_pc_set(false);
260*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
261*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->pc_set());
262*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
263*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
264*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
265*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
266*eb293b8fSAndroid Build Coastguard Worker       break;
267*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
268*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}\n",
269*eb293b8fSAndroid Build Coastguard Worker                 GetFakeLogPrint());
270*eb293b8fSAndroid Build Coastguard Worker       break;
271*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
272*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
273*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
274*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 48\n"
275*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r4 = [cfa - 48]\n"
276*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r5 = [cfa - 44]\n"
277*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r6 = [cfa - 40]\n"
278*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r7 = [cfa - 36]\n"
279*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r8 = [cfa - 32]\n"
280*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r9 = [cfa - 28]\n"
281*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r10 = [cfa - 24]\n"
282*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r11 = [cfa - 20]\n"
283*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r12 = [cfa - 16]\n"
284*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r13 = [cfa - 12]\n"
285*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r14 = [cfa - 8]\n"
286*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r15 = [cfa - 4]\n",
287*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
288*eb293b8fSAndroid Build Coastguard Worker       break;
289*eb293b8fSAndroid Build Coastguard Worker   }
290*eb293b8fSAndroid Build Coastguard Worker   // Popping r13 results in a modified cfa.
291*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x29U, exidx_->cfa());
292*eb293b8fSAndroid Build Coastguard Worker 
293*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x20U, (*exidx_->regs())[4]);
294*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x21U, (*exidx_->regs())[5]);
295*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x22U, (*exidx_->regs())[6]);
296*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x23U, (*exidx_->regs())[7]);
297*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x24U, (*exidx_->regs())[8]);
298*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x25U, (*exidx_->regs())[9]);
299*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x26U, (*exidx_->regs())[10]);
300*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x27U, (*exidx_->regs())[11]);
301*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x28U, (*exidx_->regs())[12]);
302*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x29U, (*exidx_->regs())[13]);
303*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2aU, (*exidx_->regs())[14]);
304*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2bU, (*exidx_->regs())[15]);
305*eb293b8fSAndroid Build Coastguard Worker 
306*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
307*eb293b8fSAndroid Build Coastguard Worker   exidx_->set_cfa(0x10034);
308*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x81);
309*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x28);
310*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10034, 0x11);
311*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10038, 0x22);
312*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x1003c, 0x33);
313*eb293b8fSAndroid Build Coastguard Worker   exidx_->set_pc_set(false);
314*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
315*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
316*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
317*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
318*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
319*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
320*eb293b8fSAndroid Build Coastguard Worker       break;
321*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
322*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r7, r9, r12}\n", GetFakeLogPrint());
323*eb293b8fSAndroid Build Coastguard Worker       break;
324*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
325*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
326*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
327*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 12\n"
328*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r7 = [cfa - 12]\n"
329*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r9 = [cfa - 8]\n"
330*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r12 = [cfa - 4]\n",
331*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
332*eb293b8fSAndroid Build Coastguard Worker       break;
333*eb293b8fSAndroid Build Coastguard Worker   }
334*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10040U, exidx_->cfa());
335*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x11U, (*exidx_->regs())[7]);
336*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x22U, (*exidx_->regs())[9]);
337*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x33U, (*exidx_->regs())[12]);
338*eb293b8fSAndroid Build Coastguard Worker }
339*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,set_vsp_from_register)340*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, set_vsp_from_register) {
341*eb293b8fSAndroid Build Coastguard Worker   // 1001nnnn: Set vsp = r[nnnn] (nnnn != 13, 15)
342*eb293b8fSAndroid Build Coastguard Worker   exidx_->set_cfa(0x100);
343*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 15; i++) {
344*eb293b8fSAndroid Build Coastguard Worker     (*regs_arm_)[i] = i + 1;
345*eb293b8fSAndroid Build Coastguard Worker   }
346*eb293b8fSAndroid Build Coastguard Worker 
347*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x90);
348*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
349*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
350*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
351*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
352*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
353*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
354*eb293b8fSAndroid Build Coastguard Worker       break;
355*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
356*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = r0\n", GetFakeLogPrint());
357*eb293b8fSAndroid Build Coastguard Worker       break;
358*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
359*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
360*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r0\n", GetFakeLogPrint());
361*eb293b8fSAndroid Build Coastguard Worker       break;
362*eb293b8fSAndroid Build Coastguard Worker   }
363*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, exidx_->cfa());
364*eb293b8fSAndroid Build Coastguard Worker 
365*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
366*eb293b8fSAndroid Build Coastguard Worker   exidx_->set_cfa(0x100);
367*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 15; i++) {
368*eb293b8fSAndroid Build Coastguard Worker     (*regs_arm_)[i] = i + 1;
369*eb293b8fSAndroid Build Coastguard Worker   }
370*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x93);
371*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
372*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
373*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
374*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
375*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
376*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
377*eb293b8fSAndroid Build Coastguard Worker       break;
378*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
379*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = r3\n", GetFakeLogPrint());
380*eb293b8fSAndroid Build Coastguard Worker       break;
381*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
382*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
383*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r3\n", GetFakeLogPrint());
384*eb293b8fSAndroid Build Coastguard Worker       break;
385*eb293b8fSAndroid Build Coastguard Worker   }
386*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, exidx_->cfa());
387*eb293b8fSAndroid Build Coastguard Worker 
388*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
389*eb293b8fSAndroid Build Coastguard Worker   exidx_->set_cfa(0x100);
390*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 15; i++) {
391*eb293b8fSAndroid Build Coastguard Worker     (*regs_arm_)[i] = i + 1;
392*eb293b8fSAndroid Build Coastguard Worker   }
393*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x9e);
394*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
395*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
396*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
397*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
398*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
399*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
400*eb293b8fSAndroid Build Coastguard Worker       break;
401*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
402*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = r14\n", GetFakeLogPrint());
403*eb293b8fSAndroid Build Coastguard Worker       break;
404*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
405*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
406*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r14\n", GetFakeLogPrint());
407*eb293b8fSAndroid Build Coastguard Worker       break;
408*eb293b8fSAndroid Build Coastguard Worker   }
409*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(15U, exidx_->cfa());
410*eb293b8fSAndroid Build Coastguard Worker }
411*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,reserved_prefix)412*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, reserved_prefix) {
413*eb293b8fSAndroid Build Coastguard Worker   // 10011101: Reserved as prefix for ARM register to register moves
414*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x9d);
415*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
416*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
417*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
418*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
419*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
420*eb293b8fSAndroid Build Coastguard Worker       break;
421*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
422*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
423*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind [Reserved]\n", GetFakeLogPrint());
424*eb293b8fSAndroid Build Coastguard Worker       break;
425*eb293b8fSAndroid Build Coastguard Worker   }
426*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_RESERVED, exidx_->status());
427*eb293b8fSAndroid Build Coastguard Worker 
428*eb293b8fSAndroid Build Coastguard Worker   // 10011111: Reserved as prefix for Intel Wireless MMX register to register moves
429*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
430*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x9f);
431*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
432*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
433*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
434*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
435*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
436*eb293b8fSAndroid Build Coastguard Worker       break;
437*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
438*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
439*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind [Reserved]\n", GetFakeLogPrint());
440*eb293b8fSAndroid Build Coastguard Worker       break;
441*eb293b8fSAndroid Build Coastguard Worker   }
442*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_RESERVED, exidx_->status());
443*eb293b8fSAndroid Build Coastguard Worker }
444*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_registers)445*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_registers) {
446*eb293b8fSAndroid Build Coastguard Worker   // 10100nnn: Pop r4-r[4+nnn]
447*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xa0);
448*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x14);
449*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
450*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
451*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
452*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
453*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
454*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
455*eb293b8fSAndroid Build Coastguard Worker       break;
456*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
457*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r4}\n", GetFakeLogPrint());
458*eb293b8fSAndroid Build Coastguard Worker       break;
459*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
460*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
461*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
462*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 4\n"
463*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r4 = [cfa - 4]\n",
464*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
465*eb293b8fSAndroid Build Coastguard Worker       break;
466*eb293b8fSAndroid Build Coastguard Worker   }
467*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10004U, exidx_->cfa());
468*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x14U, (*exidx_->regs())[4]);
469*eb293b8fSAndroid Build Coastguard Worker 
470*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
471*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xa3);
472*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x20);
473*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10004, 0x30);
474*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10008, 0x40);
475*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x1000c, 0x50);
476*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
477*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
478*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
479*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
480*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
481*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
482*eb293b8fSAndroid Build Coastguard Worker       break;
483*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
484*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r4-r7}\n", GetFakeLogPrint());
485*eb293b8fSAndroid Build Coastguard Worker       break;
486*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
487*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
488*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
489*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 16\n"
490*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r4 = [cfa - 16]\n"
491*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r5 = [cfa - 12]\n"
492*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r6 = [cfa - 8]\n"
493*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r7 = [cfa - 4]\n",
494*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
495*eb293b8fSAndroid Build Coastguard Worker       break;
496*eb293b8fSAndroid Build Coastguard Worker   }
497*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10010U, exidx_->cfa());
498*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x20U, (*exidx_->regs())[4]);
499*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x30U, (*exidx_->regs())[5]);
500*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x40U, (*exidx_->regs())[6]);
501*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x50U, (*exidx_->regs())[7]);
502*eb293b8fSAndroid Build Coastguard Worker 
503*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
504*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xa7);
505*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x41);
506*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10004, 0x51);
507*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10008, 0x61);
508*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x1000c, 0x71);
509*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10010, 0x81);
510*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10014, 0x91);
511*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10018, 0xa1);
512*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x1001c, 0xb1);
513*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
514*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
515*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
516*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
517*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
518*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
519*eb293b8fSAndroid Build Coastguard Worker       break;
520*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
521*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r4-r11}\n", GetFakeLogPrint());
522*eb293b8fSAndroid Build Coastguard Worker       break;
523*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
524*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
525*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
526*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 32\n"
527*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r4 = [cfa - 32]\n"
528*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r5 = [cfa - 28]\n"
529*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r6 = [cfa - 24]\n"
530*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r7 = [cfa - 20]\n"
531*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r8 = [cfa - 16]\n"
532*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r9 = [cfa - 12]\n"
533*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r10 = [cfa - 8]\n"
534*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r11 = [cfa - 4]\n",
535*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
536*eb293b8fSAndroid Build Coastguard Worker       break;
537*eb293b8fSAndroid Build Coastguard Worker   }
538*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10020U, exidx_->cfa());
539*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x41U, (*exidx_->regs())[4]);
540*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x51U, (*exidx_->regs())[5]);
541*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x61U, (*exidx_->regs())[6]);
542*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x71U, (*exidx_->regs())[7]);
543*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x81U, (*exidx_->regs())[8]);
544*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x91U, (*exidx_->regs())[9]);
545*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xa1U, (*exidx_->regs())[10]);
546*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xb1U, (*exidx_->regs())[11]);
547*eb293b8fSAndroid Build Coastguard Worker }
548*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_registers_with_r14)549*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_registers_with_r14) {
550*eb293b8fSAndroid Build Coastguard Worker   // 10101nnn: Pop r4-r[4+nnn], r14
551*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xa8);
552*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x12);
553*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10004, 0x22);
554*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
555*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
556*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
557*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
558*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
559*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
560*eb293b8fSAndroid Build Coastguard Worker       break;
561*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
562*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r4, r14}\n", GetFakeLogPrint());
563*eb293b8fSAndroid Build Coastguard Worker       break;
564*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
565*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
566*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
567*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 8\n"
568*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r4 = [cfa - 8]\n"
569*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r14 = [cfa - 4]\n",
570*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
571*eb293b8fSAndroid Build Coastguard Worker       break;
572*eb293b8fSAndroid Build Coastguard Worker   }
573*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
574*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x12U, (*exidx_->regs())[4]);
575*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x22U, (*exidx_->regs())[14]);
576*eb293b8fSAndroid Build Coastguard Worker 
577*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
578*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xab);
579*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x1);
580*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10004, 0x2);
581*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10008, 0x3);
582*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x1000c, 0x4);
583*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10010, 0x5);
584*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
585*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
586*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
587*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
588*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
589*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
590*eb293b8fSAndroid Build Coastguard Worker       break;
591*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
592*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r4-r7, r14}\n", GetFakeLogPrint());
593*eb293b8fSAndroid Build Coastguard Worker       break;
594*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
595*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
596*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
597*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 20\n"
598*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r4 = [cfa - 20]\n"
599*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r5 = [cfa - 16]\n"
600*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r6 = [cfa - 12]\n"
601*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r7 = [cfa - 8]\n"
602*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r14 = [cfa - 4]\n",
603*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
604*eb293b8fSAndroid Build Coastguard Worker       break;
605*eb293b8fSAndroid Build Coastguard Worker   }
606*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10014U, exidx_->cfa());
607*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1U, (*exidx_->regs())[4]);
608*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2U, (*exidx_->regs())[5]);
609*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x3U, (*exidx_->regs())[6]);
610*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x4U, (*exidx_->regs())[7]);
611*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x5U, (*exidx_->regs())[14]);
612*eb293b8fSAndroid Build Coastguard Worker 
613*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
614*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xaf);
615*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x1a);
616*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10004, 0x2a);
617*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10008, 0x3a);
618*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x1000c, 0x4a);
619*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10010, 0x5a);
620*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10014, 0x6a);
621*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10018, 0x7a);
622*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x1001c, 0x8a);
623*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10020, 0x9a);
624*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
625*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
626*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
627*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
628*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
629*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
630*eb293b8fSAndroid Build Coastguard Worker       break;
631*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
632*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r4-r11, r14}\n", GetFakeLogPrint());
633*eb293b8fSAndroid Build Coastguard Worker       break;
634*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
635*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
636*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
637*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 36\n"
638*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r4 = [cfa - 36]\n"
639*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r5 = [cfa - 32]\n"
640*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r6 = [cfa - 28]\n"
641*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r7 = [cfa - 24]\n"
642*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r8 = [cfa - 20]\n"
643*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r9 = [cfa - 16]\n"
644*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r10 = [cfa - 12]\n"
645*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r11 = [cfa - 8]\n"
646*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r14 = [cfa - 4]\n",
647*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
648*eb293b8fSAndroid Build Coastguard Worker       break;
649*eb293b8fSAndroid Build Coastguard Worker   }
650*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10024U, exidx_->cfa());
651*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1aU, (*exidx_->regs())[4]);
652*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2aU, (*exidx_->regs())[5]);
653*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x3aU, (*exidx_->regs())[6]);
654*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x4aU, (*exidx_->regs())[7]);
655*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x5aU, (*exidx_->regs())[8]);
656*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x6aU, (*exidx_->regs())[9]);
657*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x7aU, (*exidx_->regs())[10]);
658*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x8aU, (*exidx_->regs())[11]);
659*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x9aU, (*exidx_->regs())[14]);
660*eb293b8fSAndroid Build Coastguard Worker }
661*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,finish)662*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, finish) {
663*eb293b8fSAndroid Build Coastguard Worker   // 10110000: Finish
664*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb0);
665*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
666*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
667*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
668*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
669*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
670*eb293b8fSAndroid Build Coastguard Worker       break;
671*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
672*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind finish\n", GetFakeLogPrint());
673*eb293b8fSAndroid Build Coastguard Worker       break;
674*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
675*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
676*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13\n", GetFakeLogPrint());
677*eb293b8fSAndroid Build Coastguard Worker       break;
678*eb293b8fSAndroid Build Coastguard Worker   }
679*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10000U, exidx_->cfa());
680*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_FINISH, exidx_->status());
681*eb293b8fSAndroid Build Coastguard Worker }
682*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,spare)683*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, spare) {
684*eb293b8fSAndroid Build Coastguard Worker   // 10110001 00000000: Spare
685*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb1);
686*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
687*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
688*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
689*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
690*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
691*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
692*eb293b8fSAndroid Build Coastguard Worker       break;
693*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
694*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
695*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint());
696*eb293b8fSAndroid Build Coastguard Worker       break;
697*eb293b8fSAndroid Build Coastguard Worker   }
698*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10000U, exidx_->cfa());
699*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
700*eb293b8fSAndroid Build Coastguard Worker 
701*eb293b8fSAndroid Build Coastguard Worker   // 10110001 xxxxyyyy: Spare (xxxx != 0000)
702*eb293b8fSAndroid Build Coastguard Worker   for (size_t x = 1; x < 16; x++) {
703*eb293b8fSAndroid Build Coastguard Worker     for (size_t y = 0; y < 16; y++) {
704*eb293b8fSAndroid Build Coastguard Worker       ResetExidx();
705*eb293b8fSAndroid Build Coastguard Worker       data_->push_back(0xb1);
706*eb293b8fSAndroid Build Coastguard Worker       data_->push_back((x << 4) | y);
707*eb293b8fSAndroid Build Coastguard Worker       ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
708*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
709*eb293b8fSAndroid Build Coastguard Worker       switch (log_) {
710*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_NONE:
711*eb293b8fSAndroid Build Coastguard Worker           ASSERT_EQ("", GetFakeLogPrint());
712*eb293b8fSAndroid Build Coastguard Worker           break;
713*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_FULL:
714*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_BY_REG:
715*eb293b8fSAndroid Build Coastguard Worker           ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
716*eb293b8fSAndroid Build Coastguard Worker           break;
717*eb293b8fSAndroid Build Coastguard Worker       }
718*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
719*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
720*eb293b8fSAndroid Build Coastguard Worker     }
721*eb293b8fSAndroid Build Coastguard Worker   }
722*eb293b8fSAndroid Build Coastguard Worker 
723*eb293b8fSAndroid Build Coastguard Worker   // 101101nn: Spare
724*eb293b8fSAndroid Build Coastguard Worker   for (size_t n = 0; n < 4; n++) {
725*eb293b8fSAndroid Build Coastguard Worker     ResetExidx();
726*eb293b8fSAndroid Build Coastguard Worker     data_->push_back(0xb4 | n);
727*eb293b8fSAndroid Build Coastguard Worker     ASSERT_FALSE(exidx_->Decode()) << "n = " << n;
728*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ("", GetFakeLogBuf()) << "n = " << n;
729*eb293b8fSAndroid Build Coastguard Worker     switch (log_) {
730*eb293b8fSAndroid Build Coastguard Worker       case ARM_LOG_NONE:
731*eb293b8fSAndroid Build Coastguard Worker         ASSERT_EQ("", GetFakeLogPrint());
732*eb293b8fSAndroid Build Coastguard Worker         break;
733*eb293b8fSAndroid Build Coastguard Worker       case ARM_LOG_FULL:
734*eb293b8fSAndroid Build Coastguard Worker       case ARM_LOG_BY_REG:
735*eb293b8fSAndroid Build Coastguard Worker         ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "n = " << n;
736*eb293b8fSAndroid Build Coastguard Worker         break;
737*eb293b8fSAndroid Build Coastguard Worker     }
738*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x10000U, exidx_->cfa()) << "n = " << n;
739*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
740*eb293b8fSAndroid Build Coastguard Worker   }
741*eb293b8fSAndroid Build Coastguard Worker 
742*eb293b8fSAndroid Build Coastguard Worker   // 11000111 00000000: Spare
743*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
744*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc7);
745*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
746*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
747*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
748*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
749*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
750*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
751*eb293b8fSAndroid Build Coastguard Worker       break;
752*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
753*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
754*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint());
755*eb293b8fSAndroid Build Coastguard Worker       break;
756*eb293b8fSAndroid Build Coastguard Worker   }
757*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10000U, exidx_->cfa());
758*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
759*eb293b8fSAndroid Build Coastguard Worker 
760*eb293b8fSAndroid Build Coastguard Worker   // 11000111 xxxxyyyy: Spare (xxxx != 0000)
761*eb293b8fSAndroid Build Coastguard Worker   for (size_t x = 1; x < 16; x++) {
762*eb293b8fSAndroid Build Coastguard Worker     for (size_t y = 0; y < 16; y++) {
763*eb293b8fSAndroid Build Coastguard Worker       ResetExidx();
764*eb293b8fSAndroid Build Coastguard Worker       data_->push_back(0xc7);
765*eb293b8fSAndroid Build Coastguard Worker       data_->push_back(0x10);
766*eb293b8fSAndroid Build Coastguard Worker       ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
767*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
768*eb293b8fSAndroid Build Coastguard Worker       switch (log_) {
769*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_NONE:
770*eb293b8fSAndroid Build Coastguard Worker           ASSERT_EQ("", GetFakeLogPrint());
771*eb293b8fSAndroid Build Coastguard Worker           break;
772*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_FULL:
773*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_BY_REG:
774*eb293b8fSAndroid Build Coastguard Worker           ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
775*eb293b8fSAndroid Build Coastguard Worker           break;
776*eb293b8fSAndroid Build Coastguard Worker       }
777*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
778*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
779*eb293b8fSAndroid Build Coastguard Worker     }
780*eb293b8fSAndroid Build Coastguard Worker   }
781*eb293b8fSAndroid Build Coastguard Worker 
782*eb293b8fSAndroid Build Coastguard Worker   // 11001yyy: Spare (yyy != 000, 001)
783*eb293b8fSAndroid Build Coastguard Worker   for (size_t y = 2; y < 8; y++) {
784*eb293b8fSAndroid Build Coastguard Worker     ResetExidx();
785*eb293b8fSAndroid Build Coastguard Worker     data_->push_back(0xc8 | y);
786*eb293b8fSAndroid Build Coastguard Worker     ASSERT_FALSE(exidx_->Decode()) << "y = " << y;
787*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ("", GetFakeLogBuf()) << "y = " << y;
788*eb293b8fSAndroid Build Coastguard Worker     switch (log_) {
789*eb293b8fSAndroid Build Coastguard Worker       case ARM_LOG_NONE:
790*eb293b8fSAndroid Build Coastguard Worker         ASSERT_EQ("", GetFakeLogPrint());
791*eb293b8fSAndroid Build Coastguard Worker         break;
792*eb293b8fSAndroid Build Coastguard Worker       case ARM_LOG_FULL:
793*eb293b8fSAndroid Build Coastguard Worker       case ARM_LOG_BY_REG:
794*eb293b8fSAndroid Build Coastguard Worker         ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "y = " << y;
795*eb293b8fSAndroid Build Coastguard Worker         break;
796*eb293b8fSAndroid Build Coastguard Worker     }
797*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x10000U, exidx_->cfa()) << "y = " << y;
798*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
799*eb293b8fSAndroid Build Coastguard Worker   }
800*eb293b8fSAndroid Build Coastguard Worker 
801*eb293b8fSAndroid Build Coastguard Worker   // 11xxxyyy: Spare (xxx != 000, 001, 010)
802*eb293b8fSAndroid Build Coastguard Worker   for (size_t x = 3; x < 8; x++) {
803*eb293b8fSAndroid Build Coastguard Worker     for (size_t y = 0; y < 8; y++) {
804*eb293b8fSAndroid Build Coastguard Worker       ResetExidx();
805*eb293b8fSAndroid Build Coastguard Worker       data_->push_back(0xc0 | (x << 3) | y);
806*eb293b8fSAndroid Build Coastguard Worker       ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
807*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
808*eb293b8fSAndroid Build Coastguard Worker       switch (log_) {
809*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_NONE:
810*eb293b8fSAndroid Build Coastguard Worker           ASSERT_EQ("", GetFakeLogPrint());
811*eb293b8fSAndroid Build Coastguard Worker           break;
812*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_FULL:
813*eb293b8fSAndroid Build Coastguard Worker         case ARM_LOG_BY_REG:
814*eb293b8fSAndroid Build Coastguard Worker           ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
815*eb293b8fSAndroid Build Coastguard Worker           break;
816*eb293b8fSAndroid Build Coastguard Worker       }
817*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
818*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
819*eb293b8fSAndroid Build Coastguard Worker     }
820*eb293b8fSAndroid Build Coastguard Worker   }
821*eb293b8fSAndroid Build Coastguard Worker }
822*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_registers_under_mask)823*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_registers_under_mask) {
824*eb293b8fSAndroid Build Coastguard Worker   // 10110001 0000iiii: Pop integer registers {r0, r1, r2, r3}
825*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb1);
826*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x01);
827*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x45);
828*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
829*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
830*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
831*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
832*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
833*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
834*eb293b8fSAndroid Build Coastguard Worker       break;
835*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
836*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r0}\n", GetFakeLogPrint());
837*eb293b8fSAndroid Build Coastguard Worker       break;
838*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
839*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
840*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
841*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 4\n"
842*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r0 = [cfa - 4]\n",
843*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
844*eb293b8fSAndroid Build Coastguard Worker       break;
845*eb293b8fSAndroid Build Coastguard Worker   }
846*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10004U, exidx_->cfa());
847*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x45U, (*exidx_->regs())[0]);
848*eb293b8fSAndroid Build Coastguard Worker 
849*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
850*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb1);
851*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x0a);
852*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x23);
853*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10004, 0x24);
854*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
855*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
856*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
857*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
858*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
859*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
860*eb293b8fSAndroid Build Coastguard Worker       break;
861*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
862*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r1, r3}\n", GetFakeLogPrint());
863*eb293b8fSAndroid Build Coastguard Worker       break;
864*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
865*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
866*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
867*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 8\n"
868*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r1 = [cfa - 8]\n"
869*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r3 = [cfa - 4]\n",
870*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
871*eb293b8fSAndroid Build Coastguard Worker       break;
872*eb293b8fSAndroid Build Coastguard Worker   }
873*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
874*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x23U, (*exidx_->regs())[1]);
875*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x24U, (*exidx_->regs())[3]);
876*eb293b8fSAndroid Build Coastguard Worker 
877*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
878*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb1);
879*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x0f);
880*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x65);
881*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10004, 0x54);
882*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10008, 0x43);
883*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x1000c, 0x32);
884*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
885*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
886*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
887*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
888*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
889*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
890*eb293b8fSAndroid Build Coastguard Worker       break;
891*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
892*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {r0, r1, r2, r3}\n", GetFakeLogPrint());
893*eb293b8fSAndroid Build Coastguard Worker       break;
894*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
895*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
896*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
897*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 16\n"
898*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r0 = [cfa - 16]\n"
899*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r1 = [cfa - 12]\n"
900*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r2 = [cfa - 8]\n"
901*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r3 = [cfa - 4]\n",
902*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
903*eb293b8fSAndroid Build Coastguard Worker       break;
904*eb293b8fSAndroid Build Coastguard Worker   }
905*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10010U, exidx_->cfa());
906*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x65U, (*exidx_->regs())[0]);
907*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x54U, (*exidx_->regs())[1]);
908*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x43U, (*exidx_->regs())[2]);
909*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x32U, (*exidx_->regs())[3]);
910*eb293b8fSAndroid Build Coastguard Worker }
911*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,vsp_large_incr)912*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, vsp_large_incr) {
913*eb293b8fSAndroid Build Coastguard Worker   // 10110010 uleb128: vsp = vsp + 0x204 + (uleb128 << 2)
914*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb2);
915*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x7f);
916*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
917*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
918*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
919*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
920*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
921*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
922*eb293b8fSAndroid Build Coastguard Worker       break;
923*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
924*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp + 1024\n", GetFakeLogPrint());
925*eb293b8fSAndroid Build Coastguard Worker       break;
926*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
927*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
928*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 + 1024\n", GetFakeLogPrint());
929*eb293b8fSAndroid Build Coastguard Worker       break;
930*eb293b8fSAndroid Build Coastguard Worker   }
931*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10400U, exidx_->cfa());
932*eb293b8fSAndroid Build Coastguard Worker 
933*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
934*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb2);
935*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xff);
936*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x02);
937*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
938*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
939*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
940*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
941*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
942*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
943*eb293b8fSAndroid Build Coastguard Worker       break;
944*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
945*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp + 2048\n", GetFakeLogPrint());
946*eb293b8fSAndroid Build Coastguard Worker       break;
947*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
948*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
949*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 + 2048\n", GetFakeLogPrint());
950*eb293b8fSAndroid Build Coastguard Worker       break;
951*eb293b8fSAndroid Build Coastguard Worker   }
952*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10800U, exidx_->cfa());
953*eb293b8fSAndroid Build Coastguard Worker 
954*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
955*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb2);
956*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xff);
957*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x82);
958*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x30);
959*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
960*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
961*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
962*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
963*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
964*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
965*eb293b8fSAndroid Build Coastguard Worker       break;
966*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
967*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind vsp = vsp + 3147776\n", GetFakeLogPrint());
968*eb293b8fSAndroid Build Coastguard Worker       break;
969*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
970*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
971*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 + 3147776\n", GetFakeLogPrint());
972*eb293b8fSAndroid Build Coastguard Worker       break;
973*eb293b8fSAndroid Build Coastguard Worker   }
974*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x310800U, exidx_->cfa());
975*eb293b8fSAndroid Build Coastguard Worker }
976*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_vfp_fstmfdx)977*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_vfp_fstmfdx) {
978*eb293b8fSAndroid Build Coastguard Worker   // 10110011 sssscccc: Pop VFP double precision registers D[ssss]-D[ssss+cccc] by FSTMFDX
979*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb3);
980*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
981*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
982*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
983*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
984*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
985*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
986*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
987*eb293b8fSAndroid Build Coastguard Worker       break;
988*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
989*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint());
990*eb293b8fSAndroid Build Coastguard Worker       break;
991*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
992*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
993*eb293b8fSAndroid Build Coastguard Worker       break;
994*eb293b8fSAndroid Build Coastguard Worker   }
995*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1000cU, exidx_->cfa());
996*eb293b8fSAndroid Build Coastguard Worker 
997*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
998*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb3);
999*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x48);
1000*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1001*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1002*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1003*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1004*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1005*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1006*eb293b8fSAndroid Build Coastguard Worker       break;
1007*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1008*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d4-d12}\n", GetFakeLogPrint());
1009*eb293b8fSAndroid Build Coastguard Worker       break;
1010*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1011*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1012*eb293b8fSAndroid Build Coastguard Worker       break;
1013*eb293b8fSAndroid Build Coastguard Worker   }
1014*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1004cU, exidx_->cfa());
1015*eb293b8fSAndroid Build Coastguard Worker }
1016*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_vfp8_fstmfdx)1017*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_vfp8_fstmfdx) {
1018*eb293b8fSAndroid Build Coastguard Worker   // 10111nnn: Pop VFP double precision registers D[8]-D[8+nnn] by FSTMFDX
1019*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb8);
1020*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1021*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1022*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1023*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1024*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1025*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1026*eb293b8fSAndroid Build Coastguard Worker       break;
1027*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1028*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint());
1029*eb293b8fSAndroid Build Coastguard Worker       break;
1030*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1031*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1032*eb293b8fSAndroid Build Coastguard Worker       break;
1033*eb293b8fSAndroid Build Coastguard Worker   }
1034*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1000cU, exidx_->cfa());
1035*eb293b8fSAndroid Build Coastguard Worker 
1036*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1037*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xbb);
1038*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1039*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1040*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1041*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1042*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1043*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1044*eb293b8fSAndroid Build Coastguard Worker       break;
1045*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1046*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d8-d11}\n", GetFakeLogPrint());
1047*eb293b8fSAndroid Build Coastguard Worker       break;
1048*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1049*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1050*eb293b8fSAndroid Build Coastguard Worker       break;
1051*eb293b8fSAndroid Build Coastguard Worker   }
1052*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10024U, exidx_->cfa());
1053*eb293b8fSAndroid Build Coastguard Worker 
1054*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1055*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xbf);
1056*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1057*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1058*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1059*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1060*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1061*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1062*eb293b8fSAndroid Build Coastguard Worker       break;
1063*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1064*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint());
1065*eb293b8fSAndroid Build Coastguard Worker       break;
1066*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1067*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1068*eb293b8fSAndroid Build Coastguard Worker       break;
1069*eb293b8fSAndroid Build Coastguard Worker   }
1070*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10044U, exidx_->cfa());
1071*eb293b8fSAndroid Build Coastguard Worker }
1072*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_mmx_wr10)1073*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_mmx_wr10) {
1074*eb293b8fSAndroid Build Coastguard Worker   // 11000nnn: Intel Wireless MMX pop wR[10]-wR[10+nnn] (nnn != 6, 7)
1075*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc0);
1076*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1077*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1078*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1079*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1080*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1081*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1082*eb293b8fSAndroid Build Coastguard Worker       break;
1083*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1084*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wR10}\n", GetFakeLogPrint());
1085*eb293b8fSAndroid Build Coastguard Worker       break;
1086*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1087*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1088*eb293b8fSAndroid Build Coastguard Worker       break;
1089*eb293b8fSAndroid Build Coastguard Worker   }
1090*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
1091*eb293b8fSAndroid Build Coastguard Worker 
1092*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1093*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc2);
1094*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1095*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1096*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1097*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1098*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1099*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1100*eb293b8fSAndroid Build Coastguard Worker       break;
1101*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1102*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wR10-wR12}\n", GetFakeLogPrint());
1103*eb293b8fSAndroid Build Coastguard Worker       break;
1104*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1105*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1106*eb293b8fSAndroid Build Coastguard Worker       break;
1107*eb293b8fSAndroid Build Coastguard Worker   }
1108*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10018U, exidx_->cfa());
1109*eb293b8fSAndroid Build Coastguard Worker 
1110*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1111*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc5);
1112*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1113*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1114*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1115*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1116*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1117*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1118*eb293b8fSAndroid Build Coastguard Worker       break;
1119*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1120*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wR10-wR15}\n", GetFakeLogPrint());
1121*eb293b8fSAndroid Build Coastguard Worker       break;
1122*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1123*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1124*eb293b8fSAndroid Build Coastguard Worker       break;
1125*eb293b8fSAndroid Build Coastguard Worker   }
1126*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10030U, exidx_->cfa());
1127*eb293b8fSAndroid Build Coastguard Worker }
1128*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_mmx_wr)1129*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_mmx_wr) {
1130*eb293b8fSAndroid Build Coastguard Worker   // 11000110 sssscccc: Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc]
1131*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc6);
1132*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1133*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1134*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1135*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1136*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1137*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1138*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1139*eb293b8fSAndroid Build Coastguard Worker       break;
1140*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1141*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wR0}\n", GetFakeLogPrint());
1142*eb293b8fSAndroid Build Coastguard Worker       break;
1143*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1144*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1145*eb293b8fSAndroid Build Coastguard Worker       break;
1146*eb293b8fSAndroid Build Coastguard Worker   }
1147*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
1148*eb293b8fSAndroid Build Coastguard Worker 
1149*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1150*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc6);
1151*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x25);
1152*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1153*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1154*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1155*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1156*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1157*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1158*eb293b8fSAndroid Build Coastguard Worker       break;
1159*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1160*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wR2-wR7}\n", GetFakeLogPrint());
1161*eb293b8fSAndroid Build Coastguard Worker       break;
1162*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1163*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1164*eb293b8fSAndroid Build Coastguard Worker       break;
1165*eb293b8fSAndroid Build Coastguard Worker   }
1166*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10030U, exidx_->cfa());
1167*eb293b8fSAndroid Build Coastguard Worker 
1168*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1169*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc6);
1170*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xff);
1171*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1172*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1173*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1174*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1175*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1176*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1177*eb293b8fSAndroid Build Coastguard Worker       break;
1178*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1179*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wR15-wR30}\n", GetFakeLogPrint());
1180*eb293b8fSAndroid Build Coastguard Worker       break;
1181*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1182*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wRX register display\n", GetFakeLogPrint());
1183*eb293b8fSAndroid Build Coastguard Worker       break;
1184*eb293b8fSAndroid Build Coastguard Worker   }
1185*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10080U, exidx_->cfa());
1186*eb293b8fSAndroid Build Coastguard Worker }
1187*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_mmx_wcgr)1188*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_mmx_wcgr) {
1189*eb293b8fSAndroid Build Coastguard Worker   // 11000111 0000iiii: Intel Wireless MMX pop wCGR registes {wCGR0,1,2,3}
1190*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc7);
1191*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x01);
1192*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1193*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1194*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1195*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1196*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1197*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1198*eb293b8fSAndroid Build Coastguard Worker       break;
1199*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1200*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wCGR0}\n", GetFakeLogPrint());
1201*eb293b8fSAndroid Build Coastguard Worker       break;
1202*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1203*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wCGR register display\n", GetFakeLogPrint());
1204*eb293b8fSAndroid Build Coastguard Worker       break;
1205*eb293b8fSAndroid Build Coastguard Worker   }
1206*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10004U, exidx_->cfa());
1207*eb293b8fSAndroid Build Coastguard Worker 
1208*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1209*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc7);
1210*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x0a);
1211*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1212*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1213*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1214*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1215*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1216*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1217*eb293b8fSAndroid Build Coastguard Worker       break;
1218*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1219*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wCGR1, wCGR3}\n", GetFakeLogPrint());
1220*eb293b8fSAndroid Build Coastguard Worker       break;
1221*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1222*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wCGR register display\n", GetFakeLogPrint());
1223*eb293b8fSAndroid Build Coastguard Worker       break;
1224*eb293b8fSAndroid Build Coastguard Worker   }
1225*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
1226*eb293b8fSAndroid Build Coastguard Worker 
1227*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1228*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc7);
1229*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x0f);
1230*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1231*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1232*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1233*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1234*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1235*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1236*eb293b8fSAndroid Build Coastguard Worker       break;
1237*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1238*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {wCGR0, wCGR1, wCGR2, wCGR3}\n", GetFakeLogPrint());
1239*eb293b8fSAndroid Build Coastguard Worker       break;
1240*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1241*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported wCGR register display\n", GetFakeLogPrint());
1242*eb293b8fSAndroid Build Coastguard Worker       break;
1243*eb293b8fSAndroid Build Coastguard Worker   }
1244*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10010U, exidx_->cfa());
1245*eb293b8fSAndroid Build Coastguard Worker }
1246*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_vfp16_vpush)1247*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_vfp16_vpush) {
1248*eb293b8fSAndroid Build Coastguard Worker   // 11001000 sssscccc: Pop VFP double precision registers d[16+ssss]-D[16+ssss+cccc] by VPUSH
1249*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc8);
1250*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1251*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1252*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1253*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1254*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1255*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1256*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1257*eb293b8fSAndroid Build Coastguard Worker       break;
1258*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1259*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d16}\n", GetFakeLogPrint());
1260*eb293b8fSAndroid Build Coastguard Worker       break;
1261*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1262*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1263*eb293b8fSAndroid Build Coastguard Worker       break;
1264*eb293b8fSAndroid Build Coastguard Worker   }
1265*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
1266*eb293b8fSAndroid Build Coastguard Worker 
1267*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1268*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc8);
1269*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x14);
1270*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1271*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1272*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1273*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1274*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1275*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1276*eb293b8fSAndroid Build Coastguard Worker       break;
1277*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1278*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d17-d21}\n", GetFakeLogPrint());
1279*eb293b8fSAndroid Build Coastguard Worker       break;
1280*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1281*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1282*eb293b8fSAndroid Build Coastguard Worker       break;
1283*eb293b8fSAndroid Build Coastguard Worker   }
1284*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10028U, exidx_->cfa());
1285*eb293b8fSAndroid Build Coastguard Worker 
1286*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1287*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc8);
1288*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xff);
1289*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1290*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1291*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1292*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1293*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1294*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1295*eb293b8fSAndroid Build Coastguard Worker       break;
1296*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1297*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d31-d46}\n", GetFakeLogPrint());
1298*eb293b8fSAndroid Build Coastguard Worker       break;
1299*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1300*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1301*eb293b8fSAndroid Build Coastguard Worker       break;
1302*eb293b8fSAndroid Build Coastguard Worker   }
1303*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10080U, exidx_->cfa());
1304*eb293b8fSAndroid Build Coastguard Worker }
1305*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_vfp_vpush)1306*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_vfp_vpush) {
1307*eb293b8fSAndroid Build Coastguard Worker   // 11001001 sssscccc: Pop VFP double precision registers d[ssss]-D[ssss+cccc] by VPUSH
1308*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc9);
1309*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1310*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1311*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1312*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1313*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1314*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1315*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1316*eb293b8fSAndroid Build Coastguard Worker       break;
1317*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1318*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint());
1319*eb293b8fSAndroid Build Coastguard Worker       break;
1320*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1321*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1322*eb293b8fSAndroid Build Coastguard Worker       break;
1323*eb293b8fSAndroid Build Coastguard Worker   }
1324*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
1325*eb293b8fSAndroid Build Coastguard Worker 
1326*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1327*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc9);
1328*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x23);
1329*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1330*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1331*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1332*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1333*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1334*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1335*eb293b8fSAndroid Build Coastguard Worker       break;
1336*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1337*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d2-d5}\n", GetFakeLogPrint());
1338*eb293b8fSAndroid Build Coastguard Worker       break;
1339*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1340*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1341*eb293b8fSAndroid Build Coastguard Worker       break;
1342*eb293b8fSAndroid Build Coastguard Worker   }
1343*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10020U, exidx_->cfa());
1344*eb293b8fSAndroid Build Coastguard Worker 
1345*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1346*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc9);
1347*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xff);
1348*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1349*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1350*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1351*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1352*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1353*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1354*eb293b8fSAndroid Build Coastguard Worker       break;
1355*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1356*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d15-d30}\n", GetFakeLogPrint());
1357*eb293b8fSAndroid Build Coastguard Worker       break;
1358*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1359*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1360*eb293b8fSAndroid Build Coastguard Worker       break;
1361*eb293b8fSAndroid Build Coastguard Worker   }
1362*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10080U, exidx_->cfa());
1363*eb293b8fSAndroid Build Coastguard Worker }
1364*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,pop_vfp8_vpush)1365*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, pop_vfp8_vpush) {
1366*eb293b8fSAndroid Build Coastguard Worker   // 11010nnn: Pop VFP double precision registers D[8]-D[8+nnn] by VPUSH
1367*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xd0);
1368*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1369*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1370*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1371*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1372*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1373*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1374*eb293b8fSAndroid Build Coastguard Worker       break;
1375*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1376*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint());
1377*eb293b8fSAndroid Build Coastguard Worker       break;
1378*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1379*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1380*eb293b8fSAndroid Build Coastguard Worker       break;
1381*eb293b8fSAndroid Build Coastguard Worker   }
1382*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10008U, exidx_->cfa());
1383*eb293b8fSAndroid Build Coastguard Worker 
1384*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1385*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xd2);
1386*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1387*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1388*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1389*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1390*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1391*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1392*eb293b8fSAndroid Build Coastguard Worker       break;
1393*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1394*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d8-d10}\n", GetFakeLogPrint());
1395*eb293b8fSAndroid Build Coastguard Worker       break;
1396*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1397*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1398*eb293b8fSAndroid Build Coastguard Worker       break;
1399*eb293b8fSAndroid Build Coastguard Worker   }
1400*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10018U, exidx_->cfa());
1401*eb293b8fSAndroid Build Coastguard Worker 
1402*eb293b8fSAndroid Build Coastguard Worker   ResetExidx();
1403*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xd7);
1404*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Decode());
1405*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1406*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("", GetFakeLogBuf());
1407*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1408*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1409*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1410*eb293b8fSAndroid Build Coastguard Worker       break;
1411*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1412*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint());
1413*eb293b8fSAndroid Build Coastguard Worker       break;
1414*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1415*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind Unsupported DX register display\n", GetFakeLogPrint());
1416*eb293b8fSAndroid Build Coastguard Worker       break;
1417*eb293b8fSAndroid Build Coastguard Worker   }
1418*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10040U, exidx_->cfa());
1419*eb293b8fSAndroid Build Coastguard Worker }
1420*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,expect_truncated)1421*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, expect_truncated) {
1422*eb293b8fSAndroid Build Coastguard Worker   // This test verifies that any op that requires extra ops will
1423*eb293b8fSAndroid Build Coastguard Worker   // fail if the data is not present.
1424*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x80);
1425*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
1426*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1427*eb293b8fSAndroid Build Coastguard Worker 
1428*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
1429*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb1);
1430*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
1431*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1432*eb293b8fSAndroid Build Coastguard Worker 
1433*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
1434*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb2);
1435*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
1436*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1437*eb293b8fSAndroid Build Coastguard Worker 
1438*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
1439*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb3);
1440*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
1441*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1442*eb293b8fSAndroid Build Coastguard Worker 
1443*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
1444*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc6);
1445*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
1446*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1447*eb293b8fSAndroid Build Coastguard Worker 
1448*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
1449*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc7);
1450*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
1451*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1452*eb293b8fSAndroid Build Coastguard Worker 
1453*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
1454*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc8);
1455*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
1456*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1457*eb293b8fSAndroid Build Coastguard Worker 
1458*eb293b8fSAndroid Build Coastguard Worker   data_->clear();
1459*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xc9);
1460*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->Decode());
1461*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1462*eb293b8fSAndroid Build Coastguard Worker }
1463*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,verify_no_truncated)1464*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, verify_no_truncated) {
1465*eb293b8fSAndroid Build Coastguard Worker   // This test verifies that no pattern results in a crash or truncation.
1466*eb293b8fSAndroid Build Coastguard Worker   MemoryFakeAlwaysReadZero memory_zero;
1467*eb293b8fSAndroid Build Coastguard Worker   Init(&memory_zero);
1468*eb293b8fSAndroid Build Coastguard Worker 
1469*eb293b8fSAndroid Build Coastguard Worker   for (size_t x = 0; x < 256; x++) {
1470*eb293b8fSAndroid Build Coastguard Worker     if (x == 0xb2) {
1471*eb293b8fSAndroid Build Coastguard Worker       // This opcode is followed by an uleb128, so just skip this one.
1472*eb293b8fSAndroid Build Coastguard Worker       continue;
1473*eb293b8fSAndroid Build Coastguard Worker     }
1474*eb293b8fSAndroid Build Coastguard Worker     for (size_t y = 0; y < 256; y++) {
1475*eb293b8fSAndroid Build Coastguard Worker       data_->clear();
1476*eb293b8fSAndroid Build Coastguard Worker       data_->push_back(x);
1477*eb293b8fSAndroid Build Coastguard Worker       data_->push_back(y);
1478*eb293b8fSAndroid Build Coastguard Worker       if (!exidx_->Decode()) {
1479*eb293b8fSAndroid Build Coastguard Worker         ASSERT_NE(ARM_STATUS_TRUNCATED, exidx_->status())
1480*eb293b8fSAndroid Build Coastguard Worker             << "x y = 0x" << std::hex << x << " 0x" << y;
1481*eb293b8fSAndroid Build Coastguard Worker         ASSERT_NE(ARM_STATUS_READ_FAILED, exidx_->status())
1482*eb293b8fSAndroid Build Coastguard Worker             << "x y = 0x" << std::hex << x << " 0x" << y;
1483*eb293b8fSAndroid Build Coastguard Worker       }
1484*eb293b8fSAndroid Build Coastguard Worker     }
1485*eb293b8fSAndroid Build Coastguard Worker   }
1486*eb293b8fSAndroid Build Coastguard Worker }
1487*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,eval_multiple_decodes)1488*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, eval_multiple_decodes) {
1489*eb293b8fSAndroid Build Coastguard Worker   // vsp = vsp + 4
1490*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1491*eb293b8fSAndroid Build Coastguard Worker   // vsp = vsp + 12
1492*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x02);
1493*eb293b8fSAndroid Build Coastguard Worker   // Finish
1494*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb0);
1495*eb293b8fSAndroid Build Coastguard Worker 
1496*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Eval());
1497*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1498*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1499*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1500*eb293b8fSAndroid Build Coastguard Worker       break;
1501*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1502*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1503*eb293b8fSAndroid Build Coastguard Worker           "4 unwind vsp = vsp + 4\n"
1504*eb293b8fSAndroid Build Coastguard Worker           "4 unwind vsp = vsp + 12\n"
1505*eb293b8fSAndroid Build Coastguard Worker           "4 unwind finish\n",
1506*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1507*eb293b8fSAndroid Build Coastguard Worker       break;
1508*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1509*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
1510*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("4 unwind cfa = r13 + 16\n", GetFakeLogPrint());
1511*eb293b8fSAndroid Build Coastguard Worker       break;
1512*eb293b8fSAndroid Build Coastguard Worker   }
1513*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10010U, exidx_->cfa());
1514*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(exidx_->pc_set());
1515*eb293b8fSAndroid Build Coastguard Worker }
1516*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,eval_vsp_add_after_pop)1517*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, eval_vsp_add_after_pop) {
1518*eb293b8fSAndroid Build Coastguard Worker   // Pop {r15}
1519*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x88);
1520*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1521*eb293b8fSAndroid Build Coastguard Worker   // vsp = vsp + 12
1522*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x02);
1523*eb293b8fSAndroid Build Coastguard Worker   // Finish
1524*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb0);
1525*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x10);
1526*eb293b8fSAndroid Build Coastguard Worker 
1527*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Eval());
1528*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1529*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1530*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1531*eb293b8fSAndroid Build Coastguard Worker       break;
1532*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1533*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1534*eb293b8fSAndroid Build Coastguard Worker           "4 unwind pop {r15}\n"
1535*eb293b8fSAndroid Build Coastguard Worker           "4 unwind vsp = vsp + 12\n"
1536*eb293b8fSAndroid Build Coastguard Worker           "4 unwind finish\n",
1537*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1538*eb293b8fSAndroid Build Coastguard Worker       break;
1539*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1540*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
1541*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1542*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 16\n"
1543*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r15 = [cfa - 16]\n",
1544*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1545*eb293b8fSAndroid Build Coastguard Worker       break;
1546*eb293b8fSAndroid Build Coastguard Worker   }
1547*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10010U, exidx_->cfa());
1548*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->pc_set());
1549*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1550*eb293b8fSAndroid Build Coastguard Worker }
1551*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,eval_vsp_add_large_after_pop)1552*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, eval_vsp_add_large_after_pop) {
1553*eb293b8fSAndroid Build Coastguard Worker   // Pop {r15}
1554*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x88);
1555*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1556*eb293b8fSAndroid Build Coastguard Worker   // vsp = vsp + 1024
1557*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb2);
1558*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x7f);
1559*eb293b8fSAndroid Build Coastguard Worker   // Finish
1560*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb0);
1561*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x10);
1562*eb293b8fSAndroid Build Coastguard Worker 
1563*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Eval());
1564*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1565*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1566*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1567*eb293b8fSAndroid Build Coastguard Worker       break;
1568*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1569*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1570*eb293b8fSAndroid Build Coastguard Worker           "4 unwind pop {r15}\n"
1571*eb293b8fSAndroid Build Coastguard Worker           "4 unwind vsp = vsp + 1024\n"
1572*eb293b8fSAndroid Build Coastguard Worker           "4 unwind finish\n",
1573*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1574*eb293b8fSAndroid Build Coastguard Worker       break;
1575*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1576*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
1577*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1578*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 1028\n"
1579*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r15 = [cfa - 1028]\n",
1580*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1581*eb293b8fSAndroid Build Coastguard Worker       break;
1582*eb293b8fSAndroid Build Coastguard Worker   }
1583*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10404U, exidx_->cfa());
1584*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->pc_set());
1585*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1586*eb293b8fSAndroid Build Coastguard Worker }
1587*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,eval_vsp_sub_after_pop)1588*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, eval_vsp_sub_after_pop) {
1589*eb293b8fSAndroid Build Coastguard Worker   // Pop {r15}
1590*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x88);
1591*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1592*eb293b8fSAndroid Build Coastguard Worker   // vsp = vsp - 4
1593*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x41);
1594*eb293b8fSAndroid Build Coastguard Worker   // Finish
1595*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb0);
1596*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10000, 0x10);
1597*eb293b8fSAndroid Build Coastguard Worker 
1598*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Eval());
1599*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1600*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1601*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1602*eb293b8fSAndroid Build Coastguard Worker       break;
1603*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1604*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1605*eb293b8fSAndroid Build Coastguard Worker           "4 unwind pop {r15}\n"
1606*eb293b8fSAndroid Build Coastguard Worker           "4 unwind vsp = vsp - 8\n"
1607*eb293b8fSAndroid Build Coastguard Worker           "4 unwind finish\n",
1608*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1609*eb293b8fSAndroid Build Coastguard Worker       break;
1610*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1611*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
1612*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1613*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 - 4\n"
1614*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r15 = [cfa + 4]\n",
1615*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1616*eb293b8fSAndroid Build Coastguard Worker       break;
1617*eb293b8fSAndroid Build Coastguard Worker   }
1618*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xfffcU, exidx_->cfa());
1619*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->pc_set());
1620*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1621*eb293b8fSAndroid Build Coastguard Worker }
1622*eb293b8fSAndroid Build Coastguard Worker 
TEST_P(ArmExidxDecodeTest,eval_pc_set)1623*eb293b8fSAndroid Build Coastguard Worker TEST_P(ArmExidxDecodeTest, eval_pc_set) {
1624*eb293b8fSAndroid Build Coastguard Worker   // vsp = vsp + 4
1625*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1626*eb293b8fSAndroid Build Coastguard Worker   // vsp = vsp + 12
1627*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x02);
1628*eb293b8fSAndroid Build Coastguard Worker   // Pop {r15}
1629*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x88);
1630*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x00);
1631*eb293b8fSAndroid Build Coastguard Worker   // vsp = vsp + 12
1632*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0x02);
1633*eb293b8fSAndroid Build Coastguard Worker   // Finish
1634*eb293b8fSAndroid Build Coastguard Worker   data_->push_back(0xb0);
1635*eb293b8fSAndroid Build Coastguard Worker 
1636*eb293b8fSAndroid Build Coastguard Worker   process_memory_.SetData32(0x10010, 0x10);
1637*eb293b8fSAndroid Build Coastguard Worker 
1638*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->Eval());
1639*eb293b8fSAndroid Build Coastguard Worker   switch (log_) {
1640*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_NONE:
1641*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ("", GetFakeLogPrint());
1642*eb293b8fSAndroid Build Coastguard Worker       break;
1643*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_FULL:
1644*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1645*eb293b8fSAndroid Build Coastguard Worker           "4 unwind vsp = vsp + 4\n"
1646*eb293b8fSAndroid Build Coastguard Worker           "4 unwind vsp = vsp + 12\n"
1647*eb293b8fSAndroid Build Coastguard Worker           "4 unwind pop {r15}\n"
1648*eb293b8fSAndroid Build Coastguard Worker           "4 unwind vsp = vsp + 12\n"
1649*eb293b8fSAndroid Build Coastguard Worker           "4 unwind finish\n",
1650*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1651*eb293b8fSAndroid Build Coastguard Worker       break;
1652*eb293b8fSAndroid Build Coastguard Worker     case ARM_LOG_BY_REG:
1653*eb293b8fSAndroid Build Coastguard Worker       exidx_->LogByReg();
1654*eb293b8fSAndroid Build Coastguard Worker       ASSERT_EQ(
1655*eb293b8fSAndroid Build Coastguard Worker           "4 unwind cfa = r13 + 32\n"
1656*eb293b8fSAndroid Build Coastguard Worker           "4 unwind r15 = [cfa - 16]\n",
1657*eb293b8fSAndroid Build Coastguard Worker           GetFakeLogPrint());
1658*eb293b8fSAndroid Build Coastguard Worker       break;
1659*eb293b8fSAndroid Build Coastguard Worker   }
1660*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10020U, exidx_->cfa());
1661*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(exidx_->pc_set());
1662*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1663*eb293b8fSAndroid Build Coastguard Worker }
1664*eb293b8fSAndroid Build Coastguard Worker 
1665*eb293b8fSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(Unwindstack, ArmExidxDecodeTest,
1666*eb293b8fSAndroid Build Coastguard Worker                          ::testing::Values("logging", "register_logging", "no_logging"));
1667*eb293b8fSAndroid Build Coastguard Worker 
1668*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
1669