blob: 30e57a142dd89920057d09219b3a2d5ad3f5b9bb [file] [log] [blame]
Christopher Ferrisf6f691b2017-09-25 19:23:07 -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 <elf.h>
18#include <stdint.h>
19#include <sys/mman.h>
20
21#include <memory>
22#include <set>
23#include <string>
24
25#include <gtest/gtest.h>
26
27#include <unwindstack/Elf.h>
28#include <unwindstack/Maps.h>
29#include <unwindstack/Memory.h>
30#include <unwindstack/Regs.h>
Christopher Ferris02fdb562017-12-08 15:04:49 -080031#include <unwindstack/RegsArm.h>
32#include <unwindstack/RegsArm64.h>
33#include <unwindstack/RegsX86.h>
34#include <unwindstack/RegsX86_64.h>
Douglas Leung61b1a1a2017-11-08 10:53:53 +010035#include <unwindstack/RegsMips.h>
36#include <unwindstack/RegsMips64.h>
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070037#include <unwindstack/Unwinder.h>
38
39#include "ElfFake.h"
40#include "MemoryFake.h"
41#include "RegsFake.h"
42
43namespace unwindstack {
44
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070045class UnwinderTest : public ::testing::Test {
46 protected:
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080047 static void AddMapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
48 const char* name, Elf* elf = nullptr) {
49 std::string str_name(name);
50 maps_->Add(start, end, offset, flags, name, static_cast<uint64_t>(-1));
51 if (elf != nullptr) {
Florian Mayer3d67d342019-02-27 18:00:37 +000052 const auto& map_info = *--maps_->end();
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080053 map_info->elf.reset(elf);
54 }
55 }
56
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070057 static void SetUpTestCase() {
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080058 maps_.reset(new Maps);
59
Christopher Ferris02fdb562017-12-08 15:04:49 -080060 ElfFake* elf = new ElfFake(new MemoryFake);
Christopher Ferris78133452019-03-14 13:44:38 -070061 ElfInterfaceFake* interface_fake = new ElfInterfaceFake(nullptr);
62 interface_fake->FakeSetBuildID("FAKE");
63 elf->FakeSetInterface(interface_fake);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080064 AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070065
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080066 AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070067
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080068 AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
69 "/dev/fake_device");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070070
Christopher Ferris02fdb562017-12-08 15:04:49 -080071 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070072 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080073 AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070074
Christopher Ferris02fdb562017-12-08 15:04:49 -080075 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070076 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080077 AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070078
Christopher Ferris02fdb562017-12-08 15:04:49 -080079 elf = new ElfFake(new MemoryFake);
Christopher Ferrise69f4702017-10-19 16:08:58 -070080 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080081 AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070082
Christopher Ferris02fdb562017-12-08 15:04:49 -080083 elf = new ElfFake(new MemoryFake);
Christopher Ferris02a6c442019-03-11 14:43:33 -070084 ElfInterfaceFake* interface = new ElfInterfaceFake(nullptr);
85 interface->FakeSetSoname("lib_fake.so");
86 elf->FakeSetInterface(interface);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080087 AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
Christopher Ferris02a6c442019-03-11 14:43:33 -070088 MapInfo* map_info = maps_->Find(0x43000);
89 ASSERT_TRUE(map_info != nullptr);
90 map_info->elf_start_offset = 0x1d000;
Christopher Ferrise69f4702017-10-19 16:08:58 -070091
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080092 AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
Christopher Ferris02fdb562017-12-08 15:04:49 -080093
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080094 AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
Florian Mayer3d67d342019-02-27 18:00:37 +000095 const auto& info = *--maps_->end();
Christopher Ferrise762f1f2018-02-06 14:51:48 -080096 info->load_bias = 0;
Christopher Ferrise762f1f2018-02-06 14:51:48 -080097
Christopher Ferrise4df5f52018-02-12 13:24:18 -080098 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -080099 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
100 elf->FakeSetLoadBias(0x5000);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800101 AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
102 elf);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800103
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800104 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800105 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800106 AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_offset.oat",
107 elf);
Florian Mayer3d67d342019-02-27 18:00:37 +0000108 const auto& info2 = *--maps_->end();
109 info2->elf_offset = 0x8000;
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800110
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700111 elf = new ElfFake(new MemoryFake);
112 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
113 AddMapInfo(0xc0000, 0xc1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/unreadable.so", elf);
114 const auto& info3 = *--maps_->end();
115 info3->memory_backed_elf = true;
116
117 elf = new ElfFake(new MemoryFake);
118 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
119 AddMapInfo(0xc1000, 0xc2000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "[vdso]", elf);
120 const auto& info4 = *--maps_->end();
121 info4->memory_backed_elf = true;
122
123 elf = new ElfFake(new MemoryFake);
124 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
125 AddMapInfo(0xc2000, 0xc3000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "", elf);
126 const auto& info5 = *--maps_->end();
127 info5->memory_backed_elf = true;
128
Christopher Ferris98aaf4c2019-05-03 11:13:17 -0700129 elf = new ElfFake(new MemoryFake);
130 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
131 AddMapInfo(0xc3000, 0xc4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/memfd:/jit-cache", elf);
132 const auto& info6 = *--maps_->end();
133 info6->memory_backed_elf = true;
134
Christopher Ferris02fdb562017-12-08 15:04:49 -0800135 process_memory_.reset(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700136 }
137
138 void SetUp() override {
139 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800140 regs_.FakeSetArch(ARCH_ARM);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700141 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700142 }
143
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800144 static std::unique_ptr<Maps> maps_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700145 static RegsFake regs_;
146 static std::shared_ptr<Memory> process_memory_;
147};
148
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800149std::unique_ptr<Maps> UnwinderTest::maps_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700150RegsFake UnwinderTest::regs_(5);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700151std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
152
153TEST_F(UnwinderTest, multiple_frames) {
154 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
155 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
156 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
157
Yabin Cui11e96fe2018-03-14 18:16:22 -0700158 regs_.set_pc(0x1000);
159 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700160 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
161 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
162 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
163
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800164 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700165 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800166 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700167 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700168
169 ASSERT_EQ(3U, unwinder.NumFrames());
170
171 auto* frame = &unwinder.frames()[0];
172 EXPECT_EQ(0U, frame->num);
173 EXPECT_EQ(0U, frame->rel_pc);
174 EXPECT_EQ(0x1000U, frame->pc);
175 EXPECT_EQ(0x10000U, frame->sp);
176 EXPECT_EQ("Frame0", frame->function_name);
177 EXPECT_EQ(0U, frame->function_offset);
178 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800179 EXPECT_EQ(0U, frame->map_elf_start_offset);
180 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700181 EXPECT_EQ(0x1000U, frame->map_start);
182 EXPECT_EQ(0x8000U, frame->map_end);
183 EXPECT_EQ(0U, frame->map_load_bias);
184 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
185
186 frame = &unwinder.frames()[1];
187 EXPECT_EQ(1U, frame->num);
188 EXPECT_EQ(0x100U, frame->rel_pc);
189 EXPECT_EQ(0x1100U, frame->pc);
190 EXPECT_EQ(0x10010U, frame->sp);
191 EXPECT_EQ("Frame1", frame->function_name);
192 EXPECT_EQ(1U, frame->function_offset);
193 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800194 EXPECT_EQ(0U, frame->map_elf_start_offset);
195 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700196 EXPECT_EQ(0x1000U, frame->map_start);
197 EXPECT_EQ(0x8000U, frame->map_end);
198 EXPECT_EQ(0U, frame->map_load_bias);
199 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
200
201 frame = &unwinder.frames()[2];
202 EXPECT_EQ(2U, frame->num);
203 EXPECT_EQ(0x200U, frame->rel_pc);
204 EXPECT_EQ(0x1200U, frame->pc);
205 EXPECT_EQ(0x10020U, frame->sp);
206 EXPECT_EQ("Frame2", frame->function_name);
207 EXPECT_EQ(2U, frame->function_offset);
208 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800209 EXPECT_EQ(0U, frame->map_elf_start_offset);
210 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700211 EXPECT_EQ(0x1000U, frame->map_start);
212 EXPECT_EQ(0x8000U, frame->map_end);
213 EXPECT_EQ(0U, frame->map_load_bias);
214 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
215}
216
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800217TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
218 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
219 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
220 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
221
Yabin Cui11e96fe2018-03-14 18:16:22 -0700222 regs_.set_pc(0x1000);
223 regs_.set_sp(0x10000);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800224 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
225 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
226 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
227
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800228 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800229 unwinder.SetResolveNames(false);
230 unwinder.Unwind();
231 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700232 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800233
234 ASSERT_EQ(3U, unwinder.NumFrames());
235
236 auto* frame = &unwinder.frames()[0];
237 EXPECT_EQ(0U, frame->num);
238 EXPECT_EQ(0U, frame->rel_pc);
239 EXPECT_EQ(0x1000U, frame->pc);
240 EXPECT_EQ(0x10000U, frame->sp);
241 EXPECT_EQ("", frame->function_name);
242 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000243 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800244 EXPECT_EQ(0U, frame->map_elf_start_offset);
245 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800246 EXPECT_EQ(0x1000U, frame->map_start);
247 EXPECT_EQ(0x8000U, frame->map_end);
248 EXPECT_EQ(0U, frame->map_load_bias);
249 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
250
251 frame = &unwinder.frames()[1];
252 EXPECT_EQ(1U, frame->num);
253 EXPECT_EQ(0x100U, frame->rel_pc);
254 EXPECT_EQ(0x1100U, frame->pc);
255 EXPECT_EQ(0x10010U, frame->sp);
256 EXPECT_EQ("", frame->function_name);
257 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000258 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800259 EXPECT_EQ(0U, frame->map_elf_start_offset);
260 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800261 EXPECT_EQ(0x1000U, frame->map_start);
262 EXPECT_EQ(0x8000U, frame->map_end);
263 EXPECT_EQ(0U, frame->map_load_bias);
264 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
265
266 frame = &unwinder.frames()[2];
267 EXPECT_EQ(2U, frame->num);
268 EXPECT_EQ(0x200U, frame->rel_pc);
269 EXPECT_EQ(0x1200U, frame->pc);
270 EXPECT_EQ(0x10020U, frame->sp);
271 EXPECT_EQ("", frame->function_name);
272 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000273 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800274 EXPECT_EQ(0U, frame->map_elf_start_offset);
275 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800276 EXPECT_EQ(0x1000U, frame->map_start);
277 EXPECT_EQ(0x8000U, frame->map_end);
278 EXPECT_EQ(0U, frame->map_load_bias);
279 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
280}
281
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800282TEST_F(UnwinderTest, non_zero_load_bias) {
283 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
284
Yabin Cui11e96fe2018-03-14 18:16:22 -0700285 regs_.set_pc(0xa5500);
286 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800287 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
288
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800289 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800290 unwinder.Unwind();
291 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700292 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800293
294 ASSERT_EQ(1U, unwinder.NumFrames());
295
296 auto* frame = &unwinder.frames()[0];
297 EXPECT_EQ(0U, frame->num);
298 EXPECT_EQ(0x5500U, frame->rel_pc);
299 EXPECT_EQ(0xa5500U, frame->pc);
300 EXPECT_EQ(0x10000U, frame->sp);
301 EXPECT_EQ("Frame0", frame->function_name);
302 EXPECT_EQ(0U, frame->function_offset);
303 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800304 EXPECT_EQ(0U, frame->map_elf_start_offset);
305 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800306 EXPECT_EQ(0xa5000U, frame->map_start);
307 EXPECT_EQ(0xa6000U, frame->map_end);
308 EXPECT_EQ(0x5000U, frame->map_load_bias);
309 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
310}
311
312TEST_F(UnwinderTest, non_zero_elf_offset) {
313 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
314
Yabin Cui11e96fe2018-03-14 18:16:22 -0700315 regs_.set_pc(0xa7500);
316 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800317 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
318
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800319 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800320 unwinder.Unwind();
321 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700322 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800323
324 ASSERT_EQ(1U, unwinder.NumFrames());
325
326 auto* frame = &unwinder.frames()[0];
327 EXPECT_EQ(0U, frame->num);
328 EXPECT_EQ(0x8500U, frame->rel_pc);
329 EXPECT_EQ(0xa7500U, frame->pc);
330 EXPECT_EQ(0x10000U, frame->sp);
331 EXPECT_EQ("Frame0", frame->function_name);
332 EXPECT_EQ(0U, frame->function_offset);
333 EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800334 EXPECT_EQ(0U, frame->map_elf_start_offset);
335 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800336 EXPECT_EQ(0xa7000U, frame->map_start);
337 EXPECT_EQ(0xa8000U, frame->map_end);
338 EXPECT_EQ(0U, frame->map_load_bias);
339 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
340}
341
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700342TEST_F(UnwinderTest, non_zero_map_offset) {
343 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
344
Yabin Cui11e96fe2018-03-14 18:16:22 -0700345 regs_.set_pc(0x43000);
346 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700347 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
348
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800349 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700350 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800351 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700352 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700353
354 ASSERT_EQ(1U, unwinder.NumFrames());
355
356 auto* frame = &unwinder.frames()[0];
357 EXPECT_EQ(0U, frame->num);
358 EXPECT_EQ(0U, frame->rel_pc);
359 EXPECT_EQ(0x43000U, frame->pc);
360 EXPECT_EQ(0x10000U, frame->sp);
361 EXPECT_EQ("Frame0", frame->function_name);
362 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700363 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
364 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
365 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
366 EXPECT_EQ(0x43000U, frame->map_start);
367 EXPECT_EQ(0x44000U, frame->map_end);
368 EXPECT_EQ(0U, frame->map_load_bias);
369 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
370}
371
372TEST_F(UnwinderTest, disable_embedded_soname) {
373 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
374
375 regs_.set_pc(0x43000);
376 regs_.set_sp(0x10000);
377 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
378
379 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
380 unwinder.SetEmbeddedSoname(false);
381 unwinder.Unwind();
382 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700383 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris02a6c442019-03-11 14:43:33 -0700384
385 ASSERT_EQ(1U, unwinder.NumFrames());
386
387 auto* frame = &unwinder.frames()[0];
388 EXPECT_EQ(0U, frame->num);
389 EXPECT_EQ(0U, frame->rel_pc);
390 EXPECT_EQ(0x43000U, frame->pc);
391 EXPECT_EQ(0x10000U, frame->sp);
392 EXPECT_EQ("Frame0", frame->function_name);
393 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700394 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700395 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800396 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700397 EXPECT_EQ(0x43000U, frame->map_start);
398 EXPECT_EQ(0x44000U, frame->map_end);
399 EXPECT_EQ(0U, frame->map_load_bias);
400 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
401}
402
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700403// Verify that no attempt to continue after the step indicates it is done.
404TEST_F(UnwinderTest, no_frames_after_finished) {
405 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
406 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
407 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
408 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
409 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
410
Yabin Cui11e96fe2018-03-14 18:16:22 -0700411 regs_.set_pc(0x1000);
412 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700413 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
414 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
415 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
416
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800417 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700418 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800419 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700420 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700421
422 ASSERT_EQ(1U, unwinder.NumFrames());
423
424 auto* frame = &unwinder.frames()[0];
425 EXPECT_EQ(0U, frame->num);
426 EXPECT_EQ(0U, frame->rel_pc);
427 EXPECT_EQ(0x1000U, frame->pc);
428 EXPECT_EQ(0x10000U, frame->sp);
429 EXPECT_EQ("Frame0", frame->function_name);
430 EXPECT_EQ(0U, frame->function_offset);
431 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800432 EXPECT_EQ(0U, frame->map_elf_start_offset);
433 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700434 EXPECT_EQ(0x1000U, frame->map_start);
435 EXPECT_EQ(0x8000U, frame->map_end);
436 EXPECT_EQ(0U, frame->map_load_bias);
437 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
438}
439
440// Verify the maximum frames to save.
441TEST_F(UnwinderTest, max_frames) {
442 for (size_t i = 0; i < 30; i++) {
443 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
444 ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
445 }
446
Yabin Cui11e96fe2018-03-14 18:16:22 -0700447 regs_.set_pc(0x1000);
448 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700449
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800450 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700451 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800452 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700453 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700454
455 ASSERT_EQ(20U, unwinder.NumFrames());
456
457 for (size_t i = 0; i < 20; i++) {
458 auto* frame = &unwinder.frames()[i];
459 EXPECT_EQ(i, frame->num);
460 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
461 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
462 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
463 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
464 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
465 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800466 EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
467 EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700468 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
469 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
470 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
471 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
472 }
473}
474
475// Verify that initial map names frames are removed.
476TEST_F(UnwinderTest, verify_frames_skipped) {
477 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
478 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
479 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
480
Yabin Cui11e96fe2018-03-14 18:16:22 -0700481 regs_.set_pc(0x20000);
482 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700483 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
484 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
485 ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false));
486 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
487 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
488 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
489 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
490 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
491
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800492 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700493 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
494 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800495 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700496 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700497
498 ASSERT_EQ(3U, unwinder.NumFrames());
499
500 auto* frame = &unwinder.frames()[0];
501 EXPECT_EQ(0U, frame->num);
502 EXPECT_EQ(0U, frame->rel_pc);
503 EXPECT_EQ(0x1000U, frame->pc);
504 EXPECT_EQ(0x10050U, frame->sp);
505 EXPECT_EQ("Frame0", frame->function_name);
506 EXPECT_EQ(0U, frame->function_offset);
507 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800508 EXPECT_EQ(0U, frame->map_elf_start_offset);
509 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700510 EXPECT_EQ(0x1000U, frame->map_start);
511 EXPECT_EQ(0x8000U, frame->map_end);
512 EXPECT_EQ(0U, frame->map_load_bias);
513 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
514
515 frame = &unwinder.frames()[1];
516 EXPECT_EQ(1U, frame->num);
517 EXPECT_EQ(0x1000U, frame->rel_pc);
518 EXPECT_EQ(0x21000U, frame->pc);
519 EXPECT_EQ(0x10060U, frame->sp);
520 EXPECT_EQ("Frame1", frame->function_name);
521 EXPECT_EQ(1U, frame->function_offset);
522 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800523 EXPECT_EQ(0U, frame->map_elf_start_offset);
524 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700525 EXPECT_EQ(0x20000U, frame->map_start);
526 EXPECT_EQ(0x22000U, frame->map_end);
527 EXPECT_EQ(0U, frame->map_load_bias);
528 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
529
530 frame = &unwinder.frames()[2];
531 EXPECT_EQ(2U, frame->num);
532 EXPECT_EQ(0U, frame->rel_pc);
533 EXPECT_EQ(0x23000U, frame->pc);
534 EXPECT_EQ(0x10070U, frame->sp);
535 EXPECT_EQ("Frame2", frame->function_name);
536 EXPECT_EQ(2U, frame->function_offset);
537 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800538 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700539 EXPECT_EQ(0x23000U, frame->map_start);
540 EXPECT_EQ(0x24000U, frame->map_end);
541 EXPECT_EQ(0U, frame->map_load_bias);
542 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
543}
544
545// Verify SP in a non-existant map is okay.
546TEST_F(UnwinderTest, sp_not_in_map) {
547 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
548 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
549
Yabin Cui11e96fe2018-03-14 18:16:22 -0700550 regs_.set_pc(0x1000);
551 regs_.set_sp(0x63000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700552 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
553 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
554
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800555 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700556 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800557 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700558 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700559
560 ASSERT_EQ(2U, unwinder.NumFrames());
561
562 auto* frame = &unwinder.frames()[0];
563 EXPECT_EQ(0U, frame->num);
564 EXPECT_EQ(0U, frame->rel_pc);
565 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700566 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700567 EXPECT_EQ("Frame0", frame->function_name);
568 EXPECT_EQ(0U, frame->function_offset);
569 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800570 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700571 EXPECT_EQ(0x1000U, frame->map_start);
572 EXPECT_EQ(0x8000U, frame->map_end);
573 EXPECT_EQ(0U, frame->map_load_bias);
574 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
575
576 frame = &unwinder.frames()[1];
577 EXPECT_EQ(1U, frame->num);
578 EXPECT_EQ(0x1000U, frame->rel_pc);
579 EXPECT_EQ(0x21000U, frame->pc);
580 EXPECT_EQ(0x50020U, frame->sp);
581 EXPECT_EQ("Frame1", frame->function_name);
582 EXPECT_EQ(1U, frame->function_offset);
583 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800584 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700585 EXPECT_EQ(0x20000U, frame->map_start);
586 EXPECT_EQ(0x22000U, frame->map_end);
587 EXPECT_EQ(0U, frame->map_load_bias);
588 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
589}
590
591// Verify PC in a device stops the unwind.
592TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
593 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
594 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
595 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
596
Yabin Cui11e96fe2018-03-14 18:16:22 -0700597 regs_.set_pc(0x13000);
598 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700599 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
600 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
601 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
602
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800603 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700604 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800605 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700606 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700607
608 ASSERT_EQ(1U, unwinder.NumFrames());
609}
610
611// Verify SP in a device stops the unwind.
612TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
613 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
614 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
615 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
616
Yabin Cui11e96fe2018-03-14 18:16:22 -0700617 regs_.set_pc(0x1000);
618 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700619 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
620 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
621 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
622
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800623 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700624 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800625 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700626 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700627
628 ASSERT_EQ(1U, unwinder.NumFrames());
629}
630
631// Verify a no map info frame gets a frame.
632TEST_F(UnwinderTest, pc_without_map) {
633 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
634
Yabin Cui11e96fe2018-03-14 18:16:22 -0700635 regs_.set_pc(0x41000);
636 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700637
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800638 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700639 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800640 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700641 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700642
643 ASSERT_EQ(1U, unwinder.NumFrames());
644
645 auto* frame = &unwinder.frames()[0];
646 EXPECT_EQ(0U, frame->num);
647 EXPECT_EQ(0x41000U, frame->rel_pc);
648 EXPECT_EQ(0x41000U, frame->pc);
649 EXPECT_EQ(0x13000U, frame->sp);
650 EXPECT_EQ("", frame->function_name);
651 EXPECT_EQ(0U, frame->function_offset);
652 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800653 EXPECT_EQ(0U, frame->map_elf_start_offset);
654 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700655 EXPECT_EQ(0U, frame->map_start);
656 EXPECT_EQ(0U, frame->map_end);
657 EXPECT_EQ(0U, frame->map_load_bias);
658 EXPECT_EQ(0, frame->map_flags);
659}
660
661// Verify that a speculative frame is added.
662TEST_F(UnwinderTest, speculative_frame) {
663 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
664 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
665
666 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700667 regs_.set_pc(0);
668 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700669 regs_.FakeSetReturnAddress(0x1202);
670 regs_.FakeSetReturnAddressValid(true);
671
672 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
673 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
674
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800675 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700676 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800677 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700678 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700679
680 ASSERT_EQ(3U, unwinder.NumFrames());
681
682 auto* frame = &unwinder.frames()[0];
683 EXPECT_EQ(0U, frame->num);
684 EXPECT_EQ(0U, frame->rel_pc);
685 EXPECT_EQ(0U, frame->pc);
686 EXPECT_EQ(0x10000U, frame->sp);
687 EXPECT_EQ("", frame->function_name);
688 EXPECT_EQ(0U, frame->function_offset);
689 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800690 EXPECT_EQ(0U, frame->map_elf_start_offset);
691 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700692 EXPECT_EQ(0U, frame->map_start);
693 EXPECT_EQ(0U, frame->map_end);
694 EXPECT_EQ(0U, frame->map_load_bias);
695 EXPECT_EQ(0, frame->map_flags);
696
697 frame = &unwinder.frames()[1];
698 EXPECT_EQ(1U, frame->num);
699 EXPECT_EQ(0x200U, frame->rel_pc);
700 EXPECT_EQ(0x1200U, frame->pc);
701 EXPECT_EQ(0x10000U, frame->sp);
702 EXPECT_EQ("Frame0", frame->function_name);
703 EXPECT_EQ(0U, frame->function_offset);
704 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800705 EXPECT_EQ(0U, frame->map_elf_start_offset);
706 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700707 EXPECT_EQ(0x1000U, frame->map_start);
708 EXPECT_EQ(0x8000U, frame->map_end);
709 EXPECT_EQ(0U, frame->map_load_bias);
710 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
711
712 frame = &unwinder.frames()[2];
713 EXPECT_EQ(2U, frame->num);
714 EXPECT_EQ(0x100U, frame->rel_pc);
715 EXPECT_EQ(0x23100U, frame->pc);
716 EXPECT_EQ(0x10020U, frame->sp);
717 EXPECT_EQ("Frame1", frame->function_name);
718 EXPECT_EQ(1U, frame->function_offset);
719 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800720 EXPECT_EQ(0U, frame->map_elf_start_offset);
721 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700722 EXPECT_EQ(0x23000U, frame->map_start);
723 EXPECT_EQ(0x24000U, frame->map_end);
724 EXPECT_EQ(0U, frame->map_load_bias);
725 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
726}
727
728// Verify that a speculative frame is added then removed because no other
729// frames are added.
730TEST_F(UnwinderTest, speculative_frame_removed) {
731 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
732 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
733
734 // Fake as if code called a nullptr function.
Christopher Ferris065f1562018-12-13 09:33:45 -0800735 regs_.set_pc(0x20000);
736 regs_.set_sp(0x10000);
737 ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
738 regs_.FakeSetReturnAddress(0x12);
739 regs_.FakeSetReturnAddressValid(true);
740
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800741 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris065f1562018-12-13 09:33:45 -0800742 unwinder.Unwind();
743 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700744 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris065f1562018-12-13 09:33:45 -0800745
746 ASSERT_EQ(2U, unwinder.NumFrames());
747
748 auto* frame = &unwinder.frames()[0];
749 EXPECT_EQ(0U, frame->num);
750 EXPECT_EQ(0U, frame->rel_pc);
751 EXPECT_EQ(0x20000U, frame->pc);
752 EXPECT_EQ(0x10000U, frame->sp);
753 EXPECT_EQ("Frame0", frame->function_name);
754 EXPECT_EQ(0U, frame->function_offset);
755 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800756 EXPECT_EQ(0U, frame->map_elf_start_offset);
757 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800758 EXPECT_EQ(0x20000U, frame->map_start);
759 EXPECT_EQ(0x22000U, frame->map_end);
760 EXPECT_EQ(0U, frame->map_load_bias);
761 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
762
763 frame = &unwinder.frames()[1];
764 EXPECT_EQ(1U, frame->num);
765 EXPECT_EQ(0U, frame->rel_pc);
766 EXPECT_EQ(0U, frame->pc);
767 EXPECT_EQ(0x10010U, frame->sp);
768 EXPECT_EQ("", frame->function_name);
769 EXPECT_EQ(0U, frame->function_offset);
770 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800771 EXPECT_EQ(0U, frame->map_elf_start_offset);
772 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800773 EXPECT_EQ(0U, frame->map_start);
774 EXPECT_EQ(0U, frame->map_end);
775 EXPECT_EQ(0U, frame->map_load_bias);
776 EXPECT_EQ(0, frame->map_flags);
777}
778
779// Verify that a speculative frame is added and left if there are only
780// two frames and the pc is in the middle nowhere.
781TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
782 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
783 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
784
785 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700786 regs_.set_pc(0);
787 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700788 regs_.FakeSetReturnAddress(0x1202);
789 regs_.FakeSetReturnAddressValid(true);
790
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800791 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700792 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800793 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700794 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700795
Christopher Ferris065f1562018-12-13 09:33:45 -0800796 ASSERT_EQ(2U, unwinder.NumFrames());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700797
798 auto* frame = &unwinder.frames()[0];
799 EXPECT_EQ(0U, frame->num);
800 EXPECT_EQ(0U, frame->rel_pc);
801 EXPECT_EQ(0U, frame->pc);
802 EXPECT_EQ(0x10000U, frame->sp);
803 EXPECT_EQ("", frame->function_name);
804 EXPECT_EQ(0U, frame->function_offset);
805 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800806 EXPECT_EQ(0U, frame->map_elf_start_offset);
807 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700808 EXPECT_EQ(0U, frame->map_start);
809 EXPECT_EQ(0U, frame->map_end);
810 EXPECT_EQ(0U, frame->map_load_bias);
811 EXPECT_EQ(0, frame->map_flags);
Christopher Ferris065f1562018-12-13 09:33:45 -0800812
813 frame = &unwinder.frames()[1];
814 EXPECT_EQ(1U, frame->num);
815 EXPECT_EQ(0x200U, frame->rel_pc);
816 EXPECT_EQ(0x1200U, frame->pc);
817 EXPECT_EQ(0x10000U, frame->sp);
818 EXPECT_EQ("Frame0", frame->function_name);
819 EXPECT_EQ(0U, frame->function_offset);
820 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800821 EXPECT_EQ(0U, frame->map_elf_start_offset);
822 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800823 EXPECT_EQ(0x1000U, frame->map_start);
824 EXPECT_EQ(0x8000U, frame->map_end);
825 EXPECT_EQ(0U, frame->map_load_bias);
826 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700827}
828
Florian Mayerc479e4e2019-01-23 13:35:40 +0000829// Verify that a speculative frame does not cause a crash when it wasn't
830// really added due to a filter.
831TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
832 regs_.set_pc(0x23000);
833 regs_.set_sp(0x10000);
834 regs_.FakeSetReturnAddress(0x23100);
835 regs_.FakeSetReturnAddressValid(true);
836
837 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
838
839 std::vector<std::string> skip_names{"libanother.so"};
840 unwinder.Unwind(&skip_names);
841 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700842 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Florian Mayerc479e4e2019-01-23 13:35:40 +0000843
844 ASSERT_EQ(0U, unwinder.NumFrames());
845}
846
Christopher Ferrise69f4702017-10-19 16:08:58 -0700847// Verify that an unwind stops when a frame is in given suffix.
848TEST_F(UnwinderTest, map_ignore_suffixes) {
849 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
850 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
851 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
852 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
853
854 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700855 regs_.set_pc(0x1000);
856 regs_.set_sp(0x10000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700857 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
858 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
859 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
860
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800861 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700862 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700863 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800864 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700865 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700866
867 ASSERT_EQ(2U, unwinder.NumFrames());
868 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800869 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700870 ASSERT_TRUE(map_info != nullptr);
871 EXPECT_TRUE(map_info->elf == nullptr);
872
873 auto* frame = &unwinder.frames()[0];
874 EXPECT_EQ(0U, frame->num);
875 EXPECT_EQ(0U, frame->rel_pc);
876 EXPECT_EQ(0x1000U, frame->pc);
877 EXPECT_EQ(0x10000U, frame->sp);
878 EXPECT_EQ("Frame0", frame->function_name);
879 EXPECT_EQ(0U, frame->function_offset);
880 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800881 EXPECT_EQ(0U, frame->map_elf_start_offset);
882 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700883 EXPECT_EQ(0x1000U, frame->map_start);
884 EXPECT_EQ(0x8000U, frame->map_end);
885 EXPECT_EQ(0U, frame->map_load_bias);
886 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
887
888 frame = &unwinder.frames()[1];
889 EXPECT_EQ(1U, frame->num);
890 EXPECT_EQ(0x400U, frame->rel_pc);
891 EXPECT_EQ(0x43400U, frame->pc);
892 EXPECT_EQ(0x10010U, frame->sp);
893 EXPECT_EQ("Frame1", frame->function_name);
894 EXPECT_EQ(1U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700895 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
896 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800897 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700898 EXPECT_EQ(0x43000U, frame->map_start);
899 EXPECT_EQ(0x44000U, frame->map_end);
900 EXPECT_EQ(0U, frame->map_load_bias);
901 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
902}
903
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700904// Verify that an unwind stops when the sp and pc don't change.
905TEST_F(UnwinderTest, sp_pc_do_not_change) {
906 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
907 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
908 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
909 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
910 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
911
Yabin Cui11e96fe2018-03-14 18:16:22 -0700912 regs_.set_pc(0x1000);
913 regs_.set_sp(0x10000);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700914 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
915 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
916 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
917 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
918 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
919 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
920
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800921 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700922 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800923 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700924 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700925
926 ASSERT_EQ(3U, unwinder.NumFrames());
927
928 auto* frame = &unwinder.frames()[0];
929 EXPECT_EQ(0U, frame->num);
930 EXPECT_EQ(0U, frame->rel_pc);
931 EXPECT_EQ(0x1000U, frame->pc);
932 EXPECT_EQ(0x10000U, frame->sp);
933 EXPECT_EQ("Frame0", frame->function_name);
934 EXPECT_EQ(0U, frame->function_offset);
935 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800936 EXPECT_EQ(0U, frame->map_elf_start_offset);
937 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700938 EXPECT_EQ(0x1000U, frame->map_start);
939 EXPECT_EQ(0x8000U, frame->map_end);
940 EXPECT_EQ(0U, frame->map_load_bias);
941 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
942
943 frame = &unwinder.frames()[1];
944 EXPECT_EQ(1U, frame->num);
945 EXPECT_EQ(0x400U, frame->rel_pc);
946 EXPECT_EQ(0x33400U, frame->pc);
947 EXPECT_EQ(0x10010U, frame->sp);
948 EXPECT_EQ("Frame1", frame->function_name);
949 EXPECT_EQ(1U, frame->function_offset);
950 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800951 EXPECT_EQ(0U, frame->map_elf_start_offset);
952 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700953 EXPECT_EQ(0x33000U, frame->map_start);
954 EXPECT_EQ(0x34000U, frame->map_end);
955 EXPECT_EQ(0U, frame->map_load_bias);
956 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
957
958 frame = &unwinder.frames()[2];
959 EXPECT_EQ(2U, frame->num);
960 EXPECT_EQ(0x500U, frame->rel_pc);
961 EXPECT_EQ(0x33500U, frame->pc);
962 EXPECT_EQ(0x10020U, frame->sp);
963 EXPECT_EQ("Frame2", frame->function_name);
964 EXPECT_EQ(2U, frame->function_offset);
965 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800966 EXPECT_EQ(0U, frame->map_elf_start_offset);
967 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700968 EXPECT_EQ(0x33000U, frame->map_start);
969 EXPECT_EQ(0x34000U, frame->map_end);
970 EXPECT_EQ(0U, frame->map_load_bias);
971 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
972}
973
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800974TEST_F(UnwinderTest, dex_pc_in_map) {
975 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700976 regs_.set_pc(0x1000);
977 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800978 regs_.FakeSetDexPc(0xa3400);
979
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800980 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800981 unwinder.Unwind();
982 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700983 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800984
985 ASSERT_EQ(2U, unwinder.NumFrames());
986
987 auto* frame = &unwinder.frames()[0];
988 EXPECT_EQ(0U, frame->num);
989 EXPECT_EQ(0x400U, frame->rel_pc);
990 EXPECT_EQ(0xa3400U, frame->pc);
991 EXPECT_EQ(0x10000U, frame->sp);
992 EXPECT_EQ("", frame->function_name);
993 EXPECT_EQ(0U, frame->function_offset);
994 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800995 EXPECT_EQ(0U, frame->map_elf_start_offset);
996 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800997 EXPECT_EQ(0xa3000U, frame->map_start);
998 EXPECT_EQ(0xa4000U, frame->map_end);
999 EXPECT_EQ(0U, frame->map_load_bias);
1000 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1001
1002 frame = &unwinder.frames()[1];
1003 EXPECT_EQ(1U, frame->num);
1004 EXPECT_EQ(0U, frame->rel_pc);
1005 EXPECT_EQ(0x1000U, frame->pc);
1006 EXPECT_EQ(0x10000U, frame->sp);
1007 EXPECT_EQ("Frame0", frame->function_name);
1008 EXPECT_EQ(0U, frame->function_offset);
1009 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001010 EXPECT_EQ(0U, frame->map_elf_start_offset);
1011 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001012 EXPECT_EQ(0x1000U, frame->map_start);
1013 EXPECT_EQ(0x8000U, frame->map_end);
1014 EXPECT_EQ(0U, frame->map_load_bias);
1015 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1016}
1017
1018TEST_F(UnwinderTest, dex_pc_not_in_map) {
1019 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001020 regs_.set_pc(0x1000);
1021 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001022 regs_.FakeSetDexPc(0x50000);
1023
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001024 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001025 unwinder.Unwind();
1026 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001027 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001028
1029 ASSERT_EQ(2U, unwinder.NumFrames());
1030
1031 auto* frame = &unwinder.frames()[0];
1032 EXPECT_EQ(0U, frame->num);
1033 EXPECT_EQ(0x50000U, frame->rel_pc);
1034 EXPECT_EQ(0x50000U, frame->pc);
1035 EXPECT_EQ(0x10000U, frame->sp);
1036 EXPECT_EQ("", frame->function_name);
1037 EXPECT_EQ(0U, frame->function_offset);
1038 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001039 EXPECT_EQ(0U, frame->map_elf_start_offset);
1040 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001041 EXPECT_EQ(0U, frame->map_start);
1042 EXPECT_EQ(0U, frame->map_end);
1043 EXPECT_EQ(0U, frame->map_load_bias);
1044 EXPECT_EQ(0, frame->map_flags);
1045
1046 frame = &unwinder.frames()[1];
1047 EXPECT_EQ(1U, frame->num);
1048 EXPECT_EQ(0U, frame->rel_pc);
1049 EXPECT_EQ(0x1000U, frame->pc);
1050 EXPECT_EQ(0x10000U, frame->sp);
1051 EXPECT_EQ("Frame0", frame->function_name);
1052 EXPECT_EQ(0U, frame->function_offset);
1053 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001054 EXPECT_EQ(0U, frame->map_elf_start_offset);
1055 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001056 EXPECT_EQ(0x1000U, frame->map_start);
1057 EXPECT_EQ(0x8000U, frame->map_end);
1058 EXPECT_EQ(0U, frame->map_load_bias);
1059 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1060}
1061
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001062TEST_F(UnwinderTest, dex_pc_multiple_frames) {
1063 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1064 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001065 regs_.set_pc(0x1000);
1066 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001067 regs_.FakeSetDexPc(0xa3400);
1068 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
1069 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1070
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001071 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001072 unwinder.Unwind();
1073 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001074 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001075
1076 ASSERT_EQ(3U, unwinder.NumFrames());
1077
1078 auto* frame = &unwinder.frames()[0];
1079 EXPECT_EQ(0U, frame->num);
1080 EXPECT_EQ(0x400U, frame->rel_pc);
1081 EXPECT_EQ(0xa3400U, frame->pc);
1082 EXPECT_EQ(0x10000U, frame->sp);
1083 EXPECT_EQ("", frame->function_name);
1084 EXPECT_EQ(0U, frame->function_offset);
1085 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001086 EXPECT_EQ(0U, frame->map_elf_start_offset);
1087 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001088 EXPECT_EQ(0xa3000U, frame->map_start);
1089 EXPECT_EQ(0xa4000U, frame->map_end);
1090 EXPECT_EQ(0U, frame->map_load_bias);
1091 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1092
1093 frame = &unwinder.frames()[1];
1094 EXPECT_EQ(1U, frame->num);
1095 EXPECT_EQ(0U, frame->rel_pc);
1096 EXPECT_EQ(0x1000U, frame->pc);
1097 EXPECT_EQ(0x10000U, frame->sp);
1098 EXPECT_EQ("Frame0", frame->function_name);
1099 EXPECT_EQ(0U, frame->function_offset);
1100 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001101 EXPECT_EQ(0U, frame->map_elf_start_offset);
1102 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001103 EXPECT_EQ(0x1000U, frame->map_start);
1104 EXPECT_EQ(0x8000U, frame->map_end);
1105 EXPECT_EQ(0U, frame->map_load_bias);
1106 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1107
1108 frame = &unwinder.frames()[2];
1109 EXPECT_EQ(2U, frame->num);
1110 EXPECT_EQ(0x400U, frame->rel_pc);
1111 EXPECT_EQ(0x33400U, frame->pc);
1112 EXPECT_EQ(0x10010U, frame->sp);
1113 EXPECT_EQ("Frame1", frame->function_name);
1114 EXPECT_EQ(1U, frame->function_offset);
1115 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001116 EXPECT_EQ(0U, frame->map_elf_start_offset);
1117 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001118 EXPECT_EQ(0x33000U, frame->map_start);
1119 EXPECT_EQ(0x34000U, frame->map_end);
1120 EXPECT_EQ(0U, frame->map_load_bias);
1121 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1122}
1123
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001124TEST_F(UnwinderTest, dex_pc_max_frames) {
1125 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1126 regs_.set_pc(0x1000);
1127 regs_.set_sp(0x10000);
1128 regs_.FakeSetDexPc(0xa3400);
1129
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001130 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001131 unwinder.Unwind();
1132 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001133 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001134
1135 ASSERT_EQ(1U, unwinder.NumFrames());
1136
1137 auto* frame = &unwinder.frames()[0];
1138 EXPECT_EQ(0U, frame->num);
1139 EXPECT_EQ(0x400U, frame->rel_pc);
1140 EXPECT_EQ(0xa3400U, frame->pc);
1141 EXPECT_EQ(0x10000U, frame->sp);
1142 EXPECT_EQ("", frame->function_name);
1143 EXPECT_EQ(0U, frame->function_offset);
1144 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001145 EXPECT_EQ(0U, frame->map_elf_start_offset);
1146 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001147 EXPECT_EQ(0xa3000U, frame->map_start);
1148 EXPECT_EQ(0xa4000U, frame->map_end);
1149 EXPECT_EQ(0U, frame->map_load_bias);
1150 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1151}
1152
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001153TEST_F(UnwinderTest, elf_from_memory_not_file) {
1154 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1155
1156 regs_.set_pc(0xc0050);
1157 regs_.set_sp(0x10000);
1158 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1159
1160 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1161 unwinder.Unwind();
1162 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1163 EXPECT_TRUE(unwinder.elf_from_memory_not_file());
1164
1165 ASSERT_EQ(1U, unwinder.NumFrames());
1166
1167 auto* frame = &unwinder.frames()[0];
1168 EXPECT_EQ(0U, frame->num);
1169 EXPECT_EQ(0x50U, frame->rel_pc);
1170 EXPECT_EQ(0xc0050U, frame->pc);
1171 EXPECT_EQ(0x10000U, frame->sp);
1172 EXPECT_EQ("Frame0", frame->function_name);
1173 EXPECT_EQ(0U, frame->function_offset);
1174 EXPECT_EQ("/fake/unreadable.so", frame->map_name);
1175 EXPECT_EQ(0U, frame->map_elf_start_offset);
1176 EXPECT_EQ(0U, frame->map_exact_offset);
1177 EXPECT_EQ(0xc0000U, frame->map_start);
1178 EXPECT_EQ(0xc1000U, frame->map_end);
1179 EXPECT_EQ(0U, frame->map_load_bias);
1180 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1181}
1182
1183TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
1184 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1185
1186 regs_.set_pc(0xc1050);
1187 regs_.set_sp(0x10000);
1188 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1189
1190 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1191 unwinder.Unwind();
1192 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1193 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1194
1195 ASSERT_EQ(1U, unwinder.NumFrames());
1196
1197 auto* frame = &unwinder.frames()[0];
1198 EXPECT_EQ(0U, frame->num);
1199 EXPECT_EQ(0x50U, frame->rel_pc);
1200 EXPECT_EQ(0xc1050U, frame->pc);
1201 EXPECT_EQ(0x10000U, frame->sp);
1202 EXPECT_EQ("Frame0", frame->function_name);
1203 EXPECT_EQ(0U, frame->function_offset);
1204 EXPECT_EQ("[vdso]", frame->map_name);
1205 EXPECT_EQ(0U, frame->map_elf_start_offset);
1206 EXPECT_EQ(0U, frame->map_exact_offset);
1207 EXPECT_EQ(0xc1000U, frame->map_start);
1208 EXPECT_EQ(0xc2000U, frame->map_end);
1209 EXPECT_EQ(0U, frame->map_load_bias);
1210 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1211}
1212
1213TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
1214 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1215
1216 regs_.set_pc(0xc2050);
1217 regs_.set_sp(0x10000);
1218 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1219
1220 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1221 unwinder.Unwind();
1222 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1223 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1224
1225 ASSERT_EQ(1U, unwinder.NumFrames());
1226
1227 auto* frame = &unwinder.frames()[0];
1228 EXPECT_EQ(0U, frame->num);
1229 EXPECT_EQ(0x50U, frame->rel_pc);
1230 EXPECT_EQ(0xc2050U, frame->pc);
1231 EXPECT_EQ(0x10000U, frame->sp);
1232 EXPECT_EQ("Frame0", frame->function_name);
1233 EXPECT_EQ(0U, frame->function_offset);
1234 EXPECT_EQ("", frame->map_name);
1235 EXPECT_EQ(0U, frame->map_elf_start_offset);
1236 EXPECT_EQ(0U, frame->map_exact_offset);
1237 EXPECT_EQ(0xc2000U, frame->map_start);
1238 EXPECT_EQ(0xc3000U, frame->map_end);
1239 EXPECT_EQ(0U, frame->map_load_bias);
1240 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1241}
1242
Christopher Ferris98aaf4c2019-05-03 11:13:17 -07001243TEST_F(UnwinderTest, elf_from_memory_but_from_memfd) {
1244 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1245
1246 regs_.set_pc(0xc3050);
1247 regs_.set_sp(0x10000);
1248 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1249
1250 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1251 unwinder.Unwind();
1252 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1253 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1254
1255 ASSERT_EQ(1U, unwinder.NumFrames());
1256
1257 auto* frame = &unwinder.frames()[0];
1258 EXPECT_EQ(0U, frame->num);
1259 EXPECT_EQ(0x50U, frame->rel_pc);
1260 EXPECT_EQ(0xc3050U, frame->pc);
1261 EXPECT_EQ(0x10000U, frame->sp);
1262 EXPECT_EQ("Frame0", frame->function_name);
1263 EXPECT_EQ(0U, frame->function_offset);
1264 EXPECT_EQ("/memfd:/jit-cache", frame->map_name);
1265 EXPECT_EQ(0U, frame->map_elf_start_offset);
1266 EXPECT_EQ(0U, frame->map_exact_offset);
1267 EXPECT_EQ(0xc3000U, frame->map_start);
1268 EXPECT_EQ(0xc4000U, frame->map_end);
1269 EXPECT_EQ(0U, frame->map_load_bias);
1270 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1271}
1272
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001273// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001274TEST_F(UnwinderTest, format_frame) {
1275 RegsFake regs_arm(10);
1276 regs_arm.FakeSetArch(ARCH_ARM);
1277 Unwinder unwinder32(10, maps_.get(), &regs_arm, process_memory_);
1278
1279 RegsFake regs_arm64(10);
1280 regs_arm64.FakeSetArch(ARCH_ARM64);
1281 Unwinder unwinder64(10, maps_.get(), &regs_arm64, process_memory_);
1282
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001283 FrameData frame;
1284 frame.num = 1;
1285 frame.rel_pc = 0x1000;
1286 frame.pc = 0x4000;
1287 frame.sp = 0x1000;
1288 frame.function_name = "function";
1289 frame.function_offset = 100;
1290 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001291 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001292 frame.map_start = 0x3000;
1293 frame.map_end = 0x6000;
1294 frame.map_flags = PROT_READ;
1295
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001296 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001297 unwinder64.FormatFrame(frame));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001298 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001299 unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001300
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001301 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001302 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001303 unwinder64.FormatFrame(frame));
1304 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001305
1306 frame.function_offset = 0;
1307 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
Christopher Ferris78133452019-03-14 13:44:38 -07001308 unwinder64.FormatFrame(frame));
1309 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001310
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001311 // Verify the function name is demangled.
1312 frame.function_name = "_ZN4funcEv";
Christopher Ferris78133452019-03-14 13:44:38 -07001313 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())", unwinder64.FormatFrame(frame));
1314 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", unwinder32.FormatFrame(frame));
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001315
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001316 frame.function_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001317 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", unwinder64.FormatFrame(frame));
1318 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001319
1320 frame.map_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001321 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", unwinder64.FormatFrame(frame));
1322 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001323
1324 frame.map_start = 0;
1325 frame.map_end = 0;
Christopher Ferris78133452019-03-14 13:44:38 -07001326 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", unwinder64.FormatFrame(frame));
1327 EXPECT_EQ(" #01 pc 00001000 <unknown>", unwinder32.FormatFrame(frame));
1328}
1329
1330TEST_F(UnwinderTest, format_frame_build_id) {
1331 RegsFake regs(10);
1332 regs.FakeSetArch(ARCH_ARM);
1333 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1334
1335 FrameData frame;
1336 frame.num = 1;
1337 frame.rel_pc = 0x1000;
1338 frame.pc = 0x4000;
1339 frame.sp = 0x1000;
1340 frame.function_name = "function";
1341 frame.function_offset = 100;
1342 frame.map_name = "/fake/libfake.so";
1343 frame.map_elf_start_offset = 0;
1344 frame.map_start = 0x3000;
1345 frame.map_end = 0x6000;
1346 frame.map_flags = PROT_READ;
1347
1348 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder.FormatFrame(frame));
1349 unwinder.SetDisplayBuildID(true);
1350 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100) (BuildId: 46414b45)",
1351 unwinder.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001352}
1353
Christopher Ferris02fdb562017-12-08 15:04:49 -08001354static std::string ArchToString(ArchEnum arch) {
1355 if (arch == ARCH_ARM) {
1356 return "Arm";
1357 } else if (arch == ARCH_ARM64) {
1358 return "Arm64";
1359 } else if (arch == ARCH_X86) {
1360 return "X86";
1361 } else if (arch == ARCH_X86_64) {
1362 return "X86_64";
1363 } else {
1364 return "Unknown";
1365 }
1366}
1367
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001368// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001369TEST_F(UnwinderTest, format_frame_by_arch) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001370 std::vector<Regs*> reg_list;
1371 RegsArm* arm = new RegsArm;
1372 arm->set_pc(0x2300);
1373 arm->set_sp(0x10000);
1374 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001375
Christopher Ferris02fdb562017-12-08 15:04:49 -08001376 RegsArm64* arm64 = new RegsArm64;
1377 arm64->set_pc(0x2300);
1378 arm64->set_sp(0x10000);
1379 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001380
Christopher Ferris02fdb562017-12-08 15:04:49 -08001381 RegsX86* x86 = new RegsX86;
1382 x86->set_pc(0x2300);
1383 x86->set_sp(0x10000);
1384 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001385
Christopher Ferris02fdb562017-12-08 15:04:49 -08001386 RegsX86_64* x86_64 = new RegsX86_64;
1387 x86_64->set_pc(0x2300);
1388 x86_64->set_sp(0x10000);
1389 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001390
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001391 RegsMips* mips = new RegsMips;
1392 mips->set_pc(0x2300);
1393 mips->set_sp(0x10000);
1394 reg_list.push_back(mips);
1395
1396 RegsMips64* mips64 = new RegsMips64;
1397 mips64->set_pc(0x2300);
1398 mips64->set_sp(0x10000);
1399 reg_list.push_back(mips64);
1400
Christopher Ferris02fdb562017-12-08 15:04:49 -08001401 for (auto regs : reg_list) {
1402 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001403
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001404 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001405 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001406
Christopher Ferris02fdb562017-12-08 15:04:49 -08001407 ASSERT_EQ(1U, unwinder.NumFrames());
1408 std::string expected;
1409 switch (regs->Arch()) {
1410 case ARCH_ARM:
1411 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001412 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001413 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1414 break;
1415 case ARCH_ARM64:
1416 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001417 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001418 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1419 break;
1420 default:
1421 expected = "";
1422 }
1423 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1424 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1425 delete regs;
1426 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001427}
1428
1429} // namespace unwindstack