#!/usr/bin/env python
#===- lib/asan/scripts/asan_symbolize.py -----------------------------------===#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
#===------------------------------------------------------------------------===#
"""
Example of use:
  asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" -s "$HOME/SymbolFiles" < asan.log

PLUGINS

This script provides a way for external plug-ins to hook into the behaviour of
various parts of this script (see `--plugins`). This is useful for situations
where it is necessary to handle site-specific quirks (e.g. binaries with debug
symbols only accessible via a remote service) without having to modify the
script itself.
  
"""
import argparse
import bisect
import errno
import getopt
import logging
import os
import re
import subprocess
import sys
from distutils.spawn import find_executable

symbolizers = {}
demangle = False
binutils_prefix = None
fix_filename_patterns = None
logfile = sys.stdin
allow_system_symbolizer = True
force_system_symbolizer = False

# FIXME: merge the code that calls fix_filename().
def fix_filename(file_name):
  if fix_filename_patterns:
    for path_to_cut in fix_filename_patterns:
      file_name = re.sub('.*' + path_to_cut, '', file_name)
  file_name = re.sub('.*asan_[a-z_]*.(cc|cpp):[0-9]*', '_asan_rtl_', file_name)
  file_name = re.sub('.*crtstuff.c:0', '???:0', file_name)
  return file_name

def is_valid_arch(s):
  return s in ["i386", "x86_64", "x86_64h", "arm", "armv6", "armv7", "armv7s",
               "armv7k", "arm64", "powerpc64", "powerpc64le", "s390x", "s390"]

def guess_arch(addr):
  # Guess which arch we're running. 10 = len('0x') + 8 hex digits.
  if len(addr) > 10:
    return 'x86_64'
  else:
    return 'i386'

class Symbolizer(object):
  def __init__(self):
    pass

  def symbolize(self, addr, binary, offset):
    """Symbolize the given address (pair of binary and offset).

    Overriden in subclasses.
    Args:
        addr: virtual address of an instruction.
        binary: path to executable/shared object containing this instruction.
        offset: instruction offset in the @binary.
    Returns:
        list of strings (one string for each inlined frame) describing
        the code locations for this instruction (that is, function name, file
        name, line and column numbers).
    """
    return None


class LLVMSymbolizer(Symbolizer):
  def __init__(self, symbolizer_path, default_arch, system, dsym_hints=[]):
    super(LLVMSymbolizer, self).__init__()
    self.symbolizer_path = symbolizer_path
    self.default_arch = default_arch
    self.system = system
    self.dsym_hints = dsym_hints
    self.pipe = self.open_llvm_symbolizer()

  def open_llvm_symbolizer(self):
    cmd = [self.symbolizer_path,
           '--use-symbol-table=true',
           '--demangle=%s' % demangle,
           '--functions=linkage',
           '--inlining=true',
           '--default-arch=%s' % self.default_arch]
    if self.system == 'Darwin':
      for hint in self.dsym_hints:
        cmd.append('--dsym-hint=%s' % hint)
    logging.debug(' '.join(cmd))
    try:
      result = subprocess.Popen(cmd, stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                bufsize=0,
                                universal_newlines=True)
    except OSError:
      result = None
    return result

  def symbolize(self, addr, binary, offset):
    """Overrides Symbolizer.symbolize."""
    if not self.pipe:
      return None
    result = []
    try:
      symbolizer_input = '"%s" %s' % (binary, offset)
      logging.debug(symbolizer_input)
      self.pipe.stdin.write("%s\n" % symbolizer_input)
      while True:
        function_name = self.pipe.stdout.readline().rstrip()
        if not function_name:
          break
        file_name = self.pipe.stdout.readline().rstrip()
        file_name = fix_filename(file_name)
        if (not function_name.startswith('??') or
            not file_name.startswith('??')):
          # Append only non-trivial frames.
          result.append('%s in %s %s' % (addr, function_name,
                                         file_name))
    except Exception:
      result = []
    if not result:
      result = None
    return result


def LLVMSymbolizerFactory(system, default_arch, dsym_hints=[]):
  symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH')
  if not symbolizer_path:
    symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH')
    if not symbolizer_path:
      # Assume llvm-symbolizer is in PATH.
      symbolizer_path = 'llvm-symbolizer'
  return LLVMSymbolizer(symbolizer_path, default_arch, system, dsym_hints)


class Addr2LineSymbolizer(Symbolizer):
  def __init__(self, binary):
    super(Addr2LineSymbolizer, self).__init__()
    self.binary = binary
    self.pipe = self.open_addr2line()
    self.output_terminator = -1

  def open_addr2line(self):
    addr2line_tool = 'addr2line'
    if binutils_prefix:
      addr2line_tool = binutils_prefix + addr2line_tool
    logging.debug('addr2line binary is %s' % find_executable(addr2line_tool))
    cmd = [addr2line_tool, '-fi']
    if demangle:
      cmd += ['--demangle']
    cmd += ['-e', self.binary]
    logging.debug(' '.join(cmd))
    return subprocess.Popen(cmd,
                            stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                            bufsize=0,
                            universal_newlines=True)

  def symbolize(self, addr, binary, offset):
    """Overrides Symbolizer.symbolize."""
    if self.binary != binary:
      return None
    lines = []
    try:
      self.pipe.stdin.write("%s\n" % offset)
      self.pipe.stdin.write("%s\n" % self.output_terminator)
      is_first_frame = True
      while True:
        function_name = self.pipe.stdout.readline().rstrip()
        logging.debug("read function_name='%s' from addr2line" % function_name)
        # If llvm-symbolizer is installed as addr2line, older versions of
        # llvm-symbolizer will print -1 when presented with -1 and not print
        # a second line. In that case we will block for ever trying to read the
        # file name. This also happens for non-existent files, in which case GNU
        # addr2line exits immediate, but llvm-symbolizer does not (see
        # https://llvm.org/PR42754).
        if function_name == '-1':
          logging.debug("got function '-1' -> no more input")
          break
        file_name = self.pipe.stdout.readline().rstrip()
        logging.debug("read file_name='%s' from addr2line" % file_name)
        if is_first_frame:
          is_first_frame = False
        elif function_name == '??':
          assert file_name == '??:0', file_name
          logging.debug("got function '??' -> no more input")
          break
        elif not function_name:
          assert not file_name, file_name
          logging.debug("got empty function name -> no more input")
          break
        if not function_name and not file_name:
          logging.debug("got empty function and file name -> unknown function")
          function_name = '??'
          file_name = '??:0'
        lines.append((function_name, file_name))
    except IOError as e:
      # EPIPE happens if addr2line exits early (which some implementations do
      # if an invalid file is passed).
      if e.errno == errno.EPIPE:
        logging.debug("addr2line exited early (broken pipe), returncode=%d" % self.pipe.poll())
      else:
        logging.debug("unexpected I/O exception communicating with addr2line", exc_info=e)
      lines.append(('??', '??:0'))
    except Exception as e:
      logging.debug("got unknown exception communicating with addr2line", exc_info=e)
      lines.append(('??', '??:0'))
    return ['%s in %s %s' % (addr, function, fix_filename(file)) for (function, file) in lines]

class UnbufferedLineConverter(object):
  """
  Wrap a child process that responds to each line of input with one line of
  output.  Uses pty to trick the child into providing unbuffered output.
  """
  def __init__(self, args, close_stderr=False):
    # Local imports so that the script can start on Windows.
    import pty
    import termios
    pid, fd = pty.fork()
    if pid == 0:
      # We're the child. Transfer control to command.
      if close_stderr:
        dev_null = os.open('/dev/null', 0)
        os.dup2(dev_null, 2)
      os.execvp(args[0], args)
    else:
      # Disable echoing.
      attr = termios.tcgetattr(fd)
      attr[3] = attr[3] & ~termios.ECHO
      termios.tcsetattr(fd, termios.TCSANOW, attr)
      # Set up a file()-like interface to the child process
      self.r = os.fdopen(fd, "r", 1)
      self.w = os.fdopen(os.dup(fd), "w", 1)

  def convert(self, line):
    self.w.write(line + "\n")
    return self.readline()

  def readline(self):
    return self.r.readline().rstrip()


class DarwinSymbolizer(Symbolizer):
  def __init__(self, addr, binary, arch):
    super(DarwinSymbolizer, self).__init__()
    self.binary = binary
    self.arch = arch
    self.open_atos()

  def open_atos(self):
    logging.debug('atos -o %s -arch %s', self.binary, self.arch)
    cmdline = ['atos', '-o', self.binary, '-arch', self.arch]
    self.atos = UnbufferedLineConverter(cmdline, close_stderr=True)

  def symbolize(self, addr, binary, offset):
    """Overrides Symbolizer.symbolize."""
    if self.binary != binary:
      return None
    if not os.path.exists(binary):
      # If the binary doesn't exist atos will exit which will lead to IOError
      # exceptions being raised later on so just don't try to symbolize.
      return ['{} ({}:{}+{})'.format(addr, binary, self.arch, offset)]
    atos_line = self.atos.convert('0x%x' % int(offset, 16))
    while "got symbolicator for" in atos_line:
      atos_line = self.atos.readline()
    # A well-formed atos response looks like this:
    #   foo(type1, type2) (in object.name) (filename.cc:80)
    # NOTE:
    #   * For C functions atos omits parentheses and argument types.
    #   * For C++ functions the function name (i.e., `foo` above) may contain
    #     templates which may contain parentheses.
    match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line)
    logging.debug('atos_line: %s', atos_line)
    if match:
      function_name = match.group(1)
      file_name = fix_filename(match.group(3))
      return ['%s in %s %s' % (addr, function_name, file_name)]
    else:
      return ['%s in %s' % (addr, atos_line)]


# Chain several symbolizers so that if one symbolizer fails, we fall back
# to the next symbolizer in chain.
class ChainSymbolizer(Symbolizer):
  def __init__(self, symbolizer_list):
    super(ChainSymbolizer, self).__init__()
    self.symbolizer_list = symbolizer_list

  def symbolize(self, addr, binary, offset):
    """Overrides Symbolizer.symbolize."""
    for symbolizer in self.symbolizer_list:
      if symbolizer:
        result = symbolizer.symbolize(addr, binary, offset)
        if result:
          return result
    return None

  def append_symbolizer(self, symbolizer):
    self.symbolizer_list.append(symbolizer)


def BreakpadSymbolizerFactory(binary):
  suffix = os.getenv('BREAKPAD_SUFFIX')
  if suffix:
    filename = binary + suffix
    if os.access(filename, os.F_OK):
      return BreakpadSymbolizer(filename)
  return None


def SystemSymbolizerFactory(system, addr, binary, arch):
  if system == 'Darwin':
    return DarwinSymbolizer(addr, binary, arch)
  elif system in ['Linux', 'FreeBSD', 'NetBSD', 'SunOS']:
    return Addr2LineSymbolizer(binary)


class BreakpadSymbolizer(Symbolizer):
  def __init__(self, filename):
    super(BreakpadSymbolizer, self).__init__()
    self.filename = filename
    lines = file(filename).readlines()
    self.files = []
    self.symbols = {}
    self.address_list = []
    self.addresses = {}
    # MODULE mac x86_64 A7001116478B33F18FF9BEDE9F615F190 t
    fragments = lines[0].rstrip().split()
    self.arch = fragments[2]
    self.debug_id = fragments[3]
    self.binary = ' '.join(fragments[4:])
    self.parse_lines(lines[1:])

  def parse_lines(self, lines):
    cur_function_addr = ''
    for line in lines:
      fragments = line.split()
      if fragments[0] == 'FILE':
        assert int(fragments[1]) == len(self.files)
        self.files.append(' '.join(fragments[2:]))
      elif fragments[0] == 'PUBLIC':
        self.symbols[int(fragments[1], 16)] = ' '.join(fragments[3:])
      elif fragments[0] in ['CFI', 'STACK']:
        pass
      elif fragments[0] == 'FUNC':
        cur_function_addr = int(fragments[1], 16)
        if not cur_function_addr in self.symbols.keys():
          self.symbols[cur_function_addr] = ' '.join(fragments[4:])
      else:
        # Line starting with an address.
        addr = int(fragments[0], 16)
        self.address_list.append(addr)
        # Tuple of symbol address, size, line, file number.
        self.addresses[addr] = (cur_function_addr,
                                int(fragments[1], 16),
                                int(fragments[2]),
                                int(fragments[3]))
    self.address_list.sort()

  def get_sym_file_line(self, addr):
    key = None
    if addr in self.addresses.keys():
      key = addr
    else:
      index = bisect.bisect_left(self.address_list, addr)
      if index == 0:
        return None
      else:
        key = self.address_list[index - 1]
    sym_id, size, line_no, file_no = self.addresses[key]
    symbol = self.symbols[sym_id]
    filename = self.files[file_no]
    if addr < key + size:
      return symbol, filename, line_no
    else:
      return None

  def symbolize(self, addr, binary, offset):
    if self.binary != binary:
      return None
    res = self.get_sym_file_line(int(offset, 16))
    if res:
      function_name, file_name, line_no = res
      result = ['%s in %s %s:%d' % (
          addr, function_name, file_name, line_no)]
      print(result)
      return result
    else:
      return None


class SymbolizationLoop(object):
  def __init__(self, plugin_proxy=None, dsym_hint_producer=None):
    self.plugin_proxy = plugin_proxy
    if sys.platform == 'win32':
      # ASan on Windows uses dbghelp.dll to symbolize in-process, which works
      # even in sandboxed processes.  Nothing needs to be done here.
      self.process_line = self.process_line_echo
    else:
      # Used by clients who may want to supply a different binary name.
      # E.g. in Chrome several binaries may share a single .dSYM.
      self.dsym_hint_producer = dsym_hint_producer
      self.system = os.uname()[0]
      if self.system not in ['Linux', 'Darwin', 'FreeBSD', 'NetBSD','SunOS']:
        raise Exception('Unknown system')
      self.llvm_symbolizers = {}
      self.last_llvm_symbolizer = None
      self.dsym_hints = set([])
      self.frame_no = 0
      self.process_line = self.process_line_posix
      self.using_module_map = plugin_proxy.has_plugin(ModuleMapPlugIn.get_name())

  def symbolize_address(self, addr, binary, offset, arch):
    # On non-Darwin (i.e. on platforms without .dSYM debug info) always use
    # a single symbolizer binary.
    # On Darwin, if the dsym hint producer is present:
    #  1. check whether we've seen this binary already; if so,
    #     use |llvm_symbolizers[binary]|, which has already loaded the debug
    #     info for this binary (might not be the case for
    #     |last_llvm_symbolizer|);
    #  2. otherwise check if we've seen all the hints for this binary already;
    #     if so, reuse |last_llvm_symbolizer| which has the full set of hints;
    #  3. otherwise create a new symbolizer and pass all currently known
    #     .dSYM hints to it.
    result = None
    if not force_system_symbolizer:
      if not binary in self.llvm_symbolizers:
        use_new_symbolizer = True
        if self.system == 'Darwin' and self.dsym_hint_producer:
          dsym_hints_for_binary = set(self.dsym_hint_producer(binary))
          use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints)
          self.dsym_hints |= dsym_hints_for_binary
        if self.last_llvm_symbolizer and not use_new_symbolizer:
            self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
        else:
          self.last_llvm_symbolizer = LLVMSymbolizerFactory(
              self.system, arch, self.dsym_hints)
          self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
      # Use the chain of symbolizers:
      # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
      # (fall back to next symbolizer if the previous one fails).
      if not binary in symbolizers:
        symbolizers[binary] = ChainSymbolizer(
            [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
      result = symbolizers[binary].symbolize(addr, binary, offset)
    else:
      symbolizers[binary] = ChainSymbolizer([])
    if result is None:
      if not allow_system_symbolizer:
        raise Exception('Failed to launch or use llvm-symbolizer.')
      # Initialize system symbolizer only if other symbolizers failed.
      symbolizers[binary].append_symbolizer(
          SystemSymbolizerFactory(self.system, addr, binary, arch))
      result = symbolizers[binary].symbolize(addr, binary, offset)
    # The system symbolizer must produce some result.
    assert result
    return result

  def get_symbolized_lines(self, symbolized_lines, inc_frame_counter=True):
    if not symbolized_lines:
      if inc_frame_counter:
        self.frame_no += 1
      return [self.current_line]
    else:
      assert inc_frame_counter
      result = []
      for symbolized_frame in symbolized_lines:
        result.append('    #%s %s' % (str(self.frame_no), symbolized_frame.rstrip()))
        self.frame_no += 1
      return result

  def process_logfile(self):
    self.frame_no = 0
    for line in logfile:
      processed = self.process_line(line)
      print('\n'.join(processed))

  def process_line_echo(self, line):
    return [line.rstrip()]

  def process_line_posix(self, line):
    self.current_line = line.rstrip()
    # Unsymbolicated:
    # #0 0x7f6e35cf2e45  (/blah/foo.so+0x11fe45)
    # Partially symbolicated:
    # #0 0x7f6e35cf2e45 in foo (foo.so+0x11fe45)
    # NOTE: We have to very liberal with symbol
    # names in the regex because it could be an
    # Objective-C or C++ demangled name.
    stack_trace_line_format = (
        '^( *#([0-9]+) *)(0x[0-9a-f]+) *(?:in *.+)? *\((.*)\+(0x[0-9a-f]+)\)')
    match = re.match(stack_trace_line_format, line)
    if not match:
      logging.debug('Line "{}" does not match regex'.format(line))
      # Not a frame line so don't increment the frame counter.
      return self.get_symbolized_lines(None, inc_frame_counter=False)
    logging.debug(line)
    _, frameno_str, addr, binary, offset = match.groups()

    if not self.using_module_map and not os.path.isabs(binary):
      # Do not try to symbolicate if the binary is just the module file name
      # and a module map is unavailable.
      # FIXME(dliew): This is currently necessary for reports on Darwin that are
      # partially symbolicated by `atos`.
      return self.get_symbolized_lines(None)
    arch = ""
    # Arch can be embedded in the filename, e.g.: "libabc.dylib:x86_64h"
    colon_pos = binary.rfind(":")
    if colon_pos != -1:
      maybe_arch = binary[colon_pos+1:]
      if is_valid_arch(maybe_arch):
        arch = maybe_arch
        binary = binary[0:colon_pos]
    if arch == "":
      arch = guess_arch(addr)
    if frameno_str == '0':
      # Assume that frame #0 is the first frame of new stack trace.
      self.frame_no = 0
    original_binary = binary
    binary = self.plugin_proxy.filter_binary_path(binary)
    if binary is None:
      # The binary filter has told us this binary can't be symbolized.
      logging.debug('Skipping symbolication of binary "%s"', original_binary)
      return self.get_symbolized_lines(None)
    symbolized_line = self.symbolize_address(addr, binary, offset, arch)
    if not symbolized_line:
      if original_binary != binary:
        symbolized_line = self.symbolize_address(addr, original_binary, offset, arch)
    return self.get_symbolized_lines(symbolized_line)

class AsanSymbolizerPlugInProxy(object):
  """
    Serves several purposes:
    - Manages the lifetime of plugins (must be used a `with` statement).
    - Provides interface for calling into plugins from within this script.
  """
  def __init__(self):
    self._plugins = [ ]
    self._plugin_names = set()

  def _load_plugin_from_file_impl_py_gt_2(self, file_path, globals_space):
      with open(file_path, 'r') as f:
        exec(f.read(), globals_space, None)

  def load_plugin_from_file(self, file_path):
    logging.info('Loading plugins from "{}"'.format(file_path))
    globals_space = dict(globals())
    # Provide function to register plugins
    def register_plugin(plugin):
      logging.info('Registering plugin %s', plugin.get_name())
      self.add_plugin(plugin)
    globals_space['register_plugin'] = register_plugin
    if sys.version_info.major < 3:
      execfile(file_path, globals_space, None)
    else:
      # Indirection here is to avoid a bug in older Python 2 versions:
      # `SyntaxError: unqualified exec is not allowed in function ...`
      self._load_plugin_from_file_impl_py_gt_2(file_path, globals_space)

  def add_plugin(self, plugin):
    assert isinstance(plugin, AsanSymbolizerPlugIn)
    self._plugins.append(plugin)
    self._plugin_names.add(plugin.get_name())
    plugin._receive_proxy(self)

  def remove_plugin(self, plugin):
    assert isinstance(plugin, AsanSymbolizerPlugIn)
    self._plugins.remove(plugin)
    self._plugin_names.remove(plugin.get_name())
    logging.debug('Removing plugin %s', plugin.get_name())
    plugin.destroy()

  def has_plugin(self, name):
    """
      Returns true iff the plugin name is currently
      being managed by AsanSymbolizerPlugInProxy.
    """
    return name in self._plugin_names

  def register_cmdline_args(self, parser):
    plugins = list(self._plugins)
    for plugin in plugins:
      plugin.register_cmdline_args(parser)

  def process_cmdline_args(self, pargs):
    # Use copy so we can remove items as we iterate.
    plugins = list(self._plugins)
    for plugin in plugins:
      keep = plugin.process_cmdline_args(pargs)
      assert isinstance(keep, bool)
      if not keep:
        self.remove_plugin(plugin)

  def __enter__(self):
    return self

  def __exit__(self, exc_type, exc_val, exc_tb):
    for plugin in self._plugins:
      plugin.destroy()
    # Don't suppress raised exceptions
    return False

  def _filter_single_value(self, function_name, input_value):
    """
      Helper for filter style plugin functions.
    """
    new_value = input_value
    for plugin in self._plugins:
      result = getattr(plugin, function_name)(new_value)
      if result is None:
        return None
      new_value = result
    return new_value

  def filter_binary_path(self, binary_path):
    """
      Consult available plugins to filter the path to a binary
      to make it suitable for symbolication.

      Returns `None` if symbolication should not be attempted for this
      binary.
    """
    return self._filter_single_value('filter_binary_path', binary_path)

  def filter_module_desc(self, module_desc):
    """
      Consult available plugins to determine the module
      description suitable for symbolication.

      Returns `None` if symbolication should not be attempted for this module.
    """
    assert isinstance(module_desc, ModuleDesc)
    return self._filter_single_value('filter_module_desc', module_desc)

class AsanSymbolizerPlugIn(object):
  """
    This is the interface the `asan_symbolize.py` code uses to talk
    to plugins.
  """
  @classmethod
  def get_name(cls):
    """
      Returns the name of the plugin.
    """
    return cls.__name__

  def _receive_proxy(self, proxy):
    assert isinstance(proxy, AsanSymbolizerPlugInProxy)
    self.proxy = proxy

  def register_cmdline_args(self, parser):
    """
      Hook for registering command line arguments to be
      consumed in `process_cmdline_args()`.

      `parser` - Instance of `argparse.ArgumentParser`.
    """
    pass

  def process_cmdline_args(self, pargs):
    """
      Hook for handling parsed arguments. Implementations
      should not modify `pargs`.

      `pargs` - Instance of `argparse.Namespace` containing
      parsed command line arguments.

      Return `True` if plug-in should be used, otherwise
      return `False`.
    """
    return True

  def destroy(self):
    """
      Hook called when a plugin is about to be destroyed.
      Implementations should free any allocated resources here.
    """
    pass

  # Symbolization hooks
  def filter_binary_path(self, binary_path):
    """
      Given a binary path return a binary path suitable for symbolication.

      Implementations should return `None` if symbolication of this binary
      should be skipped.
    """
    return binary_path

  def filter_module_desc(self, module_desc):
    """
      Given a ModuleDesc object (`module_desc`) return
      a ModuleDesc suitable for symbolication.

      Implementations should return `None` if symbolication of this binary
      should be skipped.
    """
    return module_desc

class ModuleDesc(object):
  def __init__(self, name, arch, start_addr, end_addr, module_path, uuid):
    self.name = name
    self.arch = arch
    self.start_addr = start_addr
    self.end_addr = end_addr
    # Module path from an ASan report.
    self.module_path = module_path
    # Module for performing symbolization, by default same as above.
    self.module_path_for_symbolization = module_path
    self.uuid = uuid
    assert self.is_valid()

  def __str__(self):
    assert self.is_valid()
    return "{name} {arch} {start_addr:#016x}-{end_addr:#016x} {module_path} {uuid}".format(
      name=self.name,
      arch=self.arch,
      start_addr=self.start_addr,
      end_addr=self.end_addr,
      module_path=self.module_path if self.module_path == self.module_path_for_symbolization else '{} ({})'.format(self.module_path_for_symbolization, self.module_path),
      uuid=self.uuid
    )

  def is_valid(self):
    if not isinstance(self.name, str):
      return False
    if not isinstance(self.arch, str):
      return False
    if not isinstance(self.start_addr, int):
      return False
    if self.start_addr < 0:
      return False
    if not isinstance(self.end_addr, int):
      return False
    if self.end_addr <= self.start_addr:
      return False
    if not isinstance(self.module_path, str):
      return False
    if not os.path.isabs(self.module_path):
      return False
    if not isinstance(self.module_path_for_symbolization, str):
      return False
    if not os.path.isabs(self.module_path_for_symbolization):
      return False
    if not isinstance(self.uuid, str):
      return False
    return True

class GetUUIDFromBinaryException(Exception):
  def __init__(self, msg):
    super(GetUUIDFromBinaryException, self).__init__(msg)

_get_uuid_from_binary_cache = dict()

def get_uuid_from_binary(path_to_binary, arch=None):
  cache_key = (path_to_binary, arch)
  cached_value = _get_uuid_from_binary_cache.get(cache_key)
  if cached_value:
    return cached_value
  if not os.path.exists(path_to_binary):
    raise GetUUIDFromBinaryException('Binary "{}" does not exist'.format(path_to_binary))
  cmd = [ '/usr/bin/otool', '-l']
  if arch:
    cmd.extend(['-arch', arch])
  cmd.append(path_to_binary)
  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
  # Look for this output:
  # cmd LC_UUID
  # cmdsize 24
  # uuid 4CA778FE-5BF9-3C45-AE59-7DF01B2BE83F
  if isinstance(output, str):
    output_str = output
  else:
    assert isinstance(output, bytes)
    output_str = output.decode()
  assert isinstance(output_str, str)
  lines = output_str.split('\n')
  uuid = None
  for index, line in enumerate(lines):
    stripped_line = line.strip()
    if not stripped_line.startswith('cmd LC_UUID'):
      continue
    uuid_line = lines[index+2].strip()
    if not uuid_line.startswith('uuid'):
      raise GetUUIDFromBinaryException('Malformed output: "{}"'.format(uuid_line))
    split_uuid_line = uuid_line.split()
    uuid = split_uuid_line[1]
    break
  if uuid is None:
    logging.error('Failed to retrieve UUID from binary {}'.format(path_to_binary))
    logging.error('otool output was:\n{}'.format(output_str))
    raise GetUUIDFromBinaryException('Failed to retrieve UUID from binary "{}"'.format(path_to_binary))
  else:
    # Update cache
    _get_uuid_from_binary_cache[cache_key] = uuid
  return uuid

class ModuleMap(object):
  def __init__(self):
    self._module_name_to_description_map = dict()

  def add_module(self, desc):
    assert isinstance(desc, ModuleDesc)
    assert desc.name not in self._module_name_to_description_map
    self._module_name_to_description_map[desc.name] = desc

  def find_module_by_name(self, name):
    return self._module_name_to_description_map.get(name, None)

  def __str__(self):
    s = '{} modules:\n'.format(self.num_modules)
    for module_desc in sorted(self._module_name_to_description_map.values(), key=lambda v: v.start_addr):
      s += str(module_desc) + '\n'
    return s

  @property
  def num_modules(self):
    return len(self._module_name_to_description_map)

  @property
  def modules(self):
    return set(self._module_name_to_description_map.values())

  def get_module_path_for_symbolication(self, module_name, proxy, validate_uuid):
    module_desc = self.find_module_by_name(module_name)
    if module_desc is None:
      return None
    # Allow a plug-in to change the module description to make it
    # suitable for symbolication or avoid symbolication altogether.
    module_desc = proxy.filter_module_desc(module_desc)
    if module_desc is None:
      return None
    if validate_uuid:
      logging.debug('Validating UUID of {}'.format(module_desc.module_path_for_symbolization))
      try:
        uuid = get_uuid_from_binary(module_desc.module_path_for_symbolization, arch = module_desc.arch)
        if uuid != module_desc.uuid:
          logging.warning("Detected UUID mismatch {} != {}".format(uuid, module_desc.uuid))
          # UUIDs don't match. Tell client to not symbolize this.
          return None
      except GetUUIDFromBinaryException as e:
        logging.error('Failed to get binary from UUID: %s', str(e))
        return None
    else:
      logging.warning('Skipping validation of UUID of {}'.format(module_desc.module_path_for_symbolization))
    return module_desc.module_path_for_symbolization

  @staticmethod
  def parse_from_file(module_map_path):
    if not os.path.exists(module_map_path):
      raise Exception('module map "{}" does not exist'.format(module_map_path))
    with open(module_map_path, 'r') as f:
      mm = None
      # E.g.
      # 0x2db4000-0x102ddc000 /path/to (arm64) <0D6BBDE0-FF90-3680-899D-8E6F9528E04C>
      hex_regex = lambda name: r'0x(?P<' + name + r'>[0-9a-f]+)'
      module_path_regex = r'(?P<path>.+)'
      arch_regex = r'\((?P<arch>.+)\)'
      uuid_regex = r'<(?P<uuid>[0-9A-Z-]+)>'
      line_regex = r'^{}-{}\s+{}\s+{}\s+{}'.format(
        hex_regex('start_addr'),
        hex_regex('end_addr'),
        module_path_regex,
        arch_regex,
        uuid_regex
      )
      matcher = re.compile(line_regex)
      line_num = 0
      line = 'dummy'
      while line != '':
        line = f.readline()
        line_num += 1
        if mm is None:
          if line.startswith('Process module map:'):
            mm = ModuleMap()
          continue
        if line.startswith('End of module map'):
          break
        m_obj = matcher.match(line)
        if not m_obj:
          raise Exception('Failed to parse line {} "{}"'.format(line_num, line))
        arch = m_obj.group('arch')
        start_addr = int(m_obj.group('start_addr'), base=16)
        end_addr = int(m_obj.group('end_addr'), base=16)
        module_path = m_obj.group('path')
        uuid = m_obj.group('uuid')
        module_desc = ModuleDesc(
          name=os.path.basename(module_path),
          arch=arch,
          start_addr=start_addr,
          end_addr=end_addr,
          module_path=module_path,
          uuid=uuid
        )
        mm.add_module(module_desc)
      if mm is not None:
        logging.debug('Loaded Module map from "{}":\n{}'.format(
          f.name,
          str(mm))
        )
      return mm

class SysRootFilterPlugIn(AsanSymbolizerPlugIn):
  """
    Simple plug-in to add sys root prefix to all binary paths
    used for symbolication.
  """
  def __init__(self):
    self.sysroot_path = ""

  def register_cmdline_args(self, parser):
    parser.add_argument('-s', dest='sys_root', metavar='SYSROOT',
                      help='set path to sysroot for sanitized binaries')

  def process_cmdline_args(self, pargs):
    if pargs.sys_root is None:
      # Not being used so remove ourselves.
      return False
    self.sysroot_path = pargs.sys_root
    return True

  def filter_binary_path(self, path):
    return self.sysroot_path + path

class ModuleMapPlugIn(AsanSymbolizerPlugIn):
  def __init__(self):
    self._module_map = None
    self._uuid_validation = True
  def register_cmdline_args(self, parser):
    parser.add_argument('--module-map',
                        help='Path to text file containing module map'
                        'output. See print_module_map ASan option.')
    parser.add_argument('--skip-uuid-validation',
                        default=False,
                        action='store_true',
                        help='Skips validating UUID of modules using otool.')

  def process_cmdline_args(self, pargs):
    if not pargs.module_map:
      return False
    self._module_map = ModuleMap.parse_from_file(args.module_map)
    if self._module_map is None:
      msg = 'Failed to find module map'
      logging.error(msg)
      raise Exception(msg)
    self._uuid_validation = not pargs.skip_uuid_validation
    return True

  def filter_binary_path(self, binary_path):
    if os.path.isabs(binary_path):
      # This is a binary path so transform into
      # a module name
      module_name = os.path.basename(binary_path)
    else:
      module_name = binary_path
    return self._module_map.get_module_path_for_symbolication(
      module_name,
      self.proxy,
      self._uuid_validation
    )

def add_logging_args(parser):
  parser.add_argument('--log-dest',
    default=None,
    help='Destination path for script logging (default stderr).',
  )
  parser.add_argument('--log-level',
    choices=['debug', 'info', 'warning', 'error', 'critical'],
    default='info',
    help='Log level for script (default: %(default)s).'
  )

def setup_logging():
  # Set up a parser just for parsing the logging arguments.
  # This is necessary because logging should be configured before we
  # perform the main argument parsing.
  parser = argparse.ArgumentParser(add_help=False)
  add_logging_args(parser)
  pargs, unparsed_args = parser.parse_known_args()

  log_level = getattr(logging, pargs.log_level.upper())
  if log_level == logging.DEBUG:
    log_format = '%(levelname)s: [%(funcName)s() %(filename)s:%(lineno)d] %(message)s'
  else:
    log_format = '%(levelname)s: %(message)s'
  basic_config = {
    'level': log_level,
    'format': log_format
  }
  log_dest = pargs.log_dest
  if log_dest:
    basic_config['filename'] = log_dest
  logging.basicConfig(**basic_config)
  logging.debug('Logging level set to "{}" and directing output to "{}"'.format(
    pargs.log_level,
    'stderr' if log_dest is None else log_dest)
  )
  return unparsed_args

def add_load_plugin_args(parser):
  parser.add_argument('-p', '--plugins',
    help='Load plug-in', nargs='+', default=[])

def setup_plugins(plugin_proxy, args):
  parser = argparse.ArgumentParser(add_help=False)
  add_load_plugin_args(parser)
  pargs , unparsed_args = parser.parse_known_args()
  for plugin_path in pargs.plugins:
    plugin_proxy.load_plugin_from_file(plugin_path)
  # Add built-in plugins.
  plugin_proxy.add_plugin(ModuleMapPlugIn())
  plugin_proxy.add_plugin(SysRootFilterPlugIn())
  return unparsed_args

if __name__ == '__main__':
  remaining_args = setup_logging()
  with AsanSymbolizerPlugInProxy() as plugin_proxy:
    remaining_args = setup_plugins(plugin_proxy, remaining_args)
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description='ASan symbolization script',
        epilog=__doc__)
    parser.add_argument('path_to_cut', nargs='*',
                        help='pattern to be cut from the result file path ')
    parser.add_argument('-d','--demangle', action='store_true',
                        help='demangle function names')
    parser.add_argument('-c', metavar='CROSS_COMPILE',
                        help='set prefix for binutils')
    parser.add_argument('-l','--logfile', default=sys.stdin,
                        type=argparse.FileType('r'),
                        help='set log file name to parse, default is stdin')
    parser.add_argument('--force-system-symbolizer', action='store_true',
                        help='don\'t use llvm-symbolizer')
    # Add logging arguments so that `--help` shows them.
    add_logging_args(parser)
    # Add load plugin arguments so that `--help` shows them.
    add_load_plugin_args(parser)
    plugin_proxy.register_cmdline_args(parser)
    args = parser.parse_args(remaining_args)
    plugin_proxy.process_cmdline_args(args)
    if args.path_to_cut:
      fix_filename_patterns = args.path_to_cut
    if args.demangle:
      demangle = True
    if args.c:
      binutils_prefix = args.c
    if args.logfile:
      logfile = args.logfile
    else:
      logfile = sys.stdin
    if args.force_system_symbolizer:
      force_system_symbolizer = True
    if force_system_symbolizer:
      assert(allow_system_symbolizer)
    loop = SymbolizationLoop(plugin_proxy)
    loop.process_logfile()
