diff options
Diffstat (limited to 'simpleperf')
-rw-r--r-- | simpleperf/Android.bp | 1 | ||||
-rw-r--r-- | simpleperf/environment.cpp | 12 | ||||
-rw-r--r-- | simpleperf/perf_regs.cpp | 11 | ||||
-rw-r--r-- | simpleperf/perf_regs.h | 4 | ||||
-rw-r--r-- | simpleperf/perf_regs_test.cpp | 35 |
5 files changed, 56 insertions, 7 deletions
diff --git a/simpleperf/Android.bp b/simpleperf/Android.bp index 6fa14fdd..de729837 100644 --- a/simpleperf/Android.bp +++ b/simpleperf/Android.bp @@ -488,6 +488,7 @@ cc_defaults { "dso_test.cpp", "gtest_main.cpp", "kallsyms_test.cpp", + "perf_regs_test.cpp", "read_apk_test.cpp", "read_elf_test.cpp", "read_symbol_map_test.cpp", diff --git a/simpleperf/environment.cpp b/simpleperf/environment.cpp index 44beee70..e373871c 100644 --- a/simpleperf/environment.cpp +++ b/simpleperf/environment.cpp @@ -405,12 +405,24 @@ bool SetPerfEventMlockKb(uint64_t mlock_kb) { } ArchType GetMachineArch() { +#if defined(__i386__) + // For 32 bit x86 build, we can't get machine arch by uname(). + ArchType arch = ARCH_UNSUPPORTED; + std::unique_ptr<FILE, decltype(&pclose)> fp(popen("uname -m", "re"), pclose); + if (fp) { + char machine[40]; + if (fgets(machine, sizeof(machine), fp.get()) == machine) { + arch = GetArchType(android::base::Trim(machine)); + } + } +#else utsname uname_buf; if (TEMP_FAILURE_RETRY(uname(&uname_buf)) != 0) { PLOG(WARNING) << "uname() failed"; return GetBuildArch(); } ArchType arch = GetArchType(uname_buf.machine); +#endif if (arch != ARCH_UNSUPPORTED) { return arch; } diff --git a/simpleperf/perf_regs.cpp b/simpleperf/perf_regs.cpp index 3abf591d..114cb16c 100644 --- a/simpleperf/perf_regs.cpp +++ b/simpleperf/perf_regs.cpp @@ -26,7 +26,6 @@ #include "perf_event.h" ArchType ScopedCurrentArch::current_arch = ARCH_UNSUPPORTED; -ArchType ScopedCurrentArch::current_arch32 = ARCH_UNSUPPORTED; ArchType GetArchType(const std::string& arch) { if (arch == "x86" || arch == "i686") { @@ -59,6 +58,13 @@ ArchType GetArchForAbi(ArchType machine_arch, int abi) { if (machine_arch == ARCH_ARM64) { return ARCH_ARM; } + } else if (abi == PERF_SAMPLE_REGS_ABI_64) { + if (machine_arch == ARCH_X86_32) { + return ARCH_X86_64; + } + if (machine_arch == ARCH_ARM) { + return ARCH_ARM64; + } } return machine_arch; } @@ -154,8 +160,7 @@ std::string GetRegName(size_t regno, ArchType arch) { } RegSet::RegSet(int abi, uint64_t valid_mask, const uint64_t* valid_regs) : valid_mask(valid_mask) { - arch = (abi == PERF_SAMPLE_REGS_ABI_32) ? ScopedCurrentArch::GetCurrentArch32() - : ScopedCurrentArch::GetCurrentArch(); + arch = GetArchForAbi(ScopedCurrentArch::GetCurrentArch(), abi); memset(data, 0, sizeof(data)); for (int i = 0, j = 0; i < 64; ++i) { if ((valid_mask >> i) & 1) { diff --git a/simpleperf/perf_regs.h b/simpleperf/perf_regs.h index 8ebbf04d..f5b30aa0 100644 --- a/simpleperf/perf_regs.h +++ b/simpleperf/perf_regs.h @@ -67,19 +67,15 @@ class ScopedCurrentArch { public: explicit ScopedCurrentArch(ArchType arch) : saved_arch(current_arch) { current_arch = arch; - current_arch32 = GetArchForAbi(arch, PERF_SAMPLE_REGS_ABI_32); } ~ScopedCurrentArch() { current_arch = saved_arch; - current_arch32 = GetArchForAbi(saved_arch, PERF_SAMPLE_REGS_ABI_32); } static ArchType GetCurrentArch() { return current_arch; } - static ArchType GetCurrentArch32() { return current_arch32; } private: ArchType saved_arch; static ArchType current_arch; - static ArchType current_arch32; }; struct RegSet { diff --git a/simpleperf/perf_regs_test.cpp b/simpleperf/perf_regs_test.cpp new file mode 100644 index 00000000..c0977b29 --- /dev/null +++ b/simpleperf/perf_regs_test.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "perf_regs.h" + +#include <gtest/gtest.h> + +TEST(RegSet, arch) { + ArchType arch_pairs[2][2] = { + {ARCH_X86_32, ARCH_X86_64}, + {ARCH_ARM, ARCH_ARM64}, + }; + for (ArchType* arch_pair : arch_pairs) { + for (size_t i = 0; i < 2; i++) { + ScopedCurrentArch scoped_arch(arch_pair[i]); + RegSet reg32(PERF_SAMPLE_REGS_ABI_32, 0, nullptr); + ASSERT_EQ(reg32.arch, arch_pair[0]) << i; + RegSet reg64(PERF_SAMPLE_REGS_ABI_64, 0, nullptr); + ASSERT_EQ(reg64.arch, arch_pair[1]) << i; + } + } +} |