blob: 915f24884fdb76a357b2bb200f82d65024b2877d [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"
Christopher Ferris06996a82020-08-27 19:33:12 -070040#include "ElfTestUtils.h"
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070041#include "MemoryFake.h"
42#include "RegsFake.h"
43
44namespace unwindstack {
45
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070046class UnwinderTest : public ::testing::Test {
47 protected:
Christopher Ferris06996a82020-08-27 19:33:12 -070048 static MapInfo* AddMapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
49 const char* name, Elf* elf = nullptr) {
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080050 std::string str_name(name);
51 maps_->Add(start, end, offset, flags, name, static_cast<uint64_t>(-1));
Christopher Ferris06996a82020-08-27 19:33:12 -070052 MapInfo* map_info = maps_->Find(start);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080053 if (elf != nullptr) {
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080054 map_info->elf.reset(elf);
55 }
Christopher Ferris06996a82020-08-27 19:33:12 -070056 return map_info;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080057 }
58
Christopher Ferris7e21eba2019-06-20 16:16:42 -070059 static void SetUpTestSuite() {
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080060 maps_.reset(new Maps);
61
Christopher Ferrisafbed692020-08-27 11:46:36 -070062 memory_ = new MemoryFake;
63 process_memory_.reset(memory_);
64
Christopher Ferris06996a82020-08-27 19:33:12 -070065 ElfFake* elf;
66 ElfInterfaceFake* interface;
67 MapInfo* map_info;
68
69 elf = new ElfFake(new MemoryFake);
70 interface = new ElfInterfaceFake(nullptr);
71 interface->FakeSetBuildID("FAKE");
72 elf->FakeSetInterface(interface);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080073 AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070074
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080075 AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070076
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080077 AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
78 "/dev/fake_device");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070079
Christopher Ferris02fdb562017-12-08 15:04:49 -080080 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070081 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080082 AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070083
Christopher Ferris02fdb562017-12-08 15:04:49 -080084 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070085 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080086 AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070087
Christopher Ferris02fdb562017-12-08 15:04:49 -080088 elf = new ElfFake(new MemoryFake);
Christopher Ferrise69f4702017-10-19 16:08:58 -070089 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080090 AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070091
Christopher Ferris02fdb562017-12-08 15:04:49 -080092 elf = new ElfFake(new MemoryFake);
Christopher Ferris06996a82020-08-27 19:33:12 -070093 interface = new ElfInterfaceFake(nullptr);
Christopher Ferris02a6c442019-03-11 14:43:33 -070094 interface->FakeSetSoname("lib_fake.so");
95 elf->FakeSetInterface(interface);
Christopher Ferris06996a82020-08-27 19:33:12 -070096 map_info = AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
Christopher Ferris02a6c442019-03-11 14:43:33 -070097 map_info->elf_start_offset = 0x1d000;
Christopher Ferrise69f4702017-10-19 16:08:58 -070098
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080099 AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
Christopher Ferris02fdb562017-12-08 15:04:49 -0800100
Christopher Ferris06996a82020-08-27 19:33:12 -0700101 map_info =
102 AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
103 map_info->load_bias = 0;
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800104
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800105 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800106 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
107 elf->FakeSetLoadBias(0x5000);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800108 AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
109 elf);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800110
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800111 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800112 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferris06996a82020-08-27 19:33:12 -0700113 map_info = AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
114 "/fake/fake_offset.oat", elf);
115 map_info->elf_offset = 0x8000;
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800116
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700117 elf = new ElfFake(new MemoryFake);
118 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferris06996a82020-08-27 19:33:12 -0700119 map_info = AddMapInfo(0xc0000, 0xc1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
120 "/fake/unreadable.so", elf);
121 map_info->memory_backed_elf = true;
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700122
123 elf = new ElfFake(new MemoryFake);
124 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferris06996a82020-08-27 19:33:12 -0700125 map_info = AddMapInfo(0xc1000, 0xc2000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "[vdso]", elf);
126 map_info->memory_backed_elf = true;
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700127
128 elf = new ElfFake(new MemoryFake);
129 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferris06996a82020-08-27 19:33:12 -0700130 map_info = AddMapInfo(0xc2000, 0xc3000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "", elf);
131 map_info->memory_backed_elf = true;
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700132
Christopher Ferris98aaf4c2019-05-03 11:13:17 -0700133 elf = new ElfFake(new MemoryFake);
134 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferris06996a82020-08-27 19:33:12 -0700135 map_info = AddMapInfo(0xc3000, 0xc4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
136 "/memfd:/jit-cache", elf);
137 map_info->memory_backed_elf = true;
Christopher Ferris98aaf4c2019-05-03 11:13:17 -0700138
Christopher Ferris06996a82020-08-27 19:33:12 -0700139 map_info =
140 AddMapInfo(0xd0000, 0xd1000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.apk");
141 map_info->load_bias = 0;
Christopher Ferrisa4bdb982019-06-04 11:52:16 -0700142
Christopher Ferrisafbed692020-08-27 11:46:36 -0700143 elf = new ElfFake(new MemoryFake);
144 interface = new ElfInterfaceFake(nullptr);
145 elf->FakeSetInterface(interface);
146 interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x1800);
Christopher Ferris06996a82020-08-27 19:33:12 -0700147 interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x1900);
Christopher Ferrisafbed692020-08-27 11:46:36 -0700148 interface->FakeSetDataOffset(0x1000);
149 interface->FakeSetDataVaddrStart(0x1000);
Christopher Ferris06996a82020-08-27 19:33:12 -0700150 interface->FakeSetDataVaddrEnd(0x8000);
Christopher Ferrisafbed692020-08-27 11:46:36 -0700151 AddMapInfo(0xf0000, 0xf1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/global.so", elf);
152 AddMapInfo(0xf1000, 0xf9000, 0x1000, PROT_READ | PROT_WRITE, "/fake/global.so");
Christopher Ferris06996a82020-08-27 19:33:12 -0700153 // dex debug data
Christopher Ferrisafbed692020-08-27 11:46:36 -0700154 memory_->SetData32(0xf180c, 0xf3000);
155 memory_->SetData32(0xf3000, 0xf4000);
156 memory_->SetData32(0xf3004, 0xf4000);
157 memory_->SetData32(0xf3008, 0xf5000);
Christopher Ferris06996a82020-08-27 19:33:12 -0700158 // jit debug data
159 memory_->SetData32(0xf1900, 1);
160 memory_->SetData32(0xf1904, 0);
161 memory_->SetData32(0xf1908, 0xf6000);
162 memory_->SetData32(0xf190c, 0xf6000);
163 memory_->SetData32(0xf6000, 0);
164 memory_->SetData32(0xf6004, 0);
165 memory_->SetData32(0xf6008, 0xf7000);
166 memory_->SetData32(0xf600c, 0);
167 memory_->SetData64(0xf6010, 0x1000);
168
169 elf = new ElfFake(new MemoryFake);
170 elf->FakeSetValid(false);
171 elf->FakeSetLoadBias(0x300);
172 map_info = AddMapInfo(0x100000, 0x101000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC,
173 "/fake/jit.so", elf);
174 map_info->elf_start_offset = 0x100;
175 map_info->offset = 0x200;
176
177#if 0
178 elf = new ElfFake(new MemoryFake);
179 interface = new ElfInterfaceFake(nullptr);
180 interface->FakePushFunctionData(FunctionData("Fake0", 10));
181 AddMapInfo(0x110000, 0x111000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/elf.so", elf);
182#endif
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700183 }
184
185 void SetUp() override {
186 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800187 regs_.FakeSetArch(ARCH_ARM);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700188 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700189 }
190
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800191 static std::unique_ptr<Maps> maps_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700192 static RegsFake regs_;
Christopher Ferrisafbed692020-08-27 11:46:36 -0700193 static MemoryFake* memory_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700194 static std::shared_ptr<Memory> process_memory_;
195};
196
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800197std::unique_ptr<Maps> UnwinderTest::maps_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700198RegsFake UnwinderTest::regs_(5);
Christopher Ferrisafbed692020-08-27 11:46:36 -0700199MemoryFake* UnwinderTest::memory_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700200std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
201
202TEST_F(UnwinderTest, multiple_frames) {
203 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
204 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
205 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
206
Yabin Cui11e96fe2018-03-14 18:16:22 -0700207 regs_.set_pc(0x1000);
208 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700209 ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
210 ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700211 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
212
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800213 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700214 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800215 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100216 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700217 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700218
219 ASSERT_EQ(3U, unwinder.NumFrames());
220
221 auto* frame = &unwinder.frames()[0];
222 EXPECT_EQ(0U, frame->num);
223 EXPECT_EQ(0U, frame->rel_pc);
224 EXPECT_EQ(0x1000U, frame->pc);
225 EXPECT_EQ(0x10000U, frame->sp);
226 EXPECT_EQ("Frame0", frame->function_name);
227 EXPECT_EQ(0U, frame->function_offset);
228 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800229 EXPECT_EQ(0U, frame->map_elf_start_offset);
230 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700231 EXPECT_EQ(0x1000U, frame->map_start);
232 EXPECT_EQ(0x8000U, frame->map_end);
233 EXPECT_EQ(0U, frame->map_load_bias);
234 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
235
236 frame = &unwinder.frames()[1];
237 EXPECT_EQ(1U, frame->num);
238 EXPECT_EQ(0x100U, frame->rel_pc);
239 EXPECT_EQ(0x1100U, frame->pc);
240 EXPECT_EQ(0x10010U, frame->sp);
241 EXPECT_EQ("Frame1", frame->function_name);
242 EXPECT_EQ(1U, frame->function_offset);
243 EXPECT_EQ("/system/fake/libc.so", 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 Ferrisf6f691b2017-09-25 19:23:07 -0700246 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()[2];
252 EXPECT_EQ(2U, frame->num);
253 EXPECT_EQ(0x200U, frame->rel_pc);
254 EXPECT_EQ(0x1200U, frame->pc);
255 EXPECT_EQ(0x10020U, frame->sp);
256 EXPECT_EQ("Frame2", frame->function_name);
257 EXPECT_EQ(2U, frame->function_offset);
258 EXPECT_EQ("/system/fake/libc.so", 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 Ferrisf6f691b2017-09-25 19:23:07 -0700261 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
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800267TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
268 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
269 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
270 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
271
Yabin Cui11e96fe2018-03-14 18:16:22 -0700272 regs_.set_pc(0x1000);
273 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700274 ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
275 ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800276 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
277
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800278 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800279 unwinder.SetResolveNames(false);
280 unwinder.Unwind();
281 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100282 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700283 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800284
285 ASSERT_EQ(3U, unwinder.NumFrames());
286
287 auto* frame = &unwinder.frames()[0];
288 EXPECT_EQ(0U, frame->num);
289 EXPECT_EQ(0U, frame->rel_pc);
290 EXPECT_EQ(0x1000U, frame->pc);
291 EXPECT_EQ(0x10000U, frame->sp);
292 EXPECT_EQ("", frame->function_name);
293 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000294 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800295 EXPECT_EQ(0U, frame->map_elf_start_offset);
296 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800297 EXPECT_EQ(0x1000U, frame->map_start);
298 EXPECT_EQ(0x8000U, frame->map_end);
299 EXPECT_EQ(0U, frame->map_load_bias);
300 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
301
302 frame = &unwinder.frames()[1];
303 EXPECT_EQ(1U, frame->num);
304 EXPECT_EQ(0x100U, frame->rel_pc);
305 EXPECT_EQ(0x1100U, frame->pc);
306 EXPECT_EQ(0x10010U, frame->sp);
307 EXPECT_EQ("", frame->function_name);
308 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000309 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800310 EXPECT_EQ(0U, frame->map_elf_start_offset);
311 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800312 EXPECT_EQ(0x1000U, frame->map_start);
313 EXPECT_EQ(0x8000U, frame->map_end);
314 EXPECT_EQ(0U, frame->map_load_bias);
315 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
316
317 frame = &unwinder.frames()[2];
318 EXPECT_EQ(2U, frame->num);
319 EXPECT_EQ(0x200U, frame->rel_pc);
320 EXPECT_EQ(0x1200U, frame->pc);
321 EXPECT_EQ(0x10020U, frame->sp);
322 EXPECT_EQ("", frame->function_name);
323 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000324 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800325 EXPECT_EQ(0U, frame->map_elf_start_offset);
326 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800327 EXPECT_EQ(0x1000U, frame->map_start);
328 EXPECT_EQ(0x8000U, frame->map_end);
329 EXPECT_EQ(0U, frame->map_load_bias);
330 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
331}
332
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800333TEST_F(UnwinderTest, non_zero_load_bias) {
334 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
335
Yabin Cui11e96fe2018-03-14 18:16:22 -0700336 regs_.set_pc(0xa5500);
337 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800338 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
339
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800340 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800341 unwinder.Unwind();
342 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100343 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700344 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800345
346 ASSERT_EQ(1U, unwinder.NumFrames());
347
348 auto* frame = &unwinder.frames()[0];
349 EXPECT_EQ(0U, frame->num);
350 EXPECT_EQ(0x5500U, frame->rel_pc);
351 EXPECT_EQ(0xa5500U, frame->pc);
352 EXPECT_EQ(0x10000U, frame->sp);
353 EXPECT_EQ("Frame0", frame->function_name);
354 EXPECT_EQ(0U, frame->function_offset);
355 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800356 EXPECT_EQ(0U, frame->map_elf_start_offset);
357 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800358 EXPECT_EQ(0xa5000U, frame->map_start);
359 EXPECT_EQ(0xa6000U, frame->map_end);
360 EXPECT_EQ(0x5000U, frame->map_load_bias);
361 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
362}
363
364TEST_F(UnwinderTest, non_zero_elf_offset) {
365 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
366
Yabin Cui11e96fe2018-03-14 18:16:22 -0700367 regs_.set_pc(0xa7500);
368 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800369 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
370
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800371 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800372 unwinder.Unwind();
373 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100374 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700375 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800376
377 ASSERT_EQ(1U, unwinder.NumFrames());
378
379 auto* frame = &unwinder.frames()[0];
380 EXPECT_EQ(0U, frame->num);
381 EXPECT_EQ(0x8500U, frame->rel_pc);
382 EXPECT_EQ(0xa7500U, frame->pc);
383 EXPECT_EQ(0x10000U, frame->sp);
384 EXPECT_EQ("Frame0", frame->function_name);
385 EXPECT_EQ(0U, frame->function_offset);
386 EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800387 EXPECT_EQ(0U, frame->map_elf_start_offset);
388 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800389 EXPECT_EQ(0xa7000U, frame->map_start);
390 EXPECT_EQ(0xa8000U, frame->map_end);
391 EXPECT_EQ(0U, frame->map_load_bias);
392 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
393}
394
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700395TEST_F(UnwinderTest, non_zero_map_offset) {
396 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
397
Yabin Cui11e96fe2018-03-14 18:16:22 -0700398 regs_.set_pc(0x43000);
399 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700400 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
401
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800402 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700403 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800404 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100405 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700406 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700407
408 ASSERT_EQ(1U, unwinder.NumFrames());
409
410 auto* frame = &unwinder.frames()[0];
411 EXPECT_EQ(0U, frame->num);
412 EXPECT_EQ(0U, frame->rel_pc);
413 EXPECT_EQ(0x43000U, frame->pc);
414 EXPECT_EQ(0x10000U, frame->sp);
415 EXPECT_EQ("Frame0", frame->function_name);
416 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700417 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
418 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
419 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
420 EXPECT_EQ(0x43000U, frame->map_start);
421 EXPECT_EQ(0x44000U, frame->map_end);
422 EXPECT_EQ(0U, frame->map_load_bias);
423 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
424}
425
426TEST_F(UnwinderTest, disable_embedded_soname) {
427 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
428
429 regs_.set_pc(0x43000);
430 regs_.set_sp(0x10000);
431 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
432
433 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
434 unwinder.SetEmbeddedSoname(false);
435 unwinder.Unwind();
436 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100437 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700438 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris02a6c442019-03-11 14:43:33 -0700439
440 ASSERT_EQ(1U, unwinder.NumFrames());
441
442 auto* frame = &unwinder.frames()[0];
443 EXPECT_EQ(0U, frame->num);
444 EXPECT_EQ(0U, frame->rel_pc);
445 EXPECT_EQ(0x43000U, frame->pc);
446 EXPECT_EQ(0x10000U, frame->sp);
447 EXPECT_EQ("Frame0", frame->function_name);
448 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700449 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700450 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800451 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700452 EXPECT_EQ(0x43000U, frame->map_start);
453 EXPECT_EQ(0x44000U, frame->map_end);
454 EXPECT_EQ(0U, frame->map_load_bias);
455 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
456}
457
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700458// Verify that no attempt to continue after the step indicates it is done.
459TEST_F(UnwinderTest, no_frames_after_finished) {
460 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
461 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
462 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
463 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
464 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
465
Yabin Cui11e96fe2018-03-14 18:16:22 -0700466 regs_.set_pc(0x1000);
467 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700468 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
469 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
470 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
471
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800472 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700473 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800474 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100475 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700476 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700477
478 ASSERT_EQ(1U, unwinder.NumFrames());
479
480 auto* frame = &unwinder.frames()[0];
481 EXPECT_EQ(0U, frame->num);
482 EXPECT_EQ(0U, frame->rel_pc);
483 EXPECT_EQ(0x1000U, frame->pc);
484 EXPECT_EQ(0x10000U, frame->sp);
485 EXPECT_EQ("Frame0", frame->function_name);
486 EXPECT_EQ(0U, frame->function_offset);
487 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800488 EXPECT_EQ(0U, frame->map_elf_start_offset);
489 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700490 EXPECT_EQ(0x1000U, frame->map_start);
491 EXPECT_EQ(0x8000U, frame->map_end);
492 EXPECT_EQ(0U, frame->map_load_bias);
493 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
494}
495
496// Verify the maximum frames to save.
497TEST_F(UnwinderTest, max_frames) {
498 for (size_t i = 0; i < 30; i++) {
499 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700500 ElfInterfaceFake::FakePushStepData(StepData(0x1104 + i * 0x100, 0x10010 + i * 0x10, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700501 }
502
Yabin Cui11e96fe2018-03-14 18:16:22 -0700503 regs_.set_pc(0x1000);
504 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700505
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800506 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700507 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800508 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100509 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700510 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700511
512 ASSERT_EQ(20U, unwinder.NumFrames());
513
514 for (size_t i = 0; i < 20; i++) {
515 auto* frame = &unwinder.frames()[i];
516 EXPECT_EQ(i, frame->num);
517 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
518 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
519 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
520 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
521 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
522 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800523 EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
524 EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700525 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
526 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
527 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
528 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
529 }
530}
531
532// Verify that initial map names frames are removed.
533TEST_F(UnwinderTest, verify_frames_skipped) {
534 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
535 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
536 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
537
Yabin Cui11e96fe2018-03-14 18:16:22 -0700538 regs_.set_pc(0x20000);
539 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700540 ElfInterfaceFake::FakePushStepData(StepData(0x23004, 0x10010, false));
541 ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
542 ElfInterfaceFake::FakePushStepData(StepData(0x20004, 0x10030, false));
543 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10040, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700544 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700545 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10060, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700546 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
547 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
548
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800549 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700550 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
551 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800552 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100553 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700554 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700555
556 ASSERT_EQ(3U, unwinder.NumFrames());
557
558 auto* frame = &unwinder.frames()[0];
559 EXPECT_EQ(0U, frame->num);
560 EXPECT_EQ(0U, frame->rel_pc);
561 EXPECT_EQ(0x1000U, frame->pc);
562 EXPECT_EQ(0x10050U, frame->sp);
563 EXPECT_EQ("Frame0", frame->function_name);
564 EXPECT_EQ(0U, frame->function_offset);
565 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800566 EXPECT_EQ(0U, frame->map_elf_start_offset);
567 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700568 EXPECT_EQ(0x1000U, frame->map_start);
569 EXPECT_EQ(0x8000U, frame->map_end);
570 EXPECT_EQ(0U, frame->map_load_bias);
571 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
572
573 frame = &unwinder.frames()[1];
574 EXPECT_EQ(1U, frame->num);
575 EXPECT_EQ(0x1000U, frame->rel_pc);
576 EXPECT_EQ(0x21000U, frame->pc);
577 EXPECT_EQ(0x10060U, frame->sp);
578 EXPECT_EQ("Frame1", frame->function_name);
579 EXPECT_EQ(1U, frame->function_offset);
580 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800581 EXPECT_EQ(0U, frame->map_elf_start_offset);
582 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700583 EXPECT_EQ(0x20000U, frame->map_start);
584 EXPECT_EQ(0x22000U, frame->map_end);
585 EXPECT_EQ(0U, frame->map_load_bias);
586 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
587
588 frame = &unwinder.frames()[2];
589 EXPECT_EQ(2U, frame->num);
590 EXPECT_EQ(0U, frame->rel_pc);
591 EXPECT_EQ(0x23000U, frame->pc);
592 EXPECT_EQ(0x10070U, frame->sp);
593 EXPECT_EQ("Frame2", frame->function_name);
594 EXPECT_EQ(2U, frame->function_offset);
595 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800596 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700597 EXPECT_EQ(0x23000U, frame->map_start);
598 EXPECT_EQ(0x24000U, frame->map_end);
599 EXPECT_EQ(0U, frame->map_load_bias);
600 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
601}
602
603// Verify SP in a non-existant map is okay.
604TEST_F(UnwinderTest, sp_not_in_map) {
605 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
606 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
607
Yabin Cui11e96fe2018-03-14 18:16:22 -0700608 regs_.set_pc(0x1000);
609 regs_.set_sp(0x63000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700610 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x50020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700611 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
612
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800613 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700614 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800615 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100616 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700617 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700618
619 ASSERT_EQ(2U, unwinder.NumFrames());
620
621 auto* frame = &unwinder.frames()[0];
622 EXPECT_EQ(0U, frame->num);
623 EXPECT_EQ(0U, frame->rel_pc);
624 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700625 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700626 EXPECT_EQ("Frame0", frame->function_name);
627 EXPECT_EQ(0U, frame->function_offset);
628 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800629 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700630 EXPECT_EQ(0x1000U, frame->map_start);
631 EXPECT_EQ(0x8000U, frame->map_end);
632 EXPECT_EQ(0U, frame->map_load_bias);
633 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
634
635 frame = &unwinder.frames()[1];
636 EXPECT_EQ(1U, frame->num);
637 EXPECT_EQ(0x1000U, frame->rel_pc);
638 EXPECT_EQ(0x21000U, frame->pc);
639 EXPECT_EQ(0x50020U, frame->sp);
640 EXPECT_EQ("Frame1", frame->function_name);
641 EXPECT_EQ(1U, frame->function_offset);
642 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800643 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700644 EXPECT_EQ(0x20000U, frame->map_start);
645 EXPECT_EQ(0x22000U, frame->map_end);
646 EXPECT_EQ(0U, frame->map_load_bias);
647 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
648}
649
650// Verify PC in a device stops the unwind.
651TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
652 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
653 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
654 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
655
Yabin Cui11e96fe2018-03-14 18:16:22 -0700656 regs_.set_pc(0x13000);
657 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700658 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
659 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
660 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
661
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800662 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700663 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800664 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100665 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700666 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700667
668 ASSERT_EQ(1U, unwinder.NumFrames());
669}
670
671// Verify SP in a device stops the unwind.
672TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
673 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
674 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
675 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
676
Yabin Cui11e96fe2018-03-14 18:16:22 -0700677 regs_.set_pc(0x1000);
678 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700679 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
680 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
681 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
682
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800683 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700684 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800685 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100686 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700687 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700688
689 ASSERT_EQ(1U, unwinder.NumFrames());
690}
691
692// Verify a no map info frame gets a frame.
693TEST_F(UnwinderTest, pc_without_map) {
694 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
695
Yabin Cui11e96fe2018-03-14 18:16:22 -0700696 regs_.set_pc(0x41000);
697 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700698
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800699 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700700 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800701 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100702 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700703 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700704
705 ASSERT_EQ(1U, unwinder.NumFrames());
706
707 auto* frame = &unwinder.frames()[0];
708 EXPECT_EQ(0U, frame->num);
709 EXPECT_EQ(0x41000U, frame->rel_pc);
710 EXPECT_EQ(0x41000U, frame->pc);
711 EXPECT_EQ(0x13000U, frame->sp);
712 EXPECT_EQ("", frame->function_name);
713 EXPECT_EQ(0U, frame->function_offset);
714 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800715 EXPECT_EQ(0U, frame->map_elf_start_offset);
716 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700717 EXPECT_EQ(0U, frame->map_start);
718 EXPECT_EQ(0U, frame->map_end);
719 EXPECT_EQ(0U, frame->map_load_bias);
720 EXPECT_EQ(0, frame->map_flags);
721}
722
723// Verify that a speculative frame is added.
724TEST_F(UnwinderTest, speculative_frame) {
725 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
726 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
727
728 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700729 regs_.set_pc(0);
730 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700731 regs_.FakeSetReturnAddress(0x1204);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700732 regs_.FakeSetReturnAddressValid(true);
733
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700734 ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700735 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
736
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800737 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700738 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800739 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100740 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700741 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700742
743 ASSERT_EQ(3U, unwinder.NumFrames());
744
745 auto* frame = &unwinder.frames()[0];
746 EXPECT_EQ(0U, frame->num);
747 EXPECT_EQ(0U, frame->rel_pc);
748 EXPECT_EQ(0U, frame->pc);
749 EXPECT_EQ(0x10000U, frame->sp);
750 EXPECT_EQ("", frame->function_name);
751 EXPECT_EQ(0U, frame->function_offset);
752 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800753 EXPECT_EQ(0U, frame->map_elf_start_offset);
754 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700755 EXPECT_EQ(0U, frame->map_start);
756 EXPECT_EQ(0U, frame->map_end);
757 EXPECT_EQ(0U, frame->map_load_bias);
758 EXPECT_EQ(0, frame->map_flags);
759
760 frame = &unwinder.frames()[1];
761 EXPECT_EQ(1U, frame->num);
762 EXPECT_EQ(0x200U, frame->rel_pc);
763 EXPECT_EQ(0x1200U, frame->pc);
764 EXPECT_EQ(0x10000U, frame->sp);
765 EXPECT_EQ("Frame0", frame->function_name);
766 EXPECT_EQ(0U, frame->function_offset);
767 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800768 EXPECT_EQ(0U, frame->map_elf_start_offset);
769 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700770 EXPECT_EQ(0x1000U, frame->map_start);
771 EXPECT_EQ(0x8000U, frame->map_end);
772 EXPECT_EQ(0U, frame->map_load_bias);
773 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
774
775 frame = &unwinder.frames()[2];
776 EXPECT_EQ(2U, frame->num);
777 EXPECT_EQ(0x100U, frame->rel_pc);
778 EXPECT_EQ(0x23100U, frame->pc);
779 EXPECT_EQ(0x10020U, frame->sp);
780 EXPECT_EQ("Frame1", frame->function_name);
781 EXPECT_EQ(1U, frame->function_offset);
782 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800783 EXPECT_EQ(0U, frame->map_elf_start_offset);
784 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700785 EXPECT_EQ(0x23000U, frame->map_start);
786 EXPECT_EQ(0x24000U, frame->map_end);
787 EXPECT_EQ(0U, frame->map_load_bias);
788 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
789}
790
791// Verify that a speculative frame is added then removed because no other
792// frames are added.
793TEST_F(UnwinderTest, speculative_frame_removed) {
794 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
795 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
796
797 // Fake as if code called a nullptr function.
Christopher Ferris065f1562018-12-13 09:33:45 -0800798 regs_.set_pc(0x20000);
799 regs_.set_sp(0x10000);
800 ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
801 regs_.FakeSetReturnAddress(0x12);
802 regs_.FakeSetReturnAddressValid(true);
803
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800804 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris065f1562018-12-13 09:33:45 -0800805 unwinder.Unwind();
806 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100807 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700808 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris065f1562018-12-13 09:33:45 -0800809
810 ASSERT_EQ(2U, unwinder.NumFrames());
811
812 auto* frame = &unwinder.frames()[0];
813 EXPECT_EQ(0U, frame->num);
814 EXPECT_EQ(0U, frame->rel_pc);
815 EXPECT_EQ(0x20000U, frame->pc);
816 EXPECT_EQ(0x10000U, frame->sp);
817 EXPECT_EQ("Frame0", frame->function_name);
818 EXPECT_EQ(0U, frame->function_offset);
819 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800820 EXPECT_EQ(0U, frame->map_elf_start_offset);
821 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800822 EXPECT_EQ(0x20000U, frame->map_start);
823 EXPECT_EQ(0x22000U, frame->map_end);
824 EXPECT_EQ(0U, frame->map_load_bias);
825 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
826
827 frame = &unwinder.frames()[1];
828 EXPECT_EQ(1U, frame->num);
829 EXPECT_EQ(0U, frame->rel_pc);
830 EXPECT_EQ(0U, frame->pc);
831 EXPECT_EQ(0x10010U, frame->sp);
832 EXPECT_EQ("", frame->function_name);
833 EXPECT_EQ(0U, frame->function_offset);
834 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800835 EXPECT_EQ(0U, frame->map_elf_start_offset);
836 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800837 EXPECT_EQ(0U, frame->map_start);
838 EXPECT_EQ(0U, frame->map_end);
839 EXPECT_EQ(0U, frame->map_load_bias);
840 EXPECT_EQ(0, frame->map_flags);
841}
842
843// Verify that a speculative frame is added and left if there are only
844// two frames and the pc is in the middle nowhere.
845TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
846 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
847 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
848
849 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700850 regs_.set_pc(0);
851 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700852 regs_.FakeSetReturnAddress(0x1204);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700853 regs_.FakeSetReturnAddressValid(true);
854
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800855 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700856 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800857 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100858 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700859 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700860
Christopher Ferris065f1562018-12-13 09:33:45 -0800861 ASSERT_EQ(2U, unwinder.NumFrames());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700862
863 auto* frame = &unwinder.frames()[0];
864 EXPECT_EQ(0U, frame->num);
865 EXPECT_EQ(0U, frame->rel_pc);
866 EXPECT_EQ(0U, frame->pc);
867 EXPECT_EQ(0x10000U, frame->sp);
868 EXPECT_EQ("", frame->function_name);
869 EXPECT_EQ(0U, frame->function_offset);
870 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800871 EXPECT_EQ(0U, frame->map_elf_start_offset);
872 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700873 EXPECT_EQ(0U, frame->map_start);
874 EXPECT_EQ(0U, frame->map_end);
875 EXPECT_EQ(0U, frame->map_load_bias);
876 EXPECT_EQ(0, frame->map_flags);
Christopher Ferris065f1562018-12-13 09:33:45 -0800877
878 frame = &unwinder.frames()[1];
879 EXPECT_EQ(1U, frame->num);
880 EXPECT_EQ(0x200U, frame->rel_pc);
881 EXPECT_EQ(0x1200U, frame->pc);
882 EXPECT_EQ(0x10000U, frame->sp);
883 EXPECT_EQ("Frame0", frame->function_name);
884 EXPECT_EQ(0U, frame->function_offset);
885 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800886 EXPECT_EQ(0U, frame->map_elf_start_offset);
887 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800888 EXPECT_EQ(0x1000U, frame->map_start);
889 EXPECT_EQ(0x8000U, frame->map_end);
890 EXPECT_EQ(0U, frame->map_load_bias);
891 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700892}
893
Florian Mayerc479e4e2019-01-23 13:35:40 +0000894// Verify that a speculative frame does not cause a crash when it wasn't
895// really added due to a filter.
896TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
897 regs_.set_pc(0x23000);
898 regs_.set_sp(0x10000);
899 regs_.FakeSetReturnAddress(0x23100);
900 regs_.FakeSetReturnAddressValid(true);
901
902 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
903
904 std::vector<std::string> skip_names{"libanother.so"};
905 unwinder.Unwind(&skip_names);
906 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100907 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700908 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Florian Mayerc479e4e2019-01-23 13:35:40 +0000909
910 ASSERT_EQ(0U, unwinder.NumFrames());
911}
912
Christopher Ferrise69f4702017-10-19 16:08:58 -0700913// Verify that an unwind stops when a frame is in given suffix.
914TEST_F(UnwinderTest, map_ignore_suffixes) {
915 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
916 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
917 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
918 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
919
920 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700921 regs_.set_pc(0x1000);
922 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700923 ElfInterfaceFake::FakePushStepData(StepData(0x43404, 0x10010, false));
924 ElfInterfaceFake::FakePushStepData(StepData(0x53504, 0x10020, false));
Christopher Ferrise69f4702017-10-19 16:08:58 -0700925 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
926
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800927 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700928 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700929 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800930 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100931 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700932 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700933
934 ASSERT_EQ(2U, unwinder.NumFrames());
935 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800936 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700937 ASSERT_TRUE(map_info != nullptr);
938 EXPECT_TRUE(map_info->elf == nullptr);
939
940 auto* frame = &unwinder.frames()[0];
941 EXPECT_EQ(0U, frame->num);
942 EXPECT_EQ(0U, frame->rel_pc);
943 EXPECT_EQ(0x1000U, frame->pc);
944 EXPECT_EQ(0x10000U, frame->sp);
945 EXPECT_EQ("Frame0", frame->function_name);
946 EXPECT_EQ(0U, frame->function_offset);
947 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800948 EXPECT_EQ(0U, frame->map_elf_start_offset);
949 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700950 EXPECT_EQ(0x1000U, frame->map_start);
951 EXPECT_EQ(0x8000U, frame->map_end);
952 EXPECT_EQ(0U, frame->map_load_bias);
953 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
954
955 frame = &unwinder.frames()[1];
956 EXPECT_EQ(1U, frame->num);
957 EXPECT_EQ(0x400U, frame->rel_pc);
958 EXPECT_EQ(0x43400U, frame->pc);
959 EXPECT_EQ(0x10010U, frame->sp);
960 EXPECT_EQ("Frame1", frame->function_name);
961 EXPECT_EQ(1U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700962 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
963 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800964 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700965 EXPECT_EQ(0x43000U, frame->map_start);
966 EXPECT_EQ(0x44000U, frame->map_end);
967 EXPECT_EQ(0U, frame->map_load_bias);
968 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
969}
970
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700971// Verify that an unwind stops when the sp and pc don't change.
972TEST_F(UnwinderTest, sp_pc_do_not_change) {
973 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
974 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
975 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
976 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
977 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
978
Yabin Cui11e96fe2018-03-14 18:16:22 -0700979 regs_.set_pc(0x1000);
980 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700981 ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
982 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
983 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
984 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
985 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700986 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
987
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800988 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700989 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800990 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100991 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700992 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700993
994 ASSERT_EQ(3U, unwinder.NumFrames());
995
996 auto* frame = &unwinder.frames()[0];
997 EXPECT_EQ(0U, frame->num);
998 EXPECT_EQ(0U, frame->rel_pc);
999 EXPECT_EQ(0x1000U, frame->pc);
1000 EXPECT_EQ(0x10000U, frame->sp);
1001 EXPECT_EQ("Frame0", frame->function_name);
1002 EXPECT_EQ(0U, frame->function_offset);
1003 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001004 EXPECT_EQ(0U, frame->map_elf_start_offset);
1005 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -07001006 EXPECT_EQ(0x1000U, frame->map_start);
1007 EXPECT_EQ(0x8000U, frame->map_end);
1008 EXPECT_EQ(0U, frame->map_load_bias);
1009 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1010
1011 frame = &unwinder.frames()[1];
1012 EXPECT_EQ(1U, frame->num);
1013 EXPECT_EQ(0x400U, frame->rel_pc);
1014 EXPECT_EQ(0x33400U, frame->pc);
1015 EXPECT_EQ(0x10010U, frame->sp);
1016 EXPECT_EQ("Frame1", frame->function_name);
1017 EXPECT_EQ(1U, frame->function_offset);
1018 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001019 EXPECT_EQ(0U, frame->map_elf_start_offset);
1020 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -07001021 EXPECT_EQ(0x33000U, frame->map_start);
1022 EXPECT_EQ(0x34000U, frame->map_end);
1023 EXPECT_EQ(0U, frame->map_load_bias);
1024 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1025
1026 frame = &unwinder.frames()[2];
1027 EXPECT_EQ(2U, frame->num);
1028 EXPECT_EQ(0x500U, frame->rel_pc);
1029 EXPECT_EQ(0x33500U, frame->pc);
1030 EXPECT_EQ(0x10020U, frame->sp);
1031 EXPECT_EQ("Frame2", frame->function_name);
1032 EXPECT_EQ(2U, frame->function_offset);
1033 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001034 EXPECT_EQ(0U, frame->map_elf_start_offset);
1035 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -07001036 EXPECT_EQ(0x33000U, frame->map_start);
1037 EXPECT_EQ(0x34000U, frame->map_end);
1038 EXPECT_EQ(0U, frame->map_load_bias);
1039 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1040}
1041
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001042TEST_F(UnwinderTest, dex_pc_in_map) {
1043 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001044 regs_.set_pc(0x1000);
1045 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001046 regs_.FakeSetDexPc(0xa3400);
1047
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001048 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001049 unwinder.Unwind();
1050 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001051 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001052 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001053
1054 ASSERT_EQ(2U, unwinder.NumFrames());
1055
1056 auto* frame = &unwinder.frames()[0];
1057 EXPECT_EQ(0U, frame->num);
1058 EXPECT_EQ(0x400U, frame->rel_pc);
1059 EXPECT_EQ(0xa3400U, frame->pc);
1060 EXPECT_EQ(0x10000U, frame->sp);
1061 EXPECT_EQ("", frame->function_name);
1062 EXPECT_EQ(0U, frame->function_offset);
1063 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001064 EXPECT_EQ(0U, frame->map_elf_start_offset);
1065 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001066 EXPECT_EQ(0xa3000U, frame->map_start);
1067 EXPECT_EQ(0xa4000U, frame->map_end);
1068 EXPECT_EQ(0U, frame->map_load_bias);
1069 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1070
1071 frame = &unwinder.frames()[1];
1072 EXPECT_EQ(1U, frame->num);
1073 EXPECT_EQ(0U, frame->rel_pc);
1074 EXPECT_EQ(0x1000U, frame->pc);
1075 EXPECT_EQ(0x10000U, frame->sp);
1076 EXPECT_EQ("Frame0", frame->function_name);
1077 EXPECT_EQ(0U, frame->function_offset);
1078 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001079 EXPECT_EQ(0U, frame->map_elf_start_offset);
1080 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001081 EXPECT_EQ(0x1000U, frame->map_start);
1082 EXPECT_EQ(0x8000U, frame->map_end);
1083 EXPECT_EQ(0U, frame->map_load_bias);
1084 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1085}
1086
Christopher Ferrisa4bdb982019-06-04 11:52:16 -07001087TEST_F(UnwinderTest, dex_pc_in_map_non_zero_offset) {
1088 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1089 regs_.set_pc(0x1000);
1090 regs_.set_sp(0x10000);
1091 regs_.FakeSetDexPc(0xd0400);
1092
1093 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1094 unwinder.Unwind();
1095 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001096 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferrisa4bdb982019-06-04 11:52:16 -07001097 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1098
1099 ASSERT_EQ(2U, unwinder.NumFrames());
1100
1101 auto* frame = &unwinder.frames()[0];
1102 EXPECT_EQ(0U, frame->num);
1103 EXPECT_EQ(0x400U, frame->rel_pc);
1104 EXPECT_EQ(0xd0400U, frame->pc);
1105 EXPECT_EQ(0x10000U, frame->sp);
1106 EXPECT_EQ("", frame->function_name);
1107 EXPECT_EQ(0U, frame->function_offset);
1108 EXPECT_EQ("/fake/fake.apk", frame->map_name);
1109 EXPECT_EQ(0x1000U, frame->map_elf_start_offset);
1110 EXPECT_EQ(0x1000U, frame->map_exact_offset);
1111 EXPECT_EQ(0xd0000U, frame->map_start);
1112 EXPECT_EQ(0xd1000U, frame->map_end);
1113 EXPECT_EQ(0U, frame->map_load_bias);
1114 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1115
1116 frame = &unwinder.frames()[1];
1117 EXPECT_EQ(1U, frame->num);
1118 EXPECT_EQ(0U, frame->rel_pc);
1119 EXPECT_EQ(0x1000U, frame->pc);
1120 EXPECT_EQ(0x10000U, frame->sp);
1121 EXPECT_EQ("Frame0", frame->function_name);
1122 EXPECT_EQ(0U, frame->function_offset);
1123 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
1124 EXPECT_EQ(0U, frame->map_elf_start_offset);
1125 EXPECT_EQ(0U, frame->map_exact_offset);
1126 EXPECT_EQ(0x1000U, frame->map_start);
1127 EXPECT_EQ(0x8000U, frame->map_end);
1128 EXPECT_EQ(0U, frame->map_load_bias);
1129 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1130}
1131
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001132TEST_F(UnwinderTest, dex_pc_not_in_map) {
1133 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001134 regs_.set_pc(0x1000);
1135 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001136 regs_.FakeSetDexPc(0x50000);
1137
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001138 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001139 unwinder.Unwind();
1140 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001141 EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001142 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001143
1144 ASSERT_EQ(2U, unwinder.NumFrames());
1145
1146 auto* frame = &unwinder.frames()[0];
1147 EXPECT_EQ(0U, frame->num);
1148 EXPECT_EQ(0x50000U, frame->rel_pc);
1149 EXPECT_EQ(0x50000U, frame->pc);
1150 EXPECT_EQ(0x10000U, frame->sp);
1151 EXPECT_EQ("", frame->function_name);
1152 EXPECT_EQ(0U, frame->function_offset);
1153 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001154 EXPECT_EQ(0U, frame->map_elf_start_offset);
1155 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001156 EXPECT_EQ(0U, frame->map_start);
1157 EXPECT_EQ(0U, frame->map_end);
1158 EXPECT_EQ(0U, frame->map_load_bias);
1159 EXPECT_EQ(0, frame->map_flags);
1160
1161 frame = &unwinder.frames()[1];
1162 EXPECT_EQ(1U, frame->num);
1163 EXPECT_EQ(0U, frame->rel_pc);
1164 EXPECT_EQ(0x1000U, frame->pc);
1165 EXPECT_EQ(0x10000U, frame->sp);
1166 EXPECT_EQ("Frame0", frame->function_name);
1167 EXPECT_EQ(0U, frame->function_offset);
1168 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001169 EXPECT_EQ(0U, frame->map_elf_start_offset);
1170 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001171 EXPECT_EQ(0x1000U, frame->map_start);
1172 EXPECT_EQ(0x8000U, frame->map_end);
1173 EXPECT_EQ(0U, frame->map_load_bias);
1174 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1175}
1176
Christopher Ferrisafbed692020-08-27 11:46:36 -07001177TEST_F(UnwinderTest, dex_pc_not_in_map_valid_dex_files) {
1178 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1179 regs_.set_pc(0x1000);
1180 regs_.set_sp(0x10000);
1181 regs_.FakeSetDexPc(0x50000);
1182
1183 DexFiles dex_files(process_memory_);
1184 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1185 unwinder.SetDexFiles(&dex_files, ARCH_ARM);
1186 unwinder.Unwind();
1187 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1188 EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
1189 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1190
1191 ASSERT_EQ(2U, unwinder.NumFrames());
1192
1193 auto* frame = &unwinder.frames()[0];
1194 EXPECT_EQ(0U, frame->num);
1195 EXPECT_EQ(0x50000U, frame->rel_pc);
1196 EXPECT_EQ(0x50000U, frame->pc);
1197 EXPECT_EQ(0x10000U, frame->sp);
1198 EXPECT_EQ("", frame->function_name);
1199 EXPECT_EQ(0U, frame->function_offset);
1200 EXPECT_EQ("", frame->map_name);
1201 EXPECT_EQ(0U, frame->map_elf_start_offset);
1202 EXPECT_EQ(0U, frame->map_exact_offset);
1203 EXPECT_EQ(0U, frame->map_start);
1204 EXPECT_EQ(0U, frame->map_end);
1205 EXPECT_EQ(0U, frame->map_load_bias);
1206 EXPECT_EQ(0, frame->map_flags);
1207
1208 frame = &unwinder.frames()[1];
1209 EXPECT_EQ(1U, frame->num);
1210 EXPECT_EQ(0U, frame->rel_pc);
1211 EXPECT_EQ(0x1000U, frame->pc);
1212 EXPECT_EQ(0x10000U, frame->sp);
1213 EXPECT_EQ("Frame0", frame->function_name);
1214 EXPECT_EQ(0U, frame->function_offset);
1215 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
1216 EXPECT_EQ(0U, frame->map_elf_start_offset);
1217 EXPECT_EQ(0U, frame->map_exact_offset);
1218 EXPECT_EQ(0x1000U, frame->map_start);
1219 EXPECT_EQ(0x8000U, frame->map_end);
1220 EXPECT_EQ(0U, frame->map_load_bias);
1221 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1222}
1223
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001224TEST_F(UnwinderTest, dex_pc_multiple_frames) {
1225 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1226 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001227 regs_.set_pc(0x1000);
1228 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001229 regs_.FakeSetDexPc(0xa3400);
Peter Collingbourne5ac39272020-03-19 17:27:58 -07001230 ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001231 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1232
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001233 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001234 unwinder.Unwind();
1235 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001236 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001237 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001238
1239 ASSERT_EQ(3U, unwinder.NumFrames());
1240
1241 auto* frame = &unwinder.frames()[0];
1242 EXPECT_EQ(0U, frame->num);
1243 EXPECT_EQ(0x400U, frame->rel_pc);
1244 EXPECT_EQ(0xa3400U, frame->pc);
1245 EXPECT_EQ(0x10000U, frame->sp);
1246 EXPECT_EQ("", frame->function_name);
1247 EXPECT_EQ(0U, frame->function_offset);
1248 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001249 EXPECT_EQ(0U, frame->map_elf_start_offset);
1250 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001251 EXPECT_EQ(0xa3000U, frame->map_start);
1252 EXPECT_EQ(0xa4000U, frame->map_end);
1253 EXPECT_EQ(0U, frame->map_load_bias);
1254 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1255
1256 frame = &unwinder.frames()[1];
1257 EXPECT_EQ(1U, frame->num);
1258 EXPECT_EQ(0U, frame->rel_pc);
1259 EXPECT_EQ(0x1000U, frame->pc);
1260 EXPECT_EQ(0x10000U, frame->sp);
1261 EXPECT_EQ("Frame0", frame->function_name);
1262 EXPECT_EQ(0U, frame->function_offset);
1263 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001264 EXPECT_EQ(0U, frame->map_elf_start_offset);
1265 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001266 EXPECT_EQ(0x1000U, frame->map_start);
1267 EXPECT_EQ(0x8000U, frame->map_end);
1268 EXPECT_EQ(0U, frame->map_load_bias);
1269 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1270
1271 frame = &unwinder.frames()[2];
1272 EXPECT_EQ(2U, frame->num);
1273 EXPECT_EQ(0x400U, frame->rel_pc);
1274 EXPECT_EQ(0x33400U, frame->pc);
1275 EXPECT_EQ(0x10010U, frame->sp);
1276 EXPECT_EQ("Frame1", frame->function_name);
1277 EXPECT_EQ(1U, frame->function_offset);
1278 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001279 EXPECT_EQ(0U, frame->map_elf_start_offset);
1280 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001281 EXPECT_EQ(0x33000U, frame->map_start);
1282 EXPECT_EQ(0x34000U, frame->map_end);
1283 EXPECT_EQ(0U, frame->map_load_bias);
1284 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1285}
1286
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001287TEST_F(UnwinderTest, dex_pc_max_frames) {
1288 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1289 regs_.set_pc(0x1000);
1290 regs_.set_sp(0x10000);
1291 regs_.FakeSetDexPc(0xa3400);
1292
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001293 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001294 unwinder.Unwind();
1295 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001296 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001297 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001298
1299 ASSERT_EQ(1U, unwinder.NumFrames());
1300
1301 auto* frame = &unwinder.frames()[0];
1302 EXPECT_EQ(0U, frame->num);
1303 EXPECT_EQ(0x400U, frame->rel_pc);
1304 EXPECT_EQ(0xa3400U, frame->pc);
1305 EXPECT_EQ(0x10000U, frame->sp);
1306 EXPECT_EQ("", frame->function_name);
1307 EXPECT_EQ(0U, frame->function_offset);
1308 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001309 EXPECT_EQ(0U, frame->map_elf_start_offset);
1310 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001311 EXPECT_EQ(0xa3000U, frame->map_start);
1312 EXPECT_EQ(0xa4000U, frame->map_end);
1313 EXPECT_EQ(0U, frame->map_load_bias);
1314 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1315}
1316
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001317TEST_F(UnwinderTest, elf_from_memory_not_file) {
1318 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1319
1320 regs_.set_pc(0xc0050);
1321 regs_.set_sp(0x10000);
1322 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1323
1324 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1325 unwinder.Unwind();
1326 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001327 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001328 EXPECT_TRUE(unwinder.elf_from_memory_not_file());
1329
1330 ASSERT_EQ(1U, unwinder.NumFrames());
1331
1332 auto* frame = &unwinder.frames()[0];
1333 EXPECT_EQ(0U, frame->num);
1334 EXPECT_EQ(0x50U, frame->rel_pc);
1335 EXPECT_EQ(0xc0050U, frame->pc);
1336 EXPECT_EQ(0x10000U, frame->sp);
1337 EXPECT_EQ("Frame0", frame->function_name);
1338 EXPECT_EQ(0U, frame->function_offset);
1339 EXPECT_EQ("/fake/unreadable.so", frame->map_name);
1340 EXPECT_EQ(0U, frame->map_elf_start_offset);
1341 EXPECT_EQ(0U, frame->map_exact_offset);
1342 EXPECT_EQ(0xc0000U, frame->map_start);
1343 EXPECT_EQ(0xc1000U, frame->map_end);
1344 EXPECT_EQ(0U, frame->map_load_bias);
1345 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1346}
1347
1348TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
1349 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1350
1351 regs_.set_pc(0xc1050);
1352 regs_.set_sp(0x10000);
1353 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1354
1355 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1356 unwinder.Unwind();
1357 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001358 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001359 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1360
1361 ASSERT_EQ(1U, unwinder.NumFrames());
1362
1363 auto* frame = &unwinder.frames()[0];
1364 EXPECT_EQ(0U, frame->num);
1365 EXPECT_EQ(0x50U, frame->rel_pc);
1366 EXPECT_EQ(0xc1050U, frame->pc);
1367 EXPECT_EQ(0x10000U, frame->sp);
1368 EXPECT_EQ("Frame0", frame->function_name);
1369 EXPECT_EQ(0U, frame->function_offset);
1370 EXPECT_EQ("[vdso]", frame->map_name);
1371 EXPECT_EQ(0U, frame->map_elf_start_offset);
1372 EXPECT_EQ(0U, frame->map_exact_offset);
1373 EXPECT_EQ(0xc1000U, frame->map_start);
1374 EXPECT_EQ(0xc2000U, frame->map_end);
1375 EXPECT_EQ(0U, frame->map_load_bias);
1376 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1377}
1378
1379TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
1380 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1381
1382 regs_.set_pc(0xc2050);
1383 regs_.set_sp(0x10000);
1384 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1385
1386 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1387 unwinder.Unwind();
1388 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001389 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001390 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1391
1392 ASSERT_EQ(1U, unwinder.NumFrames());
1393
1394 auto* frame = &unwinder.frames()[0];
1395 EXPECT_EQ(0U, frame->num);
1396 EXPECT_EQ(0x50U, frame->rel_pc);
1397 EXPECT_EQ(0xc2050U, frame->pc);
1398 EXPECT_EQ(0x10000U, frame->sp);
1399 EXPECT_EQ("Frame0", frame->function_name);
1400 EXPECT_EQ(0U, frame->function_offset);
1401 EXPECT_EQ("", frame->map_name);
1402 EXPECT_EQ(0U, frame->map_elf_start_offset);
1403 EXPECT_EQ(0U, frame->map_exact_offset);
1404 EXPECT_EQ(0xc2000U, frame->map_start);
1405 EXPECT_EQ(0xc3000U, frame->map_end);
1406 EXPECT_EQ(0U, frame->map_load_bias);
1407 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1408}
1409
Christopher Ferris98aaf4c2019-05-03 11:13:17 -07001410TEST_F(UnwinderTest, elf_from_memory_but_from_memfd) {
1411 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1412
1413 regs_.set_pc(0xc3050);
1414 regs_.set_sp(0x10000);
1415 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1416
1417 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1418 unwinder.Unwind();
1419 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001420 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris98aaf4c2019-05-03 11:13:17 -07001421 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1422
1423 ASSERT_EQ(1U, unwinder.NumFrames());
1424
1425 auto* frame = &unwinder.frames()[0];
1426 EXPECT_EQ(0U, frame->num);
1427 EXPECT_EQ(0x50U, frame->rel_pc);
1428 EXPECT_EQ(0xc3050U, frame->pc);
1429 EXPECT_EQ(0x10000U, frame->sp);
1430 EXPECT_EQ("Frame0", frame->function_name);
1431 EXPECT_EQ(0U, frame->function_offset);
1432 EXPECT_EQ("/memfd:/jit-cache", frame->map_name);
1433 EXPECT_EQ(0U, frame->map_elf_start_offset);
1434 EXPECT_EQ(0U, frame->map_exact_offset);
1435 EXPECT_EQ(0xc3000U, frame->map_start);
1436 EXPECT_EQ(0xc4000U, frame->map_end);
1437 EXPECT_EQ(0U, frame->map_load_bias);
1438 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1439}
1440
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001441// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001442TEST_F(UnwinderTest, format_frame) {
1443 RegsFake regs_arm(10);
1444 regs_arm.FakeSetArch(ARCH_ARM);
1445 Unwinder unwinder32(10, maps_.get(), &regs_arm, process_memory_);
1446
1447 RegsFake regs_arm64(10);
1448 regs_arm64.FakeSetArch(ARCH_ARM64);
1449 Unwinder unwinder64(10, maps_.get(), &regs_arm64, process_memory_);
1450
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001451 FrameData frame;
1452 frame.num = 1;
1453 frame.rel_pc = 0x1000;
1454 frame.pc = 0x4000;
1455 frame.sp = 0x1000;
1456 frame.function_name = "function";
1457 frame.function_offset = 100;
1458 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001459 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001460 frame.map_start = 0x3000;
1461 frame.map_end = 0x6000;
1462 frame.map_flags = PROT_READ;
1463
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001464 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001465 unwinder64.FormatFrame(frame));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001466 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001467 unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001468
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001469 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001470 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001471 unwinder64.FormatFrame(frame));
1472 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001473
1474 frame.function_offset = 0;
1475 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
Christopher Ferris78133452019-03-14 13:44:38 -07001476 unwinder64.FormatFrame(frame));
1477 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001478
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001479 // Verify the function name is demangled.
1480 frame.function_name = "_ZN4funcEv";
Christopher Ferris78133452019-03-14 13:44:38 -07001481 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())", unwinder64.FormatFrame(frame));
1482 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", unwinder32.FormatFrame(frame));
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001483
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001484 frame.function_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001485 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", unwinder64.FormatFrame(frame));
1486 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001487
1488 frame.map_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001489 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", unwinder64.FormatFrame(frame));
1490 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001491
1492 frame.map_start = 0;
1493 frame.map_end = 0;
Christopher Ferris78133452019-03-14 13:44:38 -07001494 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", unwinder64.FormatFrame(frame));
1495 EXPECT_EQ(" #01 pc 00001000 <unknown>", unwinder32.FormatFrame(frame));
1496}
1497
1498TEST_F(UnwinderTest, format_frame_build_id) {
1499 RegsFake regs(10);
1500 regs.FakeSetArch(ARCH_ARM);
1501 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1502
1503 FrameData frame;
1504 frame.num = 1;
1505 frame.rel_pc = 0x1000;
1506 frame.pc = 0x4000;
1507 frame.sp = 0x1000;
1508 frame.function_name = "function";
1509 frame.function_offset = 100;
1510 frame.map_name = "/fake/libfake.so";
1511 frame.map_elf_start_offset = 0;
1512 frame.map_start = 0x3000;
1513 frame.map_end = 0x6000;
1514 frame.map_flags = PROT_READ;
1515
1516 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder.FormatFrame(frame));
1517 unwinder.SetDisplayBuildID(true);
1518 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100) (BuildId: 46414b45)",
1519 unwinder.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001520}
1521
Christopher Ferris02fdb562017-12-08 15:04:49 -08001522static std::string ArchToString(ArchEnum arch) {
1523 if (arch == ARCH_ARM) {
1524 return "Arm";
1525 } else if (arch == ARCH_ARM64) {
1526 return "Arm64";
1527 } else if (arch == ARCH_X86) {
1528 return "X86";
1529 } else if (arch == ARCH_X86_64) {
1530 return "X86_64";
1531 } else {
1532 return "Unknown";
1533 }
1534}
1535
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001536// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001537TEST_F(UnwinderTest, format_frame_by_arch) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001538 std::vector<Regs*> reg_list;
1539 RegsArm* arm = new RegsArm;
1540 arm->set_pc(0x2300);
1541 arm->set_sp(0x10000);
1542 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001543
Christopher Ferris02fdb562017-12-08 15:04:49 -08001544 RegsArm64* arm64 = new RegsArm64;
1545 arm64->set_pc(0x2300);
1546 arm64->set_sp(0x10000);
1547 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001548
Christopher Ferris02fdb562017-12-08 15:04:49 -08001549 RegsX86* x86 = new RegsX86;
1550 x86->set_pc(0x2300);
1551 x86->set_sp(0x10000);
1552 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001553
Christopher Ferris02fdb562017-12-08 15:04:49 -08001554 RegsX86_64* x86_64 = new RegsX86_64;
1555 x86_64->set_pc(0x2300);
1556 x86_64->set_sp(0x10000);
1557 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001558
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001559 RegsMips* mips = new RegsMips;
1560 mips->set_pc(0x2300);
1561 mips->set_sp(0x10000);
1562 reg_list.push_back(mips);
1563
1564 RegsMips64* mips64 = new RegsMips64;
1565 mips64->set_pc(0x2300);
1566 mips64->set_sp(0x10000);
1567 reg_list.push_back(mips64);
1568
Christopher Ferris02fdb562017-12-08 15:04:49 -08001569 for (auto regs : reg_list) {
1570 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001571
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001572 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001573 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001574
Christopher Ferris02fdb562017-12-08 15:04:49 -08001575 ASSERT_EQ(1U, unwinder.NumFrames());
1576 std::string expected;
1577 switch (regs->Arch()) {
1578 case ARCH_ARM:
1579 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001580 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001581 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1582 break;
1583 case ARCH_ARM64:
1584 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001585 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001586 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1587 break;
1588 default:
1589 expected = "";
1590 }
1591 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1592 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1593 delete regs;
1594 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001595}
1596
Christopher Ferris06996a82020-08-27 19:33:12 -07001597TEST_F(UnwinderTest, build_frame_pc_only_errors) {
1598 RegsFake regs(10);
1599 regs.FakeSetArch(ARCH_ARM);
1600 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1601
1602 FrameData frame;
1603
1604 // Pc not in map
1605 frame = unwinder.BuildFrameFromPcOnly(0x10);
1606 EXPECT_EQ(0x10U, frame.pc);
1607 EXPECT_EQ(0x10U, frame.rel_pc);
1608
1609 // No regs set
1610 unwinder.SetRegs(nullptr);
1611 frame = unwinder.BuildFrameFromPcOnly(0x100310);
1612 EXPECT_EQ(0x100310U, frame.pc);
1613 EXPECT_EQ(0x100310U, frame.rel_pc);
1614 unwinder.SetRegs(&regs);
1615
1616 // Invalid elf
1617 frame = unwinder.BuildFrameFromPcOnly(0x100310);
1618 EXPECT_EQ(0x10030eU, frame.pc);
1619 EXPECT_EQ(0x60eU, frame.rel_pc);
1620 EXPECT_EQ("/fake/jit.so", frame.map_name);
1621 EXPECT_EQ(0x100U, frame.map_elf_start_offset);
1622 EXPECT_EQ(0x200U, frame.map_exact_offset);
1623 EXPECT_EQ(0x100000U, frame.map_start);
1624 EXPECT_EQ(0x101000U, frame.map_end);
1625 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame.map_flags);
1626 EXPECT_EQ(0x300U, frame.map_load_bias);
1627 EXPECT_EQ("", frame.function_name);
1628 EXPECT_EQ(0U, frame.function_offset);
1629}
1630
1631TEST_F(UnwinderTest, build_frame_pc_valid_elf) {
1632 RegsFake regs(10);
1633 regs.FakeSetArch(ARCH_ARM);
1634 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1635
1636 FrameData frame;
1637
1638 // Valid elf, no function data.
1639 frame = unwinder.BuildFrameFromPcOnly(0x1010);
1640 EXPECT_EQ(0x100cU, frame.pc);
1641 EXPECT_EQ(0xcU, frame.rel_pc);
1642 EXPECT_EQ("/system/fake/libc.so", frame.map_name);
1643 EXPECT_EQ(0U, frame.map_elf_start_offset);
1644 EXPECT_EQ(0U, frame.map_exact_offset);
1645 EXPECT_EQ(0x1000U, frame.map_start);
1646 EXPECT_EQ(0x8000U, frame.map_end);
1647 EXPECT_EQ(PROT_READ | PROT_WRITE, frame.map_flags);
1648 EXPECT_EQ(0U, frame.map_load_bias);
1649 EXPECT_EQ("", frame.function_name);
1650 EXPECT_EQ(0U, frame.function_offset);
1651
1652 // Valid elf, function data present, but do not resolve.
1653 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
1654 unwinder.SetResolveNames(false);
1655
1656 frame = unwinder.BuildFrameFromPcOnly(0x1010);
1657 EXPECT_EQ(0x100cU, frame.pc);
1658 EXPECT_EQ(0xcU, frame.rel_pc);
1659 EXPECT_EQ("/system/fake/libc.so", frame.map_name);
1660 EXPECT_EQ(0U, frame.map_elf_start_offset);
1661 EXPECT_EQ(0U, frame.map_exact_offset);
1662 EXPECT_EQ(0x1000U, frame.map_start);
1663 EXPECT_EQ(0x8000U, frame.map_end);
1664 EXPECT_EQ(PROT_READ | PROT_WRITE, frame.map_flags);
1665 EXPECT_EQ(0U, frame.map_load_bias);
1666 EXPECT_EQ("", frame.function_name);
1667 EXPECT_EQ(0U, frame.function_offset);
1668
1669 // Valid elf, function data present.
1670 unwinder.SetResolveNames(true);
1671
1672 frame = unwinder.BuildFrameFromPcOnly(0x1010);
1673 EXPECT_EQ(0x100cU, frame.pc);
1674 EXPECT_EQ(0xcU, frame.rel_pc);
1675 EXPECT_EQ("/system/fake/libc.so", frame.map_name);
1676 EXPECT_EQ(0U, frame.map_elf_start_offset);
1677 EXPECT_EQ(0U, frame.map_exact_offset);
1678 EXPECT_EQ(0x1000U, frame.map_start);
1679 EXPECT_EQ(0x8000U, frame.map_end);
1680 EXPECT_EQ(PROT_READ | PROT_WRITE, frame.map_flags);
1681 EXPECT_EQ(0U, frame.map_load_bias);
1682 EXPECT_EQ("Frame0", frame.function_name);
1683 EXPECT_EQ(10U, frame.function_offset);
1684}
1685
1686TEST_F(UnwinderTest, build_frame_pc_in_jit) {
1687 // Create the elf data for the jit debug information.
1688 Elf32_Ehdr ehdr = {};
1689 TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
1690 ehdr.e_phoff = 0x50;
1691 ehdr.e_phnum = 1;
1692 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1693 ehdr.e_shoff = 0x100;
1694 ehdr.e_shstrndx = 1;
1695 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1696 ehdr.e_shnum = 3;
1697 memory_->SetMemory(0xf7000, &ehdr, sizeof(ehdr));
1698
1699 Elf32_Phdr phdr = {};
1700 phdr.p_flags = PF_X;
1701 phdr.p_type = PT_LOAD;
1702 phdr.p_offset = 0x100000;
1703 phdr.p_vaddr = 0x100000;
1704 phdr.p_memsz = 0x1000;
1705 memory_->SetMemory(0xf7050, &phdr, sizeof(phdr));
1706
1707 Elf32_Shdr shdr = {};
1708 shdr.sh_type = SHT_NULL;
1709 memory_->SetMemory(0xf7100, &shdr, sizeof(shdr));
1710
1711 shdr.sh_type = SHT_SYMTAB;
1712 shdr.sh_link = 2;
1713 shdr.sh_addr = 0x300;
1714 shdr.sh_offset = 0x300;
1715 shdr.sh_entsize = sizeof(Elf32_Sym);
1716 shdr.sh_size = shdr.sh_entsize;
1717 memory_->SetMemory(0xf7100 + sizeof(shdr), &shdr, sizeof(shdr));
1718
1719 memset(&shdr, 0, sizeof(shdr));
1720 shdr.sh_type = SHT_STRTAB;
1721 shdr.sh_name = 0x500;
1722 shdr.sh_offset = 0x400;
1723 shdr.sh_size = 0x100;
1724 memory_->SetMemory(0xf7100 + 2 * sizeof(shdr), &shdr, sizeof(shdr));
1725
1726 Elf32_Sym sym = {};
1727 sym.st_shndx = 2;
1728 sym.st_info = STT_FUNC;
1729 sym.st_value = 0x100300;
1730 sym.st_size = 0x100;
1731 memory_->SetMemory(0xf7300, &sym, sizeof(sym));
1732 memory_->SetMemory(0xf7400, "FakeJitFunction");
1733
1734 RegsFake regs(10);
1735 regs.FakeSetArch(ARCH_ARM);
1736 JitDebug jit_debug(process_memory_);
1737 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1738 unwinder.SetJitDebug(&jit_debug, ARCH_ARM);
1739
1740 FrameData frame = unwinder.BuildFrameFromPcOnly(0x100310);
1741 EXPECT_EQ(0x10030eU, frame.pc);
1742 EXPECT_EQ(0x60eU, frame.rel_pc);
1743 EXPECT_EQ("/fake/jit.so", frame.map_name);
1744 EXPECT_EQ(0x100U, frame.map_elf_start_offset);
1745 EXPECT_EQ(0x200U, frame.map_exact_offset);
1746 EXPECT_EQ(0x100000U, frame.map_start);
1747 EXPECT_EQ(0x101000U, frame.map_end);
1748 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame.map_flags);
1749 EXPECT_EQ(0U, frame.map_load_bias);
1750 EXPECT_EQ("FakeJitFunction", frame.function_name);
1751 EXPECT_EQ(0xeU, frame.function_offset);
1752}
1753
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001754} // namespace unwindstack