blob: ef9e61cfa07b6199b51283f68d4030a260513b0a [file] [log] [blame]
Christopher Ferriseb4a6db2017-07-19 12:37:45 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdint.h>
18
19#include <gtest/gtest.h>
20
21#include <unwindstack/Elf.h>
Christopher Ferrisd06001d2017-11-30 18:56:01 -080022#include <unwindstack/RegsArm.h>
23#include <unwindstack/RegsArm64.h>
24#include <unwindstack/RegsX86.h>
25#include <unwindstack/RegsX86_64.h>
Douglas Leung61b1a1a2017-11-08 10:53:53 +010026#include <unwindstack/RegsMips.h>
27#include <unwindstack/RegsMips64.h>
Christopher Ferriseb4a6db2017-07-19 12:37:45 -070028
Christopher Ferrisd06001d2017-11-30 18:56:01 -080029#include "MachineArm.h"
30#include "MachineArm64.h"
31#include "MachineX86.h"
32#include "MachineX86_64.h"
Douglas Leung61b1a1a2017-11-08 10:53:53 +010033#include "MachineMips.h"
34#include "MachineMips64.h"
Christopher Ferriseb4a6db2017-07-19 12:37:45 -070035
36#include "MemoryFake.h"
37
38namespace unwindstack {
39
40class RegsStepIfSignalHandlerTest : public ::testing::Test {
41 protected:
42 void SetUp() override {
43 elf_memory_ = new MemoryFake;
44 elf_.reset(new Elf(elf_memory_));
45 }
46
47 void ArmStepIfSignalHandlerNonRt(uint32_t pc_data);
48 void ArmStepIfSignalHandlerRt(uint32_t pc_data);
49
50 MemoryFake* elf_memory_;
51 MemoryFake process_memory_;
52 std::unique_ptr<Elf> elf_;
53};
54
55void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerNonRt(uint32_t pc_data) {
56 uint64_t addr = 0x1000;
57 RegsArm regs;
58 regs[ARM_REG_PC] = 0x5000;
59 regs[ARM_REG_SP] = addr;
60 regs.SetFromRaw();
61
62 elf_memory_->SetData32(0x5000, pc_data);
63
64 for (uint64_t index = 0; index <= 30; index++) {
65 process_memory_.SetData32(addr + index * 4, index * 0x10);
66 }
67
68 ASSERT_TRUE(regs.StepIfSignalHandler(0x5000, elf_.get(), &process_memory_));
69 EXPECT_EQ(0x100U, regs[ARM_REG_SP]);
70 EXPECT_EQ(0x120U, regs[ARM_REG_PC]);
71 EXPECT_EQ(0x100U, regs.sp());
72 EXPECT_EQ(0x120U, regs.pc());
73}
74
75TEST_F(RegsStepIfSignalHandlerTest, arm_step_if_signal_handler_non_rt) {
76 // Form 1
77 ArmStepIfSignalHandlerNonRt(0xe3a07077);
78
79 // Form 2
80 ArmStepIfSignalHandlerNonRt(0xef900077);
81
82 // Form 3
83 ArmStepIfSignalHandlerNonRt(0xdf002777);
84}
85
86void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerRt(uint32_t pc_data) {
87 uint64_t addr = 0x1000;
88 RegsArm regs;
89 regs[ARM_REG_PC] = 0x5000;
90 regs[ARM_REG_SP] = addr;
91 regs.SetFromRaw();
92
93 elf_memory_->SetData32(0x5000, pc_data);
94
95 for (uint64_t index = 0; index <= 100; index++) {
96 process_memory_.SetData32(addr + index * 4, index * 0x10);
97 }
98
99 ASSERT_TRUE(regs.StepIfSignalHandler(0x5000, elf_.get(), &process_memory_));
100 EXPECT_EQ(0x350U, regs[ARM_REG_SP]);
101 EXPECT_EQ(0x370U, regs[ARM_REG_PC]);
102 EXPECT_EQ(0x350U, regs.sp());
103 EXPECT_EQ(0x370U, regs.pc());
104}
105
106TEST_F(RegsStepIfSignalHandlerTest, arm_step_if_signal_handler_rt) {
107 // Form 1
108 ArmStepIfSignalHandlerRt(0xe3a070ad);
109
110 // Form 2
111 ArmStepIfSignalHandlerRt(0xef9000ad);
112
113 // Form 3
114 ArmStepIfSignalHandlerRt(0xdf0027ad);
115}
116
117TEST_F(RegsStepIfSignalHandlerTest, arm64_step_if_signal_handler) {
118 uint64_t addr = 0x1000;
119 RegsArm64 regs;
120 regs[ARM64_REG_PC] = 0x8000;
121 regs[ARM64_REG_SP] = addr;
122 regs.SetFromRaw();
123
124 elf_memory_->SetData64(0x8000, 0xd4000001d2801168ULL);
125
126 for (uint64_t index = 0; index <= 100; index++) {
127 process_memory_.SetData64(addr + index * 8, index * 0x10);
128 }
129
130 ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
131 EXPECT_EQ(0x460U, regs[ARM64_REG_SP]);
132 EXPECT_EQ(0x470U, regs[ARM64_REG_PC]);
133 EXPECT_EQ(0x460U, regs.sp());
134 EXPECT_EQ(0x470U, regs.pc());
135}
136
137TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_no_siginfo) {
138 uint64_t addr = 0xa00;
139 RegsX86 regs;
140 regs[X86_REG_EIP] = 0x4100;
141 regs[X86_REG_ESP] = addr;
142 regs.SetFromRaw();
143
144 elf_memory_->SetData64(0x4100, 0x80cd00000077b858ULL);
145 for (uint64_t index = 0; index <= 25; index++) {
146 process_memory_.SetData32(addr + index * 4, index * 0x10);
147 }
148
149 ASSERT_TRUE(regs.StepIfSignalHandler(0x4100, elf_.get(), &process_memory_));
150 EXPECT_EQ(0x70U, regs[X86_REG_EBP]);
151 EXPECT_EQ(0x80U, regs[X86_REG_ESP]);
152 EXPECT_EQ(0x90U, regs[X86_REG_EBX]);
153 EXPECT_EQ(0xa0U, regs[X86_REG_EDX]);
154 EXPECT_EQ(0xb0U, regs[X86_REG_ECX]);
155 EXPECT_EQ(0xc0U, regs[X86_REG_EAX]);
156 EXPECT_EQ(0xf0U, regs[X86_REG_EIP]);
157 EXPECT_EQ(0x80U, regs.sp());
158 EXPECT_EQ(0xf0U, regs.pc());
159}
160
161TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_siginfo) {
162 uint64_t addr = 0xa00;
163 RegsX86 regs;
164 regs[X86_REG_EIP] = 0x4100;
165 regs[X86_REG_ESP] = addr;
166 regs.SetFromRaw();
167
168 elf_memory_->SetData64(0x4100, 0x0080cd000000adb8ULL);
169 addr += 8;
170 // Pointer to ucontext data.
171 process_memory_.SetData32(addr, 0x8100);
172
173 addr = 0x8100;
174 for (uint64_t index = 0; index <= 30; index++) {
175 process_memory_.SetData32(addr + index * 4, index * 0x10);
176 }
177
178 ASSERT_TRUE(regs.StepIfSignalHandler(0x4100, elf_.get(), &process_memory_));
179 EXPECT_EQ(0xb0U, regs[X86_REG_EBP]);
180 EXPECT_EQ(0xc0U, regs[X86_REG_ESP]);
181 EXPECT_EQ(0xd0U, regs[X86_REG_EBX]);
182 EXPECT_EQ(0xe0U, regs[X86_REG_EDX]);
183 EXPECT_EQ(0xf0U, regs[X86_REG_ECX]);
184 EXPECT_EQ(0x100U, regs[X86_REG_EAX]);
185 EXPECT_EQ(0x130U, regs[X86_REG_EIP]);
186 EXPECT_EQ(0xc0U, regs.sp());
187 EXPECT_EQ(0x130U, regs.pc());
188}
189
190TEST_F(RegsStepIfSignalHandlerTest, x86_64_step_if_signal_handler) {
191 uint64_t addr = 0x500;
192 RegsX86_64 regs;
193 regs[X86_64_REG_RIP] = 0x7000;
194 regs[X86_64_REG_RSP] = addr;
195 regs.SetFromRaw();
196
197 elf_memory_->SetData64(0x7000, 0x0f0000000fc0c748);
198 elf_memory_->SetData16(0x7008, 0x0f05);
199
200 for (uint64_t index = 0; index <= 30; index++) {
201 process_memory_.SetData64(addr + index * 8, index * 0x10);
202 }
203
204 ASSERT_TRUE(regs.StepIfSignalHandler(0x7000, elf_.get(), &process_memory_));
205 EXPECT_EQ(0x140U, regs[X86_64_REG_RSP]);
206 EXPECT_EQ(0x150U, regs[X86_64_REG_RIP]);
207 EXPECT_EQ(0x140U, regs.sp());
208 EXPECT_EQ(0x150U, regs.pc());
209}
210
Douglas Leung61b1a1a2017-11-08 10:53:53 +0100211TEST_F(RegsStepIfSignalHandlerTest, mips_step_if_signal_handler_non_rt) {
212 uint64_t addr = 0x1000;
213 RegsMips regs;
214 regs[MIPS_REG_PC] = 0x8000;
215 regs[MIPS_REG_SP] = addr;
216 regs.SetFromRaw();
217
218 elf_memory_->SetData64(0x8000, 0x0000000c24021017ULL);
219
220 for (uint64_t index = 0; index <= 50; index++) {
221 process_memory_.SetData64(addr + index * 8, index * 0x10);
222 }
223
224 ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
225 EXPECT_EQ(0x220U, regs[MIPS_REG_SP]);
226 EXPECT_EQ(0x040U, regs[MIPS_REG_PC]);
227 EXPECT_EQ(0x220U, regs.sp());
228 EXPECT_EQ(0x040U, regs.pc());
229}
230
231TEST_F(RegsStepIfSignalHandlerTest, mips_step_if_signal_handler_rt) {
232 uint64_t addr = 0x1000;
233 RegsMips regs;
234 regs[MIPS_REG_PC] = 0x8000;
235 regs[MIPS_REG_SP] = addr;
236 regs.SetFromRaw();
237
238 elf_memory_->SetData64(0x8000, 0x0000000c24021061ULL);
239
240 for (uint64_t index = 0; index <= 100; index++) {
241 process_memory_.SetData64(addr + index * 8, index * 0x10);
242 }
243
244 ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
245 EXPECT_EQ(0x350U, regs[MIPS_REG_SP]);
246 EXPECT_EQ(0x170U, regs[MIPS_REG_PC]);
247 EXPECT_EQ(0x350U, regs.sp());
248 EXPECT_EQ(0x170U, regs.pc());
249}
250
251TEST_F(RegsStepIfSignalHandlerTest, mips64_step_if_signal_handler) {
252 uint64_t addr = 0x1000;
253 RegsMips64 regs;
254 regs[MIPS64_REG_PC] = 0x8000;
255 regs[MIPS64_REG_SP] = addr;
256 regs.SetFromRaw();
257
258 elf_memory_->SetData64(0x8000, 0x0000000c2402145bULL);
259
260 for (uint64_t index = 0; index <= 100; index++) {
261 process_memory_.SetData64(addr + index * 8, index * 0x10);
262 }
263
264 ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
265 EXPECT_EQ(0x350U, regs[MIPS64_REG_SP]);
266 EXPECT_EQ(0x600U, regs[MIPS64_REG_PC]);
267 EXPECT_EQ(0x350U, regs.sp());
268 EXPECT_EQ(0x600U, regs.pc());
269}
270
Christopher Ferriseb4a6db2017-07-19 12:37:45 -0700271} // namespace unwindstack