Index: tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper.py |
diff --git a/tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper.py b/tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper.py |
index b746251b6b81c4b8b9c84f2ebd93607fa0d236b9..f2e21440385eb434bb870307841356d9be3dcbbc 100644 |
--- a/tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper.py |
+++ b/tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper.py |
@@ -6,16 +6,27 @@ import glob |
import hashlib |
import logging |
import os |
+import platform |
import re |
import shutil |
import subprocess |
+from telemetry.core import util |
from telemetry.core.platform.profiler import android_prebuilt_profiler_helper |
_TEXT_SECTION = '.text' |
+def _ElfMachineId(elf_file): |
+ headers = subprocess.check_output(['readelf', '-h', elf_file]) |
+ return re.match(r'.*Machine:\s+(\w+)', headers, re.DOTALL).group(1) |
+ |
+ |
+def _ElfSectionAsString(elf_file, section): |
+ return subprocess.check_output(['readelf', '-p', section, elf_file]) |
+ |
+ |
def _ElfSectionMd5Sum(elf_file, section): |
result = subprocess.check_output( |
'readelf -p%s "%s" | md5sum' % (section, elf_file), shell=True) |
@@ -23,20 +34,27 @@ def _ElfSectionMd5Sum(elf_file, section): |
def _FindMatchingUnstrippedLibraryOnHost(device, lib): |
- out_path = os.path.join(os.environ.get('CHROMIUM_OUT_DIR', 'out'), 'Release') |
lib_base = os.path.basename(lib) |
device_md5 = device.old_interface.RunShellCommandWithSU('md5 "%s"' % lib)[0] |
device_md5 = device_md5.split(' ', 1)[0] |
- # First find a matching stripped library on the host. This avoids the need to |
- # pull the stripped library from the device, which can take tens of seconds. |
- host_lib_pattern = os.path.join(out_path, '*_apk', 'libs', '*', lib_base) |
- for stripped_host_lib in glob.glob(host_lib_pattern): |
- with open(stripped_host_lib) as f: |
- host_md5 = hashlib.md5(f.read()).hexdigest() |
- if host_md5 == device_md5: |
- break |
+ def FindMatchingStrippedLibrary(out_path): |
+ # First find a matching stripped library on the host. This avoids the need |
+ # to pull the stripped library from the device, which can take tens of |
+ # seconds. |
+ host_lib_pattern = os.path.join(out_path, '*_apk', 'libs', '*', lib_base) |
+ for stripped_host_lib in glob.glob(host_lib_pattern): |
+ with open(stripped_host_lib) as f: |
+ host_md5 = hashlib.md5(f.read()).hexdigest() |
+ if host_md5 == device_md5: |
+ return stripped_host_lib |
+ |
+ for build_dir, build_type in util.GetBuildDirectories(): |
+ out_path = os.path.join(build_dir, build_type) |
+ stripped_host_lib = FindMatchingStrippedLibrary(out_path) |
+ if stripped_host_lib: |
+ break |
else: |
return None |
@@ -176,3 +194,41 @@ def PrepareDeviceForPerf(device): |
device.old_interface.SetProtectedFileContents( |
'/proc/sys/kernel/kptr_restrict', '0') |
return android_prebuilt_profiler_helper.GetDevicePath('perf') |
+ |
+ |
+def GetToolchainBinaryPath(library_file, binary_name): |
+ """Return the path to an Android toolchain binary on the host. |
+ |
+ Args: |
+ library_file: ELF library which is used to identify the used ABI, |
+ architecture and toolchain. |
+ binary_name: Binary to search for, e.g., 'objdump' |
+ Returns: |
+ Full path to binary or None if the binary was not found. |
+ """ |
+ # Mapping from ELF machine identifiers to GNU toolchain names. |
+ toolchain_configs = { |
+ 'x86': 'i686-linux-android', |
+ 'MIPS': 'mipsel-linux-android', |
+ 'ARM': 'arm-linux-androideabi', |
+ 'x86-64': 'x86_64-linux-android', |
+ 'AArch64': 'aarch64-linux-android', |
+ } |
+ toolchain_config = toolchain_configs[_ElfMachineId(library_file)] |
+ host_os = platform.uname()[0].lower() |
+ host_machine = platform.uname()[4] |
+ |
+ elf_comment = _ElfSectionAsString(library_file, '.comment') |
+ toolchain_version = re.match(r'.*GCC: \(GNU\) ([\w.]+)', |
+ elf_comment, re.DOTALL) |
+ if not toolchain_version: |
+ return None |
+ toolchain_version = toolchain_version.group(1) |
+ |
+ path = os.path.join(util.GetChromiumSrcDir(), 'third_party', 'android_tools', |
+ 'ndk', 'toolchains', |
+ '%s-%s' % (toolchain_config, toolchain_version), |
+ 'prebuilt', '%s-%s' % (host_os, host_machine), 'bin', |
+ '%s-%s' % (toolchain_config, binary_name)) |
+ path = os.path.abspath(path) |
+ return path if os.path.exists(path) else None |