xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/DwarfOpTest.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 <ios>
20*eb293b8fSAndroid Build Coastguard Worker #include <memory>
21*eb293b8fSAndroid Build Coastguard Worker #include <vector>
22*eb293b8fSAndroid Build Coastguard Worker 
23*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
24*eb293b8fSAndroid Build Coastguard Worker 
25*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/DwarfError.h>
26*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/DwarfMemory.h>
27*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Log.h>
28*eb293b8fSAndroid Build Coastguard Worker 
29*eb293b8fSAndroid Build Coastguard Worker #include "DwarfOp.h"
30*eb293b8fSAndroid Build Coastguard Worker 
31*eb293b8fSAndroid Build Coastguard Worker #include "RegsFake.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 template <typename TypeParam>
37*eb293b8fSAndroid Build Coastguard Worker class DwarfOpTest : public ::testing::Test {
38*eb293b8fSAndroid Build Coastguard Worker  protected:
SetUp()39*eb293b8fSAndroid Build Coastguard Worker   void SetUp() override {
40*eb293b8fSAndroid Build Coastguard Worker     op_memory_ = new MemoryFake;
41*eb293b8fSAndroid Build Coastguard Worker     std::shared_ptr<Memory> op_memory(op_memory_);
42*eb293b8fSAndroid Build Coastguard Worker     mem_.reset(new DwarfMemory(op_memory));
43*eb293b8fSAndroid Build Coastguard Worker     regular_memory_.Clear();
44*eb293b8fSAndroid Build Coastguard Worker     op_.reset(new DwarfOp<TypeParam>(mem_.get(), &regular_memory_));
45*eb293b8fSAndroid Build Coastguard Worker   }
46*eb293b8fSAndroid Build Coastguard Worker 
47*eb293b8fSAndroid Build Coastguard Worker   MemoryFake* op_memory_;
48*eb293b8fSAndroid Build Coastguard Worker   MemoryFake regular_memory_;
49*eb293b8fSAndroid Build Coastguard Worker 
50*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<DwarfMemory> mem_;
51*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<DwarfOp<TypeParam>> op_;
52*eb293b8fSAndroid Build Coastguard Worker };
53*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_SUITE_P(DwarfOpTest);
54*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,decode)55*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, decode) {
56*eb293b8fSAndroid Build Coastguard Worker   // Memory error.
57*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
58*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
59*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, this->op_->LastErrorAddress());
60*eb293b8fSAndroid Build Coastguard Worker 
61*eb293b8fSAndroid Build Coastguard Worker   // No error.
62*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x96});
63*eb293b8fSAndroid Build Coastguard Worker   this->mem_->set_cur_offset(0);
64*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
65*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_NONE, this->op_->LastErrorCode());
66*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x96U, this->op_->cur_op());
67*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->mem_->cur_offset());
68*eb293b8fSAndroid Build Coastguard Worker }
69*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,eval)70*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, eval) {
71*eb293b8fSAndroid Build Coastguard Worker   // Memory error.
72*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Eval(0, 2));
73*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
74*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, this->op_->LastErrorAddress());
75*eb293b8fSAndroid Build Coastguard Worker 
76*eb293b8fSAndroid Build Coastguard Worker   // Register set.
77*eb293b8fSAndroid Build Coastguard Worker   // Do this first, to verify that subsequent calls reset the value.
78*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x50});
79*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(0, 1));
80*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->is_register());
81*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->mem_->cur_offset());
82*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
83*eb293b8fSAndroid Build Coastguard Worker 
84*eb293b8fSAndroid Build Coastguard Worker   // Multi operation opcodes.
85*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
86*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x04, 0x08, 0x03, 0x08, 0x02, 0x08, 0x01,
87*eb293b8fSAndroid Build Coastguard Worker   };
88*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
89*eb293b8fSAndroid Build Coastguard Worker 
90*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(0, 8));
91*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_NONE, this->op_->LastErrorCode());
92*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->is_register());
93*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(8U, this->mem_->cur_offset());
94*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
95*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackAt(0));
96*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackAt(1));
97*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackAt(2));
98*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackAt(3));
99*eb293b8fSAndroid Build Coastguard Worker 
100*eb293b8fSAndroid Build Coastguard Worker   // Infinite loop.
101*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x2f, 0xfd, 0xff});
102*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Eval(0, 4));
103*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_TOO_MANY_ITERATIONS, this->op_->LastErrorCode());
104*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->is_register());
105*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
106*eb293b8fSAndroid Build Coastguard Worker }
107*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,illegal_opcode)108*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, illegal_opcode) {
109*eb293b8fSAndroid Build Coastguard Worker   // Fill the buffer with all of the illegal opcodes.
110*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {0x00, 0x01, 0x02, 0x04, 0x05, 0x07};
111*eb293b8fSAndroid Build Coastguard Worker   for (size_t opcode = 0xa0; opcode < 256; opcode++) {
112*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(opcode);
113*eb293b8fSAndroid Build Coastguard Worker   }
114*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
115*eb293b8fSAndroid Build Coastguard Worker 
116*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < opcode_buffer.size(); i++) {
117*eb293b8fSAndroid Build Coastguard Worker     ASSERT_FALSE(this->op_->Decode());
118*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
119*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(opcode_buffer[i], this->op_->cur_op());
120*eb293b8fSAndroid Build Coastguard Worker   }
121*eb293b8fSAndroid Build Coastguard Worker }
122*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,not_implemented)123*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, not_implemented) {
124*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
125*eb293b8fSAndroid Build Coastguard Worker       // Push values so that any not implemented ops will return the right error.
126*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x03, 0x08, 0x02, 0x08, 0x01,
127*eb293b8fSAndroid Build Coastguard Worker       // xderef
128*eb293b8fSAndroid Build Coastguard Worker       0x18,
129*eb293b8fSAndroid Build Coastguard Worker       // fbreg
130*eb293b8fSAndroid Build Coastguard Worker       0x91, 0x01,
131*eb293b8fSAndroid Build Coastguard Worker       // piece
132*eb293b8fSAndroid Build Coastguard Worker       0x93, 0x01,
133*eb293b8fSAndroid Build Coastguard Worker       // xderef_size
134*eb293b8fSAndroid Build Coastguard Worker       0x95, 0x01,
135*eb293b8fSAndroid Build Coastguard Worker       // push_object_address
136*eb293b8fSAndroid Build Coastguard Worker       0x97,
137*eb293b8fSAndroid Build Coastguard Worker       // call2
138*eb293b8fSAndroid Build Coastguard Worker       0x98, 0x01, 0x02,
139*eb293b8fSAndroid Build Coastguard Worker       // call4
140*eb293b8fSAndroid Build Coastguard Worker       0x99, 0x01, 0x02, 0x03, 0x04,
141*eb293b8fSAndroid Build Coastguard Worker       // call_ref
142*eb293b8fSAndroid Build Coastguard Worker       0x9a,
143*eb293b8fSAndroid Build Coastguard Worker       // form_tls_address
144*eb293b8fSAndroid Build Coastguard Worker       0x9b,
145*eb293b8fSAndroid Build Coastguard Worker       // call_frame_cfa
146*eb293b8fSAndroid Build Coastguard Worker       0x9c,
147*eb293b8fSAndroid Build Coastguard Worker       // bit_piece
148*eb293b8fSAndroid Build Coastguard Worker       0x9d, 0x01, 0x01,
149*eb293b8fSAndroid Build Coastguard Worker       // implicit_value
150*eb293b8fSAndroid Build Coastguard Worker       0x9e, 0x01,
151*eb293b8fSAndroid Build Coastguard Worker       // stack_value
152*eb293b8fSAndroid Build Coastguard Worker       0x9f,
153*eb293b8fSAndroid Build Coastguard Worker   };
154*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
155*eb293b8fSAndroid Build Coastguard Worker 
156*eb293b8fSAndroid Build Coastguard Worker   // Push the stack values.
157*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
158*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
159*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
160*eb293b8fSAndroid Build Coastguard Worker 
161*eb293b8fSAndroid Build Coastguard Worker   while (this->mem_->cur_offset() < opcode_buffer.size()) {
162*eb293b8fSAndroid Build Coastguard Worker     ASSERT_FALSE(this->op_->Decode());
163*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->op_->LastErrorCode());
164*eb293b8fSAndroid Build Coastguard Worker   }
165*eb293b8fSAndroid Build Coastguard Worker }
166*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_addr)167*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_addr) {
168*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {0x03, 0x12, 0x23, 0x34, 0x45};
169*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 8) {
170*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x56);
171*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x67);
172*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x78);
173*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x89);
174*eb293b8fSAndroid Build Coastguard Worker   }
175*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
176*eb293b8fSAndroid Build Coastguard Worker 
177*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
178*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x03, this->op_->cur_op());
179*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
180*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
181*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x45342312U, this->op_->StackAt(0));
182*eb293b8fSAndroid Build Coastguard Worker   } else {
183*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x8978675645342312UL, this->op_->StackAt(0));
184*eb293b8fSAndroid Build Coastguard Worker   }
185*eb293b8fSAndroid Build Coastguard Worker }
186*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_deref)187*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_deref) {
188*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
189*eb293b8fSAndroid Build Coastguard Worker       // Try a dereference with nothing on the stack.
190*eb293b8fSAndroid Build Coastguard Worker       0x06,
191*eb293b8fSAndroid Build Coastguard Worker       // Add an address, then dereference.
192*eb293b8fSAndroid Build Coastguard Worker       0x0a, 0x10, 0x20, 0x06,
193*eb293b8fSAndroid Build Coastguard Worker       // Now do another dereference that should fail in memory.
194*eb293b8fSAndroid Build Coastguard Worker       0x06,
195*eb293b8fSAndroid Build Coastguard Worker   };
196*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
197*eb293b8fSAndroid Build Coastguard Worker   TypeParam value = 0x12345678;
198*eb293b8fSAndroid Build Coastguard Worker   this->regular_memory_.SetMemory(0x2010, &value, sizeof(value));
199*eb293b8fSAndroid Build Coastguard Worker 
200*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
201*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
202*eb293b8fSAndroid Build Coastguard Worker 
203*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
204*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
205*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
206*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x06, this->op_->cur_op());
207*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
208*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(value, this->op_->StackAt(0));
209*eb293b8fSAndroid Build Coastguard Worker 
210*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
211*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
212*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x12345678U, this->op_->LastErrorAddress());
213*eb293b8fSAndroid Build Coastguard Worker }
214*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_deref_size)215*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_deref_size) {
216*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x94});
217*eb293b8fSAndroid Build Coastguard Worker   TypeParam value = 0x12345678;
218*eb293b8fSAndroid Build Coastguard Worker   this->regular_memory_.SetMemory(0x2010, &value, sizeof(value));
219*eb293b8fSAndroid Build Coastguard Worker 
220*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
221*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
222*eb293b8fSAndroid Build Coastguard Worker 
223*eb293b8fSAndroid Build Coastguard Worker   // Read all byte sizes up to the sizeof the type.
224*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 1; i < sizeof(TypeParam); i++) {
225*eb293b8fSAndroid Build Coastguard Worker     this->op_memory_->SetMemory(
226*eb293b8fSAndroid Build Coastguard Worker         0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, static_cast<uint8_t>(i)});
227*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(this->op_->Eval(0, 5)) << "Failed at size " << i;
228*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed at size " << i;
229*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x94, this->op_->cur_op()) << "Failed at size " << i;
230*eb293b8fSAndroid Build Coastguard Worker     TypeParam expected_value = 0;
231*eb293b8fSAndroid Build Coastguard Worker     memcpy(&expected_value, &value, i);
232*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(expected_value, this->op_->StackAt(0)) << "Failed at size " << i;
233*eb293b8fSAndroid Build Coastguard Worker   }
234*eb293b8fSAndroid Build Coastguard Worker 
235*eb293b8fSAndroid Build Coastguard Worker   // Zero byte read.
236*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, 0x00});
237*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Eval(0, 5));
238*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
239*eb293b8fSAndroid Build Coastguard Worker 
240*eb293b8fSAndroid Build Coastguard Worker   // Read too many bytes.
241*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0,
242*eb293b8fSAndroid Build Coastguard Worker                               std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, sizeof(TypeParam) + 1});
243*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Eval(0, 5));
244*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
245*eb293b8fSAndroid Build Coastguard Worker 
246*eb293b8fSAndroid Build Coastguard Worker   // Force bad memory read.
247*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x40, 0x94, 0x01});
248*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Eval(0, 5));
249*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
250*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x4010U, this->op_->LastErrorAddress());
251*eb293b8fSAndroid Build Coastguard Worker }
252*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,const_unsigned)253*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, const_unsigned) {
254*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
255*eb293b8fSAndroid Build Coastguard Worker       // const1u
256*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x12, 0x08, 0xff,
257*eb293b8fSAndroid Build Coastguard Worker       // const2u
258*eb293b8fSAndroid Build Coastguard Worker       0x0a, 0x45, 0x12, 0x0a, 0x00, 0xff,
259*eb293b8fSAndroid Build Coastguard Worker       // const4u
260*eb293b8fSAndroid Build Coastguard Worker       0x0c, 0x12, 0x23, 0x34, 0x45, 0x0c, 0x03, 0x02, 0x01, 0xff,
261*eb293b8fSAndroid Build Coastguard Worker       // const8u
262*eb293b8fSAndroid Build Coastguard Worker       0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x0e, 0x87, 0x98, 0xa9, 0xba, 0xcb,
263*eb293b8fSAndroid Build Coastguard Worker       0xdc, 0xed, 0xfe,
264*eb293b8fSAndroid Build Coastguard Worker   };
265*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
266*eb293b8fSAndroid Build Coastguard Worker 
267*eb293b8fSAndroid Build Coastguard Worker   // const1u
268*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
269*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x08, this->op_->cur_op());
270*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
271*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x12U, this->op_->StackAt(0));
272*eb293b8fSAndroid Build Coastguard Worker 
273*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
274*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x08, this->op_->cur_op());
275*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
276*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xffU, this->op_->StackAt(0));
277*eb293b8fSAndroid Build Coastguard Worker 
278*eb293b8fSAndroid Build Coastguard Worker   // const2u
279*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
280*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0a, this->op_->cur_op());
281*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
282*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1245U, this->op_->StackAt(0));
283*eb293b8fSAndroid Build Coastguard Worker 
284*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
285*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0a, this->op_->cur_op());
286*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
287*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xff00U, this->op_->StackAt(0));
288*eb293b8fSAndroid Build Coastguard Worker 
289*eb293b8fSAndroid Build Coastguard Worker   // const4u
290*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
291*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0c, this->op_->cur_op());
292*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5U, this->op_->StackSize());
293*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x45342312U, this->op_->StackAt(0));
294*eb293b8fSAndroid Build Coastguard Worker 
295*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
296*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0c, this->op_->cur_op());
297*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(6U, this->op_->StackSize());
298*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xff010203U, this->op_->StackAt(0));
299*eb293b8fSAndroid Build Coastguard Worker 
300*eb293b8fSAndroid Build Coastguard Worker   // const8u
301*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
302*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0e, this->op_->cur_op());
303*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(7U, this->op_->StackSize());
304*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
305*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x05060708U, this->op_->StackAt(0));
306*eb293b8fSAndroid Build Coastguard Worker   } else {
307*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x0102030405060708ULL, this->op_->StackAt(0));
308*eb293b8fSAndroid Build Coastguard Worker   }
309*eb293b8fSAndroid Build Coastguard Worker 
310*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
311*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0e, this->op_->cur_op());
312*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(8U, this->op_->StackSize());
313*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
314*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0xbaa99887UL, this->op_->StackAt(0));
315*eb293b8fSAndroid Build Coastguard Worker   } else {
316*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0xfeeddccbbaa99887ULL, this->op_->StackAt(0));
317*eb293b8fSAndroid Build Coastguard Worker   }
318*eb293b8fSAndroid Build Coastguard Worker }
319*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,const_signed)320*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, const_signed) {
321*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
322*eb293b8fSAndroid Build Coastguard Worker       // const1s
323*eb293b8fSAndroid Build Coastguard Worker       0x09, 0x12, 0x09, 0xff,
324*eb293b8fSAndroid Build Coastguard Worker       // const2s
325*eb293b8fSAndroid Build Coastguard Worker       0x0b, 0x21, 0x32, 0x0b, 0x08, 0xff,
326*eb293b8fSAndroid Build Coastguard Worker       // const4s
327*eb293b8fSAndroid Build Coastguard Worker       0x0d, 0x45, 0x34, 0x23, 0x12, 0x0d, 0x01, 0x02, 0x03, 0xff,
328*eb293b8fSAndroid Build Coastguard Worker       // const8s
329*eb293b8fSAndroid Build Coastguard Worker       0x0f, 0x89, 0x78, 0x67, 0x56, 0x45, 0x34, 0x23, 0x12, 0x0f, 0x04, 0x03, 0x02, 0x01, 0xef,
330*eb293b8fSAndroid Build Coastguard Worker       0xef, 0xef, 0xff,
331*eb293b8fSAndroid Build Coastguard Worker   };
332*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
333*eb293b8fSAndroid Build Coastguard Worker 
334*eb293b8fSAndroid Build Coastguard Worker   // const1s
335*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
336*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x09, this->op_->cur_op());
337*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
338*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x12U, this->op_->StackAt(0));
339*eb293b8fSAndroid Build Coastguard Worker 
340*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
341*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x09, this->op_->cur_op());
342*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
343*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-1), this->op_->StackAt(0));
344*eb293b8fSAndroid Build Coastguard Worker 
345*eb293b8fSAndroid Build Coastguard Worker   // const2s
346*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
347*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0b, this->op_->cur_op());
348*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
349*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x3221U, this->op_->StackAt(0));
350*eb293b8fSAndroid Build Coastguard Worker 
351*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
352*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0b, this->op_->cur_op());
353*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
354*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-248), this->op_->StackAt(0));
355*eb293b8fSAndroid Build Coastguard Worker 
356*eb293b8fSAndroid Build Coastguard Worker   // const4s
357*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
358*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0d, this->op_->cur_op());
359*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5U, this->op_->StackSize());
360*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x12233445U, this->op_->StackAt(0));
361*eb293b8fSAndroid Build Coastguard Worker 
362*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
363*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0d, this->op_->cur_op());
364*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(6U, this->op_->StackSize());
365*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-16580095), this->op_->StackAt(0));
366*eb293b8fSAndroid Build Coastguard Worker 
367*eb293b8fSAndroid Build Coastguard Worker   // const8s
368*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
369*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0f, this->op_->cur_op());
370*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(7U, this->op_->StackSize());
371*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
372*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x56677889ULL, this->op_->StackAt(0));
373*eb293b8fSAndroid Build Coastguard Worker   } else {
374*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x1223344556677889ULL, this->op_->StackAt(0));
375*eb293b8fSAndroid Build Coastguard Worker   }
376*eb293b8fSAndroid Build Coastguard Worker 
377*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
378*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x0f, this->op_->cur_op());
379*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(8U, this->op_->StackSize());
380*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
381*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x01020304U, this->op_->StackAt(0));
382*eb293b8fSAndroid Build Coastguard Worker   } else {
383*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(static_cast<TypeParam>(-4521264810949884LL), this->op_->StackAt(0));
384*eb293b8fSAndroid Build Coastguard Worker   }
385*eb293b8fSAndroid Build Coastguard Worker }
386*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,const_uleb)387*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, const_uleb) {
388*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
389*eb293b8fSAndroid Build Coastguard Worker       // Single byte ULEB128
390*eb293b8fSAndroid Build Coastguard Worker       0x10, 0x22, 0x10, 0x7f,
391*eb293b8fSAndroid Build Coastguard Worker       // Multi byte ULEB128
392*eb293b8fSAndroid Build Coastguard Worker       0x10, 0xa2, 0x22, 0x10, 0xa2, 0x74, 0x10, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
393*eb293b8fSAndroid Build Coastguard Worker       0x09, 0x10, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x79,
394*eb293b8fSAndroid Build Coastguard Worker   };
395*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
396*eb293b8fSAndroid Build Coastguard Worker 
397*eb293b8fSAndroid Build Coastguard Worker   // Single byte ULEB128
398*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
399*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10, this->op_->cur_op());
400*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
401*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x22U, this->op_->StackAt(0));
402*eb293b8fSAndroid Build Coastguard Worker 
403*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
404*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10, this->op_->cur_op());
405*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
406*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x7fU, this->op_->StackAt(0));
407*eb293b8fSAndroid Build Coastguard Worker 
408*eb293b8fSAndroid Build Coastguard Worker   // Multi byte ULEB128
409*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
410*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10, this->op_->cur_op());
411*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
412*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1122U, this->op_->StackAt(0));
413*eb293b8fSAndroid Build Coastguard Worker 
414*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
415*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10, this->op_->cur_op());
416*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
417*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x3a22U, this->op_->StackAt(0));
418*eb293b8fSAndroid Build Coastguard Worker 
419*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
420*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10, this->op_->cur_op());
421*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5U, this->op_->StackSize());
422*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
423*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x5080c101U, this->op_->StackAt(0));
424*eb293b8fSAndroid Build Coastguard Worker   } else {
425*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x9101c305080c101ULL, this->op_->StackAt(0));
426*eb293b8fSAndroid Build Coastguard Worker   }
427*eb293b8fSAndroid Build Coastguard Worker 
428*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
429*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10, this->op_->cur_op());
430*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(6U, this->op_->StackSize());
431*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
432*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x5080c101U, this->op_->StackAt(0));
433*eb293b8fSAndroid Build Coastguard Worker   } else {
434*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x79101c305080c101ULL, this->op_->StackAt(0));
435*eb293b8fSAndroid Build Coastguard Worker   }
436*eb293b8fSAndroid Build Coastguard Worker }
437*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,const_sleb)438*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, const_sleb) {
439*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
440*eb293b8fSAndroid Build Coastguard Worker       // Single byte SLEB128
441*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x22, 0x11, 0x7f,
442*eb293b8fSAndroid Build Coastguard Worker       // Multi byte SLEB128
443*eb293b8fSAndroid Build Coastguard Worker       0x11, 0xa2, 0x22, 0x11, 0xa2, 0x74, 0x11, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
444*eb293b8fSAndroid Build Coastguard Worker       0x09, 0x11,
445*eb293b8fSAndroid Build Coastguard Worker   };
446*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
447*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0xb8);
448*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0xd3);
449*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x63);
450*eb293b8fSAndroid Build Coastguard Worker   } else {
451*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x81);
452*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x82);
453*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x83);
454*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x84);
455*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x85);
456*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x86);
457*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x87);
458*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x88);
459*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x79);
460*eb293b8fSAndroid Build Coastguard Worker   }
461*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
462*eb293b8fSAndroid Build Coastguard Worker 
463*eb293b8fSAndroid Build Coastguard Worker   // Single byte SLEB128
464*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
465*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x11, this->op_->cur_op());
466*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
467*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x22U, this->op_->StackAt(0));
468*eb293b8fSAndroid Build Coastguard Worker 
469*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
470*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x11, this->op_->cur_op());
471*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
472*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-1), this->op_->StackAt(0));
473*eb293b8fSAndroid Build Coastguard Worker 
474*eb293b8fSAndroid Build Coastguard Worker   // Multi byte SLEB128
475*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
476*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x11, this->op_->cur_op());
477*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
478*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1122U, this->op_->StackAt(0));
479*eb293b8fSAndroid Build Coastguard Worker 
480*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
481*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x11, this->op_->cur_op());
482*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
483*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-1502), this->op_->StackAt(0));
484*eb293b8fSAndroid Build Coastguard Worker 
485*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
486*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x11, this->op_->cur_op());
487*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5U, this->op_->StackSize());
488*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
489*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x5080c101U, this->op_->StackAt(0));
490*eb293b8fSAndroid Build Coastguard Worker   } else {
491*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x9101c305080c101ULL, this->op_->StackAt(0));
492*eb293b8fSAndroid Build Coastguard Worker   }
493*eb293b8fSAndroid Build Coastguard Worker 
494*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
495*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x11, this->op_->cur_op());
496*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(6U, this->op_->StackSize());
497*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
498*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(static_cast<TypeParam>(-464456), this->op_->StackAt(0));
499*eb293b8fSAndroid Build Coastguard Worker   } else {
500*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(static_cast<TypeParam>(-499868564803501823LL), this->op_->StackAt(0));
501*eb293b8fSAndroid Build Coastguard Worker   }
502*eb293b8fSAndroid Build Coastguard Worker }
503*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_dup)504*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_dup) {
505*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
506*eb293b8fSAndroid Build Coastguard Worker       // Should fail since nothing is on the stack.
507*eb293b8fSAndroid Build Coastguard Worker       0x12,
508*eb293b8fSAndroid Build Coastguard Worker       // Push on a value and dup.
509*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x15, 0x12,
510*eb293b8fSAndroid Build Coastguard Worker       // Do it again.
511*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x23, 0x12,
512*eb293b8fSAndroid Build Coastguard Worker   };
513*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
514*eb293b8fSAndroid Build Coastguard Worker 
515*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
516*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x12, this->op_->cur_op());
517*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
518*eb293b8fSAndroid Build Coastguard Worker 
519*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
520*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
521*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
522*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x12, this->op_->cur_op());
523*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
524*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x15U, this->op_->StackAt(0));
525*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x15U, this->op_->StackAt(1));
526*eb293b8fSAndroid Build Coastguard Worker 
527*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
528*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
529*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
530*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x12, this->op_->cur_op());
531*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
532*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x23U, this->op_->StackAt(0));
533*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x23U, this->op_->StackAt(1));
534*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x15U, this->op_->StackAt(2));
535*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x15U, this->op_->StackAt(3));
536*eb293b8fSAndroid Build Coastguard Worker }
537*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_drop)538*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_drop) {
539*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
540*eb293b8fSAndroid Build Coastguard Worker       // Push a couple of values.
541*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x10, 0x08, 0x20,
542*eb293b8fSAndroid Build Coastguard Worker       // Drop the values.
543*eb293b8fSAndroid Build Coastguard Worker       0x13, 0x13,
544*eb293b8fSAndroid Build Coastguard Worker       // Attempt to drop empty stack.
545*eb293b8fSAndroid Build Coastguard Worker       0x13,
546*eb293b8fSAndroid Build Coastguard Worker   };
547*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
548*eb293b8fSAndroid Build Coastguard Worker 
549*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
550*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
551*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
552*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
553*eb293b8fSAndroid Build Coastguard Worker 
554*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
555*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x13, this->op_->cur_op());
556*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
557*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, this->op_->StackAt(0));
558*eb293b8fSAndroid Build Coastguard Worker 
559*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
560*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x13, this->op_->cur_op());
561*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
562*eb293b8fSAndroid Build Coastguard Worker 
563*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
564*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x13, this->op_->cur_op());
565*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
566*eb293b8fSAndroid Build Coastguard Worker }
567*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_over)568*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_over) {
569*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
570*eb293b8fSAndroid Build Coastguard Worker       // Push a couple of values.
571*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x1a, 0x08, 0xed,
572*eb293b8fSAndroid Build Coastguard Worker       // Copy a value.
573*eb293b8fSAndroid Build Coastguard Worker       0x14,
574*eb293b8fSAndroid Build Coastguard Worker       // Remove all but one element.
575*eb293b8fSAndroid Build Coastguard Worker       0x13, 0x13,
576*eb293b8fSAndroid Build Coastguard Worker       // Provoke a failure with this opcode.
577*eb293b8fSAndroid Build Coastguard Worker       0x14,
578*eb293b8fSAndroid Build Coastguard Worker   };
579*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
580*eb293b8fSAndroid Build Coastguard Worker 
581*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
582*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
583*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
584*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
585*eb293b8fSAndroid Build Coastguard Worker 
586*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
587*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x14, this->op_->cur_op());
588*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
589*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1aU, this->op_->StackAt(0));
590*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xedU, this->op_->StackAt(1));
591*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1aU, this->op_->StackAt(2));
592*eb293b8fSAndroid Build Coastguard Worker 
593*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
594*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
595*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
596*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
597*eb293b8fSAndroid Build Coastguard Worker 
598*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
599*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x14, this->op_->cur_op());
600*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
601*eb293b8fSAndroid Build Coastguard Worker }
602*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_pick)603*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_pick) {
604*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
605*eb293b8fSAndroid Build Coastguard Worker       // Choose a zero index with an empty stack.
606*eb293b8fSAndroid Build Coastguard Worker       0x15,
607*eb293b8fSAndroid Build Coastguard Worker       0x0,
608*eb293b8fSAndroid Build Coastguard Worker       // Push a few values.
609*eb293b8fSAndroid Build Coastguard Worker       0x08,
610*eb293b8fSAndroid Build Coastguard Worker       0x1a,
611*eb293b8fSAndroid Build Coastguard Worker       0x08,
612*eb293b8fSAndroid Build Coastguard Worker       0xed,
613*eb293b8fSAndroid Build Coastguard Worker       0x08,
614*eb293b8fSAndroid Build Coastguard Worker       0x34,
615*eb293b8fSAndroid Build Coastguard Worker       // Copy the value at offset 2.
616*eb293b8fSAndroid Build Coastguard Worker       0x15,
617*eb293b8fSAndroid Build Coastguard Worker       0x01,
618*eb293b8fSAndroid Build Coastguard Worker       // Copy the last value in the stack.
619*eb293b8fSAndroid Build Coastguard Worker       0x15,
620*eb293b8fSAndroid Build Coastguard Worker       0x03,
621*eb293b8fSAndroid Build Coastguard Worker       // Choose an invalid index.
622*eb293b8fSAndroid Build Coastguard Worker       0x15,
623*eb293b8fSAndroid Build Coastguard Worker       0x10,
624*eb293b8fSAndroid Build Coastguard Worker   };
625*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
626*eb293b8fSAndroid Build Coastguard Worker 
627*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
628*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x15, this->op_->cur_op());
629*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
630*eb293b8fSAndroid Build Coastguard Worker 
631*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
632*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
633*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
634*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
635*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
636*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
637*eb293b8fSAndroid Build Coastguard Worker 
638*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
639*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x15, this->op_->cur_op());
640*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
641*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xedU, this->op_->StackAt(0));
642*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x34U, this->op_->StackAt(1));
643*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xedU, this->op_->StackAt(2));
644*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1aU, this->op_->StackAt(3));
645*eb293b8fSAndroid Build Coastguard Worker 
646*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
647*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x15, this->op_->cur_op());
648*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5U, this->op_->StackSize());
649*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1aU, this->op_->StackAt(0));
650*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xedU, this->op_->StackAt(1));
651*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x34U, this->op_->StackAt(2));
652*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xedU, this->op_->StackAt(3));
653*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1aU, this->op_->StackAt(4));
654*eb293b8fSAndroid Build Coastguard Worker 
655*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
656*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x15, this->op_->cur_op());
657*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
658*eb293b8fSAndroid Build Coastguard Worker }
659*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_swap)660*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_swap) {
661*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
662*eb293b8fSAndroid Build Coastguard Worker       // Push a couple of values.
663*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x26, 0x08, 0xab,
664*eb293b8fSAndroid Build Coastguard Worker       // Swap values.
665*eb293b8fSAndroid Build Coastguard Worker       0x16,
666*eb293b8fSAndroid Build Coastguard Worker       // Pop a value to cause a failure.
667*eb293b8fSAndroid Build Coastguard Worker       0x13, 0x16,
668*eb293b8fSAndroid Build Coastguard Worker   };
669*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
670*eb293b8fSAndroid Build Coastguard Worker 
671*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
672*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
673*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
674*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
675*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xabU, this->op_->StackAt(0));
676*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x26U, this->op_->StackAt(1));
677*eb293b8fSAndroid Build Coastguard Worker 
678*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
679*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x16, this->op_->cur_op());
680*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
681*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x26U, this->op_->StackAt(0));
682*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xabU, this->op_->StackAt(1));
683*eb293b8fSAndroid Build Coastguard Worker 
684*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
685*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
686*eb293b8fSAndroid Build Coastguard Worker 
687*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
688*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x16, this->op_->cur_op());
689*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
690*eb293b8fSAndroid Build Coastguard Worker }
691*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_rot)692*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_rot) {
693*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
694*eb293b8fSAndroid Build Coastguard Worker       // Rotate that should cause a failure.
695*eb293b8fSAndroid Build Coastguard Worker       0x17, 0x08, 0x10,
696*eb293b8fSAndroid Build Coastguard Worker       // Only 1 value on stack, should fail.
697*eb293b8fSAndroid Build Coastguard Worker       0x17, 0x08, 0x20,
698*eb293b8fSAndroid Build Coastguard Worker       // Only 2 values on stack, should fail.
699*eb293b8fSAndroid Build Coastguard Worker       0x17, 0x08, 0x30,
700*eb293b8fSAndroid Build Coastguard Worker       // Should rotate properly.
701*eb293b8fSAndroid Build Coastguard Worker       0x17,
702*eb293b8fSAndroid Build Coastguard Worker   };
703*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
704*eb293b8fSAndroid Build Coastguard Worker 
705*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
706*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
707*eb293b8fSAndroid Build Coastguard Worker 
708*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
709*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
710*eb293b8fSAndroid Build Coastguard Worker 
711*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
712*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
713*eb293b8fSAndroid Build Coastguard Worker 
714*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
715*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
716*eb293b8fSAndroid Build Coastguard Worker 
717*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
718*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
719*eb293b8fSAndroid Build Coastguard Worker 
720*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
721*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
722*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x30U, this->op_->StackAt(0));
723*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x20U, this->op_->StackAt(1));
724*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, this->op_->StackAt(2));
725*eb293b8fSAndroid Build Coastguard Worker 
726*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
727*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x17, this->op_->cur_op());
728*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
729*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x20U, this->op_->StackAt(0));
730*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, this->op_->StackAt(1));
731*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x30U, this->op_->StackAt(2));
732*eb293b8fSAndroid Build Coastguard Worker }
733*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_abs)734*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_abs) {
735*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
736*eb293b8fSAndroid Build Coastguard Worker       // Abs that should fail.
737*eb293b8fSAndroid Build Coastguard Worker       0x19,
738*eb293b8fSAndroid Build Coastguard Worker       // A value that is already positive.
739*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x10, 0x19,
740*eb293b8fSAndroid Build Coastguard Worker       // A value that is negative.
741*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x7f, 0x19,
742*eb293b8fSAndroid Build Coastguard Worker       // A value that is large and negative.
743*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x81, 0x80, 0x80, 0x80,
744*eb293b8fSAndroid Build Coastguard Worker   };
745*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
746*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x08);
747*eb293b8fSAndroid Build Coastguard Worker   } else {
748*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x80);
749*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x80);
750*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x01);
751*eb293b8fSAndroid Build Coastguard Worker   }
752*eb293b8fSAndroid Build Coastguard Worker   opcode_buffer.push_back(0x19);
753*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
754*eb293b8fSAndroid Build Coastguard Worker 
755*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
756*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
757*eb293b8fSAndroid Build Coastguard Worker 
758*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
759*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
760*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, this->op_->StackAt(0));
761*eb293b8fSAndroid Build Coastguard Worker 
762*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
763*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x19, this->op_->cur_op());
764*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
765*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, this->op_->StackAt(0));
766*eb293b8fSAndroid Build Coastguard Worker 
767*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
768*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
769*eb293b8fSAndroid Build Coastguard Worker 
770*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
771*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x19, this->op_->cur_op());
772*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
773*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1U, this->op_->StackAt(0));
774*eb293b8fSAndroid Build Coastguard Worker 
775*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
776*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
777*eb293b8fSAndroid Build Coastguard Worker 
778*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
779*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x19, this->op_->cur_op());
780*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
781*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
782*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(2147483647U, this->op_->StackAt(0));
783*eb293b8fSAndroid Build Coastguard Worker   } else {
784*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(4398046511105UL, this->op_->StackAt(0));
785*eb293b8fSAndroid Build Coastguard Worker   }
786*eb293b8fSAndroid Build Coastguard Worker }
787*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_and)788*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_and) {
789*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
790*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
791*eb293b8fSAndroid Build Coastguard Worker       0x1b,
792*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
793*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x20,
794*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
795*eb293b8fSAndroid Build Coastguard Worker       0x1b,
796*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
797*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x02, 0x1b,
798*eb293b8fSAndroid Build Coastguard Worker       // Push on two negative values.
799*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x7c, 0x11, 0x7f, 0x1b,
800*eb293b8fSAndroid Build Coastguard Worker       // Push one negative, one positive.
801*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x10, 0x11, 0x7c, 0x1b,
802*eb293b8fSAndroid Build Coastguard Worker       // Divide by zero.
803*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x10, 0x11, 0x00, 0x1b,
804*eb293b8fSAndroid Build Coastguard Worker   };
805*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
806*eb293b8fSAndroid Build Coastguard Worker 
807*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
808*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
809*eb293b8fSAndroid Build Coastguard Worker 
810*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
811*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
812*eb293b8fSAndroid Build Coastguard Worker 
813*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
814*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
815*eb293b8fSAndroid Build Coastguard Worker 
816*eb293b8fSAndroid Build Coastguard Worker   // Two positive values.
817*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
818*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
819*eb293b8fSAndroid Build Coastguard Worker 
820*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
821*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1b, this->op_->cur_op());
822*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
823*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x10U, this->op_->StackAt(0));
824*eb293b8fSAndroid Build Coastguard Worker 
825*eb293b8fSAndroid Build Coastguard Worker   // Two negative values.
826*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
827*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
828*eb293b8fSAndroid Build Coastguard Worker 
829*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
830*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
831*eb293b8fSAndroid Build Coastguard Worker 
832*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
833*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1b, this->op_->cur_op());
834*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
835*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x04U, this->op_->StackAt(0));
836*eb293b8fSAndroid Build Coastguard Worker 
837*eb293b8fSAndroid Build Coastguard Worker   // One negative value, one positive value.
838*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
839*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
840*eb293b8fSAndroid Build Coastguard Worker 
841*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
842*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
843*eb293b8fSAndroid Build Coastguard Worker 
844*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
845*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1b, this->op_->cur_op());
846*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
847*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-4), this->op_->StackAt(0));
848*eb293b8fSAndroid Build Coastguard Worker 
849*eb293b8fSAndroid Build Coastguard Worker   // Divide by zero.
850*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
851*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, this->op_->StackSize());
852*eb293b8fSAndroid Build Coastguard Worker 
853*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
854*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5U, this->op_->StackSize());
855*eb293b8fSAndroid Build Coastguard Worker 
856*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
857*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
858*eb293b8fSAndroid Build Coastguard Worker }
859*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_div)860*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_div) {
861*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
862*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
863*eb293b8fSAndroid Build Coastguard Worker       0x1a,
864*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
865*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x48,
866*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
867*eb293b8fSAndroid Build Coastguard Worker       0x1a,
868*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
869*eb293b8fSAndroid Build Coastguard Worker       0x08, 0xf0, 0x1a,
870*eb293b8fSAndroid Build Coastguard Worker   };
871*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
872*eb293b8fSAndroid Build Coastguard Worker 
873*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
874*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
875*eb293b8fSAndroid Build Coastguard Worker 
876*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
877*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
878*eb293b8fSAndroid Build Coastguard Worker 
879*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
880*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
881*eb293b8fSAndroid Build Coastguard Worker 
882*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
883*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
884*eb293b8fSAndroid Build Coastguard Worker 
885*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
886*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1a, this->op_->cur_op());
887*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
888*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x40U, this->op_->StackAt(0));
889*eb293b8fSAndroid Build Coastguard Worker }
890*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_minus)891*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_minus) {
892*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
893*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
894*eb293b8fSAndroid Build Coastguard Worker       0x1c,
895*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
896*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x48,
897*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
898*eb293b8fSAndroid Build Coastguard Worker       0x1c,
899*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
900*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x04, 0x1c,
901*eb293b8fSAndroid Build Coastguard Worker   };
902*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
903*eb293b8fSAndroid Build Coastguard Worker 
904*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
905*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
906*eb293b8fSAndroid Build Coastguard Worker 
907*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
908*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
909*eb293b8fSAndroid Build Coastguard Worker 
910*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
911*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
912*eb293b8fSAndroid Build Coastguard Worker 
913*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
914*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
915*eb293b8fSAndroid Build Coastguard Worker 
916*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
917*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1c, this->op_->cur_op());
918*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
919*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x44U, this->op_->StackAt(0));
920*eb293b8fSAndroid Build Coastguard Worker }
921*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_mod)922*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_mod) {
923*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
924*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
925*eb293b8fSAndroid Build Coastguard Worker       0x1d,
926*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
927*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x47,
928*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
929*eb293b8fSAndroid Build Coastguard Worker       0x1d,
930*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
931*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x04, 0x1d,
932*eb293b8fSAndroid Build Coastguard Worker       // Try a mod of zero.
933*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x01, 0x08, 0x00, 0x1d,
934*eb293b8fSAndroid Build Coastguard Worker   };
935*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
936*eb293b8fSAndroid Build Coastguard Worker 
937*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
938*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
939*eb293b8fSAndroid Build Coastguard Worker 
940*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
941*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
942*eb293b8fSAndroid Build Coastguard Worker 
943*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
944*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
945*eb293b8fSAndroid Build Coastguard Worker 
946*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
947*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
948*eb293b8fSAndroid Build Coastguard Worker 
949*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
950*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1d, this->op_->cur_op());
951*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
952*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x03U, this->op_->StackAt(0));
953*eb293b8fSAndroid Build Coastguard Worker 
954*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
955*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
956*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
957*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, this->op_->StackSize());
958*eb293b8fSAndroid Build Coastguard Worker 
959*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
960*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
961*eb293b8fSAndroid Build Coastguard Worker }
962*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_mul)963*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_mul) {
964*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
965*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
966*eb293b8fSAndroid Build Coastguard Worker       0x1e,
967*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
968*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x48,
969*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
970*eb293b8fSAndroid Build Coastguard Worker       0x1e,
971*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
972*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x04, 0x1e,
973*eb293b8fSAndroid Build Coastguard Worker   };
974*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
975*eb293b8fSAndroid Build Coastguard Worker 
976*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
977*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
978*eb293b8fSAndroid Build Coastguard Worker 
979*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
980*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
981*eb293b8fSAndroid Build Coastguard Worker 
982*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
983*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
984*eb293b8fSAndroid Build Coastguard Worker 
985*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
986*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
987*eb293b8fSAndroid Build Coastguard Worker 
988*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
989*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1e, this->op_->cur_op());
990*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
991*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x120U, this->op_->StackAt(0));
992*eb293b8fSAndroid Build Coastguard Worker }
993*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_neg)994*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_neg) {
995*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
996*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
997*eb293b8fSAndroid Build Coastguard Worker       0x1f,
998*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
999*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x48, 0x1f,
1000*eb293b8fSAndroid Build Coastguard Worker       // Push a negative value.
1001*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x7f, 0x1f,
1002*eb293b8fSAndroid Build Coastguard Worker   };
1003*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1004*eb293b8fSAndroid Build Coastguard Worker 
1005*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1006*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1007*eb293b8fSAndroid Build Coastguard Worker 
1008*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1009*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1010*eb293b8fSAndroid Build Coastguard Worker 
1011*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1012*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1f, this->op_->cur_op());
1013*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1014*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-72), this->op_->StackAt(0));
1015*eb293b8fSAndroid Build Coastguard Worker 
1016*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1017*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1018*eb293b8fSAndroid Build Coastguard Worker 
1019*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1020*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1f, this->op_->cur_op());
1021*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1022*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x01U, this->op_->StackAt(0));
1023*eb293b8fSAndroid Build Coastguard Worker }
1024*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_not)1025*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_not) {
1026*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1027*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1028*eb293b8fSAndroid Build Coastguard Worker       0x20,
1029*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
1030*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x4, 0x20,
1031*eb293b8fSAndroid Build Coastguard Worker       // Push a negative value.
1032*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x7c, 0x20,
1033*eb293b8fSAndroid Build Coastguard Worker   };
1034*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1035*eb293b8fSAndroid Build Coastguard Worker 
1036*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1037*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1038*eb293b8fSAndroid Build Coastguard Worker 
1039*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1040*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1041*eb293b8fSAndroid Build Coastguard Worker 
1042*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1043*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x20, this->op_->cur_op());
1044*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1045*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-5), this->op_->StackAt(0));
1046*eb293b8fSAndroid Build Coastguard Worker 
1047*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1048*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1049*eb293b8fSAndroid Build Coastguard Worker 
1050*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1051*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x20, this->op_->cur_op());
1052*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1053*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x03U, this->op_->StackAt(0));
1054*eb293b8fSAndroid Build Coastguard Worker }
1055*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_or)1056*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_or) {
1057*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1058*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1059*eb293b8fSAndroid Build Coastguard Worker       0x21,
1060*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
1061*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x48,
1062*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
1063*eb293b8fSAndroid Build Coastguard Worker       0x21,
1064*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
1065*eb293b8fSAndroid Build Coastguard Worker       0x08, 0xf4, 0x21,
1066*eb293b8fSAndroid Build Coastguard Worker   };
1067*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1068*eb293b8fSAndroid Build Coastguard Worker 
1069*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1070*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1071*eb293b8fSAndroid Build Coastguard Worker 
1072*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1073*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1074*eb293b8fSAndroid Build Coastguard Worker 
1075*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1076*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1077*eb293b8fSAndroid Build Coastguard Worker 
1078*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1079*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1080*eb293b8fSAndroid Build Coastguard Worker 
1081*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1082*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x21, this->op_->cur_op());
1083*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1084*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xfcU, this->op_->StackAt(0));
1085*eb293b8fSAndroid Build Coastguard Worker }
1086*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_plus)1087*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_plus) {
1088*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1089*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1090*eb293b8fSAndroid Build Coastguard Worker       0x22,
1091*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
1092*eb293b8fSAndroid Build Coastguard Worker       0x08, 0xff,
1093*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
1094*eb293b8fSAndroid Build Coastguard Worker       0x22,
1095*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
1096*eb293b8fSAndroid Build Coastguard Worker       0x08, 0xf2, 0x22,
1097*eb293b8fSAndroid Build Coastguard Worker   };
1098*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1099*eb293b8fSAndroid Build Coastguard Worker 
1100*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1101*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1102*eb293b8fSAndroid Build Coastguard Worker 
1103*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1104*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1105*eb293b8fSAndroid Build Coastguard Worker 
1106*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1107*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1108*eb293b8fSAndroid Build Coastguard Worker 
1109*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1110*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1111*eb293b8fSAndroid Build Coastguard Worker 
1112*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1113*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x22, this->op_->cur_op());
1114*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1115*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1f1U, this->op_->StackAt(0));
1116*eb293b8fSAndroid Build Coastguard Worker }
1117*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_plus_uconst)1118*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_plus_uconst) {
1119*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1120*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1121*eb293b8fSAndroid Build Coastguard Worker       0x23,
1122*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
1123*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x50, 0x23, 0x80, 0x51,
1124*eb293b8fSAndroid Build Coastguard Worker   };
1125*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1126*eb293b8fSAndroid Build Coastguard Worker 
1127*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1128*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1129*eb293b8fSAndroid Build Coastguard Worker 
1130*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1131*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1132*eb293b8fSAndroid Build Coastguard Worker 
1133*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1134*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x23, this->op_->cur_op());
1135*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1136*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x28d0U, this->op_->StackAt(0));
1137*eb293b8fSAndroid Build Coastguard Worker }
1138*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_shl)1139*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_shl) {
1140*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1141*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1142*eb293b8fSAndroid Build Coastguard Worker       0x24,
1143*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
1144*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x67,
1145*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
1146*eb293b8fSAndroid Build Coastguard Worker       0x24,
1147*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
1148*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x03, 0x24,
1149*eb293b8fSAndroid Build Coastguard Worker   };
1150*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1151*eb293b8fSAndroid Build Coastguard Worker 
1152*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1153*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1154*eb293b8fSAndroid Build Coastguard Worker 
1155*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1156*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1157*eb293b8fSAndroid Build Coastguard Worker 
1158*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1159*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1160*eb293b8fSAndroid Build Coastguard Worker 
1161*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1162*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1163*eb293b8fSAndroid Build Coastguard Worker 
1164*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1165*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x24, this->op_->cur_op());
1166*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1167*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x338U, this->op_->StackAt(0));
1168*eb293b8fSAndroid Build Coastguard Worker }
1169*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_shr)1170*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_shr) {
1171*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1172*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1173*eb293b8fSAndroid Build Coastguard Worker       0x25,
1174*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
1175*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x70,
1176*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
1177*eb293b8fSAndroid Build Coastguard Worker       0x25,
1178*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
1179*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x03, 0x25,
1180*eb293b8fSAndroid Build Coastguard Worker   };
1181*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1182*eb293b8fSAndroid Build Coastguard Worker 
1183*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1184*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1185*eb293b8fSAndroid Build Coastguard Worker 
1186*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1187*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1188*eb293b8fSAndroid Build Coastguard Worker 
1189*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1190*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1191*eb293b8fSAndroid Build Coastguard Worker 
1192*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1193*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1194*eb293b8fSAndroid Build Coastguard Worker 
1195*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1196*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x25, this->op_->cur_op());
1197*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1198*eb293b8fSAndroid Build Coastguard Worker   if (sizeof(TypeParam) == 4) {
1199*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x1ffffffeU, this->op_->StackAt(0));
1200*eb293b8fSAndroid Build Coastguard Worker   } else {
1201*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(0x1ffffffffffffffeULL, this->op_->StackAt(0));
1202*eb293b8fSAndroid Build Coastguard Worker   }
1203*eb293b8fSAndroid Build Coastguard Worker }
1204*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_shra)1205*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_shra) {
1206*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1207*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1208*eb293b8fSAndroid Build Coastguard Worker       0x26,
1209*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
1210*eb293b8fSAndroid Build Coastguard Worker       0x11, 0x70,
1211*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
1212*eb293b8fSAndroid Build Coastguard Worker       0x26,
1213*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
1214*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x03, 0x26,
1215*eb293b8fSAndroid Build Coastguard Worker   };
1216*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1217*eb293b8fSAndroid Build Coastguard Worker 
1218*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1219*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1220*eb293b8fSAndroid Build Coastguard Worker 
1221*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1222*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1223*eb293b8fSAndroid Build Coastguard Worker 
1224*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1225*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1226*eb293b8fSAndroid Build Coastguard Worker 
1227*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1228*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1229*eb293b8fSAndroid Build Coastguard Worker 
1230*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1231*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x26, this->op_->cur_op());
1232*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1233*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(static_cast<TypeParam>(-2), this->op_->StackAt(0));
1234*eb293b8fSAndroid Build Coastguard Worker }
1235*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_xor)1236*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_xor) {
1237*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1238*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1239*eb293b8fSAndroid Build Coastguard Worker       0x27,
1240*eb293b8fSAndroid Build Coastguard Worker       // Push a single value.
1241*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x11,
1242*eb293b8fSAndroid Build Coastguard Worker       // One element stack, and op will fail.
1243*eb293b8fSAndroid Build Coastguard Worker       0x27,
1244*eb293b8fSAndroid Build Coastguard Worker       // Push another value.
1245*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x41, 0x27,
1246*eb293b8fSAndroid Build Coastguard Worker   };
1247*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1248*eb293b8fSAndroid Build Coastguard Worker 
1249*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1250*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1251*eb293b8fSAndroid Build Coastguard Worker 
1252*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1253*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1254*eb293b8fSAndroid Build Coastguard Worker 
1255*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1256*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1257*eb293b8fSAndroid Build Coastguard Worker 
1258*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1259*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, this->op_->StackSize());
1260*eb293b8fSAndroid Build Coastguard Worker 
1261*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1262*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x27, this->op_->cur_op());
1263*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1264*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x50U, this->op_->StackAt(0));
1265*eb293b8fSAndroid Build Coastguard Worker }
1266*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_bra)1267*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_bra) {
1268*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1269*eb293b8fSAndroid Build Coastguard Worker       // No stack, and op will fail.
1270*eb293b8fSAndroid Build Coastguard Worker       0x28,
1271*eb293b8fSAndroid Build Coastguard Worker       // Push on a non-zero value with a positive branch.
1272*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x11, 0x28, 0x02, 0x01,
1273*eb293b8fSAndroid Build Coastguard Worker       // Push on a zero value with a positive branch.
1274*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x00, 0x28, 0x05, 0x00,
1275*eb293b8fSAndroid Build Coastguard Worker       // Push on a non-zero value with a negative branch.
1276*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x11, 0x28, 0xfc, 0xff,
1277*eb293b8fSAndroid Build Coastguard Worker       // Push on a zero value with a negative branch.
1278*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x00, 0x28, 0xf0, 0xff,
1279*eb293b8fSAndroid Build Coastguard Worker   };
1280*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1281*eb293b8fSAndroid Build Coastguard Worker 
1282*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Decode());
1283*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1284*eb293b8fSAndroid Build Coastguard Worker 
1285*eb293b8fSAndroid Build Coastguard Worker   // Push on a non-zero value with a positive branch.
1286*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1287*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1288*eb293b8fSAndroid Build Coastguard Worker 
1289*eb293b8fSAndroid Build Coastguard Worker   uint64_t offset = this->mem_->cur_offset() + 3;
1290*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1291*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x28, this->op_->cur_op());
1292*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
1293*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(offset + 0x102, this->mem_->cur_offset());
1294*eb293b8fSAndroid Build Coastguard Worker 
1295*eb293b8fSAndroid Build Coastguard Worker   // Push on a zero value with a positive branch.
1296*eb293b8fSAndroid Build Coastguard Worker   this->mem_->set_cur_offset(offset);
1297*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1298*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1299*eb293b8fSAndroid Build Coastguard Worker 
1300*eb293b8fSAndroid Build Coastguard Worker   offset = this->mem_->cur_offset() + 3;
1301*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1302*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x28, this->op_->cur_op());
1303*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
1304*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(offset, this->mem_->cur_offset());
1305*eb293b8fSAndroid Build Coastguard Worker 
1306*eb293b8fSAndroid Build Coastguard Worker   // Push on a non-zero value with a negative branch.
1307*eb293b8fSAndroid Build Coastguard Worker   this->mem_->set_cur_offset(offset);
1308*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1309*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1310*eb293b8fSAndroid Build Coastguard Worker 
1311*eb293b8fSAndroid Build Coastguard Worker   offset = this->mem_->cur_offset() + 3;
1312*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1313*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x28, this->op_->cur_op());
1314*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
1315*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(offset - 4, this->mem_->cur_offset());
1316*eb293b8fSAndroid Build Coastguard Worker 
1317*eb293b8fSAndroid Build Coastguard Worker   // Push on a zero value with a negative branch.
1318*eb293b8fSAndroid Build Coastguard Worker   this->mem_->set_cur_offset(offset);
1319*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1320*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1321*eb293b8fSAndroid Build Coastguard Worker 
1322*eb293b8fSAndroid Build Coastguard Worker   offset = this->mem_->cur_offset() + 3;
1323*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1324*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x28, this->op_->cur_op());
1325*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
1326*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(offset, this->mem_->cur_offset());
1327*eb293b8fSAndroid Build Coastguard Worker }
1328*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,compare_opcode_stack_error)1329*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, compare_opcode_stack_error) {
1330*eb293b8fSAndroid Build Coastguard Worker   // All of the ops require two stack elements. Loop through all of these
1331*eb293b8fSAndroid Build Coastguard Worker   // ops with potential errors.
1332*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1333*eb293b8fSAndroid Build Coastguard Worker       0xff,  // Place holder for compare op.
1334*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x11,
1335*eb293b8fSAndroid Build Coastguard Worker       0xff,  // Place holder for compare op.
1336*eb293b8fSAndroid Build Coastguard Worker   };
1337*eb293b8fSAndroid Build Coastguard Worker 
1338*eb293b8fSAndroid Build Coastguard Worker   for (uint8_t opcode = 0x29; opcode <= 0x2e; opcode++) {
1339*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer[0] = opcode;
1340*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer[3] = opcode;
1341*eb293b8fSAndroid Build Coastguard Worker     this->op_memory_->SetMemory(0, opcode_buffer);
1342*eb293b8fSAndroid Build Coastguard Worker 
1343*eb293b8fSAndroid Build Coastguard Worker     ASSERT_FALSE(this->op_->Eval(0, 1));
1344*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(opcode, this->op_->cur_op());
1345*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1346*eb293b8fSAndroid Build Coastguard Worker 
1347*eb293b8fSAndroid Build Coastguard Worker     ASSERT_FALSE(this->op_->Eval(1, 4));
1348*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(opcode, this->op_->cur_op());
1349*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(1U, this->op_->StackSize());
1350*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1351*eb293b8fSAndroid Build Coastguard Worker   }
1352*eb293b8fSAndroid Build Coastguard Worker }
1353*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,compare_opcodes)1354*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, compare_opcodes) {
1355*eb293b8fSAndroid Build Coastguard Worker   // Have three different checks for each compare op:
1356*eb293b8fSAndroid Build Coastguard Worker   //   - Both values the same.
1357*eb293b8fSAndroid Build Coastguard Worker   //   - The first value larger than the second.
1358*eb293b8fSAndroid Build Coastguard Worker   //   - The second value larger than the first.
1359*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1360*eb293b8fSAndroid Build Coastguard Worker       // Values the same.
1361*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x11, 0x08, 0x11,
1362*eb293b8fSAndroid Build Coastguard Worker       0xff,  // Placeholder.
1363*eb293b8fSAndroid Build Coastguard Worker       // First value larger.
1364*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x12, 0x08, 0x10,
1365*eb293b8fSAndroid Build Coastguard Worker       0xff,  // Placeholder.
1366*eb293b8fSAndroid Build Coastguard Worker       // Second value larger.
1367*eb293b8fSAndroid Build Coastguard Worker       0x08, 0x10, 0x08, 0x12,
1368*eb293b8fSAndroid Build Coastguard Worker       0xff,  // Placeholder.
1369*eb293b8fSAndroid Build Coastguard Worker   };
1370*eb293b8fSAndroid Build Coastguard Worker 
1371*eb293b8fSAndroid Build Coastguard Worker   // Opcode followed by the expected values on the stack.
1372*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> expected = {
1373*eb293b8fSAndroid Build Coastguard Worker       0x29, 1, 0, 0,  // eq
1374*eb293b8fSAndroid Build Coastguard Worker       0x2a, 1, 1, 0,  // ge
1375*eb293b8fSAndroid Build Coastguard Worker       0x2b, 0, 1, 0,  // gt
1376*eb293b8fSAndroid Build Coastguard Worker       0x2c, 1, 0, 1,  // le
1377*eb293b8fSAndroid Build Coastguard Worker       0x2d, 0, 0, 1,  // lt
1378*eb293b8fSAndroid Build Coastguard Worker       0x2e, 0, 1, 1,  // ne
1379*eb293b8fSAndroid Build Coastguard Worker   };
1380*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < expected.size(); i += 4) {
1381*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer[4] = expected[i];
1382*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer[9] = expected[i];
1383*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer[14] = expected[i];
1384*eb293b8fSAndroid Build Coastguard Worker     this->op_memory_->SetMemory(0, opcode_buffer);
1385*eb293b8fSAndroid Build Coastguard Worker 
1386*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(this->op_->Eval(0, 15))
1387*eb293b8fSAndroid Build Coastguard Worker         << "Op: 0x" << std::hex << static_cast<uint32_t>(expected[i]) << " failed";
1388*eb293b8fSAndroid Build Coastguard Worker 
1389*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(3U, this->op_->StackSize());
1390*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(expected[i + 1], this->op_->StackAt(2));
1391*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(expected[i + 2], this->op_->StackAt(1));
1392*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(expected[i + 3], this->op_->StackAt(0));
1393*eb293b8fSAndroid Build Coastguard Worker   }
1394*eb293b8fSAndroid Build Coastguard Worker }
1395*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_skip)1396*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_skip) {
1397*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1398*eb293b8fSAndroid Build Coastguard Worker       // Positive value.
1399*eb293b8fSAndroid Build Coastguard Worker       0x2f, 0x10, 0x20,
1400*eb293b8fSAndroid Build Coastguard Worker       // Negative value.
1401*eb293b8fSAndroid Build Coastguard Worker       0x2f, 0xfd, 0xff,
1402*eb293b8fSAndroid Build Coastguard Worker   };
1403*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1404*eb293b8fSAndroid Build Coastguard Worker 
1405*eb293b8fSAndroid Build Coastguard Worker   uint64_t offset = this->mem_->cur_offset() + 3;
1406*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1407*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2f, this->op_->cur_op());
1408*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
1409*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(offset + 0x2010, this->mem_->cur_offset());
1410*eb293b8fSAndroid Build Coastguard Worker 
1411*eb293b8fSAndroid Build Coastguard Worker   this->mem_->set_cur_offset(offset);
1412*eb293b8fSAndroid Build Coastguard Worker   offset = this->mem_->cur_offset() + 3;
1413*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1414*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2f, this->op_->cur_op());
1415*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
1416*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(offset - 3, this->mem_->cur_offset());
1417*eb293b8fSAndroid Build Coastguard Worker }
1418*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_lit)1419*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_lit) {
1420*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer;
1421*eb293b8fSAndroid Build Coastguard Worker 
1422*eb293b8fSAndroid Build Coastguard Worker   // Verify every lit opcode.
1423*eb293b8fSAndroid Build Coastguard Worker   for (uint8_t op = 0x30; op <= 0x4f; op++) {
1424*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(op);
1425*eb293b8fSAndroid Build Coastguard Worker   }
1426*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1427*eb293b8fSAndroid Build Coastguard Worker 
1428*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < opcode_buffer.size(); i++) {
1429*eb293b8fSAndroid Build Coastguard Worker     uint32_t op = opcode_buffer[i];
1430*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op;
1431*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(op, this->op_->cur_op());
1432*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
1433*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(op - 0x30U, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
1434*eb293b8fSAndroid Build Coastguard Worker   }
1435*eb293b8fSAndroid Build Coastguard Worker }
1436*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_reg)1437*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_reg) {
1438*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer;
1439*eb293b8fSAndroid Build Coastguard Worker 
1440*eb293b8fSAndroid Build Coastguard Worker   // Verify every reg opcode.
1441*eb293b8fSAndroid Build Coastguard Worker   for (uint8_t op = 0x50; op <= 0x6f; op++) {
1442*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(op);
1443*eb293b8fSAndroid Build Coastguard Worker   }
1444*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1445*eb293b8fSAndroid Build Coastguard Worker 
1446*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < opcode_buffer.size(); i++) {
1447*eb293b8fSAndroid Build Coastguard Worker     uint32_t op = opcode_buffer[i];
1448*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op;
1449*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(op, this->op_->cur_op());
1450*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(this->op_->is_register()) << "Failed op: 0x" << std::hex << op;
1451*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
1452*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(op - 0x50U, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
1453*eb293b8fSAndroid Build Coastguard Worker   }
1454*eb293b8fSAndroid Build Coastguard Worker }
1455*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_regx)1456*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_regx) {
1457*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1458*eb293b8fSAndroid Build Coastguard Worker       0x90, 0x02, 0x90, 0x80, 0x15,
1459*eb293b8fSAndroid Build Coastguard Worker   };
1460*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1461*eb293b8fSAndroid Build Coastguard Worker 
1462*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(0, 2));
1463*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x90, this->op_->cur_op());
1464*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->is_register());
1465*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1466*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x02U, this->op_->StackAt(0));
1467*eb293b8fSAndroid Build Coastguard Worker 
1468*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(2, 5));
1469*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x90, this->op_->cur_op());
1470*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->is_register());
1471*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1472*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0xa80U, this->op_->StackAt(0));
1473*eb293b8fSAndroid Build Coastguard Worker }
1474*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_breg)1475*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_breg) {
1476*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer;
1477*eb293b8fSAndroid Build Coastguard Worker 
1478*eb293b8fSAndroid Build Coastguard Worker   // Verify every reg opcode.
1479*eb293b8fSAndroid Build Coastguard Worker   for (uint8_t op = 0x70; op <= 0x8f; op++) {
1480*eb293b8fSAndroid Build Coastguard Worker     // Positive value added to register.
1481*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(op);
1482*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x12);
1483*eb293b8fSAndroid Build Coastguard Worker     // Negative value added to register.
1484*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(op);
1485*eb293b8fSAndroid Build Coastguard Worker     opcode_buffer.push_back(0x7e);
1486*eb293b8fSAndroid Build Coastguard Worker   }
1487*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1488*eb293b8fSAndroid Build Coastguard Worker 
1489*eb293b8fSAndroid Build Coastguard Worker   RegsImplFake<TypeParam> regs(32);
1490*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 32; i++) {
1491*eb293b8fSAndroid Build Coastguard Worker     regs[i] = i + 10;
1492*eb293b8fSAndroid Build Coastguard Worker   }
1493*eb293b8fSAndroid Build Coastguard Worker   RegsInfo<TypeParam> regs_info(&regs);
1494*eb293b8fSAndroid Build Coastguard Worker   this->op_->set_regs_info(&regs_info);
1495*eb293b8fSAndroid Build Coastguard Worker 
1496*eb293b8fSAndroid Build Coastguard Worker   uint64_t offset = 0;
1497*eb293b8fSAndroid Build Coastguard Worker   for (uint32_t op = 0x70; op <= 0x8f; op++) {
1498*eb293b8fSAndroid Build Coastguard Worker     // Positive value added to register.
1499*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op;
1500*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(op, this->op_->cur_op());
1501*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
1502*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(op - 0x70 + 10 + 0x12, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
1503*eb293b8fSAndroid Build Coastguard Worker     offset += 2;
1504*eb293b8fSAndroid Build Coastguard Worker 
1505*eb293b8fSAndroid Build Coastguard Worker     // Negative value added to register.
1506*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op;
1507*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(op, this->op_->cur_op());
1508*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
1509*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(op - 0x70 + 10 - 2, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
1510*eb293b8fSAndroid Build Coastguard Worker     offset += 2;
1511*eb293b8fSAndroid Build Coastguard Worker   }
1512*eb293b8fSAndroid Build Coastguard Worker }
1513*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_breg_invalid_register)1514*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_breg_invalid_register) {
1515*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {
1516*eb293b8fSAndroid Build Coastguard Worker       0x7f, 0x12, 0x80, 0x12,
1517*eb293b8fSAndroid Build Coastguard Worker   };
1518*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1519*eb293b8fSAndroid Build Coastguard Worker 
1520*eb293b8fSAndroid Build Coastguard Worker   RegsImplFake<TypeParam> regs(16);
1521*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 16; i++) {
1522*eb293b8fSAndroid Build Coastguard Worker     regs[i] = i + 10;
1523*eb293b8fSAndroid Build Coastguard Worker   }
1524*eb293b8fSAndroid Build Coastguard Worker   RegsInfo<TypeParam> regs_info(&regs);
1525*eb293b8fSAndroid Build Coastguard Worker   this->op_->set_regs_info(&regs_info);
1526*eb293b8fSAndroid Build Coastguard Worker 
1527*eb293b8fSAndroid Build Coastguard Worker   // Should pass since this references the last regsister.
1528*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(0, 2));
1529*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x7fU, this->op_->cur_op());
1530*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1531*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2bU, this->op_->StackAt(0));
1532*eb293b8fSAndroid Build Coastguard Worker 
1533*eb293b8fSAndroid Build Coastguard Worker   // Should fail since this references a non-existent register.
1534*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Eval(2, 4));
1535*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
1536*eb293b8fSAndroid Build Coastguard Worker }
1537*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_bregx)1538*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_bregx) {
1539*eb293b8fSAndroid Build Coastguard Worker   std::vector<uint8_t> opcode_buffer = {// Positive value added to register.
1540*eb293b8fSAndroid Build Coastguard Worker                                         0x92, 0x05, 0x20,
1541*eb293b8fSAndroid Build Coastguard Worker                                         // Negative value added to register.
1542*eb293b8fSAndroid Build Coastguard Worker                                         0x92, 0x06, 0x80, 0x7e,
1543*eb293b8fSAndroid Build Coastguard Worker                                         // Illegal register.
1544*eb293b8fSAndroid Build Coastguard Worker                                         0x92, 0x80, 0x15, 0x80, 0x02};
1545*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, opcode_buffer);
1546*eb293b8fSAndroid Build Coastguard Worker 
1547*eb293b8fSAndroid Build Coastguard Worker   RegsImplFake<TypeParam> regs(10);
1548*eb293b8fSAndroid Build Coastguard Worker   regs[5] = 0x45;
1549*eb293b8fSAndroid Build Coastguard Worker   regs[6] = 0x190;
1550*eb293b8fSAndroid Build Coastguard Worker   RegsInfo<TypeParam> regs_info(&regs);
1551*eb293b8fSAndroid Build Coastguard Worker   this->op_->set_regs_info(&regs_info);
1552*eb293b8fSAndroid Build Coastguard Worker 
1553*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(0, 3));
1554*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x92, this->op_->cur_op());
1555*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1556*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x65U, this->op_->StackAt(0));
1557*eb293b8fSAndroid Build Coastguard Worker 
1558*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(3, 7));
1559*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x92, this->op_->cur_op());
1560*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, this->op_->StackSize());
1561*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x90U, this->op_->StackAt(0));
1562*eb293b8fSAndroid Build Coastguard Worker 
1563*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(this->op_->Eval(7, 12));
1564*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
1565*eb293b8fSAndroid Build Coastguard Worker }
1566*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,op_nop)1567*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, op_nop) {
1568*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x96});
1569*eb293b8fSAndroid Build Coastguard Worker 
1570*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Decode());
1571*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x96, this->op_->cur_op());
1572*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, this->op_->StackSize());
1573*eb293b8fSAndroid Build Coastguard Worker }
1574*eb293b8fSAndroid Build Coastguard Worker 
TYPED_TEST_P(DwarfOpTest,is_dex_pc)1575*eb293b8fSAndroid Build Coastguard Worker TYPED_TEST_P(DwarfOpTest, is_dex_pc) {
1576*eb293b8fSAndroid Build Coastguard Worker   // Special sequence that indicates this is a dex pc.
1577*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '1', 0x13});
1578*eb293b8fSAndroid Build Coastguard Worker 
1579*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(0, 6));
1580*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(this->op_->dex_pc_set());
1581*eb293b8fSAndroid Build Coastguard Worker 
1582*eb293b8fSAndroid Build Coastguard Worker   // Try without the last op.
1583*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(0, 5));
1584*eb293b8fSAndroid Build Coastguard Worker   EXPECT_FALSE(this->op_->dex_pc_set());
1585*eb293b8fSAndroid Build Coastguard Worker 
1586*eb293b8fSAndroid Build Coastguard Worker   // Change the constant.
1587*eb293b8fSAndroid Build Coastguard Worker   this->op_memory_->SetMemory(0, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '2', 0x13});
1588*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(this->op_->Eval(0, 6));
1589*eb293b8fSAndroid Build Coastguard Worker   EXPECT_FALSE(this->op_->dex_pc_set());
1590*eb293b8fSAndroid Build Coastguard Worker }
1591*eb293b8fSAndroid Build Coastguard Worker 
1592*eb293b8fSAndroid Build Coastguard Worker REGISTER_TYPED_TEST_SUITE_P(DwarfOpTest, decode, eval, illegal_opcode, not_implemented, op_addr,
1593*eb293b8fSAndroid Build Coastguard Worker                             op_deref, op_deref_size, const_unsigned, const_signed, const_uleb,
1594*eb293b8fSAndroid Build Coastguard Worker                             const_sleb, op_dup, op_drop, op_over, op_pick, op_swap, op_rot, op_abs,
1595*eb293b8fSAndroid Build Coastguard Worker                             op_and, op_div, op_minus, op_mod, op_mul, op_neg, op_not, op_or,
1596*eb293b8fSAndroid Build Coastguard Worker                             op_plus, op_plus_uconst, op_shl, op_shr, op_shra, op_xor, op_bra,
1597*eb293b8fSAndroid Build Coastguard Worker                             compare_opcode_stack_error, compare_opcodes, op_skip, op_lit, op_reg,
1598*eb293b8fSAndroid Build Coastguard Worker                             op_regx, op_breg, op_breg_invalid_register, op_bregx, op_nop,
1599*eb293b8fSAndroid Build Coastguard Worker                             is_dex_pc);
1600*eb293b8fSAndroid Build Coastguard Worker 
1601*eb293b8fSAndroid Build Coastguard Worker typedef ::testing::Types<uint32_t, uint64_t> DwarfOpTestTypes;
1602*eb293b8fSAndroid Build Coastguard Worker INSTANTIATE_TYPED_TEST_SUITE_P(Libunwindstack, DwarfOpTest, DwarfOpTestTypes);
1603*eb293b8fSAndroid Build Coastguard Worker 
1604*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
1605