summaryrefslogtreecommitdiff
path: root/simpleperf
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2016-03-30 16:21:47 -0700
committerYabin Cui <yabinc@google.com>2016-03-30 16:21:47 -0700
commit257d5e69967941de7c5516a476397450063b8c3d (patch)
tree5729b8ffc4e002d9a75d5e56c49495dd0fd814b9 /simpleperf
parent6dd31f4a3fda4dc6a49bcda1fb67052bc478c3fb (diff)
downloadextras-257d5e69967941de7c5516a476397450063b8c3d.tar.gz
simpleperf: don't allow 64bit simpleperf unwinding 32bit processes.
Bug: 27927427 Change-Id: I87abc7f8d1f160da4366ed04db054206403bc803
Diffstat (limited to 'simpleperf')
-rw-r--r--simpleperf/cmd_record.cpp3
-rw-r--r--simpleperf/cmd_report.cpp3
-rw-r--r--simpleperf/dwarf_unwind.cpp3
-rw-r--r--simpleperf/perf_regs.cpp30
-rw-r--r--simpleperf/perf_regs.h2
5 files changed, 38 insertions, 3 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 910bc3e9..f4bd64c2 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -688,7 +688,8 @@ void RecordCommand::UnwindRecord(Record* record) {
ThreadEntry* thread = thread_tree_.FindThreadOrNew(r.tid_data.pid, r.tid_data.tid);
RegSet regs = CreateRegSet(r.regs_user_data.reg_mask, r.regs_user_data.regs);
std::vector<char>& stack = r.stack_user_data.data;
- std::vector<uint64_t> unwind_ips = UnwindCallChain(GetBuildArch(), *thread, regs, stack);
+ ArchType arch = GetArchForAbi(GetBuildArch(), r.regs_user_data.abi);
+ std::vector<uint64_t> unwind_ips = UnwindCallChain(arch, *thread, regs, stack);
r.callchain_data.ips.push_back(PERF_CONTEXT_USER);
r.callchain_data.ips.insert(r.callchain_data.ips.end(), unwind_ips.begin(), unwind_ips.end());
r.regs_user_data.abi = 0;
diff --git a/simpleperf/cmd_report.cpp b/simpleperf/cmd_report.cpp
index 9f3e7362..d42bf694 100644
--- a/simpleperf/cmd_report.cpp
+++ b/simpleperf/cmd_report.cpp
@@ -568,8 +568,9 @@ void ReportCommand::ProcessSampleRecord(const SampleRecord& r) {
RegSet regs = CreateRegSet(r.regs_user_data.reg_mask, r.regs_user_data.regs);
std::vector<char> stack(r.stack_user_data.data.begin(),
r.stack_user_data.data.begin() + r.stack_user_data.data.size());
+ ArchType arch = GetArchForAbi(ScopedCurrentArch::GetCurrentArch(), r.regs_user_data.abi);
std::vector<uint64_t> unwind_ips =
- UnwindCallChain(ScopedCurrentArch::GetCurrentArch(), *sample->thread, regs, stack);
+ UnwindCallChain(arch, *sample->thread, regs, stack);
if (!unwind_ips.empty()) {
ips.push_back(PERF_CONTEXT_USER);
ips.insert(ips.end(), unwind_ips.begin(), unwind_ips.end());
diff --git a/simpleperf/dwarf_unwind.cpp b/simpleperf/dwarf_unwind.cpp
index ae2e1a1f..39bbef17 100644
--- a/simpleperf/dwarf_unwind.cpp
+++ b/simpleperf/dwarf_unwind.cpp
@@ -98,7 +98,8 @@ std::vector<uint64_t> UnwindCallChain(ArchType arch, const ThreadEntry& thread,
const RegSet& regs, const std::vector<char>& stack) {
std::vector<uint64_t> result;
if (arch != GetBuildArch()) {
- LOG(ERROR) << "can't unwind data recorded on a different architecture";
+ LOG(FATAL) << "simpleperf is built in arch " << GetArchString(GetBuildArch())
+ << ", and can't do stack unwinding for arch " << GetArchString(arch);
return result;
}
uint64_t sp_reg_value;
diff --git a/simpleperf/perf_regs.cpp b/simpleperf/perf_regs.cpp
index 29d144e7..5d43db56 100644
--- a/simpleperf/perf_regs.cpp
+++ b/simpleperf/perf_regs.cpp
@@ -21,6 +21,8 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include "perf_event.h"
+
ArchType ScopedCurrentArch::current_arch = GetBuildArch();
ArchType GetArchType(const std::string& arch) {
@@ -37,6 +39,34 @@ ArchType GetArchType(const std::string& arch) {
return ARCH_UNSUPPORTED;
}
+ArchType GetArchForAbi(ArchType machine_arch, int abi) {
+ if (abi == PERF_SAMPLE_REGS_ABI_32) {
+ if (machine_arch == ARCH_X86_64) {
+ return ARCH_X86_32;
+ }
+ if (machine_arch == ARCH_ARM64) {
+ return ARCH_ARM;
+ }
+ }
+ return machine_arch;
+}
+
+std::string GetArchString(ArchType arch) {
+ switch (arch) {
+ case ARCH_X86_32:
+ return "x86";
+ case ARCH_X86_64:
+ return "x86_64";
+ case ARCH_ARM64:
+ return "arm64";
+ case ARCH_ARM:
+ return "arm";
+ default:
+ break;
+ }
+ return "unknown";
+}
+
uint64_t GetSupportedRegMask(ArchType arch) {
switch (arch) {
case ARCH_X86_32:
diff --git a/simpleperf/perf_regs.h b/simpleperf/perf_regs.h
index 9fc610f8..98c925f9 100644
--- a/simpleperf/perf_regs.h
+++ b/simpleperf/perf_regs.h
@@ -56,6 +56,8 @@ constexpr ArchType GetBuildArch() {
}
ArchType GetArchType(const std::string& arch);
+ArchType GetArchForAbi(ArchType machine_arch, int abi);
+std::string GetArchString(ArchType arch);
uint64_t GetSupportedRegMask(ArchType arch);
std::string GetRegName(size_t regno, ArchType arch);