blob: 2e0a2985c08be9d6e9db8fad26fb543432094b4e [file] [log] [blame]
Yabin Cui3c8c2132015-08-13 20:30:20 -07001/*
2 * Copyright (C) 2015 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 "dwarf_unwind.h"
18
19#include <ucontext.h>
20
21#include <backtrace/Backtrace.h>
Elliott Hughes66dd09e2015-12-04 14:00:57 -080022#include <android-base/logging.h>
Yabin Cui3c8c2132015-08-13 20:30:20 -070023
24#include "thread_tree.h"
25
Yabin Cui8a52e972015-10-01 11:32:44 -070026#define SetUContextReg(dst, perf_regno) \
27 do { \
28 uint64_t value; \
Yabin Cui3c8c2132015-08-13 20:30:20 -070029 if (GetRegValue(regs, perf_regno, &value)) { \
Chih-Hung Hsieh2019e832016-05-18 14:36:58 -070030 (dst) = value; \
Yabin Cui8a52e972015-10-01 11:32:44 -070031 } \
Yabin Cui3c8c2132015-08-13 20:30:20 -070032 } while (0)
33
34static ucontext_t BuildUContextFromRegs(const RegSet& regs __attribute__((unused))) {
35 ucontext_t ucontext;
36 memset(&ucontext, 0, sizeof(ucontext));
37#if defined(__i386__)
38 SetUContextReg(ucontext.uc_mcontext.gregs[REG_GS], PERF_REG_X86_GS);
39 SetUContextReg(ucontext.uc_mcontext.gregs[REG_FS], PERF_REG_X86_FS);
40 SetUContextReg(ucontext.uc_mcontext.gregs[REG_ES], PERF_REG_X86_ES);
41 SetUContextReg(ucontext.uc_mcontext.gregs[REG_DS], PERF_REG_X86_DS);
42 SetUContextReg(ucontext.uc_mcontext.gregs[REG_EAX], PERF_REG_X86_AX);
43 SetUContextReg(ucontext.uc_mcontext.gregs[REG_EBX], PERF_REG_X86_BX);
44 SetUContextReg(ucontext.uc_mcontext.gregs[REG_ECX], PERF_REG_X86_CX);
45 SetUContextReg(ucontext.uc_mcontext.gregs[REG_EDX], PERF_REG_X86_DX);
46 SetUContextReg(ucontext.uc_mcontext.gregs[REG_ESI], PERF_REG_X86_SI);
47 SetUContextReg(ucontext.uc_mcontext.gregs[REG_EDI], PERF_REG_X86_DI);
48 SetUContextReg(ucontext.uc_mcontext.gregs[REG_EBP], PERF_REG_X86_BP);
49 SetUContextReg(ucontext.uc_mcontext.gregs[REG_EIP], PERF_REG_X86_IP);
50 SetUContextReg(ucontext.uc_mcontext.gregs[REG_ESP], PERF_REG_X86_SP);
51 SetUContextReg(ucontext.uc_mcontext.gregs[REG_CS], PERF_REG_X86_CS);
52 SetUContextReg(ucontext.uc_mcontext.gregs[REG_EFL], PERF_REG_X86_FLAGS);
53 SetUContextReg(ucontext.uc_mcontext.gregs[REG_SS], PERF_REG_X86_SS);
54#elif defined(__x86_64__)
55 SetUContextReg(ucontext.uc_mcontext.gregs[REG_R8], PERF_REG_X86_R8);
56 SetUContextReg(ucontext.uc_mcontext.gregs[REG_R9], PERF_REG_X86_R9);
57 SetUContextReg(ucontext.uc_mcontext.gregs[REG_R10], PERF_REG_X86_R10);
58 SetUContextReg(ucontext.uc_mcontext.gregs[REG_R11], PERF_REG_X86_R11);
59 SetUContextReg(ucontext.uc_mcontext.gregs[REG_R12], PERF_REG_X86_R12);
60 SetUContextReg(ucontext.uc_mcontext.gregs[REG_R13], PERF_REG_X86_R13);
61 SetUContextReg(ucontext.uc_mcontext.gregs[REG_R14], PERF_REG_X86_R14);
62 SetUContextReg(ucontext.uc_mcontext.gregs[REG_R15], PERF_REG_X86_R15);
63 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RDI], PERF_REG_X86_DI);
64 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RSI], PERF_REG_X86_SI);
65 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RBP], PERF_REG_X86_BP);
66 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RBX], PERF_REG_X86_BX);
67 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RDX], PERF_REG_X86_DX);
68 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RAX], PERF_REG_X86_AX);
69 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RCX], PERF_REG_X86_CX);
70 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RSP], PERF_REG_X86_SP);
71 SetUContextReg(ucontext.uc_mcontext.gregs[REG_RIP], PERF_REG_X86_IP);
72#elif defined(__aarch64__)
73 for (size_t i = PERF_REG_ARM64_X0; i < PERF_REG_ARM64_MAX; ++i) {
74 SetUContextReg(ucontext.uc_mcontext.regs[i], i);
75 }
76#elif defined(__arm__)
77 SetUContextReg(ucontext.uc_mcontext.arm_r0, PERF_REG_ARM_R0);
78 SetUContextReg(ucontext.uc_mcontext.arm_r1, PERF_REG_ARM_R1);
79 SetUContextReg(ucontext.uc_mcontext.arm_r2, PERF_REG_ARM_R2);
80 SetUContextReg(ucontext.uc_mcontext.arm_r3, PERF_REG_ARM_R3);
81 SetUContextReg(ucontext.uc_mcontext.arm_r4, PERF_REG_ARM_R4);
82 SetUContextReg(ucontext.uc_mcontext.arm_r5, PERF_REG_ARM_R5);
83 SetUContextReg(ucontext.uc_mcontext.arm_r6, PERF_REG_ARM_R6);
84 SetUContextReg(ucontext.uc_mcontext.arm_r7, PERF_REG_ARM_R7);
85 SetUContextReg(ucontext.uc_mcontext.arm_r8, PERF_REG_ARM_R8);
86 SetUContextReg(ucontext.uc_mcontext.arm_r9, PERF_REG_ARM_R9);
87 SetUContextReg(ucontext.uc_mcontext.arm_r10, PERF_REG_ARM_R10);
88 SetUContextReg(ucontext.uc_mcontext.arm_fp, PERF_REG_ARM_FP);
89 SetUContextReg(ucontext.uc_mcontext.arm_ip, PERF_REG_ARM_IP);
90 SetUContextReg(ucontext.uc_mcontext.arm_sp, PERF_REG_ARM_SP);
91 SetUContextReg(ucontext.uc_mcontext.arm_lr, PERF_REG_ARM_LR);
92 SetUContextReg(ucontext.uc_mcontext.arm_pc, PERF_REG_ARM_PC);
93#endif
94 return ucontext;
95}
96
Yabin Cui417df292016-11-16 12:26:13 -080097std::vector<uint64_t> UnwindCallChain(int abi, const ThreadEntry& thread,
Yabin Cuicf31e9d2016-07-14 14:29:33 -070098 const RegSet& regs, const char* stack,
99 size_t stack_size, bool strict_arch_check) {
Yabin Cui3c8c2132015-08-13 20:30:20 -0700100 std::vector<uint64_t> result;
Yabin Cui417df292016-11-16 12:26:13 -0800101 ArchType arch = (abi != PERF_SAMPLE_REGS_ABI_32) ?
102 ScopedCurrentArch::GetCurrentArch() :
103 ScopedCurrentArch::GetCurrentArch32();
Yabin Cui4b6720d2016-03-31 14:39:19 -0700104 if (!IsArchTheSame(arch, GetBuildArch(), strict_arch_check)) {
Yabin Cui257d5e62016-03-30 16:21:47 -0700105 LOG(FATAL) << "simpleperf is built in arch " << GetArchString(GetBuildArch())
Yabin Cui4b6720d2016-03-31 14:39:19 -0700106 << ", and can't do stack unwinding for arch " << GetArchString(arch);
Yabin Cui3c8c2132015-08-13 20:30:20 -0700107 return result;
108 }
109 uint64_t sp_reg_value;
Yabin Cui48460892016-03-18 12:30:31 -0700110 if (!GetSpRegValue(regs, arch, &sp_reg_value)) {
Yabin Cui3c8c2132015-08-13 20:30:20 -0700111 LOG(ERROR) << "can't get sp reg value";
112 return result;
113 }
114 uint64_t stack_addr = sp_reg_value;
115
Yabin Cuiaa0dd192016-12-15 11:24:03 -0800116 std::vector<backtrace_map_t> bt_maps(thread.maps->size());
Yabin Cui3c8c2132015-08-13 20:30:20 -0700117 size_t map_index = 0;
Yabin Cuiaa0dd192016-12-15 11:24:03 -0800118 for (auto& map : *thread.maps) {
Yabin Cui3c8c2132015-08-13 20:30:20 -0700119 backtrace_map_t& bt_map = bt_maps[map_index++];
120 bt_map.start = map->start_addr;
121 bt_map.end = map->start_addr + map->len;
122 bt_map.offset = map->pgoff;
Yabin Cuieec606c2016-07-07 13:53:33 -0700123 bt_map.name = map->dso->GetDebugFilePath();
Yabin Cui3c8c2132015-08-13 20:30:20 -0700124 }
125 std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(thread.pid, bt_maps));
126
127 backtrace_stackinfo_t stack_info;
128 stack_info.start = stack_addr;
Yabin Cuicf31e9d2016-07-14 14:29:33 -0700129 stack_info.end = stack_addr + stack_size;
130 stack_info.data = reinterpret_cast<const uint8_t*>(stack);
Yabin Cui3c8c2132015-08-13 20:30:20 -0700131
132 std::unique_ptr<Backtrace> backtrace(
133 Backtrace::CreateOffline(thread.pid, thread.tid, backtrace_map.get(), stack_info, true));
134 ucontext_t ucontext = BuildUContextFromRegs(regs);
135 if (backtrace->Unwind(0, &ucontext)) {
136 for (auto it = backtrace->begin(); it != backtrace->end(); ++it) {
Yabin Cui8ce68142016-08-05 11:27:42 -0700137 // Unwinding in arm architecture can return 0 pc address.
138 if (it->pc == 0) {
139 break;
140 }
Yabin Cui3c8c2132015-08-13 20:30:20 -0700141 result.push_back(it->pc);
142 }
143 }
144 return result;
145}