blob: ecd40518b27172598cb2afd2d0b24e71b30c9ce1 [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 Ferris53914162018-02-08 19:27:47 -080022#include <unwindstack/MachineArm.h>
23#include <unwindstack/MachineArm64.h>
24#include <unwindstack/MachineMips.h>
25#include <unwindstack/MachineMips64.h>
26#include <unwindstack/MachineX86.h>
27#include <unwindstack/MachineX86_64.h>
Christopher Ferrisd06001d2017-11-30 18:56:01 -080028#include <unwindstack/RegsArm.h>
29#include <unwindstack/RegsArm64.h>
Douglas Leung61b1a1a2017-11-08 10:53:53 +010030#include <unwindstack/RegsMips.h>
31#include <unwindstack/RegsMips64.h>
Christopher Ferris53914162018-02-08 19:27:47 -080032#include <unwindstack/RegsX86.h>
33#include <unwindstack/RegsX86_64.h>
Christopher Ferriseb4a6db2017-07-19 12:37:45 -070034
35#include "MemoryFake.h"
36
37namespace unwindstack {
38
39class RegsStepIfSignalHandlerTest : public ::testing::Test {
40 protected:
41 void SetUp() override {
42 elf_memory_ = new MemoryFake;
43 elf_.reset(new Elf(elf_memory_));
44 }
45
46 void ArmStepIfSignalHandlerNonRt(uint32_t pc_data);
47 void ArmStepIfSignalHandlerRt(uint32_t pc_data);
48
49 MemoryFake* elf_memory_;
50 MemoryFake process_memory_;
51 std::unique_ptr<Elf> elf_;
52};
53
54void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerNonRt(uint32_t pc_data) {
55 uint64_t addr = 0x1000;
56 RegsArm regs;
57 regs[ARM_REG_PC] = 0x5000;
58 regs[ARM_REG_SP] = addr;
59 regs.SetFromRaw();
60
61 elf_memory_->SetData32(0x5000, pc_data);
62
63 for (uint64_t index = 0; index <= 30; index++) {
64 process_memory_.SetData32(addr + index * 4, index * 0x10);
65 }
66
67 ASSERT_TRUE(regs.StepIfSignalHandler(0x5000, elf_.get(), &process_memory_));
68 EXPECT_EQ(0x100U, regs[ARM_REG_SP]);
69 EXPECT_EQ(0x120U, regs[ARM_REG_PC]);
70 EXPECT_EQ(0x100U, regs.sp());
71 EXPECT_EQ(0x120U, regs.pc());
72}
73
74TEST_F(RegsStepIfSignalHandlerTest, arm_step_if_signal_handler_non_rt) {
75 // Form 1
76 ArmStepIfSignalHandlerNonRt(0xe3a07077);
77
78 // Form 2
79 ArmStepIfSignalHandlerNonRt(0xef900077);
80
81 // Form 3
82 ArmStepIfSignalHandlerNonRt(0xdf002777);
83}
84
85void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerRt(uint32_t pc_data) {
86 uint64_t addr = 0x1000;
87 RegsArm regs;
88 regs[ARM_REG_PC] = 0x5000;
89 regs[ARM_REG_SP] = addr;
90 regs.SetFromRaw();
91
92 elf_memory_->SetData32(0x5000, pc_data);
93
94 for (uint64_t index = 0; index <= 100; index++) {
95 process_memory_.SetData32(addr + index * 4, index * 0x10);
96 }
97
98 ASSERT_TRUE(regs.StepIfSignalHandler(0x5000, elf_.get(), &process_memory_));
99 EXPECT_EQ(0x350U, regs[ARM_REG_SP]);
100 EXPECT_EQ(0x370U, regs[ARM_REG_PC]);
101 EXPECT_EQ(0x350U, regs.sp());
102 EXPECT_EQ(0x370U, regs.pc());
103}
104
105TEST_F(RegsStepIfSignalHandlerTest, arm_step_if_signal_handler_rt) {
106 // Form 1
107 ArmStepIfSignalHandlerRt(0xe3a070ad);
108
109 // Form 2
110 ArmStepIfSignalHandlerRt(0xef9000ad);
111
112 // Form 3
113 ArmStepIfSignalHandlerRt(0xdf0027ad);
114}
115
116TEST_F(RegsStepIfSignalHandlerTest, arm64_step_if_signal_handler) {
117 uint64_t addr = 0x1000;
118 RegsArm64 regs;
119 regs[ARM64_REG_PC] = 0x8000;
120 regs[ARM64_REG_SP] = addr;
121 regs.SetFromRaw();
122
123 elf_memory_->SetData64(0x8000, 0xd4000001d2801168ULL);
124
125 for (uint64_t index = 0; index <= 100; index++) {
126 process_memory_.SetData64(addr + index * 8, index * 0x10);
127 }
128
129 ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
130 EXPECT_EQ(0x460U, regs[ARM64_REG_SP]);
131 EXPECT_EQ(0x470U, regs[ARM64_REG_PC]);
132 EXPECT_EQ(0x460U, regs.sp());
133 EXPECT_EQ(0x470U, regs.pc());
134}
135
136TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_no_siginfo) {
137 uint64_t addr = 0xa00;
138 RegsX86 regs;
139 regs[X86_REG_EIP] = 0x4100;
140 regs[X86_REG_ESP] = addr;
141 regs.SetFromRaw();
142
143 elf_memory_->SetData64(0x4100, 0x80cd00000077b858ULL);
144 for (uint64_t index = 0; index <= 25; index++) {
145 process_memory_.SetData32(addr + index * 4, index * 0x10);
146 }
147
148 ASSERT_TRUE(regs.StepIfSignalHandler(0x4100, elf_.get(), &process_memory_));
149 EXPECT_EQ(0x70U, regs[X86_REG_EBP]);
150 EXPECT_EQ(0x80U, regs[X86_REG_ESP]);
151 EXPECT_EQ(0x90U, regs[X86_REG_EBX]);
152 EXPECT_EQ(0xa0U, regs[X86_REG_EDX]);
153 EXPECT_EQ(0xb0U, regs[X86_REG_ECX]);
154 EXPECT_EQ(0xc0U, regs[X86_REG_EAX]);
155 EXPECT_EQ(0xf0U, regs[X86_REG_EIP]);
156 EXPECT_EQ(0x80U, regs.sp());
157 EXPECT_EQ(0xf0U, regs.pc());
158}
159
160TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_siginfo) {
161 uint64_t addr = 0xa00;
162 RegsX86 regs;
163 regs[X86_REG_EIP] = 0x4100;
164 regs[X86_REG_ESP] = addr;
165 regs.SetFromRaw();
166
167 elf_memory_->SetData64(0x4100, 0x0080cd000000adb8ULL);
168 addr += 8;
169 // Pointer to ucontext data.
170 process_memory_.SetData32(addr, 0x8100);
171
172 addr = 0x8100;
173 for (uint64_t index = 0; index <= 30; index++) {
174 process_memory_.SetData32(addr + index * 4, index * 0x10);
175 }
176
177 ASSERT_TRUE(regs.StepIfSignalHandler(0x4100, elf_.get(), &process_memory_));
178 EXPECT_EQ(0xb0U, regs[X86_REG_EBP]);
179 EXPECT_EQ(0xc0U, regs[X86_REG_ESP]);
180 EXPECT_EQ(0xd0U, regs[X86_REG_EBX]);
181 EXPECT_EQ(0xe0U, regs[X86_REG_EDX]);
182 EXPECT_EQ(0xf0U, regs[X86_REG_ECX]);
183 EXPECT_EQ(0x100U, regs[X86_REG_EAX]);
184 EXPECT_EQ(0x130U, regs[X86_REG_EIP]);
185 EXPECT_EQ(0xc0U, regs.sp());
186 EXPECT_EQ(0x130U, regs.pc());
187}
188
189TEST_F(RegsStepIfSignalHandlerTest, x86_64_step_if_signal_handler) {
190 uint64_t addr = 0x500;
191 RegsX86_64 regs;
192 regs[X86_64_REG_RIP] = 0x7000;
193 regs[X86_64_REG_RSP] = addr;
194 regs.SetFromRaw();
195
196 elf_memory_->SetData64(0x7000, 0x0f0000000fc0c748);
197 elf_memory_->SetData16(0x7008, 0x0f05);
198
199 for (uint64_t index = 0; index <= 30; index++) {
200 process_memory_.SetData64(addr + index * 8, index * 0x10);
201 }
202
203 ASSERT_TRUE(regs.StepIfSignalHandler(0x7000, elf_.get(), &process_memory_));
204 EXPECT_EQ(0x140U, regs[X86_64_REG_RSP]);
205 EXPECT_EQ(0x150U, regs[X86_64_REG_RIP]);
206 EXPECT_EQ(0x140U, regs.sp());
207 EXPECT_EQ(0x150U, regs.pc());
208}
209
Douglas Leung61b1a1a2017-11-08 10:53:53 +0100210TEST_F(RegsStepIfSignalHandlerTest, mips_step_if_signal_handler_non_rt) {
211 uint64_t addr = 0x1000;
212 RegsMips regs;
213 regs[MIPS_REG_PC] = 0x8000;
214 regs[MIPS_REG_SP] = addr;
215 regs.SetFromRaw();
216
217 elf_memory_->SetData64(0x8000, 0x0000000c24021017ULL);
218
219 for (uint64_t index = 0; index <= 50; index++) {
220 process_memory_.SetData64(addr + index * 8, index * 0x10);
221 }
222
223 ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
224 EXPECT_EQ(0x220U, regs[MIPS_REG_SP]);
225 EXPECT_EQ(0x040U, regs[MIPS_REG_PC]);
226 EXPECT_EQ(0x220U, regs.sp());
227 EXPECT_EQ(0x040U, regs.pc());
228}
229
230TEST_F(RegsStepIfSignalHandlerTest, mips_step_if_signal_handler_rt) {
231 uint64_t addr = 0x1000;
232 RegsMips regs;
233 regs[MIPS_REG_PC] = 0x8000;
234 regs[MIPS_REG_SP] = addr;
235 regs.SetFromRaw();
236
237 elf_memory_->SetData64(0x8000, 0x0000000c24021061ULL);
238
239 for (uint64_t index = 0; index <= 100; index++) {
240 process_memory_.SetData64(addr + index * 8, index * 0x10);
241 }
242
243 ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
244 EXPECT_EQ(0x350U, regs[MIPS_REG_SP]);
245 EXPECT_EQ(0x170U, regs[MIPS_REG_PC]);
246 EXPECT_EQ(0x350U, regs.sp());
247 EXPECT_EQ(0x170U, regs.pc());
248}
249
250TEST_F(RegsStepIfSignalHandlerTest, mips64_step_if_signal_handler) {
251 uint64_t addr = 0x1000;
252 RegsMips64 regs;
253 regs[MIPS64_REG_PC] = 0x8000;
254 regs[MIPS64_REG_SP] = addr;
255 regs.SetFromRaw();
256
257 elf_memory_->SetData64(0x8000, 0x0000000c2402145bULL);
258
259 for (uint64_t index = 0; index <= 100; index++) {
260 process_memory_.SetData64(addr + index * 8, index * 0x10);
261 }
262
263 ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
264 EXPECT_EQ(0x350U, regs[MIPS64_REG_SP]);
265 EXPECT_EQ(0x600U, regs[MIPS64_REG_PC]);
266 EXPECT_EQ(0x350U, regs.sp());
267 EXPECT_EQ(0x600U, regs.pc());
268}
269
Christopher Ferriseb4a6db2017-07-19 12:37:45 -0700270} // namespace unwindstack