13c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui/* 23c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * Copyright (C) 2015 The Android Open Source Project 33c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * 43c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * Licensed under the Apache License, Version 2.0 (the "License"); 53c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * you may not use this file except in compliance with the License. 63c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * You may obtain a copy of the License at 73c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * 83c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * http://www.apache.org/licenses/LICENSE-2.0 93c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * 103c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * Unless required by applicable law or agreed to in writing, software 113c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * distributed under the License is distributed on an "AS IS" BASIS, 123c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * See the License for the specific language governing permissions and 143c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui * limitations under the License. 153c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui */ 163c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 173c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#include "dwarf_unwind.h" 183c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 193c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#include <ucontext.h> 203c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 213c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#include <backtrace/Backtrace.h> 2266dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/logging.h> 233c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 243c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#include "thread_tree.h" 253c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 268a52e97bfd6e2c59ef48fedb277168a7bfbeec46Yabin Cui#define SetUContextReg(dst, perf_regno) \ 278a52e97bfd6e2c59ef48fedb277168a7bfbeec46Yabin Cui do { \ 288a52e97bfd6e2c59ef48fedb277168a7bfbeec46Yabin Cui uint64_t value; \ 293c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui if (GetRegValue(regs, perf_regno, &value)) { \ 308a52e97bfd6e2c59ef48fedb277168a7bfbeec46Yabin Cui dst = value; \ 318a52e97bfd6e2c59ef48fedb277168a7bfbeec46Yabin Cui } \ 323c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } while (0) 333c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 343c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cuistatic ucontext_t BuildUContextFromRegs(const RegSet& regs __attribute__((unused))) { 353c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui ucontext_t ucontext; 363c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui memset(&ucontext, 0, sizeof(ucontext)); 373c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#if defined(__i386__) 383c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_GS], PERF_REG_X86_GS); 393c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_FS], PERF_REG_X86_FS); 403c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_ES], PERF_REG_X86_ES); 413c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_DS], PERF_REG_X86_DS); 423c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_EAX], PERF_REG_X86_AX); 433c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_EBX], PERF_REG_X86_BX); 443c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_ECX], PERF_REG_X86_CX); 453c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_EDX], PERF_REG_X86_DX); 463c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_ESI], PERF_REG_X86_SI); 473c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_EDI], PERF_REG_X86_DI); 483c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_EBP], PERF_REG_X86_BP); 493c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_EIP], PERF_REG_X86_IP); 503c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_ESP], PERF_REG_X86_SP); 513c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_CS], PERF_REG_X86_CS); 523c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_EFL], PERF_REG_X86_FLAGS); 533c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_SS], PERF_REG_X86_SS); 543c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#elif defined(__x86_64__) 553c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_R8], PERF_REG_X86_R8); 563c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_R9], PERF_REG_X86_R9); 573c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_R10], PERF_REG_X86_R10); 583c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_R11], PERF_REG_X86_R11); 593c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_R12], PERF_REG_X86_R12); 603c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_R13], PERF_REG_X86_R13); 613c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_R14], PERF_REG_X86_R14); 623c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_R15], PERF_REG_X86_R15); 633c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RDI], PERF_REG_X86_DI); 643c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RSI], PERF_REG_X86_SI); 653c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RBP], PERF_REG_X86_BP); 663c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RBX], PERF_REG_X86_BX); 673c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RDX], PERF_REG_X86_DX); 683c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RAX], PERF_REG_X86_AX); 693c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RCX], PERF_REG_X86_CX); 703c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RSP], PERF_REG_X86_SP); 713c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.gregs[REG_RIP], PERF_REG_X86_IP); 723c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#elif defined(__aarch64__) 733c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui for (size_t i = PERF_REG_ARM64_X0; i < PERF_REG_ARM64_MAX; ++i) { 743c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.regs[i], i); 753c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 763c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#elif defined(__arm__) 773c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r0, PERF_REG_ARM_R0); 783c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r1, PERF_REG_ARM_R1); 793c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r2, PERF_REG_ARM_R2); 803c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r3, PERF_REG_ARM_R3); 813c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r4, PERF_REG_ARM_R4); 823c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r5, PERF_REG_ARM_R5); 833c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r6, PERF_REG_ARM_R6); 843c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r7, PERF_REG_ARM_R7); 853c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r8, PERF_REG_ARM_R8); 863c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r9, PERF_REG_ARM_R9); 873c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_r10, PERF_REG_ARM_R10); 883c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_fp, PERF_REG_ARM_FP); 893c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_ip, PERF_REG_ARM_IP); 903c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_sp, PERF_REG_ARM_SP); 913c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_lr, PERF_REG_ARM_LR); 923c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui SetUContextReg(ucontext.uc_mcontext.arm_pc, PERF_REG_ARM_PC); 933c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#endif 943c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui return ucontext; 953c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui} 963c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 97e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cuistd::vector<uint64_t> UnwindCallChain(ArchType arch, const ThreadEntry& thread, 98e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui const RegSet& regs, const std::vector<char>& stack) { 993c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui std::vector<uint64_t> result; 100e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui if (arch != GetBuildArch()) { 1013c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui LOG(ERROR) << "can't unwind data recorded on a different architecture"; 1023c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui return result; 1033c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 1043c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui uint64_t sp_reg_value; 105e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui if (!GetSpRegValue(regs, arch, &sp_reg_value)) { 1063c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui LOG(ERROR) << "can't get sp reg value"; 1073c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui return result; 1083c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 1093c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui uint64_t stack_addr = sp_reg_value; 1103c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 1113c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui std::vector<backtrace_map_t> bt_maps(thread.maps.size()); 1123c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui size_t map_index = 0; 1133c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui for (auto& map : thread.maps) { 1143c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui backtrace_map_t& bt_map = bt_maps[map_index++]; 1153c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui bt_map.start = map->start_addr; 1163c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui bt_map.end = map->start_addr + map->len; 1173c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui bt_map.offset = map->pgoff; 1183c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui bt_map.name = map->dso->GetAccessiblePath(); 1193c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 1203c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(thread.pid, bt_maps)); 1213c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 1223c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui backtrace_stackinfo_t stack_info; 1233c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui stack_info.start = stack_addr; 1243c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui stack_info.end = stack_addr + stack.size(); 1253c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui stack_info.data = reinterpret_cast<const uint8_t*>(stack.data()); 1263c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 1273c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui std::unique_ptr<Backtrace> backtrace( 1283c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui Backtrace::CreateOffline(thread.pid, thread.tid, backtrace_map.get(), stack_info, true)); 1293c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui ucontext_t ucontext = BuildUContextFromRegs(regs); 1303c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui if (backtrace->Unwind(0, &ucontext)) { 1313c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui for (auto it = backtrace->begin(); it != backtrace->end(); ++it) { 1323c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui result.push_back(it->pc); 1333c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 1343c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 1353c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui return result; 1363c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui} 137