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