#!/usr/bin/env python
#
# Copyright (C) 2016 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.
#

"""utils.py: export utility functions.
"""

from __future__ import print_function
import argparse
import logging
import os
import os.path
import re
import shutil
import subprocess
import sys
import time

def get_script_dir():
    return os.path.dirname(os.path.realpath(__file__))

def is_windows():
    return sys.platform == 'win32' or sys.platform == 'cygwin'

def is_darwin():
    return sys.platform == 'darwin'

def get_platform():
    if is_windows():
        return 'windows'
    if is_darwin():
        return 'darwin'
    return 'linux'

def is_python3():
    return sys.version_info >= (3, 0)


def log_debug(msg):
    logging.debug(msg)


def log_info(msg):
    logging.info(msg)


def log_warning(msg):
    logging.warning(msg)


def log_fatal(msg):
    raise Exception(msg)

def log_exit(msg):
    sys.exit(msg)

def disable_debug_log():
    logging.getLogger().setLevel(logging.WARN)

def str_to_bytes(str_value):
    if not is_python3():
        return str_value
    # In python 3, str are wide strings whereas the C api expects 8 bit strings,
    # hence we have to convert. For now using utf-8 as the encoding.
    return str_value.encode('utf-8')

def bytes_to_str(bytes_value):
    if not bytes_value:
        return ''
    if not is_python3():
        return bytes_value
    return bytes_value.decode('utf-8')

def get_target_binary_path(arch, binary_name):
    if arch == 'aarch64':
        arch = 'arm64'
    arch_dir = os.path.join(get_script_dir(), "bin", "android", arch)
    if not os.path.isdir(arch_dir):
        log_fatal("can't find arch directory: %s" % arch_dir)
    binary_path = os.path.join(arch_dir, binary_name)
    if not os.path.isfile(binary_path):
        log_fatal("can't find binary: %s" % binary_path)
    return binary_path


def get_host_binary_path(binary_name):
    dirname = os.path.join(get_script_dir(), 'bin')
    if is_windows():
        if binary_name.endswith('.so'):
            binary_name = binary_name[0:-3] + '.dll'
        elif '.' not in binary_name:
            binary_name += '.exe'
        dirname = os.path.join(dirname, 'windows')
    elif sys.platform == 'darwin': # OSX
        if binary_name.endswith('.so'):
            binary_name = binary_name[0:-3] + '.dylib'
        dirname = os.path.join(dirname, 'darwin')
    else:
        dirname = os.path.join(dirname, 'linux')
    dirname = os.path.join(dirname, 'x86_64' if sys.maxsize > 2 ** 32 else 'x86')
    binary_path = os.path.join(dirname, binary_name)
    if not os.path.isfile(binary_path):
        log_fatal("can't find binary: %s" % binary_path)
    return binary_path


def is_executable_available(executable, option='--help'):
    """ Run an executable to see if it exists. """
    try:
        subproc = subprocess.Popen([executable, option], stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        subproc.communicate()
        return subproc.returncode == 0
    except OSError:
        return False

DEFAULT_NDK_PATH = {
    'darwin': 'Library/Android/sdk/ndk-bundle',
    'linux': 'Android/Sdk/ndk-bundle',
    'windows': 'AppData/Local/Android/sdk/ndk-bundle',
}

EXPECTED_TOOLS = {
    'adb': {
        'is_binutils': False,
        'test_option': 'version',
        'path_in_ndk': '../platform-tools/adb',
    },
    'readelf': {
        'is_binutils': True,
        'accept_tool_without_arch': True,
    },
    'addr2line': {
        'is_binutils': True,
        'accept_tool_without_arch': True
    },
    'objdump': {
        'is_binutils': True,
    },
    'strip': {
        'is_binutils': True,
    },
}

def _get_binutils_path_in_ndk(toolname, arch, platform):
    if not arch:
        arch = 'arm64'
    if arch == 'arm64':
        name = 'aarch64-linux-android-' + toolname
        path = 'toolchains/aarch64-linux-android-4.9/prebuilt/%s-x86_64/bin/%s' % (platform, name)
    elif arch == 'arm':
        name = 'arm-linux-androideabi-' + toolname
        path = 'toolchains/arm-linux-androideabi-4.9/prebuilt/%s-x86_64/bin/%s' % (platform, name)
    elif arch == 'x86_64':
        name = 'x86_64-linux-android-' + toolname
        path = 'toolchains/x86_64-4.9/prebuilt/%s-x86_64/bin/%s' % (platform, name)
    elif arch == 'x86':
        name = 'i686-linux-android-' + toolname
        path = 'toolchains/x86-4.9/prebuilt/%s-x86_64/bin/%s' % (platform, name)
    else:
        log_fatal('unexpected arch %s' % arch)
    return (name, path)

def find_tool_path(toolname, ndk_path=None, arch=None):
    if toolname not in EXPECTED_TOOLS:
        return None
    tool_info = EXPECTED_TOOLS[toolname]
    is_binutils = tool_info['is_binutils']
    test_option = tool_info.get('test_option', '--help')
    platform = get_platform()
    if is_binutils:
        toolname_with_arch, path_in_ndk = _get_binutils_path_in_ndk(toolname, arch, platform)
    else:
        toolname_with_arch = toolname
        path_in_ndk = tool_info['path_in_ndk']
    path_in_ndk = path_in_ndk.replace('/', os.sep)

    # 1. Find tool in the given ndk path.
    if ndk_path:
        path = os.path.join(ndk_path, path_in_ndk)
        if is_executable_available(path, test_option):
            return path

    # 2. Find tool in the ndk directory containing simpleperf scripts.
    path = os.path.join('..', path_in_ndk)
    if is_executable_available(path, test_option):
        return path

    # 3. Find tool in the default ndk installation path.
    home = os.environ.get('HOMEPATH') if is_windows() else os.environ.get('HOME')
    if home:
        default_ndk_path = os.path.join(home, DEFAULT_NDK_PATH[platform].replace('/', os.sep))
        path = os.path.join(default_ndk_path, path_in_ndk)
        if is_executable_available(path, test_option):
            return path

    # 4. Find tool in $PATH.
    if is_executable_available(toolname_with_arch, test_option):
        return toolname_with_arch

    # 5. Find tool without arch in $PATH.
    if is_binutils and tool_info.get('accept_tool_without_arch'):
        if is_executable_available(toolname, test_option):
            return toolname
    return None


class AdbHelper(object):
    def __init__(self, enable_switch_to_root=True):
        adb_path = find_tool_path('adb')
        if not adb_path:
            log_exit("Can't find adb in PATH environment.")
        self.adb_path = adb_path
        self.enable_switch_to_root = enable_switch_to_root


    def run(self, adb_args):
        return self.run_and_return_output(adb_args)[0]


    def run_and_return_output(self, adb_args, stdout_file=None, log_output=True):
        adb_args = [self.adb_path] + adb_args
        log_debug('run adb cmd: %s' % adb_args)
        if stdout_file:
            with open(stdout_file, 'wb') as stdout_fh:
                returncode = subprocess.call(adb_args, stdout=stdout_fh)
            stdoutdata = ''
        else:
            subproc = subprocess.Popen(adb_args, stdout=subprocess.PIPE)
            (stdoutdata, _) = subproc.communicate()
            stdoutdata = bytes_to_str(stdoutdata)
            returncode = subproc.returncode
        result = (returncode == 0)
        if stdoutdata and adb_args[1] != 'push' and adb_args[1] != 'pull':
            if log_output:
                log_debug(stdoutdata)
        log_debug('run adb cmd: %s  [result %s]' % (adb_args, result))
        return (result, stdoutdata)

    def check_run(self, adb_args):
        self.check_run_and_return_output(adb_args)


    def check_run_and_return_output(self, adb_args, stdout_file=None, log_output=True):
        result, stdoutdata = self.run_and_return_output(adb_args, stdout_file, log_output)
        if not result:
            log_exit('run "adb %s" failed' % adb_args)
        return stdoutdata


    def _unroot(self):
        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
        if not result:
            return
        if 'root' not in stdoutdata:
            return
        log_info('unroot adb')
        self.run(['unroot'])
        self.run(['wait-for-device'])
        time.sleep(1)


    def switch_to_root(self):
        if not self.enable_switch_to_root:
            self._unroot()
            return False
        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
        if not result:
            return False
        if 'root' in stdoutdata:
            return True
        build_type = self.get_property('ro.build.type')
        if build_type == 'user':
            return False
        self.run(['root'])
        time.sleep(1)
        self.run(['wait-for-device'])
        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
        return result and 'root' in stdoutdata

    def get_property(self, name):
        result, stdoutdata = self.run_and_return_output(['shell', 'getprop', name])
        return stdoutdata if result else None

    def set_property(self, name, value):
        return self.run(['shell', 'setprop', name, value])


    def get_device_arch(self):
        output = self.check_run_and_return_output(['shell', 'uname', '-m'])
        if 'aarch64' in output:
            return 'arm64'
        if 'arm' in output:
            return 'arm'
        if 'x86_64' in output:
            return 'x86_64'
        if '86' in output:
            return 'x86'
        log_fatal('unsupported architecture: %s' % output.strip())
        return ''


    def get_android_version(self):
        build_version = self.get_property('ro.build.version.release')
        android_version = 0
        if build_version:
            if not build_version[0].isdigit():
                c = build_version[0].upper()
                if c.isupper() and c >= 'L':
                    android_version = ord(c) - ord('L') + 5
            else:
                strs = build_version.split('.')
                if strs:
                    android_version = int(strs[0])
        return android_version


def flatten_arg_list(arg_list):
    res = []
    if arg_list:
        for items in arg_list:
            res += items
    return res


def remove(dir_or_file):
    if os.path.isfile(dir_or_file):
        os.remove(dir_or_file)
    elif os.path.isdir(dir_or_file):
        shutil.rmtree(dir_or_file, ignore_errors=True)


def open_report_in_browser(report_path):
    if is_darwin():
        # On darwin 10.12.6, webbrowser can't open browser, so try `open` cmd first.
        try:
            subprocess.check_call(['open', report_path])
            return
        except subprocess.CalledProcessError:
            pass
    import webbrowser
    try:
        # Try to open the report with Chrome
        browser = webbrowser.get('google-chrome')
        browser.open(report_path, new=0, autoraise=True)
    except webbrowser.Error:
        # webbrowser.get() doesn't work well on darwin/windows.
        webbrowser.open_new_tab(report_path)

def is_elf_file(path):
    if os.path.isfile(path):
        with open(path, 'rb') as fh:
            data = fh.read(4)
            if len(data) == 4 and bytes_to_str(data) == '\x7fELF':
                return True
    return False

def find_real_dso_path(dso_path_in_record_file, binary_cache_path):
    """ Given the path of a shared library in perf.data, find its real path in the file system. """
    if dso_path_in_record_file[0] != '/' or dso_path_in_record_file == '//anon':
        return None
    if binary_cache_path:
        tmp_path = os.path.join(binary_cache_path, dso_path_in_record_file[1:])
        if is_elf_file(tmp_path):
            return tmp_path
    if is_elf_file(dso_path_in_record_file):
        return dso_path_in_record_file
    return None


class Addr2Nearestline(object):
    """ Use addr2line to convert (dso_path, func_addr, addr) to (source_file, line) pairs.
        For instructions generated by C++ compilers without a matching statement in source code
        (like stack corruption check, switch optimization, etc.), addr2line can't generate
        line information. However, we want to assign the instruction to the nearest line before
        the instruction (just like objdump -dl). So we use below strategy:
        Instead of finding the exact line of the instruction in an address, we find the nearest
        line to the instruction in an address. If an address doesn't have a line info, we find
        the line info of address - 1. If still no line info, then use address - 2, address - 3,
        etc.

        The implementation steps are as below:
        1. Collect all (dso_path, func_addr, addr) requests before converting. This saves the
        times to call addr2line.
        2. Convert addrs to (source_file, line) pairs for each dso_path as below:
          2.1 Check if the dso_path has .debug_line. If not, omit its conversion.
          2.2 Get arch of the dso_path, and decide the addr_step for it. addr_step is the step we
          change addr each time. For example, since instructions of arm64 are all 4 bytes long,
          addr_step for arm64 can be 4.
          2.3 Use addr2line to find line info for each addr in the dso_path.
          2.4 For each addr without line info, use addr2line to find line info for
              range(addr - addr_step, addr - addr_step * 4 - 1, -addr_step).
          2.5 For each addr without line info, use addr2line to find line info for
              range(addr - addr_step * 5, addr - addr_step * 128 - 1, -addr_step).
              (128 is a guess number. A nested switch statement in
               system/core/demangle/Demangler.cpp has >300 bytes without line info in arm64.)
    """
    class Dso(object):
        """ Info of a dynamic shared library.
            addrs: a map from address to Addr object in this dso.
        """
        def __init__(self):
            self.addrs = {}

    class Addr(object):
        """ Info of an addr request.
            func_addr: start_addr of the function containing addr.
            source_lines: a list of [file_id, line_number] for addr.
                          source_lines[:-1] are all for inlined functions.
        """
        def __init__(self, func_addr):
            self.func_addr = func_addr
            self.source_lines = None

    def __init__(self, ndk_path, binary_cache_path, with_function_name):
        self.addr2line_path = find_tool_path('addr2line', ndk_path)
        if not self.addr2line_path:
            log_exit("Can't find addr2line. Please set ndk path with --ndk_path option.")
        self.readelf = ReadElf(ndk_path)
        self.dso_map = {}  # map from dso_path to Dso.
        self.binary_cache_path = binary_cache_path
        self.with_function_name = with_function_name
        # Saving file names for each addr takes a lot of memory. So we store file ids in Addr,
        # and provide data structures connecting file id and file name here.
        self.file_name_to_id = {}
        self.file_id_to_name = []
        self.func_name_to_id = {}
        self.func_id_to_name = []

    def add_addr(self, dso_path, func_addr, addr):
        dso = self.dso_map.get(dso_path)
        if dso is None:
            dso = self.dso_map[dso_path] = self.Dso()
        if addr not in dso.addrs:
            dso.addrs[addr] = self.Addr(func_addr)

    def convert_addrs_to_lines(self):
        for dso_path in self.dso_map:
            self._convert_addrs_in_one_dso(dso_path, self.dso_map[dso_path])

    def _convert_addrs_in_one_dso(self, dso_path, dso):
        real_path = find_real_dso_path(dso_path, self.binary_cache_path)
        if not real_path:
            if dso_path not in ['//anon', 'unknown', '[kernel.kallsyms]']:
                log_debug("Can't find dso %s" % dso_path)
            return

        if not self._check_debug_line_section(real_path):
            log_debug("file %s doesn't contain .debug_line section." % real_path)
            return

        addr_step = self._get_addr_step(real_path)
        self._collect_line_info(dso, real_path, [0])
        self._collect_line_info(dso, real_path, range(-addr_step, -addr_step * 4 - 1, -addr_step))
        self._collect_line_info(dso, real_path,
                                range(-addr_step * 5, -addr_step * 128 - 1, -addr_step))

    def _check_debug_line_section(self, real_path):
        return '.debug_line' in self.readelf.get_sections(real_path)

    def _get_addr_step(self, real_path):
        arch = self.readelf.get_arch(real_path)
        if arch == 'arm64':
            return 4
        if arch == 'arm':
            return 2
        return 1

    def _collect_line_info(self, dso, real_path, addr_shifts):
        """ Use addr2line to get line info in a dso, with given addr shifts. """
        # 1. Collect addrs to send to addr2line.
        addr_set = set()
        for addr in dso.addrs:
            addr_obj = dso.addrs[addr]
            if addr_obj.source_lines:  # already has source line, no need to search.
                continue
            for shift in addr_shifts:
                # The addr after shift shouldn't change to another function.
                shifted_addr = max(addr + shift, addr_obj.func_addr)
                addr_set.add(shifted_addr)
                if shifted_addr == addr_obj.func_addr:
                    break
        if not addr_set:
            return
        addr_request = '\n'.join(['%x' % addr for addr in sorted(addr_set)])

        # 2. Use addr2line to collect line info.
        try:
            option = '-ai' + ('fC' if self.with_function_name else '')
            subproc = subprocess.Popen([self.addr2line_path, option, '-e', real_path],
                                       stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            (stdoutdata, _) = subproc.communicate(str_to_bytes(addr_request))
            stdoutdata = bytes_to_str(stdoutdata)
        except OSError:
            return
        addr_map = {}
        cur_line_list = None
        need_function_name = self.with_function_name
        cur_function_name = None
        for line in stdoutdata.strip().split('\n'):
            if line[:2] == '0x':
                # a new address
                cur_line_list = addr_map[int(line, 16)] = []
            elif need_function_name:
                cur_function_name = line.strip()
                need_function_name = False
            else:
                need_function_name = self.with_function_name
                # a file:line.
                if cur_line_list is None:
                    continue
                # Handle lines like "C:\Users\...\file:32".
                items = line.rsplit(':', 1)
                if len(items) != 2:
                    continue
                if '?' in line:
                    # if ? in line, it doesn't have a valid line info.
                    # An addr can have a list of (file, line), when the addr belongs to an inlined
                    # function. Sometimes only part of the list has ? mark. In this case, we think
                    # the line info is valid if the first line doesn't have ? mark.
                    if not cur_line_list:
                        cur_line_list = None
                    continue
                (file_path, line_number) = items
                line_number = line_number.split()[0]  # Remove comments after line number
                try:
                    line_number = int(line_number)
                except ValueError:
                    continue
                file_id = self._get_file_id(file_path)
                if self.with_function_name:
                    func_id = self._get_func_id(cur_function_name)
                    cur_line_list.append((file_id, line_number, func_id))
                else:
                    cur_line_list.append((file_id, line_number))

        # 3. Fill line info in dso.addrs.
        for addr in dso.addrs:
            addr_obj = dso.addrs[addr]
            if addr_obj.source_lines:
                continue
            for shift in addr_shifts:
                shifted_addr = max(addr + shift, addr_obj.func_addr)
                lines = addr_map.get(shifted_addr)
                if lines:
                    addr_obj.source_lines = lines
                    break
                if shifted_addr == addr_obj.func_addr:
                    break

    def _get_file_id(self, file_path):
        file_id = self.file_name_to_id.get(file_path)
        if file_id is None:
            file_id = self.file_name_to_id[file_path] = len(self.file_id_to_name)
            self.file_id_to_name.append(file_path)
        return file_id

    def _get_func_id(self, func_name):
        func_id = self.func_name_to_id.get(func_name)
        if func_id is None:
            func_id = self.func_name_to_id[func_name] = len(self.func_id_to_name)
            self.func_id_to_name.append(func_name)
        return func_id

    def get_dso(self, dso_path):
        return self.dso_map.get(dso_path)

    def get_addr_source(self, dso, addr):
        source = dso.addrs[addr].source_lines
        if source is None:
            return None
        if self.with_function_name:
            return [(self.file_id_to_name[file_id], line, self.func_id_to_name[func_id])
                    for (file_id, line, func_id) in source]
        return [(self.file_id_to_name[file_id], line) for (file_id, line) in source]


class SourceFileSearcher(object):
    """ Find source file paths in the file system.
        The file paths reported by addr2line are the paths stored in debug sections
        of shared libraries. And we need to convert them to file paths in the file
        system. It is done in below steps:
        1. Collect all file paths under the provided source_dirs. The suffix of a
           source file should contain one of below:
            h: for C/C++ header files.
            c: for C/C++ source files.
            java: for Java source files.
            kt: for Kotlin source files.
        2. Given an abstract_path reported by addr2line, select the best real path
           as below:
           2.1 Find all real paths with the same file name as the abstract path.
           2.2 Select the real path having the longest common suffix with the abstract path.
    """

    SOURCE_FILE_EXTS = {'.h', '.hh', '.H', '.hxx', '.hpp', '.h++',
                        '.c', '.cc', '.C', '.cxx', '.cpp', '.c++',
                        '.java', '.kt'}

    @classmethod
    def is_source_filename(cls, filename):
        ext = os.path.splitext(filename)[1]
        return ext in cls.SOURCE_FILE_EXTS

    def __init__(self, source_dirs):
        # Map from filename to a list of reversed directory path containing filename.
        self.filename_to_rparents = {}
        self._collect_paths(source_dirs)

    def _collect_paths(self, source_dirs):
        for source_dir in source_dirs:
            for parent, _, file_names in os.walk(source_dir):
                rparent = None
                for file_name in file_names:
                    if self.is_source_filename(file_name):
                        rparents = self.filename_to_rparents.get(file_name)
                        if rparents is None:
                            rparents = self.filename_to_rparents[file_name] = []
                        if rparent is None:
                            rparent = parent[::-1]
                        rparents.append(rparent)

    def get_real_path(self, abstract_path):
        abstract_path = abstract_path.replace('/', os.sep)
        abstract_parent, file_name = os.path.split(abstract_path)
        abstract_rparent = abstract_parent[::-1]
        real_rparents = self.filename_to_rparents.get(file_name)
        if real_rparents is None:
            return None
        best_matched_rparent = None
        best_common_length = -1
        for real_rparent in real_rparents:
            length = len(os.path.commonprefix((real_rparent, abstract_rparent)))
            if length > best_common_length:
                best_common_length = length
                best_matched_rparent = real_rparent
        if best_matched_rparent is None:
            return None
        return os.path.join(best_matched_rparent[::-1], file_name)


class Objdump(object):
    """ A wrapper of objdump to disassemble code. """
    def __init__(self, ndk_path, binary_cache_path):
        self.ndk_path = ndk_path
        self.binary_cache_path = binary_cache_path
        self.readelf = ReadElf(ndk_path)
        self.objdump_paths = {}

    def get_dso_info(self, dso_path):
        real_path = find_real_dso_path(dso_path, self.binary_cache_path)
        if not real_path:
            return None
        arch = self.readelf.get_arch(real_path)
        if arch == 'unknown':
            return None
        return (real_path, arch)

    def disassemble_code(self, dso_info, start_addr, addr_len):
        """ Disassemble [start_addr, start_addr + addr_len] of dso_path.
            Return a list of pair (disassemble_code_line, addr).
        """
        real_path, arch = dso_info
        objdump_path = self.objdump_paths.get(arch)
        if not objdump_path:
            objdump_path = find_tool_path('objdump', self.ndk_path, arch)
            if not objdump_path:
                log_exit("Can't find objdump. Please set ndk path with --ndk_path option.")
            self.objdump_paths[arch] = objdump_path

        # 3. Run objdump.
        args = [objdump_path, '-dlC', '--no-show-raw-insn',
                '--start-address=0x%x' % start_addr,
                '--stop-address=0x%x' % (start_addr + addr_len),
                real_path]
        try:
            subproc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            (stdoutdata, _) = subproc.communicate()
            stdoutdata = bytes_to_str(stdoutdata)
        except OSError:
            return None

        if not stdoutdata:
            return None
        result = []
        for line in stdoutdata.split('\n'):
            line = line.rstrip()  # Remove '\r' on Windows.
            items = line.split(':', 1)
            try:
                addr = int(items[0], 16)
            except ValueError:
                addr = 0
            result.append((line, addr))
        return result


class ReadElf(object):
    """ A wrapper of readelf. """
    def __init__(self, ndk_path):
        self.readelf_path = find_tool_path('readelf', ndk_path)
        if not self.readelf_path:
            log_exit("Can't find readelf. Please set ndk path with --ndk_path option.")

    def get_arch(self, elf_file_path):
        """ Get arch of an elf file. """
        if is_elf_file(elf_file_path):
            try:
                output = subprocess.check_output([self.readelf_path, '-h', elf_file_path])
                output = bytes_to_str(output)
                if output.find('AArch64') != -1:
                    return 'arm64'
                if output.find('ARM') != -1:
                    return 'arm'
                if output.find('X86-64') != -1:
                    return 'x86_64'
                if output.find('80386') != -1:
                    return 'x86'
            except subprocess.CalledProcessError:
                pass
        return 'unknown'

    def get_build_id(self, elf_file_path):
        """ Get build id of an elf file. """
        if is_elf_file(elf_file_path):
            try:
                output = subprocess.check_output([self.readelf_path, '-n', elf_file_path])
                output = bytes_to_str(output)
                result = re.search(r'Build ID:\s*(\S+)', output)
                if result:
                    build_id = result.group(1)
                    if len(build_id) < 40:
                        build_id += '0' * (40 - len(build_id))
                    else:
                        build_id = build_id[:40]
                    build_id = '0x' + build_id
                    return build_id
            except subprocess.CalledProcessError:
                pass
        return ""

    def get_sections(self, elf_file_path):
        """ Get sections of an elf file. """
        section_names = []
        if is_elf_file(elf_file_path):
            try:
                output = subprocess.check_output([self.readelf_path, '-SW', elf_file_path])
                output = bytes_to_str(output)
                for line in output.split('\n'):
                    # Parse line like:" [ 1] .note.android.ident NOTE  0000000000400190 ...".
                    result = re.search(r'^\s+\[\s*\d+\]\s(.+?)\s', line)
                    if result:
                        section_name = result.group(1).strip()
                        if section_name:
                            section_names.append(section_name)
            except subprocess.CalledProcessError:
                pass
        return section_names

def extant_dir(arg):
    """ArgumentParser type that only accepts extant directories.

    Args:
        arg: The string argument given on the command line.
    Returns: The argument as a realpath.
    Raises:
        argparse.ArgumentTypeError: The given path isn't a directory.
    """
    path = os.path.realpath(arg)
    if not os.path.isdir(path):
        raise argparse.ArgumentTypeError('{} is not a directory.'.format(path))
    return path

def extant_file(arg):
    """ArgumentParser type that only accepts extant files.

    Args:
        arg: The string argument given on the command line.
    Returns: The argument as a realpath.
    Raises:
        argparse.ArgumentTypeError: The given path isn't a file.
    """
    path = os.path.realpath(arg)
    if not os.path.isfile(path):
        raise argparse.ArgumentTypeError('{} is not a file.'.format(path))
    return path

logging.getLogger().setLevel(logging.DEBUG)
