# -*- coding: utf-8 -*-
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Generate minidump symbols for use by the Crash server.

This script takes expanded crash symbols published by the Android build, and
converts them to breakpad format.
"""

from __future__ import print_function

import multiprocessing
import os
import re
import zipfile

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.scripts import cros_generate_breakpad_symbols


RELOCATION_PACKER_BIN = 'relocation_packer'

# These regexps match each type of address we have to adjust.
ADDRESS_REGEXPS = (
    re.compile(r'^FUNC ([0-9a-f]+)'),
    re.compile(r'^([0-9a-f]+)'),
    re.compile(r'^PUBLIC ([0-9a-f]+)'),
    re.compile(r'^STACK CFI INIT ([0-9a-f]+)'),
    re.compile(r'^STACK CFI ([0-9a-f]+)'),
)


class OffsetDiscoveryError(Exception):
  """Raised if we can't find the offset after unpacking symbols."""


def FindExpansionOffset(unpack_result):
  """Helper to extract symbols offset from relocation_packer output.

  This can accept and handle both successful and failed unpack command output.

  Will return 0 if no adjustment is needed.

  Args:
    unpack_result: CommandResult from the relocation_packer command.

  Returns:
    Integer offset to adjust symbols by. May be 0.

  Raises:
    OffsetDiscoveryError if the unpack succeeds, but we can't parse the output.
  """
  if unpack_result.returncode != 0:
    return 0

  # Look for the number of relocations as a sanity check that we got the
  # expected output. Note that we don't otherwise care about this value.
  relocations_match = re.search(r'INFO: Relocations +: +(\d+) entries',
                                unpack_result.output)
  if not relocations_match:
    raise OffsetDiscoveryError('No Relocations in: %s' % unpack_result.output)

  # An "Expansion" line is only written if the value is nonzero.
  offset_match = re.search(r'INFO: Expansion +: +(\d+) bytes',
                           unpack_result.output)
  if not offset_match:
    return 0

  # Return offset as a negative number.
  return -int(offset_match.group(1))


def _AdjustLineSymbolOffset(line, offset):
  """Adjust the symbol offset for one line of a breakpad file.

  Args:
    line: One line of the file.
    offset: int to adjust the symbol by.

  Returns:
    The adjusted line, or original line if there is no change.
  """
  for regexp in ADDRESS_REGEXPS:
    m = regexp.search(line)
    if m:
      address = int(m.group(1), 16)

      # We ignore 0 addresses, since the zero's are fillers for unknowns.
      if address:
        address += offset

      # Return the same line with address adjusted.
      return '%s%x%s' % (line[:m.start(1)], address, line[m.end(1):])

  # Nothing recognized, no adjustment.
  return line


def _AdjustSymbolOffset(breakpad_file, offset):
  """Given a breakpad file, adjust the symbols by offset.

  Updates the file in place.

  Args:
    breakpad_file: File to read and update in place.
    offset: Integer to move symbols by.
  """
  logging.info('Adjusting symbols in %s with offset %d.',
               breakpad_file, offset)

  # Keep newlines.
  lines = osutils.ReadFile(breakpad_file).splitlines(True)
  adjusted_lines = [_AdjustLineSymbolOffset(line, offset) for line in lines]
  osutils.WriteFile(breakpad_file, ''.join(adjusted_lines))


def _UnpackGenerateBreakpad(elf_file, *args, **kwargs):
  """Unpack Android relocation symbols, and GenerateBreakpadSymbol

  This method accepts exactly the same arguments as
  cros_generate_breakpad_symbols.GenerateBreakpadSymbol, except that it requires
  elf_file, and fills in dump_sym_cmd.

  Args:
    elf_file: Name of the file to generate breakpad symbols for.
    args: See cros_generate_breakpad_symbols.GenerateBreakpadSymbol.
    kwargs: See cros_generate_breakpad_symbols.GenerateBreakpadSymbol.
  """
  # We try to unpack, and just see if it works. Real failures caused by
  # something other than a binary that's already unpacked will be logged and
  # ignored. We'll notice them when dump_syms fails later (which it will on
  # packed binaries.).
  unpack_cmd = [RELOCATION_PACKER_BIN, '-u', elf_file]
  unpack_result = cros_build_lib.run(
      unpack_cmd, redirect_stdout=True, error_code_ok=True)

  # If we unpacked, extract the offset, and remember it.
  offset = FindExpansionOffset(unpack_result)

  if offset:
    logging.info('Unpacked relocation symbols for %s with offset %d.',
                 elf_file, offset)

  # Now generate breakpad symbols from the binary.
  breakpad_file = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
      elf_file, *args, **kwargs)

  if offset:
    _AdjustSymbolOffset(breakpad_file, offset)


def GenerateBreakpadSymbols(breakpad_dir, symbols_dir):
  """Generate symbols for all binaries in symbols_dir.

  Args:
    breakpad_dir: The full path in which to write out breakpad symbols.
    symbols_dir: The full path to the binaries to process from.

  Returns:
    The number of errors that were encountered.
  """
  osutils.SafeMakedirs(breakpad_dir)
  logging.info('generating breakpad symbols from %s', symbols_dir)

  num_errors = multiprocessing.Value('i')

  # Now start generating symbols for the discovered elfs.
  with parallel.BackgroundTaskRunner(
      _UnpackGenerateBreakpad,
      breakpad_dir=breakpad_dir,
      num_errors=num_errors) as queue:

    for root, _, files in os.walk(symbols_dir):
      for f in files:
        queue.put([os.path.join(root, f)])

  return num_errors.value


def ProcessSymbolsZip(zip_archive, breakpad_dir):
  """Extract, process, and upload all symbols in a symbols zip file.

  Take the symbols file build artifact from an Android build, process it into
  breakpad format, and upload the results to the ChromeOS crashreporter.
  Significant multiprocessing is done by helper libraries, and a remote swarm
  server is used to reduce processing of duplicate symbol files.

  The symbols files are really expected to be unstripped elf files (or
  libraries), possibly using packed relocation tables. No other file types are
  expected in the zip.

  Args:
    zip_archive: Name of the zip file to process.
    breakpad_dir: Root directory for writing out breakpad files.
  """
  with osutils.TempDir(prefix='extracted-') as extract_dir:
    logging.info('Extracting %s into %s', zip_archive, extract_dir)
    with zipfile.ZipFile(zip_archive, 'r') as zf:
      # We are trusting the contents from a security point of view.
      zf.extractall(extract_dir)

    logging.info('Generate breakpad symbols from %s into %s',
                 extract_dir, breakpad_dir)
    GenerateBreakpadSymbols(breakpad_dir, extract_dir)


def main(argv):
  """Helper method mostly used for manual testing."""

  parser = commandline.ArgumentParser(description=__doc__)

  parser.add_argument('--symbols_file', type='path', required=True,
                      help='Zip file containing')
  parser.add_argument('--breakpad_dir', type='path', default='/tmp/breakpad',
                      help='Root directory for breakpad symbol files.')

  opts = parser.parse_args(argv)
  opts.Freeze()

  ProcessSymbolsZip(opts.symbols_file, opts.breakpad_dir)
