blob: ddd4b4d1b04d764c0ae4e50ab9ae5c0fd660e8ca [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 Ferrisafbed692020-08-27 11:46:36 -070060 memory_ = new MemoryFake;
61 process_memory_.reset(memory_);
62
Christopher Ferris02fdb562017-12-08 15:04:49 -080063 ElfFake* elf = new ElfFake(new MemoryFake);
Christopher Ferris78133452019-03-14 13:44:38 -070064 ElfInterfaceFake* interface_fake = new ElfInterfaceFake(nullptr);
65 interface_fake->FakeSetBuildID("FAKE");
66 elf->FakeSetInterface(interface_fake);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080067 AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070068
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080069 AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070070
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080071 AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
72 "/dev/fake_device");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070073
Christopher Ferris02fdb562017-12-08 15:04:49 -080074 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070075 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080076 AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070077
Christopher Ferris02fdb562017-12-08 15:04:49 -080078 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070079 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080080 AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070081
Christopher Ferris02fdb562017-12-08 15:04:49 -080082 elf = new ElfFake(new MemoryFake);
Christopher Ferrise69f4702017-10-19 16:08:58 -070083 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080084 AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070085
Christopher Ferris02fdb562017-12-08 15:04:49 -080086 elf = new ElfFake(new MemoryFake);
Christopher Ferris02a6c442019-03-11 14:43:33 -070087 ElfInterfaceFake* interface = new ElfInterfaceFake(nullptr);
88 interface->FakeSetSoname("lib_fake.so");
89 elf->FakeSetInterface(interface);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080090 AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
Christopher Ferris02a6c442019-03-11 14:43:33 -070091 MapInfo* map_info = maps_->Find(0x43000);
92 ASSERT_TRUE(map_info != nullptr);
93 map_info->elf_start_offset = 0x1d000;
Christopher Ferrise69f4702017-10-19 16:08:58 -070094
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080095 AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
Christopher Ferris02fdb562017-12-08 15:04:49 -080096
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080097 AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
Florian Mayer3d67d342019-02-27 18:00:37 +000098 const auto& info = *--maps_->end();
Christopher Ferrise762f1f2018-02-06 14:51:48 -080099 info->load_bias = 0;
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800100
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800101 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800102 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
103 elf->FakeSetLoadBias(0x5000);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800104 AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
105 elf);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800106
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800107 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800108 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800109 AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_offset.oat",
110 elf);
Florian Mayer3d67d342019-02-27 18:00:37 +0000111 const auto& info2 = *--maps_->end();
112 info2->elf_offset = 0x8000;
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800113
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700114 elf = new ElfFake(new MemoryFake);
115 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
116 AddMapInfo(0xc0000, 0xc1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/unreadable.so", elf);
117 const auto& info3 = *--maps_->end();
118 info3->memory_backed_elf = true;
119
120 elf = new ElfFake(new MemoryFake);
121 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
122 AddMapInfo(0xc1000, 0xc2000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "[vdso]", elf);
123 const auto& info4 = *--maps_->end();
124 info4->memory_backed_elf = true;
125
126 elf = new ElfFake(new MemoryFake);
127 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
128 AddMapInfo(0xc2000, 0xc3000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "", elf);
129 const auto& info5 = *--maps_->end();
130 info5->memory_backed_elf = true;
131
Christopher Ferris98aaf4c2019-05-03 11:13:17 -0700132 elf = new ElfFake(new MemoryFake);
133 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
134 AddMapInfo(0xc3000, 0xc4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/memfd:/jit-cache", elf);
135 const auto& info6 = *--maps_->end();
136 info6->memory_backed_elf = true;
137
Christopher Ferrisa4bdb982019-06-04 11:52:16 -0700138 AddMapInfo(0xd0000, 0xd1000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.apk");
139 const auto& info7 = *--maps_->end();
140 info7->load_bias = 0;
141
Christopher Ferrisafbed692020-08-27 11:46:36 -0700142 elf = new ElfFake(new MemoryFake);
143 interface = new ElfInterfaceFake(nullptr);
144 elf->FakeSetInterface(interface);
145 interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x1800);
146 interface->FakeSetDataOffset(0x1000);
147 interface->FakeSetDataVaddrStart(0x1000);
148 interface->FakeSetDataVaddrEnd(0x3000);
149 AddMapInfo(0xf0000, 0xf1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/global.so", elf);
150 AddMapInfo(0xf1000, 0xf9000, 0x1000, PROT_READ | PROT_WRITE, "/fake/global.so");
151 memory_->SetData32(0xf180c, 0xf3000);
152 memory_->SetData32(0xf3000, 0xf4000);
153 memory_->SetData32(0xf3004, 0xf4000);
154 memory_->SetData32(0xf3008, 0xf5000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700155 }
156
157 void SetUp() override {
158 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800159 regs_.FakeSetArch(ARCH_ARM);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700160 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700161 }
162
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800163 static std::unique_ptr<Maps> maps_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700164 static RegsFake regs_;
Christopher Ferrisafbed692020-08-27 11:46:36 -0700165 static MemoryFake* memory_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700166 static std::shared_ptr<Memory> process_memory_;
167};
168
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800169std::unique_ptr<Maps> UnwinderTest::maps_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700170RegsFake UnwinderTest::regs_(5);
Christopher Ferrisafbed692020-08-27 11:46:36 -0700171MemoryFake* UnwinderTest::memory_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700172std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
173
174TEST_F(UnwinderTest, multiple_frames) {
175 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
176 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
177 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
178
Yabin Cui11e96fe2018-03-14 18:16:22 -0700179 regs_.set_pc(0x1000);
180 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700181 ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
182 ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700183 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
184
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800185 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700186 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800187 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100188 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700189 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700190
191 ASSERT_EQ(3U, unwinder.NumFrames());
192
193 auto* frame = &unwinder.frames()[0];
194 EXPECT_EQ(0U, frame->num);
195 EXPECT_EQ(0U, frame->rel_pc);
196 EXPECT_EQ(0x1000U, frame->pc);
197 EXPECT_EQ(0x10000U, frame->sp);
198 EXPECT_EQ("Frame0", frame->function_name);
199 EXPECT_EQ(0U, frame->function_offset);
200 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800201 EXPECT_EQ(0U, frame->map_elf_start_offset);
202 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700203 EXPECT_EQ(0x1000U, frame->map_start);
204 EXPECT_EQ(0x8000U, frame->map_end);
205 EXPECT_EQ(0U, frame->map_load_bias);
206 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
207
208 frame = &unwinder.frames()[1];
209 EXPECT_EQ(1U, frame->num);
210 EXPECT_EQ(0x100U, frame->rel_pc);
211 EXPECT_EQ(0x1100U, frame->pc);
212 EXPECT_EQ(0x10010U, frame->sp);
213 EXPECT_EQ("Frame1", frame->function_name);
214 EXPECT_EQ(1U, frame->function_offset);
215 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800216 EXPECT_EQ(0U, frame->map_elf_start_offset);
217 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700218 EXPECT_EQ(0x1000U, frame->map_start);
219 EXPECT_EQ(0x8000U, frame->map_end);
220 EXPECT_EQ(0U, frame->map_load_bias);
221 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
222
223 frame = &unwinder.frames()[2];
224 EXPECT_EQ(2U, frame->num);
225 EXPECT_EQ(0x200U, frame->rel_pc);
226 EXPECT_EQ(0x1200U, frame->pc);
227 EXPECT_EQ(0x10020U, frame->sp);
228 EXPECT_EQ("Frame2", frame->function_name);
229 EXPECT_EQ(2U, frame->function_offset);
230 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800231 EXPECT_EQ(0U, frame->map_elf_start_offset);
232 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700233 EXPECT_EQ(0x1000U, frame->map_start);
234 EXPECT_EQ(0x8000U, frame->map_end);
235 EXPECT_EQ(0U, frame->map_load_bias);
236 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
237}
238
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800239TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
240 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
241 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
242 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
243
Yabin Cui11e96fe2018-03-14 18:16:22 -0700244 regs_.set_pc(0x1000);
245 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700246 ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
247 ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800248 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
249
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800250 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800251 unwinder.SetResolveNames(false);
252 unwinder.Unwind();
253 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100254 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700255 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800256
257 ASSERT_EQ(3U, unwinder.NumFrames());
258
259 auto* frame = &unwinder.frames()[0];
260 EXPECT_EQ(0U, frame->num);
261 EXPECT_EQ(0U, frame->rel_pc);
262 EXPECT_EQ(0x1000U, frame->pc);
263 EXPECT_EQ(0x10000U, frame->sp);
264 EXPECT_EQ("", frame->function_name);
265 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000266 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800267 EXPECT_EQ(0U, frame->map_elf_start_offset);
268 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800269 EXPECT_EQ(0x1000U, frame->map_start);
270 EXPECT_EQ(0x8000U, frame->map_end);
271 EXPECT_EQ(0U, frame->map_load_bias);
272 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
273
274 frame = &unwinder.frames()[1];
275 EXPECT_EQ(1U, frame->num);
276 EXPECT_EQ(0x100U, frame->rel_pc);
277 EXPECT_EQ(0x1100U, frame->pc);
278 EXPECT_EQ(0x10010U, frame->sp);
279 EXPECT_EQ("", frame->function_name);
280 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000281 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800282 EXPECT_EQ(0U, frame->map_elf_start_offset);
283 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800284 EXPECT_EQ(0x1000U, frame->map_start);
285 EXPECT_EQ(0x8000U, frame->map_end);
286 EXPECT_EQ(0U, frame->map_load_bias);
287 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
288
289 frame = &unwinder.frames()[2];
290 EXPECT_EQ(2U, frame->num);
291 EXPECT_EQ(0x200U, frame->rel_pc);
292 EXPECT_EQ(0x1200U, frame->pc);
293 EXPECT_EQ(0x10020U, frame->sp);
294 EXPECT_EQ("", frame->function_name);
295 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000296 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800297 EXPECT_EQ(0U, frame->map_elf_start_offset);
298 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800299 EXPECT_EQ(0x1000U, frame->map_start);
300 EXPECT_EQ(0x8000U, frame->map_end);
301 EXPECT_EQ(0U, frame->map_load_bias);
302 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
303}
304
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800305TEST_F(UnwinderTest, non_zero_load_bias) {
306 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
307
Yabin Cui11e96fe2018-03-14 18:16:22 -0700308 regs_.set_pc(0xa5500);
309 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800310 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
311
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800312 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800313 unwinder.Unwind();
314 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100315 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700316 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800317
318 ASSERT_EQ(1U, unwinder.NumFrames());
319
320 auto* frame = &unwinder.frames()[0];
321 EXPECT_EQ(0U, frame->num);
322 EXPECT_EQ(0x5500U, frame->rel_pc);
323 EXPECT_EQ(0xa5500U, frame->pc);
324 EXPECT_EQ(0x10000U, frame->sp);
325 EXPECT_EQ("Frame0", frame->function_name);
326 EXPECT_EQ(0U, frame->function_offset);
327 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800328 EXPECT_EQ(0U, frame->map_elf_start_offset);
329 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800330 EXPECT_EQ(0xa5000U, frame->map_start);
331 EXPECT_EQ(0xa6000U, frame->map_end);
332 EXPECT_EQ(0x5000U, frame->map_load_bias);
333 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
334}
335
336TEST_F(UnwinderTest, non_zero_elf_offset) {
337 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
338
Yabin Cui11e96fe2018-03-14 18:16:22 -0700339 regs_.set_pc(0xa7500);
340 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800341 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
342
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800343 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800344 unwinder.Unwind();
345 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100346 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700347 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800348
349 ASSERT_EQ(1U, unwinder.NumFrames());
350
351 auto* frame = &unwinder.frames()[0];
352 EXPECT_EQ(0U, frame->num);
353 EXPECT_EQ(0x8500U, frame->rel_pc);
354 EXPECT_EQ(0xa7500U, frame->pc);
355 EXPECT_EQ(0x10000U, frame->sp);
356 EXPECT_EQ("Frame0", frame->function_name);
357 EXPECT_EQ(0U, frame->function_offset);
358 EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800359 EXPECT_EQ(0U, frame->map_elf_start_offset);
360 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800361 EXPECT_EQ(0xa7000U, frame->map_start);
362 EXPECT_EQ(0xa8000U, frame->map_end);
363 EXPECT_EQ(0U, frame->map_load_bias);
364 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
365}
366
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700367TEST_F(UnwinderTest, non_zero_map_offset) {
368 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
369
Yabin Cui11e96fe2018-03-14 18:16:22 -0700370 regs_.set_pc(0x43000);
371 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700372 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
373
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800374 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700375 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800376 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100377 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700378 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700379
380 ASSERT_EQ(1U, unwinder.NumFrames());
381
382 auto* frame = &unwinder.frames()[0];
383 EXPECT_EQ(0U, frame->num);
384 EXPECT_EQ(0U, frame->rel_pc);
385 EXPECT_EQ(0x43000U, frame->pc);
386 EXPECT_EQ(0x10000U, frame->sp);
387 EXPECT_EQ("Frame0", frame->function_name);
388 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700389 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
390 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
391 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
392 EXPECT_EQ(0x43000U, frame->map_start);
393 EXPECT_EQ(0x44000U, frame->map_end);
394 EXPECT_EQ(0U, frame->map_load_bias);
395 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
396}
397
398TEST_F(UnwinderTest, disable_embedded_soname) {
399 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
400
401 regs_.set_pc(0x43000);
402 regs_.set_sp(0x10000);
403 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
404
405 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
406 unwinder.SetEmbeddedSoname(false);
407 unwinder.Unwind();
408 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100409 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700410 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris02a6c442019-03-11 14:43:33 -0700411
412 ASSERT_EQ(1U, unwinder.NumFrames());
413
414 auto* frame = &unwinder.frames()[0];
415 EXPECT_EQ(0U, frame->num);
416 EXPECT_EQ(0U, frame->rel_pc);
417 EXPECT_EQ(0x43000U, frame->pc);
418 EXPECT_EQ(0x10000U, frame->sp);
419 EXPECT_EQ("Frame0", frame->function_name);
420 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700421 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700422 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800423 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700424 EXPECT_EQ(0x43000U, frame->map_start);
425 EXPECT_EQ(0x44000U, frame->map_end);
426 EXPECT_EQ(0U, frame->map_load_bias);
427 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
428}
429
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700430// Verify that no attempt to continue after the step indicates it is done.
431TEST_F(UnwinderTest, no_frames_after_finished) {
432 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
433 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
434 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
435 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
436 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
437
Yabin Cui11e96fe2018-03-14 18:16:22 -0700438 regs_.set_pc(0x1000);
439 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700440 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
441 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
442 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
443
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800444 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700445 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800446 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100447 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700448 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700449
450 ASSERT_EQ(1U, unwinder.NumFrames());
451
452 auto* frame = &unwinder.frames()[0];
453 EXPECT_EQ(0U, frame->num);
454 EXPECT_EQ(0U, frame->rel_pc);
455 EXPECT_EQ(0x1000U, frame->pc);
456 EXPECT_EQ(0x10000U, frame->sp);
457 EXPECT_EQ("Frame0", frame->function_name);
458 EXPECT_EQ(0U, frame->function_offset);
459 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800460 EXPECT_EQ(0U, frame->map_elf_start_offset);
461 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700462 EXPECT_EQ(0x1000U, frame->map_start);
463 EXPECT_EQ(0x8000U, frame->map_end);
464 EXPECT_EQ(0U, frame->map_load_bias);
465 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
466}
467
468// Verify the maximum frames to save.
469TEST_F(UnwinderTest, max_frames) {
470 for (size_t i = 0; i < 30; i++) {
471 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700472 ElfInterfaceFake::FakePushStepData(StepData(0x1104 + i * 0x100, 0x10010 + i * 0x10, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700473 }
474
Yabin Cui11e96fe2018-03-14 18:16:22 -0700475 regs_.set_pc(0x1000);
476 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700477
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800478 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700479 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800480 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100481 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700482 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700483
484 ASSERT_EQ(20U, unwinder.NumFrames());
485
486 for (size_t i = 0; i < 20; i++) {
487 auto* frame = &unwinder.frames()[i];
488 EXPECT_EQ(i, frame->num);
489 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
490 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
491 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
492 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
493 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
494 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800495 EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
496 EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700497 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
498 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
499 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
500 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
501 }
502}
503
504// Verify that initial map names frames are removed.
505TEST_F(UnwinderTest, verify_frames_skipped) {
506 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
507 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
508 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
509
Yabin Cui11e96fe2018-03-14 18:16:22 -0700510 regs_.set_pc(0x20000);
511 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700512 ElfInterfaceFake::FakePushStepData(StepData(0x23004, 0x10010, false));
513 ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
514 ElfInterfaceFake::FakePushStepData(StepData(0x20004, 0x10030, false));
515 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10040, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700516 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700517 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10060, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700518 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
519 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
520
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800521 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700522 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
523 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800524 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100525 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700526 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700527
528 ASSERT_EQ(3U, unwinder.NumFrames());
529
530 auto* frame = &unwinder.frames()[0];
531 EXPECT_EQ(0U, frame->num);
532 EXPECT_EQ(0U, frame->rel_pc);
533 EXPECT_EQ(0x1000U, frame->pc);
534 EXPECT_EQ(0x10050U, frame->sp);
535 EXPECT_EQ("Frame0", frame->function_name);
536 EXPECT_EQ(0U, frame->function_offset);
537 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800538 EXPECT_EQ(0U, frame->map_elf_start_offset);
539 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700540 EXPECT_EQ(0x1000U, frame->map_start);
541 EXPECT_EQ(0x8000U, frame->map_end);
542 EXPECT_EQ(0U, frame->map_load_bias);
543 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
544
545 frame = &unwinder.frames()[1];
546 EXPECT_EQ(1U, frame->num);
547 EXPECT_EQ(0x1000U, frame->rel_pc);
548 EXPECT_EQ(0x21000U, frame->pc);
549 EXPECT_EQ(0x10060U, frame->sp);
550 EXPECT_EQ("Frame1", frame->function_name);
551 EXPECT_EQ(1U, frame->function_offset);
552 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800553 EXPECT_EQ(0U, frame->map_elf_start_offset);
554 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700555 EXPECT_EQ(0x20000U, frame->map_start);
556 EXPECT_EQ(0x22000U, frame->map_end);
557 EXPECT_EQ(0U, frame->map_load_bias);
558 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
559
560 frame = &unwinder.frames()[2];
561 EXPECT_EQ(2U, frame->num);
562 EXPECT_EQ(0U, frame->rel_pc);
563 EXPECT_EQ(0x23000U, frame->pc);
564 EXPECT_EQ(0x10070U, frame->sp);
565 EXPECT_EQ("Frame2", frame->function_name);
566 EXPECT_EQ(2U, frame->function_offset);
567 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800568 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700569 EXPECT_EQ(0x23000U, frame->map_start);
570 EXPECT_EQ(0x24000U, frame->map_end);
571 EXPECT_EQ(0U, frame->map_load_bias);
572 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
573}
574
575// Verify SP in a non-existant map is okay.
576TEST_F(UnwinderTest, sp_not_in_map) {
577 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
578 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
579
Yabin Cui11e96fe2018-03-14 18:16:22 -0700580 regs_.set_pc(0x1000);
581 regs_.set_sp(0x63000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700582 ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x50020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700583 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
584
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800585 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700586 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800587 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100588 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700589 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700590
591 ASSERT_EQ(2U, unwinder.NumFrames());
592
593 auto* frame = &unwinder.frames()[0];
594 EXPECT_EQ(0U, frame->num);
595 EXPECT_EQ(0U, frame->rel_pc);
596 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700597 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700598 EXPECT_EQ("Frame0", frame->function_name);
599 EXPECT_EQ(0U, frame->function_offset);
600 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800601 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700602 EXPECT_EQ(0x1000U, frame->map_start);
603 EXPECT_EQ(0x8000U, frame->map_end);
604 EXPECT_EQ(0U, frame->map_load_bias);
605 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
606
607 frame = &unwinder.frames()[1];
608 EXPECT_EQ(1U, frame->num);
609 EXPECT_EQ(0x1000U, frame->rel_pc);
610 EXPECT_EQ(0x21000U, frame->pc);
611 EXPECT_EQ(0x50020U, frame->sp);
612 EXPECT_EQ("Frame1", frame->function_name);
613 EXPECT_EQ(1U, frame->function_offset);
614 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800615 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700616 EXPECT_EQ(0x20000U, frame->map_start);
617 EXPECT_EQ(0x22000U, frame->map_end);
618 EXPECT_EQ(0U, frame->map_load_bias);
619 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
620}
621
622// Verify PC in a device stops the unwind.
623TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
624 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
625 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
626 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
627
Yabin Cui11e96fe2018-03-14 18:16:22 -0700628 regs_.set_pc(0x13000);
629 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700630 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
631 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
632 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
633
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800634 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700635 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800636 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100637 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700638 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700639
640 ASSERT_EQ(1U, unwinder.NumFrames());
641}
642
643// Verify SP in a device stops the unwind.
644TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
645 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
646 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
647 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
648
Yabin Cui11e96fe2018-03-14 18:16:22 -0700649 regs_.set_pc(0x1000);
650 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700651 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
652 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
653 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
654
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800655 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700656 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800657 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100658 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700659 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700660
661 ASSERT_EQ(1U, unwinder.NumFrames());
662}
663
664// Verify a no map info frame gets a frame.
665TEST_F(UnwinderTest, pc_without_map) {
666 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
667
Yabin Cui11e96fe2018-03-14 18:16:22 -0700668 regs_.set_pc(0x41000);
669 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700670
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800671 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700672 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800673 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100674 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700675 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700676
677 ASSERT_EQ(1U, unwinder.NumFrames());
678
679 auto* frame = &unwinder.frames()[0];
680 EXPECT_EQ(0U, frame->num);
681 EXPECT_EQ(0x41000U, frame->rel_pc);
682 EXPECT_EQ(0x41000U, frame->pc);
683 EXPECT_EQ(0x13000U, frame->sp);
684 EXPECT_EQ("", frame->function_name);
685 EXPECT_EQ(0U, frame->function_offset);
686 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800687 EXPECT_EQ(0U, frame->map_elf_start_offset);
688 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700689 EXPECT_EQ(0U, frame->map_start);
690 EXPECT_EQ(0U, frame->map_end);
691 EXPECT_EQ(0U, frame->map_load_bias);
692 EXPECT_EQ(0, frame->map_flags);
693}
694
695// Verify that a speculative frame is added.
696TEST_F(UnwinderTest, speculative_frame) {
697 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
698 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
699
700 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700701 regs_.set_pc(0);
702 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700703 regs_.FakeSetReturnAddress(0x1204);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700704 regs_.FakeSetReturnAddressValid(true);
705
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700706 ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700707 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
708
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800709 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700710 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800711 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100712 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700713 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700714
715 ASSERT_EQ(3U, unwinder.NumFrames());
716
717 auto* frame = &unwinder.frames()[0];
718 EXPECT_EQ(0U, frame->num);
719 EXPECT_EQ(0U, frame->rel_pc);
720 EXPECT_EQ(0U, frame->pc);
721 EXPECT_EQ(0x10000U, frame->sp);
722 EXPECT_EQ("", frame->function_name);
723 EXPECT_EQ(0U, frame->function_offset);
724 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800725 EXPECT_EQ(0U, frame->map_elf_start_offset);
726 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700727 EXPECT_EQ(0U, frame->map_start);
728 EXPECT_EQ(0U, frame->map_end);
729 EXPECT_EQ(0U, frame->map_load_bias);
730 EXPECT_EQ(0, frame->map_flags);
731
732 frame = &unwinder.frames()[1];
733 EXPECT_EQ(1U, frame->num);
734 EXPECT_EQ(0x200U, frame->rel_pc);
735 EXPECT_EQ(0x1200U, frame->pc);
736 EXPECT_EQ(0x10000U, frame->sp);
737 EXPECT_EQ("Frame0", frame->function_name);
738 EXPECT_EQ(0U, frame->function_offset);
739 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800740 EXPECT_EQ(0U, frame->map_elf_start_offset);
741 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700742 EXPECT_EQ(0x1000U, frame->map_start);
743 EXPECT_EQ(0x8000U, frame->map_end);
744 EXPECT_EQ(0U, frame->map_load_bias);
745 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
746
747 frame = &unwinder.frames()[2];
748 EXPECT_EQ(2U, frame->num);
749 EXPECT_EQ(0x100U, frame->rel_pc);
750 EXPECT_EQ(0x23100U, frame->pc);
751 EXPECT_EQ(0x10020U, frame->sp);
752 EXPECT_EQ("Frame1", frame->function_name);
753 EXPECT_EQ(1U, frame->function_offset);
754 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800755 EXPECT_EQ(0U, frame->map_elf_start_offset);
756 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700757 EXPECT_EQ(0x23000U, frame->map_start);
758 EXPECT_EQ(0x24000U, frame->map_end);
759 EXPECT_EQ(0U, frame->map_load_bias);
760 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
761}
762
763// Verify that a speculative frame is added then removed because no other
764// frames are added.
765TEST_F(UnwinderTest, speculative_frame_removed) {
766 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
767 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
768
769 // Fake as if code called a nullptr function.
Christopher Ferris065f1562018-12-13 09:33:45 -0800770 regs_.set_pc(0x20000);
771 regs_.set_sp(0x10000);
772 ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
773 regs_.FakeSetReturnAddress(0x12);
774 regs_.FakeSetReturnAddressValid(true);
775
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800776 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris065f1562018-12-13 09:33:45 -0800777 unwinder.Unwind();
778 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100779 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700780 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris065f1562018-12-13 09:33:45 -0800781
782 ASSERT_EQ(2U, unwinder.NumFrames());
783
784 auto* frame = &unwinder.frames()[0];
785 EXPECT_EQ(0U, frame->num);
786 EXPECT_EQ(0U, frame->rel_pc);
787 EXPECT_EQ(0x20000U, frame->pc);
788 EXPECT_EQ(0x10000U, frame->sp);
789 EXPECT_EQ("Frame0", frame->function_name);
790 EXPECT_EQ(0U, frame->function_offset);
791 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800792 EXPECT_EQ(0U, frame->map_elf_start_offset);
793 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800794 EXPECT_EQ(0x20000U, frame->map_start);
795 EXPECT_EQ(0x22000U, frame->map_end);
796 EXPECT_EQ(0U, frame->map_load_bias);
797 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
798
799 frame = &unwinder.frames()[1];
800 EXPECT_EQ(1U, frame->num);
801 EXPECT_EQ(0U, frame->rel_pc);
802 EXPECT_EQ(0U, frame->pc);
803 EXPECT_EQ(0x10010U, frame->sp);
804 EXPECT_EQ("", frame->function_name);
805 EXPECT_EQ(0U, frame->function_offset);
806 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800807 EXPECT_EQ(0U, frame->map_elf_start_offset);
808 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800809 EXPECT_EQ(0U, frame->map_start);
810 EXPECT_EQ(0U, frame->map_end);
811 EXPECT_EQ(0U, frame->map_load_bias);
812 EXPECT_EQ(0, frame->map_flags);
813}
814
815// Verify that a speculative frame is added and left if there are only
816// two frames and the pc is in the middle nowhere.
817TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
818 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
819 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
820
821 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700822 regs_.set_pc(0);
823 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700824 regs_.FakeSetReturnAddress(0x1204);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700825 regs_.FakeSetReturnAddressValid(true);
826
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800827 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700828 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800829 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100830 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700831 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700832
Christopher Ferris065f1562018-12-13 09:33:45 -0800833 ASSERT_EQ(2U, unwinder.NumFrames());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700834
835 auto* frame = &unwinder.frames()[0];
836 EXPECT_EQ(0U, frame->num);
837 EXPECT_EQ(0U, frame->rel_pc);
838 EXPECT_EQ(0U, frame->pc);
839 EXPECT_EQ(0x10000U, frame->sp);
840 EXPECT_EQ("", frame->function_name);
841 EXPECT_EQ(0U, frame->function_offset);
842 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800843 EXPECT_EQ(0U, frame->map_elf_start_offset);
844 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700845 EXPECT_EQ(0U, frame->map_start);
846 EXPECT_EQ(0U, frame->map_end);
847 EXPECT_EQ(0U, frame->map_load_bias);
848 EXPECT_EQ(0, frame->map_flags);
Christopher Ferris065f1562018-12-13 09:33:45 -0800849
850 frame = &unwinder.frames()[1];
851 EXPECT_EQ(1U, frame->num);
852 EXPECT_EQ(0x200U, frame->rel_pc);
853 EXPECT_EQ(0x1200U, frame->pc);
854 EXPECT_EQ(0x10000U, frame->sp);
855 EXPECT_EQ("Frame0", frame->function_name);
856 EXPECT_EQ(0U, frame->function_offset);
857 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800858 EXPECT_EQ(0U, frame->map_elf_start_offset);
859 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800860 EXPECT_EQ(0x1000U, frame->map_start);
861 EXPECT_EQ(0x8000U, frame->map_end);
862 EXPECT_EQ(0U, frame->map_load_bias);
863 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700864}
865
Florian Mayerc479e4e2019-01-23 13:35:40 +0000866// Verify that a speculative frame does not cause a crash when it wasn't
867// really added due to a filter.
868TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
869 regs_.set_pc(0x23000);
870 regs_.set_sp(0x10000);
871 regs_.FakeSetReturnAddress(0x23100);
872 regs_.FakeSetReturnAddressValid(true);
873
874 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
875
876 std::vector<std::string> skip_names{"libanother.so"};
877 unwinder.Unwind(&skip_names);
878 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100879 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700880 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Florian Mayerc479e4e2019-01-23 13:35:40 +0000881
882 ASSERT_EQ(0U, unwinder.NumFrames());
883}
884
Christopher Ferrise69f4702017-10-19 16:08:58 -0700885// Verify that an unwind stops when a frame is in given suffix.
886TEST_F(UnwinderTest, map_ignore_suffixes) {
887 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
888 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
889 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
890 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
891
892 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700893 regs_.set_pc(0x1000);
894 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700895 ElfInterfaceFake::FakePushStepData(StepData(0x43404, 0x10010, false));
896 ElfInterfaceFake::FakePushStepData(StepData(0x53504, 0x10020, false));
Christopher Ferrise69f4702017-10-19 16:08:58 -0700897 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
898
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800899 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700900 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700901 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800902 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100903 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700904 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700905
906 ASSERT_EQ(2U, unwinder.NumFrames());
907 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800908 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700909 ASSERT_TRUE(map_info != nullptr);
910 EXPECT_TRUE(map_info->elf == nullptr);
911
912 auto* frame = &unwinder.frames()[0];
913 EXPECT_EQ(0U, frame->num);
914 EXPECT_EQ(0U, frame->rel_pc);
915 EXPECT_EQ(0x1000U, frame->pc);
916 EXPECT_EQ(0x10000U, frame->sp);
917 EXPECT_EQ("Frame0", frame->function_name);
918 EXPECT_EQ(0U, frame->function_offset);
919 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800920 EXPECT_EQ(0U, frame->map_elf_start_offset);
921 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700922 EXPECT_EQ(0x1000U, frame->map_start);
923 EXPECT_EQ(0x8000U, frame->map_end);
924 EXPECT_EQ(0U, frame->map_load_bias);
925 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
926
927 frame = &unwinder.frames()[1];
928 EXPECT_EQ(1U, frame->num);
929 EXPECT_EQ(0x400U, frame->rel_pc);
930 EXPECT_EQ(0x43400U, frame->pc);
931 EXPECT_EQ(0x10010U, frame->sp);
932 EXPECT_EQ("Frame1", frame->function_name);
933 EXPECT_EQ(1U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700934 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
935 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800936 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700937 EXPECT_EQ(0x43000U, frame->map_start);
938 EXPECT_EQ(0x44000U, frame->map_end);
939 EXPECT_EQ(0U, frame->map_load_bias);
940 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
941}
942
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700943// Verify that an unwind stops when the sp and pc don't change.
944TEST_F(UnwinderTest, sp_pc_do_not_change) {
945 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
946 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
947 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
948 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
949 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
950
Yabin Cui11e96fe2018-03-14 18:16:22 -0700951 regs_.set_pc(0x1000);
952 regs_.set_sp(0x10000);
Peter Collingbourne5ac39272020-03-19 17:27:58 -0700953 ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
954 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
955 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
956 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
957 ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700958 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
959
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800960 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700961 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800962 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +0100963 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700964 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700965
966 ASSERT_EQ(3U, unwinder.NumFrames());
967
968 auto* frame = &unwinder.frames()[0];
969 EXPECT_EQ(0U, frame->num);
970 EXPECT_EQ(0U, frame->rel_pc);
971 EXPECT_EQ(0x1000U, frame->pc);
972 EXPECT_EQ(0x10000U, frame->sp);
973 EXPECT_EQ("Frame0", frame->function_name);
974 EXPECT_EQ(0U, frame->function_offset);
975 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800976 EXPECT_EQ(0U, frame->map_elf_start_offset);
977 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700978 EXPECT_EQ(0x1000U, frame->map_start);
979 EXPECT_EQ(0x8000U, frame->map_end);
980 EXPECT_EQ(0U, frame->map_load_bias);
981 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
982
983 frame = &unwinder.frames()[1];
984 EXPECT_EQ(1U, frame->num);
985 EXPECT_EQ(0x400U, frame->rel_pc);
986 EXPECT_EQ(0x33400U, frame->pc);
987 EXPECT_EQ(0x10010U, frame->sp);
988 EXPECT_EQ("Frame1", frame->function_name);
989 EXPECT_EQ(1U, frame->function_offset);
990 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800991 EXPECT_EQ(0U, frame->map_elf_start_offset);
992 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700993 EXPECT_EQ(0x33000U, frame->map_start);
994 EXPECT_EQ(0x34000U, frame->map_end);
995 EXPECT_EQ(0U, frame->map_load_bias);
996 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
997
998 frame = &unwinder.frames()[2];
999 EXPECT_EQ(2U, frame->num);
1000 EXPECT_EQ(0x500U, frame->rel_pc);
1001 EXPECT_EQ(0x33500U, frame->pc);
1002 EXPECT_EQ(0x10020U, frame->sp);
1003 EXPECT_EQ("Frame2", frame->function_name);
1004 EXPECT_EQ(2U, frame->function_offset);
1005 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001006 EXPECT_EQ(0U, frame->map_elf_start_offset);
1007 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -07001008 EXPECT_EQ(0x33000U, frame->map_start);
1009 EXPECT_EQ(0x34000U, frame->map_end);
1010 EXPECT_EQ(0U, frame->map_load_bias);
1011 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1012}
1013
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001014TEST_F(UnwinderTest, dex_pc_in_map) {
1015 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001016 regs_.set_pc(0x1000);
1017 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001018 regs_.FakeSetDexPc(0xa3400);
1019
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001020 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001021 unwinder.Unwind();
1022 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001023 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001024 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001025
1026 ASSERT_EQ(2U, unwinder.NumFrames());
1027
1028 auto* frame = &unwinder.frames()[0];
1029 EXPECT_EQ(0U, frame->num);
1030 EXPECT_EQ(0x400U, frame->rel_pc);
1031 EXPECT_EQ(0xa3400U, frame->pc);
1032 EXPECT_EQ(0x10000U, frame->sp);
1033 EXPECT_EQ("", frame->function_name);
1034 EXPECT_EQ(0U, frame->function_offset);
1035 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001036 EXPECT_EQ(0U, frame->map_elf_start_offset);
1037 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001038 EXPECT_EQ(0xa3000U, frame->map_start);
1039 EXPECT_EQ(0xa4000U, frame->map_end);
1040 EXPECT_EQ(0U, frame->map_load_bias);
1041 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1042
1043 frame = &unwinder.frames()[1];
1044 EXPECT_EQ(1U, frame->num);
1045 EXPECT_EQ(0U, frame->rel_pc);
1046 EXPECT_EQ(0x1000U, frame->pc);
1047 EXPECT_EQ(0x10000U, frame->sp);
1048 EXPECT_EQ("Frame0", frame->function_name);
1049 EXPECT_EQ(0U, frame->function_offset);
1050 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001051 EXPECT_EQ(0U, frame->map_elf_start_offset);
1052 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001053 EXPECT_EQ(0x1000U, frame->map_start);
1054 EXPECT_EQ(0x8000U, frame->map_end);
1055 EXPECT_EQ(0U, frame->map_load_bias);
1056 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1057}
1058
Christopher Ferrisa4bdb982019-06-04 11:52:16 -07001059TEST_F(UnwinderTest, dex_pc_in_map_non_zero_offset) {
1060 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1061 regs_.set_pc(0x1000);
1062 regs_.set_sp(0x10000);
1063 regs_.FakeSetDexPc(0xd0400);
1064
1065 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1066 unwinder.Unwind();
1067 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001068 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferrisa4bdb982019-06-04 11:52:16 -07001069 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1070
1071 ASSERT_EQ(2U, unwinder.NumFrames());
1072
1073 auto* frame = &unwinder.frames()[0];
1074 EXPECT_EQ(0U, frame->num);
1075 EXPECT_EQ(0x400U, frame->rel_pc);
1076 EXPECT_EQ(0xd0400U, frame->pc);
1077 EXPECT_EQ(0x10000U, frame->sp);
1078 EXPECT_EQ("", frame->function_name);
1079 EXPECT_EQ(0U, frame->function_offset);
1080 EXPECT_EQ("/fake/fake.apk", frame->map_name);
1081 EXPECT_EQ(0x1000U, frame->map_elf_start_offset);
1082 EXPECT_EQ(0x1000U, frame->map_exact_offset);
1083 EXPECT_EQ(0xd0000U, frame->map_start);
1084 EXPECT_EQ(0xd1000U, frame->map_end);
1085 EXPECT_EQ(0U, frame->map_load_bias);
1086 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1087
1088 frame = &unwinder.frames()[1];
1089 EXPECT_EQ(1U, frame->num);
1090 EXPECT_EQ(0U, frame->rel_pc);
1091 EXPECT_EQ(0x1000U, frame->pc);
1092 EXPECT_EQ(0x10000U, frame->sp);
1093 EXPECT_EQ("Frame0", frame->function_name);
1094 EXPECT_EQ(0U, frame->function_offset);
1095 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
1096 EXPECT_EQ(0U, frame->map_elf_start_offset);
1097 EXPECT_EQ(0U, frame->map_exact_offset);
1098 EXPECT_EQ(0x1000U, frame->map_start);
1099 EXPECT_EQ(0x8000U, frame->map_end);
1100 EXPECT_EQ(0U, frame->map_load_bias);
1101 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1102}
1103
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001104TEST_F(UnwinderTest, dex_pc_not_in_map) {
1105 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001106 regs_.set_pc(0x1000);
1107 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001108 regs_.FakeSetDexPc(0x50000);
1109
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001110 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001111 unwinder.Unwind();
1112 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001113 EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001114 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001115
1116 ASSERT_EQ(2U, unwinder.NumFrames());
1117
1118 auto* frame = &unwinder.frames()[0];
1119 EXPECT_EQ(0U, frame->num);
1120 EXPECT_EQ(0x50000U, frame->rel_pc);
1121 EXPECT_EQ(0x50000U, frame->pc);
1122 EXPECT_EQ(0x10000U, frame->sp);
1123 EXPECT_EQ("", frame->function_name);
1124 EXPECT_EQ(0U, frame->function_offset);
1125 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001126 EXPECT_EQ(0U, frame->map_elf_start_offset);
1127 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001128 EXPECT_EQ(0U, frame->map_start);
1129 EXPECT_EQ(0U, frame->map_end);
1130 EXPECT_EQ(0U, frame->map_load_bias);
1131 EXPECT_EQ(0, frame->map_flags);
1132
1133 frame = &unwinder.frames()[1];
1134 EXPECT_EQ(1U, frame->num);
1135 EXPECT_EQ(0U, frame->rel_pc);
1136 EXPECT_EQ(0x1000U, frame->pc);
1137 EXPECT_EQ(0x10000U, frame->sp);
1138 EXPECT_EQ("Frame0", frame->function_name);
1139 EXPECT_EQ(0U, frame->function_offset);
1140 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001141 EXPECT_EQ(0U, frame->map_elf_start_offset);
1142 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001143 EXPECT_EQ(0x1000U, frame->map_start);
1144 EXPECT_EQ(0x8000U, frame->map_end);
1145 EXPECT_EQ(0U, frame->map_load_bias);
1146 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1147}
1148
Christopher Ferrisafbed692020-08-27 11:46:36 -07001149TEST_F(UnwinderTest, dex_pc_not_in_map_valid_dex_files) {
1150 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1151 regs_.set_pc(0x1000);
1152 regs_.set_sp(0x10000);
1153 regs_.FakeSetDexPc(0x50000);
1154
1155 DexFiles dex_files(process_memory_);
1156 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1157 unwinder.SetDexFiles(&dex_files, ARCH_ARM);
1158 unwinder.Unwind();
1159 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1160 EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
1161 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1162
1163 ASSERT_EQ(2U, unwinder.NumFrames());
1164
1165 auto* frame = &unwinder.frames()[0];
1166 EXPECT_EQ(0U, frame->num);
1167 EXPECT_EQ(0x50000U, frame->rel_pc);
1168 EXPECT_EQ(0x50000U, frame->pc);
1169 EXPECT_EQ(0x10000U, frame->sp);
1170 EXPECT_EQ("", frame->function_name);
1171 EXPECT_EQ(0U, frame->function_offset);
1172 EXPECT_EQ("", frame->map_name);
1173 EXPECT_EQ(0U, frame->map_elf_start_offset);
1174 EXPECT_EQ(0U, frame->map_exact_offset);
1175 EXPECT_EQ(0U, frame->map_start);
1176 EXPECT_EQ(0U, frame->map_end);
1177 EXPECT_EQ(0U, frame->map_load_bias);
1178 EXPECT_EQ(0, frame->map_flags);
1179
1180 frame = &unwinder.frames()[1];
1181 EXPECT_EQ(1U, frame->num);
1182 EXPECT_EQ(0U, frame->rel_pc);
1183 EXPECT_EQ(0x1000U, frame->pc);
1184 EXPECT_EQ(0x10000U, frame->sp);
1185 EXPECT_EQ("Frame0", frame->function_name);
1186 EXPECT_EQ(0U, frame->function_offset);
1187 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
1188 EXPECT_EQ(0U, frame->map_elf_start_offset);
1189 EXPECT_EQ(0U, frame->map_exact_offset);
1190 EXPECT_EQ(0x1000U, frame->map_start);
1191 EXPECT_EQ(0x8000U, frame->map_end);
1192 EXPECT_EQ(0U, frame->map_load_bias);
1193 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1194}
1195
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001196TEST_F(UnwinderTest, dex_pc_multiple_frames) {
1197 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1198 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001199 regs_.set_pc(0x1000);
1200 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001201 regs_.FakeSetDexPc(0xa3400);
Peter Collingbourne5ac39272020-03-19 17:27:58 -07001202 ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001203 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1204
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001205 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001206 unwinder.Unwind();
1207 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001208 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001209 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001210
1211 ASSERT_EQ(3U, unwinder.NumFrames());
1212
1213 auto* frame = &unwinder.frames()[0];
1214 EXPECT_EQ(0U, frame->num);
1215 EXPECT_EQ(0x400U, frame->rel_pc);
1216 EXPECT_EQ(0xa3400U, frame->pc);
1217 EXPECT_EQ(0x10000U, frame->sp);
1218 EXPECT_EQ("", frame->function_name);
1219 EXPECT_EQ(0U, frame->function_offset);
1220 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001221 EXPECT_EQ(0U, frame->map_elf_start_offset);
1222 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001223 EXPECT_EQ(0xa3000U, frame->map_start);
1224 EXPECT_EQ(0xa4000U, frame->map_end);
1225 EXPECT_EQ(0U, frame->map_load_bias);
1226 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1227
1228 frame = &unwinder.frames()[1];
1229 EXPECT_EQ(1U, frame->num);
1230 EXPECT_EQ(0U, frame->rel_pc);
1231 EXPECT_EQ(0x1000U, frame->pc);
1232 EXPECT_EQ(0x10000U, frame->sp);
1233 EXPECT_EQ("Frame0", frame->function_name);
1234 EXPECT_EQ(0U, frame->function_offset);
1235 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001236 EXPECT_EQ(0U, frame->map_elf_start_offset);
1237 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001238 EXPECT_EQ(0x1000U, frame->map_start);
1239 EXPECT_EQ(0x8000U, frame->map_end);
1240 EXPECT_EQ(0U, frame->map_load_bias);
1241 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1242
1243 frame = &unwinder.frames()[2];
1244 EXPECT_EQ(2U, frame->num);
1245 EXPECT_EQ(0x400U, frame->rel_pc);
1246 EXPECT_EQ(0x33400U, frame->pc);
1247 EXPECT_EQ(0x10010U, frame->sp);
1248 EXPECT_EQ("Frame1", frame->function_name);
1249 EXPECT_EQ(1U, frame->function_offset);
1250 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001251 EXPECT_EQ(0U, frame->map_elf_start_offset);
1252 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001253 EXPECT_EQ(0x33000U, frame->map_start);
1254 EXPECT_EQ(0x34000U, frame->map_end);
1255 EXPECT_EQ(0U, frame->map_load_bias);
1256 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1257}
1258
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001259TEST_F(UnwinderTest, dex_pc_max_frames) {
1260 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1261 regs_.set_pc(0x1000);
1262 regs_.set_sp(0x10000);
1263 regs_.FakeSetDexPc(0xa3400);
1264
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001265 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001266 unwinder.Unwind();
1267 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001268 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001269 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001270
1271 ASSERT_EQ(1U, unwinder.NumFrames());
1272
1273 auto* frame = &unwinder.frames()[0];
1274 EXPECT_EQ(0U, frame->num);
1275 EXPECT_EQ(0x400U, frame->rel_pc);
1276 EXPECT_EQ(0xa3400U, frame->pc);
1277 EXPECT_EQ(0x10000U, frame->sp);
1278 EXPECT_EQ("", frame->function_name);
1279 EXPECT_EQ(0U, frame->function_offset);
1280 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001281 EXPECT_EQ(0U, frame->map_elf_start_offset);
1282 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001283 EXPECT_EQ(0xa3000U, frame->map_start);
1284 EXPECT_EQ(0xa4000U, frame->map_end);
1285 EXPECT_EQ(0U, frame->map_load_bias);
1286 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1287}
1288
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001289TEST_F(UnwinderTest, elf_from_memory_not_file) {
1290 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1291
1292 regs_.set_pc(0xc0050);
1293 regs_.set_sp(0x10000);
1294 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1295
1296 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1297 unwinder.Unwind();
1298 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001299 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001300 EXPECT_TRUE(unwinder.elf_from_memory_not_file());
1301
1302 ASSERT_EQ(1U, unwinder.NumFrames());
1303
1304 auto* frame = &unwinder.frames()[0];
1305 EXPECT_EQ(0U, frame->num);
1306 EXPECT_EQ(0x50U, frame->rel_pc);
1307 EXPECT_EQ(0xc0050U, frame->pc);
1308 EXPECT_EQ(0x10000U, frame->sp);
1309 EXPECT_EQ("Frame0", frame->function_name);
1310 EXPECT_EQ(0U, frame->function_offset);
1311 EXPECT_EQ("/fake/unreadable.so", frame->map_name);
1312 EXPECT_EQ(0U, frame->map_elf_start_offset);
1313 EXPECT_EQ(0U, frame->map_exact_offset);
1314 EXPECT_EQ(0xc0000U, frame->map_start);
1315 EXPECT_EQ(0xc1000U, frame->map_end);
1316 EXPECT_EQ(0U, frame->map_load_bias);
1317 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1318}
1319
1320TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
1321 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1322
1323 regs_.set_pc(0xc1050);
1324 regs_.set_sp(0x10000);
1325 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1326
1327 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1328 unwinder.Unwind();
1329 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001330 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001331 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1332
1333 ASSERT_EQ(1U, unwinder.NumFrames());
1334
1335 auto* frame = &unwinder.frames()[0];
1336 EXPECT_EQ(0U, frame->num);
1337 EXPECT_EQ(0x50U, frame->rel_pc);
1338 EXPECT_EQ(0xc1050U, frame->pc);
1339 EXPECT_EQ(0x10000U, frame->sp);
1340 EXPECT_EQ("Frame0", frame->function_name);
1341 EXPECT_EQ(0U, frame->function_offset);
1342 EXPECT_EQ("[vdso]", frame->map_name);
1343 EXPECT_EQ(0U, frame->map_elf_start_offset);
1344 EXPECT_EQ(0U, frame->map_exact_offset);
1345 EXPECT_EQ(0xc1000U, frame->map_start);
1346 EXPECT_EQ(0xc2000U, frame->map_end);
1347 EXPECT_EQ(0U, frame->map_load_bias);
1348 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1349}
1350
1351TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
1352 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1353
1354 regs_.set_pc(0xc2050);
1355 regs_.set_sp(0x10000);
1356 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1357
1358 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1359 unwinder.Unwind();
1360 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001361 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001362 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1363
1364 ASSERT_EQ(1U, unwinder.NumFrames());
1365
1366 auto* frame = &unwinder.frames()[0];
1367 EXPECT_EQ(0U, frame->num);
1368 EXPECT_EQ(0x50U, frame->rel_pc);
1369 EXPECT_EQ(0xc2050U, frame->pc);
1370 EXPECT_EQ(0x10000U, frame->sp);
1371 EXPECT_EQ("Frame0", frame->function_name);
1372 EXPECT_EQ(0U, frame->function_offset);
1373 EXPECT_EQ("", frame->map_name);
1374 EXPECT_EQ(0U, frame->map_elf_start_offset);
1375 EXPECT_EQ(0U, frame->map_exact_offset);
1376 EXPECT_EQ(0xc2000U, frame->map_start);
1377 EXPECT_EQ(0xc3000U, frame->map_end);
1378 EXPECT_EQ(0U, frame->map_load_bias);
1379 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1380}
1381
Christopher Ferris98aaf4c2019-05-03 11:13:17 -07001382TEST_F(UnwinderTest, elf_from_memory_but_from_memfd) {
1383 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1384
1385 regs_.set_pc(0xc3050);
1386 regs_.set_sp(0x10000);
1387 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1388
1389 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1390 unwinder.Unwind();
1391 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Florian Mayer96e966e2020-08-13 09:41:29 +01001392 EXPECT_EQ(WARNING_NONE, unwinder.warnings());
Christopher Ferris98aaf4c2019-05-03 11:13:17 -07001393 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1394
1395 ASSERT_EQ(1U, unwinder.NumFrames());
1396
1397 auto* frame = &unwinder.frames()[0];
1398 EXPECT_EQ(0U, frame->num);
1399 EXPECT_EQ(0x50U, frame->rel_pc);
1400 EXPECT_EQ(0xc3050U, frame->pc);
1401 EXPECT_EQ(0x10000U, frame->sp);
1402 EXPECT_EQ("Frame0", frame->function_name);
1403 EXPECT_EQ(0U, frame->function_offset);
1404 EXPECT_EQ("/memfd:/jit-cache", frame->map_name);
1405 EXPECT_EQ(0U, frame->map_elf_start_offset);
1406 EXPECT_EQ(0U, frame->map_exact_offset);
1407 EXPECT_EQ(0xc3000U, frame->map_start);
1408 EXPECT_EQ(0xc4000U, frame->map_end);
1409 EXPECT_EQ(0U, frame->map_load_bias);
1410 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1411}
1412
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001413// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001414TEST_F(UnwinderTest, format_frame) {
1415 RegsFake regs_arm(10);
1416 regs_arm.FakeSetArch(ARCH_ARM);
1417 Unwinder unwinder32(10, maps_.get(), &regs_arm, process_memory_);
1418
1419 RegsFake regs_arm64(10);
1420 regs_arm64.FakeSetArch(ARCH_ARM64);
1421 Unwinder unwinder64(10, maps_.get(), &regs_arm64, process_memory_);
1422
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001423 FrameData frame;
1424 frame.num = 1;
1425 frame.rel_pc = 0x1000;
1426 frame.pc = 0x4000;
1427 frame.sp = 0x1000;
1428 frame.function_name = "function";
1429 frame.function_offset = 100;
1430 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001431 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001432 frame.map_start = 0x3000;
1433 frame.map_end = 0x6000;
1434 frame.map_flags = PROT_READ;
1435
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001436 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001437 unwinder64.FormatFrame(frame));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001438 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001439 unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001440
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001441 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001442 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001443 unwinder64.FormatFrame(frame));
1444 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001445
1446 frame.function_offset = 0;
1447 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
Christopher Ferris78133452019-03-14 13:44:38 -07001448 unwinder64.FormatFrame(frame));
1449 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001450
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001451 // Verify the function name is demangled.
1452 frame.function_name = "_ZN4funcEv";
Christopher Ferris78133452019-03-14 13:44:38 -07001453 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())", unwinder64.FormatFrame(frame));
1454 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", unwinder32.FormatFrame(frame));
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001455
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001456 frame.function_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001457 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", unwinder64.FormatFrame(frame));
1458 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001459
1460 frame.map_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001461 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", unwinder64.FormatFrame(frame));
1462 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001463
1464 frame.map_start = 0;
1465 frame.map_end = 0;
Christopher Ferris78133452019-03-14 13:44:38 -07001466 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", unwinder64.FormatFrame(frame));
1467 EXPECT_EQ(" #01 pc 00001000 <unknown>", unwinder32.FormatFrame(frame));
1468}
1469
1470TEST_F(UnwinderTest, format_frame_build_id) {
1471 RegsFake regs(10);
1472 regs.FakeSetArch(ARCH_ARM);
1473 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1474
1475 FrameData frame;
1476 frame.num = 1;
1477 frame.rel_pc = 0x1000;
1478 frame.pc = 0x4000;
1479 frame.sp = 0x1000;
1480 frame.function_name = "function";
1481 frame.function_offset = 100;
1482 frame.map_name = "/fake/libfake.so";
1483 frame.map_elf_start_offset = 0;
1484 frame.map_start = 0x3000;
1485 frame.map_end = 0x6000;
1486 frame.map_flags = PROT_READ;
1487
1488 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder.FormatFrame(frame));
1489 unwinder.SetDisplayBuildID(true);
1490 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100) (BuildId: 46414b45)",
1491 unwinder.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001492}
1493
Christopher Ferris02fdb562017-12-08 15:04:49 -08001494static std::string ArchToString(ArchEnum arch) {
1495 if (arch == ARCH_ARM) {
1496 return "Arm";
1497 } else if (arch == ARCH_ARM64) {
1498 return "Arm64";
1499 } else if (arch == ARCH_X86) {
1500 return "X86";
1501 } else if (arch == ARCH_X86_64) {
1502 return "X86_64";
1503 } else {
1504 return "Unknown";
1505 }
1506}
1507
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001508// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001509TEST_F(UnwinderTest, format_frame_by_arch) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001510 std::vector<Regs*> reg_list;
1511 RegsArm* arm = new RegsArm;
1512 arm->set_pc(0x2300);
1513 arm->set_sp(0x10000);
1514 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001515
Christopher Ferris02fdb562017-12-08 15:04:49 -08001516 RegsArm64* arm64 = new RegsArm64;
1517 arm64->set_pc(0x2300);
1518 arm64->set_sp(0x10000);
1519 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001520
Christopher Ferris02fdb562017-12-08 15:04:49 -08001521 RegsX86* x86 = new RegsX86;
1522 x86->set_pc(0x2300);
1523 x86->set_sp(0x10000);
1524 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001525
Christopher Ferris02fdb562017-12-08 15:04:49 -08001526 RegsX86_64* x86_64 = new RegsX86_64;
1527 x86_64->set_pc(0x2300);
1528 x86_64->set_sp(0x10000);
1529 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001530
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001531 RegsMips* mips = new RegsMips;
1532 mips->set_pc(0x2300);
1533 mips->set_sp(0x10000);
1534 reg_list.push_back(mips);
1535
1536 RegsMips64* mips64 = new RegsMips64;
1537 mips64->set_pc(0x2300);
1538 mips64->set_sp(0x10000);
1539 reg_list.push_back(mips64);
1540
Christopher Ferris02fdb562017-12-08 15:04:49 -08001541 for (auto regs : reg_list) {
1542 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001543
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001544 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001545 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001546
Christopher Ferris02fdb562017-12-08 15:04:49 -08001547 ASSERT_EQ(1U, unwinder.NumFrames());
1548 std::string expected;
1549 switch (regs->Arch()) {
1550 case ARCH_ARM:
1551 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001552 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001553 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1554 break;
1555 case ARCH_ARM64:
1556 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001557 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001558 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1559 break;
1560 default:
1561 expected = "";
1562 }
1563 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1564 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1565 delete regs;
1566 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001567}
1568
1569} // namespace unwindstack