blob: d10af2f0b77d608194bb8d14acccead8b35560cc [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 Ferris7e21eba2019-06-20 16:16:42 -070057 static void SetUpTestSuite() {
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 Ferrisa4bdb982019-06-04 11:52:16 -0700135 AddMapInfo(0xd0000, 0xd1000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.apk");
136 const auto& info7 = *--maps_->end();
137 info7->load_bias = 0;
138
Christopher Ferris02fdb562017-12-08 15:04:49 -0800139 process_memory_.reset(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700140 }
141
142 void SetUp() override {
143 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800144 regs_.FakeSetArch(ARCH_ARM);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700145 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700146 }
147
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800148 static std::unique_ptr<Maps> maps_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700149 static RegsFake regs_;
150 static std::shared_ptr<Memory> process_memory_;
151};
152
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800153std::unique_ptr<Maps> UnwinderTest::maps_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700154RegsFake UnwinderTest::regs_(5);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700155std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
156
157TEST_F(UnwinderTest, multiple_frames) {
158 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
159 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
160 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
161
Yabin Cui11e96fe2018-03-14 18:16:22 -0700162 regs_.set_pc(0x1000);
163 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700164 ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
165 ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700166 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
167
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800168 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700169 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800170 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100171 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700172 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700173
174 ASSERT_EQ(3U, unwinder.NumFrames());
175
176 auto* frame = &unwinder.frames()[0];
177 EXPECT_EQ(0U, frame->num);
178 EXPECT_EQ(0U, frame->rel_pc);
179 EXPECT_EQ(0x1000U, frame->pc);
180 EXPECT_EQ(0x10000U, frame->sp);
181 EXPECT_EQ("Frame0", frame->function_name);
182 EXPECT_EQ(0U, frame->function_offset);
183 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800184 EXPECT_EQ(0U, frame->map_elf_start_offset);
185 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700186 EXPECT_EQ(0x1000U, frame->map_start);
187 EXPECT_EQ(0x8000U, frame->map_end);
188 EXPECT_EQ(0U, frame->map_load_bias);
189 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
190
191 frame = &unwinder.frames()[1];
192 EXPECT_EQ(1U, frame->num);
193 EXPECT_EQ(0x100U, frame->rel_pc);
194 EXPECT_EQ(0x1100U, frame->pc);
195 EXPECT_EQ(0x10010U, frame->sp);
196 EXPECT_EQ("Frame1", frame->function_name);
197 EXPECT_EQ(1U, frame->function_offset);
198 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800199 EXPECT_EQ(0U, frame->map_elf_start_offset);
200 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700201 EXPECT_EQ(0x1000U, frame->map_start);
202 EXPECT_EQ(0x8000U, frame->map_end);
203 EXPECT_EQ(0U, frame->map_load_bias);
204 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
205
206 frame = &unwinder.frames()[2];
207 EXPECT_EQ(2U, frame->num);
208 EXPECT_EQ(0x200U, frame->rel_pc);
209 EXPECT_EQ(0x1200U, frame->pc);
210 EXPECT_EQ(0x10020U, frame->sp);
211 EXPECT_EQ("Frame2", frame->function_name);
212 EXPECT_EQ(2U, frame->function_offset);
213 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800214 EXPECT_EQ(0U, frame->map_elf_start_offset);
215 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700216 EXPECT_EQ(0x1000U, frame->map_start);
217 EXPECT_EQ(0x8000U, frame->map_end);
218 EXPECT_EQ(0U, frame->map_load_bias);
219 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
220}
221
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800222TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
223 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
224 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
225 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
226
Yabin Cui11e96fe2018-03-14 18:16:22 -0700227 regs_.set_pc(0x1000);
228 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700229 ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
230 ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800231 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
232
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800233 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800234 unwinder.SetResolveNames(false);
235 unwinder.Unwind();
236 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100237 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700238 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800239
240 ASSERT_EQ(3U, unwinder.NumFrames());
241
242 auto* frame = &unwinder.frames()[0];
243 EXPECT_EQ(0U, frame->num);
244 EXPECT_EQ(0U, frame->rel_pc);
245 EXPECT_EQ(0x1000U, frame->pc);
246 EXPECT_EQ(0x10000U, frame->sp);
247 EXPECT_EQ("", frame->function_name);
248 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000249 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800250 EXPECT_EQ(0U, frame->map_elf_start_offset);
251 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800252 EXPECT_EQ(0x1000U, frame->map_start);
253 EXPECT_EQ(0x8000U, frame->map_end);
254 EXPECT_EQ(0U, frame->map_load_bias);
255 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
256
257 frame = &unwinder.frames()[1];
258 EXPECT_EQ(1U, frame->num);
259 EXPECT_EQ(0x100U, frame->rel_pc);
260 EXPECT_EQ(0x1100U, frame->pc);
261 EXPECT_EQ(0x10010U, frame->sp);
262 EXPECT_EQ("", frame->function_name);
263 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000264 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800265 EXPECT_EQ(0U, frame->map_elf_start_offset);
266 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800267 EXPECT_EQ(0x1000U, frame->map_start);
268 EXPECT_EQ(0x8000U, frame->map_end);
269 EXPECT_EQ(0U, frame->map_load_bias);
270 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
271
272 frame = &unwinder.frames()[2];
273 EXPECT_EQ(2U, frame->num);
274 EXPECT_EQ(0x200U, frame->rel_pc);
275 EXPECT_EQ(0x1200U, frame->pc);
276 EXPECT_EQ(0x10020U, frame->sp);
277 EXPECT_EQ("", frame->function_name);
278 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000279 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800280 EXPECT_EQ(0U, frame->map_elf_start_offset);
281 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800282 EXPECT_EQ(0x1000U, frame->map_start);
283 EXPECT_EQ(0x8000U, frame->map_end);
284 EXPECT_EQ(0U, frame->map_load_bias);
285 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
286}
287
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800288TEST_F(UnwinderTest, non_zero_load_bias) {
289 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
290
Yabin Cui11e96fe2018-03-14 18:16:22 -0700291 regs_.set_pc(0xa5500);
292 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800293 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
294
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800295 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800296 unwinder.Unwind();
297 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100298 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700299 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800300
301 ASSERT_EQ(1U, unwinder.NumFrames());
302
303 auto* frame = &unwinder.frames()[0];
304 EXPECT_EQ(0U, frame->num);
305 EXPECT_EQ(0x5500U, frame->rel_pc);
306 EXPECT_EQ(0xa5500U, frame->pc);
307 EXPECT_EQ(0x10000U, frame->sp);
308 EXPECT_EQ("Frame0", frame->function_name);
309 EXPECT_EQ(0U, frame->function_offset);
310 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800311 EXPECT_EQ(0U, frame->map_elf_start_offset);
312 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800313 EXPECT_EQ(0xa5000U, frame->map_start);
314 EXPECT_EQ(0xa6000U, frame->map_end);
315 EXPECT_EQ(0x5000U, frame->map_load_bias);
316 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
317}
318
319TEST_F(UnwinderTest, non_zero_elf_offset) {
320 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
321
Yabin Cui11e96fe2018-03-14 18:16:22 -0700322 regs_.set_pc(0xa7500);
323 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800324 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
325
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800326 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800327 unwinder.Unwind();
328 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100329 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700330 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800331
332 ASSERT_EQ(1U, unwinder.NumFrames());
333
334 auto* frame = &unwinder.frames()[0];
335 EXPECT_EQ(0U, frame->num);
336 EXPECT_EQ(0x8500U, frame->rel_pc);
337 EXPECT_EQ(0xa7500U, frame->pc);
338 EXPECT_EQ(0x10000U, frame->sp);
339 EXPECT_EQ("Frame0", frame->function_name);
340 EXPECT_EQ(0U, frame->function_offset);
341 EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800342 EXPECT_EQ(0U, frame->map_elf_start_offset);
343 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800344 EXPECT_EQ(0xa7000U, frame->map_start);
345 EXPECT_EQ(0xa8000U, frame->map_end);
346 EXPECT_EQ(0U, frame->map_load_bias);
347 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
348}
349
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700350TEST_F(UnwinderTest, non_zero_map_offset) {
351 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
352
Yabin Cui11e96fe2018-03-14 18:16:22 -0700353 regs_.set_pc(0x43000);
354 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700355 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
356
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800357 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700358 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800359 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100360 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700361 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700362
363 ASSERT_EQ(1U, unwinder.NumFrames());
364
365 auto* frame = &unwinder.frames()[0];
366 EXPECT_EQ(0U, frame->num);
367 EXPECT_EQ(0U, frame->rel_pc);
368 EXPECT_EQ(0x43000U, frame->pc);
369 EXPECT_EQ(0x10000U, frame->sp);
370 EXPECT_EQ("Frame0", frame->function_name);
371 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700372 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
373 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
374 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
375 EXPECT_EQ(0x43000U, frame->map_start);
376 EXPECT_EQ(0x44000U, frame->map_end);
377 EXPECT_EQ(0U, frame->map_load_bias);
378 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
379}
380
381TEST_F(UnwinderTest, disable_embedded_soname) {
382 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
383
384 regs_.set_pc(0x43000);
385 regs_.set_sp(0x10000);
386 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
387
388 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
389 unwinder.SetEmbeddedSoname(false);
390 unwinder.Unwind();
391 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100392 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700393 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris02a6c442019-03-11 14:43:33 -0700394
395 ASSERT_EQ(1U, unwinder.NumFrames());
396
397 auto* frame = &unwinder.frames()[0];
398 EXPECT_EQ(0U, frame->num);
399 EXPECT_EQ(0U, frame->rel_pc);
400 EXPECT_EQ(0x43000U, frame->pc);
401 EXPECT_EQ(0x10000U, frame->sp);
402 EXPECT_EQ("Frame0", frame->function_name);
403 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700404 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700405 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800406 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700407 EXPECT_EQ(0x43000U, frame->map_start);
408 EXPECT_EQ(0x44000U, frame->map_end);
409 EXPECT_EQ(0U, frame->map_load_bias);
410 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
411}
412
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700413// Verify that no attempt to continue after the step indicates it is done.
414TEST_F(UnwinderTest, no_frames_after_finished) {
415 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
416 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
417 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
418 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
419 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
420
Yabin Cui11e96fe2018-03-14 18:16:22 -0700421 regs_.set_pc(0x1000);
422 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700423 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
424 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
425 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
426
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800427 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700428 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800429 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100430 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700431 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700432
433 ASSERT_EQ(1U, unwinder.NumFrames());
434
435 auto* frame = &unwinder.frames()[0];
436 EXPECT_EQ(0U, frame->num);
437 EXPECT_EQ(0U, frame->rel_pc);
438 EXPECT_EQ(0x1000U, frame->pc);
439 EXPECT_EQ(0x10000U, frame->sp);
440 EXPECT_EQ("Frame0", frame->function_name);
441 EXPECT_EQ(0U, frame->function_offset);
442 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800443 EXPECT_EQ(0U, frame->map_elf_start_offset);
444 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700445 EXPECT_EQ(0x1000U, frame->map_start);
446 EXPECT_EQ(0x8000U, frame->map_end);
447 EXPECT_EQ(0U, frame->map_load_bias);
448 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
449}
450
451// Verify the maximum frames to save.
452TEST_F(UnwinderTest, max_frames) {
453 for (size_t i = 0; i < 30; i++) {
454 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700455 ElfInterfaceFake::FakePushStepData(StepData(0x1104 + i * 0x100, 0x10010 + i * 0x10, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700456 }
457
Yabin Cui11e96fe2018-03-14 18:16:22 -0700458 regs_.set_pc(0x1000);
459 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700460
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800461 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700462 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800463 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100464 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700465 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700466
467 ASSERT_EQ(20U, unwinder.NumFrames());
468
469 for (size_t i = 0; i < 20; i++) {
470 auto* frame = &unwinder.frames()[i];
471 EXPECT_EQ(i, frame->num);
472 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
473 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
474 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
475 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
476 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
477 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800478 EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
479 EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700480 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
481 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
482 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
483 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
484 }
485}
486
487// Verify that initial map names frames are removed.
488TEST_F(UnwinderTest, verify_frames_skipped) {
489 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
490 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
491 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
492
Yabin Cui11e96fe2018-03-14 18:16:22 -0700493 regs_.set_pc(0x20000);
494 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700495 ElfInterfaceFake::FakePushStepData(StepData(0x23004, 0x10010, false));
496 ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
497 ElfInterfaceFake::FakePushStepData(StepData(0x20004, 0x10030, false));
498 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10040, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700499 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700500 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10060, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700501 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
502 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
503
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800504 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700505 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
506 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800507 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100508 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700509 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700510
511 ASSERT_EQ(3U, unwinder.NumFrames());
512
513 auto* frame = &unwinder.frames()[0];
514 EXPECT_EQ(0U, frame->num);
515 EXPECT_EQ(0U, frame->rel_pc);
516 EXPECT_EQ(0x1000U, frame->pc);
517 EXPECT_EQ(0x10050U, frame->sp);
518 EXPECT_EQ("Frame0", frame->function_name);
519 EXPECT_EQ(0U, frame->function_offset);
520 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800521 EXPECT_EQ(0U, frame->map_elf_start_offset);
522 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700523 EXPECT_EQ(0x1000U, frame->map_start);
524 EXPECT_EQ(0x8000U, frame->map_end);
525 EXPECT_EQ(0U, frame->map_load_bias);
526 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
527
528 frame = &unwinder.frames()[1];
529 EXPECT_EQ(1U, frame->num);
530 EXPECT_EQ(0x1000U, frame->rel_pc);
531 EXPECT_EQ(0x21000U, frame->pc);
532 EXPECT_EQ(0x10060U, frame->sp);
533 EXPECT_EQ("Frame1", frame->function_name);
534 EXPECT_EQ(1U, frame->function_offset);
535 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800536 EXPECT_EQ(0U, frame->map_elf_start_offset);
537 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700538 EXPECT_EQ(0x20000U, frame->map_start);
539 EXPECT_EQ(0x22000U, frame->map_end);
540 EXPECT_EQ(0U, frame->map_load_bias);
541 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
542
543 frame = &unwinder.frames()[2];
544 EXPECT_EQ(2U, frame->num);
545 EXPECT_EQ(0U, frame->rel_pc);
546 EXPECT_EQ(0x23000U, frame->pc);
547 EXPECT_EQ(0x10070U, frame->sp);
548 EXPECT_EQ("Frame2", frame->function_name);
549 EXPECT_EQ(2U, frame->function_offset);
550 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800551 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700552 EXPECT_EQ(0x23000U, frame->map_start);
553 EXPECT_EQ(0x24000U, frame->map_end);
554 EXPECT_EQ(0U, frame->map_load_bias);
555 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
556}
557
558// Verify SP in a non-existant map is okay.
559TEST_F(UnwinderTest, sp_not_in_map) {
560 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
561 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
562
Yabin Cui11e96fe2018-03-14 18:16:22 -0700563 regs_.set_pc(0x1000);
564 regs_.set_sp(0x63000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700565 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x50020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700566 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
567
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800568 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700569 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800570 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100571 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700572 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700573
574 ASSERT_EQ(2U, unwinder.NumFrames());
575
576 auto* frame = &unwinder.frames()[0];
577 EXPECT_EQ(0U, frame->num);
578 EXPECT_EQ(0U, frame->rel_pc);
579 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700580 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700581 EXPECT_EQ("Frame0", frame->function_name);
582 EXPECT_EQ(0U, frame->function_offset);
583 EXPECT_EQ("/system/fake/libc.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(0x1000U, frame->map_start);
586 EXPECT_EQ(0x8000U, frame->map_end);
587 EXPECT_EQ(0U, frame->map_load_bias);
588 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
589
590 frame = &unwinder.frames()[1];
591 EXPECT_EQ(1U, frame->num);
592 EXPECT_EQ(0x1000U, frame->rel_pc);
593 EXPECT_EQ(0x21000U, frame->pc);
594 EXPECT_EQ(0x50020U, frame->sp);
595 EXPECT_EQ("Frame1", frame->function_name);
596 EXPECT_EQ(1U, frame->function_offset);
597 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800598 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700599 EXPECT_EQ(0x20000U, frame->map_start);
600 EXPECT_EQ(0x22000U, frame->map_end);
601 EXPECT_EQ(0U, frame->map_load_bias);
602 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
603}
604
605// Verify PC in a device stops the unwind.
606TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
607 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
608 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
609 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
610
Yabin Cui11e96fe2018-03-14 18:16:22 -0700611 regs_.set_pc(0x13000);
612 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700613 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
614 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
615 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
616
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800617 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700618 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800619 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100620 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700621 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700622
623 ASSERT_EQ(1U, unwinder.NumFrames());
624}
625
626// Verify SP in a device stops the unwind.
627TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
628 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
629 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
630 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
631
Yabin Cui11e96fe2018-03-14 18:16:22 -0700632 regs_.set_pc(0x1000);
633 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700634 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
635 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
636 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
637
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_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100641 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700642 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700643
644 ASSERT_EQ(1U, unwinder.NumFrames());
645}
646
647// Verify a no map info frame gets a frame.
648TEST_F(UnwinderTest, pc_without_map) {
649 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
650
Yabin Cui11e96fe2018-03-14 18:16:22 -0700651 regs_.set_pc(0x41000);
652 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700653
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800654 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700655 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800656 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100657 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700658 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700659
660 ASSERT_EQ(1U, unwinder.NumFrames());
661
662 auto* frame = &unwinder.frames()[0];
663 EXPECT_EQ(0U, frame->num);
664 EXPECT_EQ(0x41000U, frame->rel_pc);
665 EXPECT_EQ(0x41000U, frame->pc);
666 EXPECT_EQ(0x13000U, frame->sp);
667 EXPECT_EQ("", frame->function_name);
668 EXPECT_EQ(0U, frame->function_offset);
669 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800670 EXPECT_EQ(0U, frame->map_elf_start_offset);
671 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700672 EXPECT_EQ(0U, frame->map_start);
673 EXPECT_EQ(0U, frame->map_end);
674 EXPECT_EQ(0U, frame->map_load_bias);
675 EXPECT_EQ(0, frame->map_flags);
676}
677
678// Verify that a speculative frame is added.
679TEST_F(UnwinderTest, speculative_frame) {
680 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
681 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
682
683 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700684 regs_.set_pc(0);
685 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700686 regs_.FakeSetReturnAddress(0x1204);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700687 regs_.FakeSetReturnAddressValid(true);
688
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700689 ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700690 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
691
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800692 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700693 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800694 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100695 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700696 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700697
698 ASSERT_EQ(3U, unwinder.NumFrames());
699
700 auto* frame = &unwinder.frames()[0];
701 EXPECT_EQ(0U, frame->num);
702 EXPECT_EQ(0U, frame->rel_pc);
703 EXPECT_EQ(0U, frame->pc);
704 EXPECT_EQ(0x10000U, frame->sp);
705 EXPECT_EQ("", frame->function_name);
706 EXPECT_EQ(0U, frame->function_offset);
707 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800708 EXPECT_EQ(0U, frame->map_elf_start_offset);
709 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700710 EXPECT_EQ(0U, frame->map_start);
711 EXPECT_EQ(0U, frame->map_end);
712 EXPECT_EQ(0U, frame->map_load_bias);
713 EXPECT_EQ(0, frame->map_flags);
714
715 frame = &unwinder.frames()[1];
716 EXPECT_EQ(1U, frame->num);
717 EXPECT_EQ(0x200U, frame->rel_pc);
718 EXPECT_EQ(0x1200U, frame->pc);
719 EXPECT_EQ(0x10000U, frame->sp);
720 EXPECT_EQ("Frame0", frame->function_name);
721 EXPECT_EQ(0U, frame->function_offset);
722 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800723 EXPECT_EQ(0U, frame->map_elf_start_offset);
724 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700725 EXPECT_EQ(0x1000U, frame->map_start);
726 EXPECT_EQ(0x8000U, frame->map_end);
727 EXPECT_EQ(0U, frame->map_load_bias);
728 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
729
730 frame = &unwinder.frames()[2];
731 EXPECT_EQ(2U, frame->num);
732 EXPECT_EQ(0x100U, frame->rel_pc);
733 EXPECT_EQ(0x23100U, frame->pc);
734 EXPECT_EQ(0x10020U, frame->sp);
735 EXPECT_EQ("Frame1", frame->function_name);
736 EXPECT_EQ(1U, frame->function_offset);
737 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800738 EXPECT_EQ(0U, frame->map_elf_start_offset);
739 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700740 EXPECT_EQ(0x23000U, frame->map_start);
741 EXPECT_EQ(0x24000U, frame->map_end);
742 EXPECT_EQ(0U, frame->map_load_bias);
743 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
744}
745
746// Verify that a speculative frame is added then removed because no other
747// frames are added.
748TEST_F(UnwinderTest, speculative_frame_removed) {
749 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
750 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
751
752 // Fake as if code called a nullptr function.
Christopher Ferris065f1562018-12-13 09:33:45 -0800753 regs_.set_pc(0x20000);
754 regs_.set_sp(0x10000);
755 ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
756 regs_.FakeSetReturnAddress(0x12);
757 regs_.FakeSetReturnAddressValid(true);
758
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800759 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris065f1562018-12-13 09:33:45 -0800760 unwinder.Unwind();
761 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100762 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700763 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris065f1562018-12-13 09:33:45 -0800764
765 ASSERT_EQ(2U, unwinder.NumFrames());
766
767 auto* frame = &unwinder.frames()[0];
768 EXPECT_EQ(0U, frame->num);
769 EXPECT_EQ(0U, frame->rel_pc);
770 EXPECT_EQ(0x20000U, frame->pc);
771 EXPECT_EQ(0x10000U, frame->sp);
772 EXPECT_EQ("Frame0", frame->function_name);
773 EXPECT_EQ(0U, frame->function_offset);
774 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800775 EXPECT_EQ(0U, frame->map_elf_start_offset);
776 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800777 EXPECT_EQ(0x20000U, frame->map_start);
778 EXPECT_EQ(0x22000U, frame->map_end);
779 EXPECT_EQ(0U, frame->map_load_bias);
780 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
781
782 frame = &unwinder.frames()[1];
783 EXPECT_EQ(1U, frame->num);
784 EXPECT_EQ(0U, frame->rel_pc);
785 EXPECT_EQ(0U, frame->pc);
786 EXPECT_EQ(0x10010U, frame->sp);
787 EXPECT_EQ("", frame->function_name);
788 EXPECT_EQ(0U, frame->function_offset);
789 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800790 EXPECT_EQ(0U, frame->map_elf_start_offset);
791 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800792 EXPECT_EQ(0U, frame->map_start);
793 EXPECT_EQ(0U, frame->map_end);
794 EXPECT_EQ(0U, frame->map_load_bias);
795 EXPECT_EQ(0, frame->map_flags);
796}
797
798// Verify that a speculative frame is added and left if there are only
799// two frames and the pc is in the middle nowhere.
800TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
801 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
802 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
803
804 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700805 regs_.set_pc(0);
806 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700807 regs_.FakeSetReturnAddress(0x1204);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700808 regs_.FakeSetReturnAddressValid(true);
809
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800810 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700811 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800812 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100813 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700814 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700815
Christopher Ferris065f1562018-12-13 09:33:45 -0800816 ASSERT_EQ(2U, unwinder.NumFrames());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700817
818 auto* frame = &unwinder.frames()[0];
819 EXPECT_EQ(0U, frame->num);
820 EXPECT_EQ(0U, frame->rel_pc);
821 EXPECT_EQ(0U, frame->pc);
822 EXPECT_EQ(0x10000U, frame->sp);
823 EXPECT_EQ("", frame->function_name);
824 EXPECT_EQ(0U, frame->function_offset);
825 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800826 EXPECT_EQ(0U, frame->map_elf_start_offset);
827 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700828 EXPECT_EQ(0U, frame->map_start);
829 EXPECT_EQ(0U, frame->map_end);
830 EXPECT_EQ(0U, frame->map_load_bias);
831 EXPECT_EQ(0, frame->map_flags);
Christopher Ferris065f1562018-12-13 09:33:45 -0800832
833 frame = &unwinder.frames()[1];
834 EXPECT_EQ(1U, frame->num);
835 EXPECT_EQ(0x200U, frame->rel_pc);
836 EXPECT_EQ(0x1200U, frame->pc);
837 EXPECT_EQ(0x10000U, frame->sp);
838 EXPECT_EQ("Frame0", frame->function_name);
839 EXPECT_EQ(0U, frame->function_offset);
840 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800841 EXPECT_EQ(0U, frame->map_elf_start_offset);
842 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800843 EXPECT_EQ(0x1000U, frame->map_start);
844 EXPECT_EQ(0x8000U, frame->map_end);
845 EXPECT_EQ(0U, frame->map_load_bias);
846 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700847}
848
Florian Mayerc479e4e2019-01-23 13:35:40 +0000849// Verify that a speculative frame does not cause a crash when it wasn't
850// really added due to a filter.
851TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
852 regs_.set_pc(0x23000);
853 regs_.set_sp(0x10000);
854 regs_.FakeSetReturnAddress(0x23100);
855 regs_.FakeSetReturnAddressValid(true);
856
857 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
858
859 std::vector<std::string> skip_names{"libanother.so"};
860 unwinder.Unwind(&skip_names);
861 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100862 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700863 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Florian Mayerc479e4e2019-01-23 13:35:40 +0000864
865 ASSERT_EQ(0U, unwinder.NumFrames());
866}
867
Christopher Ferrise69f4702017-10-19 16:08:58 -0700868// Verify that an unwind stops when a frame is in given suffix.
869TEST_F(UnwinderTest, map_ignore_suffixes) {
870 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
871 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
872 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
873 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
874
875 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700876 regs_.set_pc(0x1000);
877 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700878 ElfInterfaceFake::FakePushStepData(StepData(0x43404, 0x10010, false));
879 ElfInterfaceFake::FakePushStepData(StepData(0x53504, 0x10020, false));
Christopher Ferrise69f4702017-10-19 16:08:58 -0700880 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
881
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800882 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700883 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700884 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800885 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100886 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700887 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700888
889 ASSERT_EQ(2U, unwinder.NumFrames());
890 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800891 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700892 ASSERT_TRUE(map_info != nullptr);
893 EXPECT_TRUE(map_info->elf == nullptr);
894
895 auto* frame = &unwinder.frames()[0];
896 EXPECT_EQ(0U, frame->num);
897 EXPECT_EQ(0U, frame->rel_pc);
898 EXPECT_EQ(0x1000U, frame->pc);
899 EXPECT_EQ(0x10000U, frame->sp);
900 EXPECT_EQ("Frame0", frame->function_name);
901 EXPECT_EQ(0U, frame->function_offset);
902 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800903 EXPECT_EQ(0U, frame->map_elf_start_offset);
904 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700905 EXPECT_EQ(0x1000U, frame->map_start);
906 EXPECT_EQ(0x8000U, frame->map_end);
907 EXPECT_EQ(0U, frame->map_load_bias);
908 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
909
910 frame = &unwinder.frames()[1];
911 EXPECT_EQ(1U, frame->num);
912 EXPECT_EQ(0x400U, frame->rel_pc);
913 EXPECT_EQ(0x43400U, frame->pc);
914 EXPECT_EQ(0x10010U, frame->sp);
915 EXPECT_EQ("Frame1", frame->function_name);
916 EXPECT_EQ(1U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700917 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
918 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800919 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700920 EXPECT_EQ(0x43000U, frame->map_start);
921 EXPECT_EQ(0x44000U, frame->map_end);
922 EXPECT_EQ(0U, frame->map_load_bias);
923 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
924}
925
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700926// Verify that an unwind stops when the sp and pc don't change.
927TEST_F(UnwinderTest, sp_pc_do_not_change) {
928 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
929 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
930 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
931 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
932 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
933
Yabin Cui11e96fe2018-03-14 18:16:22 -0700934 regs_.set_pc(0x1000);
935 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700936 ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
937 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
938 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
939 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
940 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700941 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
942
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800943 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700944 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800945 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100946 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700947 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700948
949 ASSERT_EQ(3U, unwinder.NumFrames());
950
951 auto* frame = &unwinder.frames()[0];
952 EXPECT_EQ(0U, frame->num);
953 EXPECT_EQ(0U, frame->rel_pc);
954 EXPECT_EQ(0x1000U, frame->pc);
955 EXPECT_EQ(0x10000U, frame->sp);
956 EXPECT_EQ("Frame0", frame->function_name);
957 EXPECT_EQ(0U, frame->function_offset);
958 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800959 EXPECT_EQ(0U, frame->map_elf_start_offset);
960 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700961 EXPECT_EQ(0x1000U, frame->map_start);
962 EXPECT_EQ(0x8000U, frame->map_end);
963 EXPECT_EQ(0U, frame->map_load_bias);
964 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
965
966 frame = &unwinder.frames()[1];
967 EXPECT_EQ(1U, frame->num);
968 EXPECT_EQ(0x400U, frame->rel_pc);
969 EXPECT_EQ(0x33400U, frame->pc);
970 EXPECT_EQ(0x10010U, frame->sp);
971 EXPECT_EQ("Frame1", frame->function_name);
972 EXPECT_EQ(1U, frame->function_offset);
973 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800974 EXPECT_EQ(0U, frame->map_elf_start_offset);
975 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700976 EXPECT_EQ(0x33000U, frame->map_start);
977 EXPECT_EQ(0x34000U, frame->map_end);
978 EXPECT_EQ(0U, frame->map_load_bias);
979 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
980
981 frame = &unwinder.frames()[2];
982 EXPECT_EQ(2U, frame->num);
983 EXPECT_EQ(0x500U, frame->rel_pc);
984 EXPECT_EQ(0x33500U, frame->pc);
985 EXPECT_EQ(0x10020U, frame->sp);
986 EXPECT_EQ("Frame2", frame->function_name);
987 EXPECT_EQ(2U, frame->function_offset);
988 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800989 EXPECT_EQ(0U, frame->map_elf_start_offset);
990 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700991 EXPECT_EQ(0x33000U, frame->map_start);
992 EXPECT_EQ(0x34000U, frame->map_end);
993 EXPECT_EQ(0U, frame->map_load_bias);
994 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
995}
996
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800997TEST_F(UnwinderTest, dex_pc_in_map) {
998 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700999 regs_.set_pc(0x1000);
1000 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001001 regs_.FakeSetDexPc(0xa3400);
1002
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001003 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001004 unwinder.Unwind();
1005 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001006 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001007 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001008
1009 ASSERT_EQ(2U, unwinder.NumFrames());
1010
1011 auto* frame = &unwinder.frames()[0];
1012 EXPECT_EQ(0U, frame->num);
1013 EXPECT_EQ(0x400U, frame->rel_pc);
1014 EXPECT_EQ(0xa3400U, frame->pc);
1015 EXPECT_EQ(0x10000U, frame->sp);
1016 EXPECT_EQ("", frame->function_name);
1017 EXPECT_EQ(0U, frame->function_offset);
1018 EXPECT_EQ("/fake/fake.vdex", 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 Ferrise762f1f2018-02-06 14:51:48 -08001021 EXPECT_EQ(0xa3000U, frame->map_start);
1022 EXPECT_EQ(0xa4000U, frame->map_end);
1023 EXPECT_EQ(0U, frame->map_load_bias);
1024 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1025
1026 frame = &unwinder.frames()[1];
1027 EXPECT_EQ(1U, frame->num);
1028 EXPECT_EQ(0U, frame->rel_pc);
1029 EXPECT_EQ(0x1000U, frame->pc);
1030 EXPECT_EQ(0x10000U, frame->sp);
1031 EXPECT_EQ("Frame0", frame->function_name);
1032 EXPECT_EQ(0U, frame->function_offset);
1033 EXPECT_EQ("/system/fake/libc.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 Ferrise762f1f2018-02-06 14:51:48 -08001036 EXPECT_EQ(0x1000U, frame->map_start);
1037 EXPECT_EQ(0x8000U, frame->map_end);
1038 EXPECT_EQ(0U, frame->map_load_bias);
1039 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1040}
1041
Christopher Ferrisa4bdb982019-06-04 11:52:16 -07001042TEST_F(UnwinderTest, dex_pc_in_map_non_zero_offset) {
1043 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1044 regs_.set_pc(0x1000);
1045 regs_.set_sp(0x10000);
1046 regs_.FakeSetDexPc(0xd0400);
1047
1048 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1049 unwinder.Unwind();
1050 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001051 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferrisa4bdb982019-06-04 11:52:16 -07001052 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1053
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(0xd0400U, 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.apk", frame->map_name);
1064 EXPECT_EQ(0x1000U, frame->map_elf_start_offset);
1065 EXPECT_EQ(0x1000U, frame->map_exact_offset);
1066 EXPECT_EQ(0xd0000U, frame->map_start);
1067 EXPECT_EQ(0xd1000U, 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);
1079 EXPECT_EQ(0U, frame->map_elf_start_offset);
1080 EXPECT_EQ(0U, frame->map_exact_offset);
1081 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 Ferrise762f1f2018-02-06 14:51:48 -08001087TEST_F(UnwinderTest, dex_pc_not_in_map) {
1088 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001089 regs_.set_pc(0x1000);
1090 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001091 regs_.FakeSetDexPc(0x50000);
1092
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001093 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001094 unwinder.Unwind();
1095 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001096 EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001097 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001098
1099 ASSERT_EQ(2U, unwinder.NumFrames());
1100
1101 auto* frame = &unwinder.frames()[0];
1102 EXPECT_EQ(0U, frame->num);
1103 EXPECT_EQ(0x50000U, frame->rel_pc);
1104 EXPECT_EQ(0x50000U, frame->pc);
1105 EXPECT_EQ(0x10000U, frame->sp);
1106 EXPECT_EQ("", frame->function_name);
1107 EXPECT_EQ(0U, frame->function_offset);
1108 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001109 EXPECT_EQ(0U, frame->map_elf_start_offset);
1110 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001111 EXPECT_EQ(0U, frame->map_start);
1112 EXPECT_EQ(0U, frame->map_end);
1113 EXPECT_EQ(0U, frame->map_load_bias);
1114 EXPECT_EQ(0, 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);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001124 EXPECT_EQ(0U, frame->map_elf_start_offset);
1125 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001126 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 Ferrisa8c39732018-02-12 08:46:19 -08001132TEST_F(UnwinderTest, dex_pc_multiple_frames) {
1133 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1134 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001135 regs_.set_pc(0x1000);
1136 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001137 regs_.FakeSetDexPc(0xa3400);
Peter Collingbourne5ac39272020-03-19 17:27:58 -07001138 ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001139 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1140
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001141 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001142 unwinder.Unwind();
1143 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001144 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001145 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001146
1147 ASSERT_EQ(3U, unwinder.NumFrames());
1148
1149 auto* frame = &unwinder.frames()[0];
1150 EXPECT_EQ(0U, frame->num);
1151 EXPECT_EQ(0x400U, frame->rel_pc);
1152 EXPECT_EQ(0xa3400U, frame->pc);
1153 EXPECT_EQ(0x10000U, frame->sp);
1154 EXPECT_EQ("", frame->function_name);
1155 EXPECT_EQ(0U, frame->function_offset);
1156 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001157 EXPECT_EQ(0U, frame->map_elf_start_offset);
1158 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001159 EXPECT_EQ(0xa3000U, frame->map_start);
1160 EXPECT_EQ(0xa4000U, frame->map_end);
1161 EXPECT_EQ(0U, frame->map_load_bias);
1162 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1163
1164 frame = &unwinder.frames()[1];
1165 EXPECT_EQ(1U, frame->num);
1166 EXPECT_EQ(0U, frame->rel_pc);
1167 EXPECT_EQ(0x1000U, frame->pc);
1168 EXPECT_EQ(0x10000U, frame->sp);
1169 EXPECT_EQ("Frame0", frame->function_name);
1170 EXPECT_EQ(0U, frame->function_offset);
1171 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001172 EXPECT_EQ(0U, frame->map_elf_start_offset);
1173 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001174 EXPECT_EQ(0x1000U, frame->map_start);
1175 EXPECT_EQ(0x8000U, frame->map_end);
1176 EXPECT_EQ(0U, frame->map_load_bias);
1177 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1178
1179 frame = &unwinder.frames()[2];
1180 EXPECT_EQ(2U, frame->num);
1181 EXPECT_EQ(0x400U, frame->rel_pc);
1182 EXPECT_EQ(0x33400U, frame->pc);
1183 EXPECT_EQ(0x10010U, frame->sp);
1184 EXPECT_EQ("Frame1", frame->function_name);
1185 EXPECT_EQ(1U, frame->function_offset);
1186 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001187 EXPECT_EQ(0U, frame->map_elf_start_offset);
1188 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001189 EXPECT_EQ(0x33000U, frame->map_start);
1190 EXPECT_EQ(0x34000U, frame->map_end);
1191 EXPECT_EQ(0U, frame->map_load_bias);
1192 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1193}
1194
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001195TEST_F(UnwinderTest, dex_pc_max_frames) {
1196 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1197 regs_.set_pc(0x1000);
1198 regs_.set_sp(0x10000);
1199 regs_.FakeSetDexPc(0xa3400);
1200
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001201 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001202 unwinder.Unwind();
1203 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001204 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001205 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001206
1207 ASSERT_EQ(1U, unwinder.NumFrames());
1208
1209 auto* frame = &unwinder.frames()[0];
1210 EXPECT_EQ(0U, frame->num);
1211 EXPECT_EQ(0x400U, frame->rel_pc);
1212 EXPECT_EQ(0xa3400U, frame->pc);
1213 EXPECT_EQ(0x10000U, frame->sp);
1214 EXPECT_EQ("", frame->function_name);
1215 EXPECT_EQ(0U, frame->function_offset);
1216 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001217 EXPECT_EQ(0U, frame->map_elf_start_offset);
1218 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001219 EXPECT_EQ(0xa3000U, frame->map_start);
1220 EXPECT_EQ(0xa4000U, frame->map_end);
1221 EXPECT_EQ(0U, frame->map_load_bias);
1222 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1223}
1224
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001225TEST_F(UnwinderTest, elf_from_memory_not_file) {
1226 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1227
1228 regs_.set_pc(0xc0050);
1229 regs_.set_sp(0x10000);
1230 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1231
1232 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1233 unwinder.Unwind();
1234 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001235 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001236 EXPECT_TRUE(unwinder.elf_from_memory_not_file());
1237
1238 ASSERT_EQ(1U, unwinder.NumFrames());
1239
1240 auto* frame = &unwinder.frames()[0];
1241 EXPECT_EQ(0U, frame->num);
1242 EXPECT_EQ(0x50U, frame->rel_pc);
1243 EXPECT_EQ(0xc0050U, frame->pc);
1244 EXPECT_EQ(0x10000U, frame->sp);
1245 EXPECT_EQ("Frame0", frame->function_name);
1246 EXPECT_EQ(0U, frame->function_offset);
1247 EXPECT_EQ("/fake/unreadable.so", frame->map_name);
1248 EXPECT_EQ(0U, frame->map_elf_start_offset);
1249 EXPECT_EQ(0U, frame->map_exact_offset);
1250 EXPECT_EQ(0xc0000U, frame->map_start);
1251 EXPECT_EQ(0xc1000U, frame->map_end);
1252 EXPECT_EQ(0U, frame->map_load_bias);
1253 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1254}
1255
1256TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
1257 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1258
1259 regs_.set_pc(0xc1050);
1260 regs_.set_sp(0x10000);
1261 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1262
1263 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1264 unwinder.Unwind();
1265 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001266 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001267 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1268
1269 ASSERT_EQ(1U, unwinder.NumFrames());
1270
1271 auto* frame = &unwinder.frames()[0];
1272 EXPECT_EQ(0U, frame->num);
1273 EXPECT_EQ(0x50U, frame->rel_pc);
1274 EXPECT_EQ(0xc1050U, frame->pc);
1275 EXPECT_EQ(0x10000U, frame->sp);
1276 EXPECT_EQ("Frame0", frame->function_name);
1277 EXPECT_EQ(0U, frame->function_offset);
1278 EXPECT_EQ("[vdso]", frame->map_name);
1279 EXPECT_EQ(0U, frame->map_elf_start_offset);
1280 EXPECT_EQ(0U, frame->map_exact_offset);
1281 EXPECT_EQ(0xc1000U, frame->map_start);
1282 EXPECT_EQ(0xc2000U, frame->map_end);
1283 EXPECT_EQ(0U, frame->map_load_bias);
1284 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1285}
1286
1287TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
1288 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1289
1290 regs_.set_pc(0xc2050);
1291 regs_.set_sp(0x10000);
1292 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1293
1294 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1295 unwinder.Unwind();
1296 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001297 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001298 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1299
1300 ASSERT_EQ(1U, unwinder.NumFrames());
1301
1302 auto* frame = &unwinder.frames()[0];
1303 EXPECT_EQ(0U, frame->num);
1304 EXPECT_EQ(0x50U, frame->rel_pc);
1305 EXPECT_EQ(0xc2050U, frame->pc);
1306 EXPECT_EQ(0x10000U, frame->sp);
1307 EXPECT_EQ("Frame0", frame->function_name);
1308 EXPECT_EQ(0U, frame->function_offset);
1309 EXPECT_EQ("", frame->map_name);
1310 EXPECT_EQ(0U, frame->map_elf_start_offset);
1311 EXPECT_EQ(0U, frame->map_exact_offset);
1312 EXPECT_EQ(0xc2000U, frame->map_start);
1313 EXPECT_EQ(0xc3000U, frame->map_end);
1314 EXPECT_EQ(0U, frame->map_load_bias);
1315 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1316}
1317
Christopher Ferris98aaf4c2019-05-03 11:13:17 -07001318TEST_F(UnwinderTest, elf_from_memory_but_from_memfd) {
1319 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1320
1321 regs_.set_pc(0xc3050);
1322 regs_.set_sp(0x10000);
1323 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1324
1325 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1326 unwinder.Unwind();
1327 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001328 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris98aaf4c2019-05-03 11:13:17 -07001329 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1330
1331 ASSERT_EQ(1U, unwinder.NumFrames());
1332
1333 auto* frame = &unwinder.frames()[0];
1334 EXPECT_EQ(0U, frame->num);
1335 EXPECT_EQ(0x50U, frame->rel_pc);
1336 EXPECT_EQ(0xc3050U, frame->pc);
1337 EXPECT_EQ(0x10000U, frame->sp);
1338 EXPECT_EQ("Frame0", frame->function_name);
1339 EXPECT_EQ(0U, frame->function_offset);
1340 EXPECT_EQ("/memfd:/jit-cache", frame->map_name);
1341 EXPECT_EQ(0U, frame->map_elf_start_offset);
1342 EXPECT_EQ(0U, frame->map_exact_offset);
1343 EXPECT_EQ(0xc3000U, frame->map_start);
1344 EXPECT_EQ(0xc4000U, frame->map_end);
1345 EXPECT_EQ(0U, frame->map_load_bias);
1346 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1347}
1348
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001349// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001350TEST_F(UnwinderTest, format_frame) {
1351 RegsFake regs_arm(10);
1352 regs_arm.FakeSetArch(ARCH_ARM);
1353 Unwinder unwinder32(10, maps_.get(), &regs_arm, process_memory_);
1354
1355 RegsFake regs_arm64(10);
1356 regs_arm64.FakeSetArch(ARCH_ARM64);
1357 Unwinder unwinder64(10, maps_.get(), &regs_arm64, process_memory_);
1358
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001359 FrameData frame;
1360 frame.num = 1;
1361 frame.rel_pc = 0x1000;
1362 frame.pc = 0x4000;
1363 frame.sp = 0x1000;
1364 frame.function_name = "function";
1365 frame.function_offset = 100;
1366 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001367 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001368 frame.map_start = 0x3000;
1369 frame.map_end = 0x6000;
1370 frame.map_flags = PROT_READ;
1371
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001372 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001373 unwinder64.FormatFrame(frame));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001374 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001375 unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001376
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001377 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001378 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001379 unwinder64.FormatFrame(frame));
1380 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001381
1382 frame.function_offset = 0;
1383 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
Christopher Ferris78133452019-03-14 13:44:38 -07001384 unwinder64.FormatFrame(frame));
1385 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001386
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001387 // Verify the function name is demangled.
1388 frame.function_name = "_ZN4funcEv";
Christopher Ferris78133452019-03-14 13:44:38 -07001389 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())", unwinder64.FormatFrame(frame));
1390 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", unwinder32.FormatFrame(frame));
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001391
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001392 frame.function_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001393 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", unwinder64.FormatFrame(frame));
1394 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001395
1396 frame.map_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001397 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", unwinder64.FormatFrame(frame));
1398 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001399
1400 frame.map_start = 0;
1401 frame.map_end = 0;
Christopher Ferris78133452019-03-14 13:44:38 -07001402 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", unwinder64.FormatFrame(frame));
1403 EXPECT_EQ(" #01 pc 00001000 <unknown>", unwinder32.FormatFrame(frame));
1404}
1405
1406TEST_F(UnwinderTest, format_frame_build_id) {
1407 RegsFake regs(10);
1408 regs.FakeSetArch(ARCH_ARM);
1409 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1410
1411 FrameData frame;
1412 frame.num = 1;
1413 frame.rel_pc = 0x1000;
1414 frame.pc = 0x4000;
1415 frame.sp = 0x1000;
1416 frame.function_name = "function";
1417 frame.function_offset = 100;
1418 frame.map_name = "/fake/libfake.so";
1419 frame.map_elf_start_offset = 0;
1420 frame.map_start = 0x3000;
1421 frame.map_end = 0x6000;
1422 frame.map_flags = PROT_READ;
1423
1424 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder.FormatFrame(frame));
1425 unwinder.SetDisplayBuildID(true);
1426 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100) (BuildId: 46414b45)",
1427 unwinder.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001428}
1429
Christopher Ferris02fdb562017-12-08 15:04:49 -08001430static std::string ArchToString(ArchEnum arch) {
1431 if (arch == ARCH_ARM) {
1432 return "Arm";
1433 } else if (arch == ARCH_ARM64) {
1434 return "Arm64";
1435 } else if (arch == ARCH_X86) {
1436 return "X86";
1437 } else if (arch == ARCH_X86_64) {
1438 return "X86_64";
1439 } else {
1440 return "Unknown";
1441 }
1442}
1443
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001444// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001445TEST_F(UnwinderTest, format_frame_by_arch) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001446 std::vector<Regs*> reg_list;
1447 RegsArm* arm = new RegsArm;
1448 arm->set_pc(0x2300);
1449 arm->set_sp(0x10000);
1450 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001451
Christopher Ferris02fdb562017-12-08 15:04:49 -08001452 RegsArm64* arm64 = new RegsArm64;
1453 arm64->set_pc(0x2300);
1454 arm64->set_sp(0x10000);
1455 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001456
Christopher Ferris02fdb562017-12-08 15:04:49 -08001457 RegsX86* x86 = new RegsX86;
1458 x86->set_pc(0x2300);
1459 x86->set_sp(0x10000);
1460 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001461
Christopher Ferris02fdb562017-12-08 15:04:49 -08001462 RegsX86_64* x86_64 = new RegsX86_64;
1463 x86_64->set_pc(0x2300);
1464 x86_64->set_sp(0x10000);
1465 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001466
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001467 RegsMips* mips = new RegsMips;
1468 mips->set_pc(0x2300);
1469 mips->set_sp(0x10000);
1470 reg_list.push_back(mips);
1471
1472 RegsMips64* mips64 = new RegsMips64;
1473 mips64->set_pc(0x2300);
1474 mips64->set_sp(0x10000);
1475 reg_list.push_back(mips64);
1476
Christopher Ferris02fdb562017-12-08 15:04:49 -08001477 for (auto regs : reg_list) {
1478 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001479
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001480 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001481 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001482
Christopher Ferris02fdb562017-12-08 15:04:49 -08001483 ASSERT_EQ(1U, unwinder.NumFrames());
1484 std::string expected;
1485 switch (regs->Arch()) {
1486 case ARCH_ARM:
1487 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001488 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001489 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1490 break;
1491 case ARCH_ARM64:
1492 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001493 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001494 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1495 break;
1496 default:
1497 expected = "";
1498 }
1499 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1500 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1501 delete regs;
1502 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001503}
1504
1505} // namespace unwindstack