diff options
author | Yabin Cui <yabinc@google.com> | 2016-03-30 16:21:47 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2016-03-30 16:21:47 -0700 |
commit | 257d5e69967941de7c5516a476397450063b8c3d (patch) | |
tree | 5729b8ffc4e002d9a75d5e56c49495dd0fd814b9 /simpleperf | |
parent | 6dd31f4a3fda4dc6a49bcda1fb67052bc478c3fb (diff) | |
download | extras-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.cpp | 3 | ||||
-rw-r--r-- | simpleperf/cmd_report.cpp | 3 | ||||
-rw-r--r-- | simpleperf/dwarf_unwind.cpp | 3 | ||||
-rw-r--r-- | simpleperf/perf_regs.cpp | 30 | ||||
-rw-r--r-- | simpleperf/perf_regs.h | 2 |
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); |