#!/usr/bin/python
#
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""From several dumps of reached offsets, create the list of reached symbols."""

import argparse
import logging
import os
import struct
import sys

_SRC_PATH = os.path.abspath(os.path.join(
    os.path.dirname(__file__), os.pardir, os.pardir))
path = os.path.join(_SRC_PATH, 'tools', 'cygprofile')
sys.path.append(path)
import process_profiles

SIZEOF_INT = 4
BITS_IN_INT = SIZEOF_INT * 8
# This is the number of bytes represented in a dump by one bit.
BYTES_GRANULARITY = 4

def _DumpToOffsets(filename):
  """From a dump, returns a list of offsets in it.

  Args:
    filename: (str) Dump filename.

  Returns:
    ([int]) offsets in the dump, that is relative to .text start.
  """
  bitfield = None
  offsets = []
  with open(filename, 'r') as f:
    bitfield = f.read()
  assert len(bitfield) % SIZEOF_INT == 0
  count = len(bitfield) / SIZEOF_INT
  for i in xrange(count):
    entry = struct.unpack_from('<I', bitfield, offset=i * SIZEOF_INT)[0]
    for bit in range(BITS_IN_INT):
      if entry & (1 << bit):
        offsets.append((i * BITS_IN_INT + bit) * BYTES_GRANULARITY)
  return offsets


def _ReachedSymbols(offsets, offset_to_symbol):
  """Returns a list of reached symbols from offsets in .text.

  Args:
    offsets: ([int]) List of reached offsets.
    offset_to_symbol: [symbol_extractor.SymbolInfo or None] as returned by
      |SymbolOffsetProcessor.GetDumpOffsetToSymbolInfo()|

  Returns:
    ([symbol_extractor.SymbolInfo])
  """
  symbol_infos = set()
  missing = 0
  for offset in offsets:
    # |offset_to_symbol| has one entry per BYTES_GRANULARITY bytes.
    index = offset / BYTES_GRANULARITY
    if index > len(offset_to_symbol):
      missing += 1
      continue
    symbol_infos.add(offset_to_symbol[index])
  if missing:
    logging.warning('Couldn\'t match %d symbols', missing)
  return symbol_infos


def _CreateArgumentParser():
  """Returns an ArgumentParser."""
  parser = argparse.ArgumentParser(description='Outputs reached symbols')
  parser.add_argument('--build-dir', type=str,
                      help='Path to the build directory', required=True)
  parser.add_argument('--dumps', type=str, help='A comma-separated list of '
                      'files with instrumentation dumps', required=False)
  parser.add_argument('--dumps-dir', type=str, help='Directory name with'
                      'reached code dumps', required=False)
  parser.add_argument('--library-name', default='libchrome.so',
                      help=('Chrome shared library name (usually libchrome.so '
                            'or libmonochrome.so'))
  parser.add_argument('--output', required=True, help='Output filename')
  return parser


def main():
  logging.basicConfig(level=logging.INFO)
  parser = _CreateArgumentParser()
  args = parser.parse_args()
  dumps = []
  if args.dumps:
    dumps.extend(args.dumps.split(','))
  elif args.dumps_dir:
    for file_name in os.listdir(args.dumps_dir):
      dumps.append(os.path.join(args.dumps_dir, file_name))
  else:
    logging.error('Either --dumps or --dumps-dir must be provided')
    parser.print_help()
    return 1
  logging.info('Parsing dumps')
  offsets = set()
  for dump_filename in dumps:
    offsets |= set(_DumpToOffsets(dump_filename))
  logging.info('Found %d reached locations', len(offsets))
  library_path = os.path.join(args.build_dir, 'lib.unstripped',
                              args.library_name)
  processor = process_profiles.SymbolOffsetProcessor(library_path)
  logging.info('Finding Symbols')
  offset_to_symbol = processor.GetDumpOffsetToSymbolInfo()
  reached_symbol_infos = _ReachedSymbols(offsets, offset_to_symbol)
  reached_symbol_infos.remove(None)
  with open(args.output, 'w') as f:
    for s in reached_symbol_infos:
        f.write('%s\n' % s.name)

  # Print some stats.
  reached_size = sum(s.size for s in reached_symbol_infos)
  logging.info('Total reached size = {}'.format(reached_size))
  all_symbol_infos = set()
  for i in offset_to_symbol:
    if i is not None:
      all_symbol_infos.add(i)
  total_size = sum(s.size for s in all_symbol_infos)
  logging.info('Total size of known symbols = {}'.format(total_size))
  coverage_percent = float(reached_size) / total_size * 100;
  logging.info('Coverage: {0:.2f}%'.format(coverage_percent))


if __name__ == '__main__':
  main()
  sys.exit(0)

