#!/usr/bin/env python
# Copyright 2014 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.

"""Generate a spatial analysis against an arbitrary library.

To use, build the 'binary_size_tool' target. Then run this tool, passing
in the location of the library to be analyzed along with any other options
you desire.
"""

import collections
import json
import logging
import multiprocessing
import optparse
import os
import re
import shutil
import struct
import subprocess
import sys
import tempfile
import time

import binary_size_utils

# This path change is not beautiful. Temporary (I hope) measure until
# the chromium project has figured out a proper way to organize the
# library of python tools. http://crbug.com/375725
elf_symbolizer_path = os.path.abspath(os.path.join(
    os.path.dirname(__file__),
    '..',
    '..',
    'build',
    'android',
    'pylib'))
sys.path.append(elf_symbolizer_path)
import symbols.elf_symbolizer as elf_symbolizer  # pylint: disable=F0401


# Node dictionary keys. These are output in json read by the webapp so
# keep them short to save file size.
# Note: If these change, the webapp must also change.
NODE_TYPE_KEY = 'k'
NODE_NAME_KEY = 'n'
NODE_CHILDREN_KEY = 'children'
NODE_SYMBOL_TYPE_KEY = 't'
NODE_SYMBOL_SIZE_KEY = 'value'
NODE_MAX_DEPTH_KEY = 'maxDepth'
NODE_LAST_PATH_ELEMENT_KEY = 'lastPathElement'

# The display name of the bucket where we put symbols without path.
NAME_NO_PATH_BUCKET = '(No Path)'

# Try to keep data buckets smaller than this to avoid killing the
# graphing lib.
BIG_BUCKET_LIMIT = 3000


def _MkChild(node, name):
  child = node[NODE_CHILDREN_KEY].get(name)
  if child is None:
    child = {NODE_NAME_KEY: name,
             NODE_CHILDREN_KEY: {}}
    node[NODE_CHILDREN_KEY][name] = child
  return child



def SplitNoPathBucket(node):
  """NAME_NO_PATH_BUCKET can be too large for the graphing lib to
  handle. Split it into sub-buckets in that case."""
  root_children = node[NODE_CHILDREN_KEY]
  if NAME_NO_PATH_BUCKET in root_children:
    no_path_bucket = root_children[NAME_NO_PATH_BUCKET]
    old_children = no_path_bucket[NODE_CHILDREN_KEY]
    count = 0
    for symbol_type, symbol_bucket in old_children.iteritems():
      count += len(symbol_bucket[NODE_CHILDREN_KEY])
    if count > BIG_BUCKET_LIMIT:
      new_children = {}
      no_path_bucket[NODE_CHILDREN_KEY] = new_children
      current_bucket = None
      index = 0
      for symbol_type, symbol_bucket in old_children.iteritems():
        for symbol_name, value in symbol_bucket[NODE_CHILDREN_KEY].iteritems():
          if index % BIG_BUCKET_LIMIT == 0:
            group_no = (index / BIG_BUCKET_LIMIT) + 1
            current_bucket = _MkChild(no_path_bucket,
                                      '%s subgroup %d' % (NAME_NO_PATH_BUCKET,
                                                          group_no))
            assert not NODE_TYPE_KEY in node or node[NODE_TYPE_KEY] == 'p'
            node[NODE_TYPE_KEY] = 'p'  # p for path
          index += 1
          symbol_size = value[NODE_SYMBOL_SIZE_KEY]
          AddSymbolIntoFileNode(current_bucket, symbol_type,
                                symbol_name, symbol_size)


def MakeChildrenDictsIntoLists(node):
  largest_list_len = 0
  if NODE_CHILDREN_KEY in node:
    largest_list_len = len(node[NODE_CHILDREN_KEY])
    child_list = []
    for child in node[NODE_CHILDREN_KEY].itervalues():
      child_largest_list_len = MakeChildrenDictsIntoLists(child)
      if child_largest_list_len > largest_list_len:
        largest_list_len = child_largest_list_len
      child_list.append(child)
    node[NODE_CHILDREN_KEY] = child_list

  return largest_list_len


def AddSymbolIntoFileNode(node, symbol_type, symbol_name, symbol_size):
  """Puts symbol into the file path node |node|.
  Returns the number of added levels in tree. I.e. returns 2."""

  # 'node' is the file node and first step is to find its symbol-type bucket.
  node[NODE_LAST_PATH_ELEMENT_KEY] = True
  node = _MkChild(node, symbol_type)
  assert not NODE_TYPE_KEY in node or node[NODE_TYPE_KEY] == 'b'
  node[NODE_SYMBOL_TYPE_KEY] = symbol_type
  node[NODE_TYPE_KEY] = 'b'  # b for bucket

  # 'node' is now the symbol-type bucket. Make the child entry.
  node = _MkChild(node, symbol_name)
  if NODE_CHILDREN_KEY in node:
    if node[NODE_CHILDREN_KEY]:
      logging.warning('A container node used as symbol for %s.' % symbol_name)
    # This is going to be used as a leaf so no use for child list.
    del node[NODE_CHILDREN_KEY]
  node[NODE_SYMBOL_SIZE_KEY] = symbol_size
  node[NODE_SYMBOL_TYPE_KEY] = symbol_type
  node[NODE_TYPE_KEY] = 's'  # s for symbol

  return 2  # Depth of the added subtree.


def MakeCompactTree(symbols, symbol_path_origin_dir):
  result = {NODE_NAME_KEY: '/',
            NODE_CHILDREN_KEY: {},
            NODE_TYPE_KEY: 'p',
            NODE_MAX_DEPTH_KEY: 0}
  seen_symbol_with_path = False
  cwd = os.path.abspath(os.getcwd())
  for symbol_name, symbol_type, symbol_size, file_path, _address in symbols:

    if 'vtable for ' in symbol_name:
      symbol_type = '@'  # hack to categorize these separately
    # Take path like '/foo/bar/baz', convert to ['foo', 'bar', 'baz']
    if file_path and file_path != "??":
      file_path = os.path.abspath(os.path.join(symbol_path_origin_dir,
                                               file_path))
      # Let the output structure be relative to $CWD if inside $CWD,
      # otherwise relative to the disk root. This is to avoid
      # unnecessary click-through levels in the output.
      if file_path.startswith(cwd + os.sep):
        file_path = file_path[len(cwd):]
      if file_path.startswith('/'):
        file_path = file_path[1:]
      seen_symbol_with_path = True
    else:
      file_path = NAME_NO_PATH_BUCKET

    path_parts = file_path.split('/')

    # Find pre-existing node in tree, or update if it already exists
    node = result
    depth = 0
    while len(path_parts) > 0:
      path_part = path_parts.pop(0)
      if len(path_part) == 0:
        continue
      depth += 1
      node = _MkChild(node, path_part)
      assert not NODE_TYPE_KEY in node or node[NODE_TYPE_KEY] == 'p'
      node[NODE_TYPE_KEY] = 'p'  # p for path

    depth += AddSymbolIntoFileNode(node, symbol_type, symbol_name, symbol_size)
    result[NODE_MAX_DEPTH_KEY] = max(result[NODE_MAX_DEPTH_KEY], depth)

  if not seen_symbol_with_path:
    logging.warning('Symbols lack paths. Data will not be structured.')

  # The (no path) bucket can be extremely large if we failed to get
  # path information. Split it into subgroups if needed.
  SplitNoPathBucket(result)

  largest_list_len = MakeChildrenDictsIntoLists(result)

  if largest_list_len > BIG_BUCKET_LIMIT:
    logging.warning('There are sections with %d nodes. '
                    'Results might be unusable.' % largest_list_len)
  return result


def DumpCompactTree(symbols, symbol_path_origin_dir, outfile):
  tree_root = MakeCompactTree(symbols, symbol_path_origin_dir)
  with open(outfile, 'w') as out:
    out.write('var tree_data=')
    # Use separators without whitespace to get a smaller file.
    json.dump(tree_root, out, separators=(',', ':'))
  print('Writing %d bytes json' % os.path.getsize(outfile))


def MakeSourceMap(symbols):
  sources = {}
  for _sym, _symbol_type, size, path, _address in symbols:
    key = None
    if path:
      key = os.path.normpath(path)
    else:
      key = '[no path]'
    if key not in sources:
      sources[key] = {'path': path, 'symbol_count': 0, 'size': 0}
    record = sources[key]
    record['size'] += size
    record['symbol_count'] += 1
  return sources


# Regex for parsing "nm" output. A sample line looks like this:
# 0167b39c 00000018 t ACCESS_DESCRIPTION_free /path/file.c:95
#
# The fields are: address, size, type, name, source location
# Regular expression explained ( see also: https://xkcd.com/208 ):
# ([0-9a-f]{8,}+)   The address
# [\s]+             Whitespace separator
# ([0-9a-f]{8,}+)   The size. From here on out it's all optional.
# [\s]+             Whitespace separator
# (\S?)             The symbol type, which is any non-whitespace char
# [\s*]             Whitespace separator
# ([^\t]*)          Symbol name, any non-tab character (spaces ok!)
# [\t]?             Tab separator
# (.*)              The location (filename[:linennum|?][ (discriminator n)]
sNmPattern = re.compile(
  r'([0-9a-f]{8,})[\s]+([0-9a-f]{8,})[\s]*(\S?)[\s*]([^\t]*)[\t]?(.*)')

class Progress():
  def __init__(self):
    self.count = 0
    self.skip_count = 0
    self.collisions = 0
    self.time_last_output = time.time()
    self.count_last_output = 0
    self.disambiguations = 0
    self.was_ambiguous = 0


def RunElfSymbolizer(outfile, library, addr2line_binary, nm_binary, jobs,
                     disambiguate, src_path):
  nm_output = RunNm(library, nm_binary)
  nm_output_lines = nm_output.splitlines()
  nm_output_lines_len = len(nm_output_lines)
  address_symbol = {}
  progress = Progress()
  def map_address_symbol(symbol, addr):
    progress.count += 1
    if addr in address_symbol:
      # 'Collision between %s and %s.' % (str(symbol.name),
      #                                   str(address_symbol[addr].name))
      progress.collisions += 1
    else:
      if symbol.disambiguated:
        progress.disambiguations += 1
      if symbol.was_ambiguous:
        progress.was_ambiguous += 1

      address_symbol[addr] = symbol

    progress_output()

  def progress_output():
    progress_chunk = 100
    if progress.count % progress_chunk == 0:
      time_now = time.time()
      time_spent = time_now - progress.time_last_output
      if time_spent > 1.0:
        # Only output at most once per second.
        progress.time_last_output = time_now
        chunk_size = progress.count - progress.count_last_output
        progress.count_last_output = progress.count
        if time_spent > 0:
          speed = chunk_size / time_spent
        else:
          speed = 0
        progress_percent = (100.0 * (progress.count + progress.skip_count) /
                            nm_output_lines_len)
        disambiguation_percent = 0
        if progress.disambiguations != 0:
          disambiguation_percent = (100.0 * progress.disambiguations /
                                    progress.was_ambiguous)

        sys.stdout.write('\r%.1f%%: Looked up %d symbols (%d collisions, '
              '%d disambiguations where %.1f%% succeeded)'
              ' - %.1f lookups/s.' %
              (progress_percent, progress.count, progress.collisions,
               progress.disambiguations, disambiguation_percent, speed))

  # In case disambiguation was disabled, we remove the source path (which upon
  # being set signals the symbolizer to enable disambiguation)
  if not disambiguate:
    src_path = None
  symbolizer = elf_symbolizer.ELFSymbolizer(library, addr2line_binary,
                                            map_address_symbol,
                                            max_concurrent_jobs=jobs,
                                            source_root_path=src_path)
  user_interrupted = False
  try:
    for line in nm_output_lines:
      match = sNmPattern.match(line)
      if match:
        location = match.group(5)
        if not location:
          addr = int(match.group(1), 16)
          size = int(match.group(2), 16)
          if addr in address_symbol:  # Already looked up, shortcut
                                      # ELFSymbolizer.
            map_address_symbol(address_symbol[addr], addr)
            continue
          elif size == 0:
            # Save time by not looking up empty symbols (do they even exist?)
            print('Empty symbol: ' + line)
          else:
            symbolizer.SymbolizeAsync(addr, addr)
            continue

      progress.skip_count += 1
  except KeyboardInterrupt:
    user_interrupted = True
    print('Interrupting - killing subprocesses. Please wait.')

  try:
    symbolizer.Join()
  except KeyboardInterrupt:
    # Don't want to abort here since we will be finished in a few seconds.
    user_interrupted = True
    print('Patience you must have my young padawan.')

  print ''

  if user_interrupted:
    print('Skipping the rest of the file mapping. '
          'Output will not be fully classified.')

  symbol_path_origin_dir = os.path.dirname(os.path.abspath(library))

  with open(outfile, 'w') as out:
    for line in nm_output_lines:
      match = sNmPattern.match(line)
      if match:
        location = match.group(5)
        if not location:
          addr = int(match.group(1), 16)
          symbol = address_symbol.get(addr)
          if symbol is not None:
            path = '??'
            if symbol.source_path is not None:
              path = os.path.abspath(os.path.join(symbol_path_origin_dir,
                                                  symbol.source_path))
            line_number = 0
            if symbol.source_line is not None:
              line_number = symbol.source_line
            out.write('%s\t%s:%d\n' % (line, path, line_number))
            continue

      out.write('%s\n' % line)

  print('%d symbols in the results.' % len(address_symbol))


def RunNm(binary, nm_binary):
  cmd = [nm_binary, '-C', '--print-size', '--size-sort', '--reverse-sort',
         binary]
  nm_process = subprocess.Popen(cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
  (process_output, err_output) = nm_process.communicate()

  if nm_process.returncode != 0:
    if err_output:
      raise Exception, err_output
    else:
      raise Exception, process_output

  return process_output


def GetNmSymbols(nm_infile, outfile, library, jobs, verbose,
                 addr2line_binary, nm_binary, disambiguate, src_path):
  if nm_infile is None:
    if outfile is None:
      outfile = tempfile.NamedTemporaryFile(delete=False).name

    if verbose:
      print 'Running parallel addr2line, dumping symbols to ' + outfile
    RunElfSymbolizer(outfile, library, addr2line_binary, nm_binary, jobs,
                     disambiguate, src_path)

    nm_infile = outfile

  elif verbose:
    print 'Using nm input from ' + nm_infile
  with file(nm_infile, 'r') as infile:
    return list(binary_size_utils.ParseNm(infile))


PAK_RESOURCE_ID_TO_STRING = { "inited": False }

def LoadPakIdsFromResourceFile(filename):
  """Given a file name, it loads everything that looks like a resource id
  into PAK_RESOURCE_ID_TO_STRING."""
  with open(filename) as resource_header:
    for line in resource_header:
      if line.startswith("#define "):
        line_data = line.split()
        if len(line_data) == 3:
          try:
            resource_number = int(line_data[2])
            resource_name = line_data[1]
            PAK_RESOURCE_ID_TO_STRING[resource_number] = resource_name
          except ValueError:
            pass

def GetReadablePakResourceName(pak_file, resource_id):
  """Pak resources have a numeric identifier. It is not helpful when
  trying to locate where footprint is generated. This does its best to
  map the number to a usable string."""
  if not PAK_RESOURCE_ID_TO_STRING['inited']:
    # Try to find resource header files generated by grit when
    # building the pak file. We'll look for files named *resources.h"
    # and lines of the type:
    #    #define MY_RESOURCE_JS 1234
    PAK_RESOURCE_ID_TO_STRING['inited'] = True
    gen_dir = os.path.join(os.path.dirname(pak_file), 'gen')
    if os.path.isdir(gen_dir):
      for dirname, _dirs, files in os.walk(gen_dir):
        for filename in files:
          if filename.endswith('resources.h'):
            LoadPakIdsFromResourceFile(os.path.join(dirname, filename))
  return PAK_RESOURCE_ID_TO_STRING.get(resource_id,
                                       'Pak Resource %d' % resource_id)

def AddPakData(symbols, pak_file):
  """Adds pseudo-symbols from a pak file."""
  pak_file = os.path.abspath(pak_file)
  with open(pak_file, 'rb') as pak:
    data = pak.read()

  PAK_FILE_VERSION = 4
  HEADER_LENGTH = 2 * 4 + 1  # Two uint32s. (file version, number of entries)
                             # and one uint8 (encoding of text resources)
  INDEX_ENTRY_SIZE = 2 + 4  # Each entry is a uint16 and a uint32.
  version, num_entries, _encoding = struct.unpack('<IIB', data[:HEADER_LENGTH])
  assert version == PAK_FILE_VERSION, ('Unsupported pak file '
                                       'version (%d) in %s. Only '
                                       'support version %d' %
                                       (version, pak_file, PAK_FILE_VERSION))
  if num_entries > 0:
    # Read the index and data.
    data = data[HEADER_LENGTH:]
    for _ in range(num_entries):
      resource_id, offset = struct.unpack('<HI', data[:INDEX_ENTRY_SIZE])
      data = data[INDEX_ENTRY_SIZE:]
      _next_id, next_offset = struct.unpack('<HI', data[:INDEX_ENTRY_SIZE])
      resource_size = next_offset - offset

      symbol_name = GetReadablePakResourceName(pak_file, resource_id)
      symbol_path = pak_file
      symbol_type = 'd' # Data. Approximation.
      symbol_size = resource_size
      symbols.append((symbol_name, symbol_type, symbol_size, symbol_path))

def _find_in_system_path(binary):
  """Locate the full path to binary in the system path or return None
  if not found."""
  system_path = os.environ["PATH"].split(os.pathsep)
  for path in system_path:
    binary_path = os.path.join(path, binary)
    if os.path.isfile(binary_path):
      return binary_path
  return None

def CheckDebugFormatSupport(library, addr2line_binary):
  """Kills the program if debug data is in an unsupported format.

  There are two common versions of the DWARF debug formats and
  since we are right now transitioning from DWARF2 to newer formats,
  it's possible to have a mix of tools that are not compatible. Detect
  that and abort rather than produce meaningless output."""
  tool_output = subprocess.check_output([addr2line_binary, '--version'])
  version_re = re.compile(r'^GNU [^ ]+ .* (\d+).(\d+).*?$', re.M)
  parsed_output = version_re.match(tool_output)
  major = int(parsed_output.group(1))
  minor = int(parsed_output.group(2))
  supports_dwarf4 = major > 2 or major == 2 and minor > 22

  if supports_dwarf4:
    return

  print('Checking version of debug information in %s.' % library)
  debug_info = subprocess.check_output(['readelf', '--debug-dump=info',
                                       '--dwarf-depth=1', library])
  dwarf_version_re = re.compile(r'^\s+Version:\s+(\d+)$', re.M)
  parsed_dwarf_format_output = dwarf_version_re.search(debug_info)
  version = int(parsed_dwarf_format_output.group(1))
  if version > 2:
    print('The supplied tools only support DWARF2 debug data but the binary\n' +
          'uses DWARF%d. Update the tools or compile the binary\n' % version +
          'with -gdwarf-2.')
    sys.exit(1)


def main():
  usage = """%prog [options]

  Runs a spatial analysis on a given library, looking up the source locations
  of its symbols and calculating how much space each directory, source file,
  and so on is taking. The result is a report that can be used to pinpoint
  sources of large portions of the binary, etceteras.

  Under normal circumstances, you only need to pass two arguments, thusly:

      %prog --library /path/to/library --destdir /path/to/output

  In this mode, the program will dump the symbols from the specified library
  and map those symbols back to source locations, producing a web-based
  report in the specified output directory.

  Other options are available via '--help'.
  """
  parser = optparse.OptionParser(usage=usage)
  parser.add_option('--nm-in', metavar='PATH',
                    help='if specified, use nm input from <path> instead of '
                    'generating it. Note that source locations should be '
                    'present in the file; i.e., no addr2line symbol lookups '
                    'will be performed when this option is specified. '
                    'Mutually exclusive with --library.')
  parser.add_option('--destdir', metavar='PATH',
                    help='write output to the specified directory. An HTML '
                    'report is generated here along with supporting files; '
                    'any existing report will be overwritten.')
  parser.add_option('--library', metavar='PATH',
                    help='if specified, process symbols in the library at '
                    'the specified path. Mutually exclusive with --nm-in.')
  parser.add_option('--pak', metavar='PATH',
                    help='if specified, includes the contents of the '
                    'specified *.pak file in the output.')
  parser.add_option('--nm-binary',
                    help='use the specified nm binary to analyze library. '
                    'This is to be used when the nm in the path is not for '
                    'the right architecture or of the right version.')
  parser.add_option('--addr2line-binary',
                    help='use the specified addr2line binary to analyze '
                    'library. This is to be used when the addr2line in '
                    'the path is not for the right architecture or '
                    'of the right version.')
  parser.add_option('--jobs', type='int',
                    help='number of jobs to use for the parallel '
                    'addr2line processing pool; defaults to 1. More '
                    'jobs greatly improve throughput but eat RAM like '
                    'popcorn, and take several gigabytes each. Start low '
                    'and ramp this number up until your machine begins to '
                    'struggle with RAM. '
                    'This argument is only valid when using --library.')
  parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
                    help='be verbose, printing lots of status information.')
  parser.add_option('--nm-out', metavar='PATH',
                    help='(deprecated) No-op. nm.out is stored in --destdir.')
  parser.add_option('--no-nm-out', action='store_true',
                    help='do not keep the nm output file. This file is useful '
                    'if you want to see the fully processed nm output after '
                    'the symbols have been mapped to source locations, or if '
                    'you plan to run explain_binary_size_delta.py. By default '
                    'the file \'nm.out\' is placed alongside the generated '
                    'report. The nm.out file is only created when using '
                    '--library.')
  parser.add_option('--disable-disambiguation', action='store_true',
                    help='disables the disambiguation process altogether,'
                    ' NOTE: this may, depending on your toolchain, produce'
                    ' output with some symbols at the top layer if addr2line'
                    ' could not get the entire source path.')
  parser.add_option('--source-path', default='./',
                    help='the path to the source code of the output binary, '
                    'default set to current directory. Used in the'
                    ' disambiguation process.')
  opts, _args = parser.parse_args()

  if ((not opts.library) and (not opts.nm_in)) or (opts.library and opts.nm_in):
    parser.error('exactly one of --library or --nm-in is required')
  if opts.nm_out:
    print >> sys.stderr, ('WARNING: --nm-out is deprecated and has no effect.')
  if (opts.nm_in):
    if opts.jobs:
      print >> sys.stderr, ('WARNING: --jobs has no effect '
                            'when used with --nm-in')
  if not opts.destdir:
    parser.error('--destdir is a required argument')
  if not opts.jobs:
    # Use the number of processors but cap between 2 and 4 since raw
    # CPU power isn't the limiting factor. It's I/O limited, memory
    # bus limited and available-memory-limited. Too many processes and
    # the computer will run out of memory and it will be slow.
    opts.jobs = max(2, min(4, str(multiprocessing.cpu_count())))

  if opts.addr2line_binary:
    assert os.path.isfile(opts.addr2line_binary)
    addr2line_binary = opts.addr2line_binary
  else:
    addr2line_binary = _find_in_system_path('addr2line')
    assert addr2line_binary, 'Unable to find addr2line in the path. '\
        'Use --addr2line-binary to specify location.'

  if opts.nm_binary:
    assert os.path.isfile(opts.nm_binary)
    nm_binary = opts.nm_binary
  else:
    nm_binary = _find_in_system_path('nm')
    assert nm_binary, 'Unable to find nm in the path. Use --nm-binary '\
        'to specify location.'

  if opts.pak:
    assert os.path.isfile(opts.pak), 'Could not find ' % opts.pak

  print('addr2line: %s' % addr2line_binary)
  print('nm: %s' % nm_binary)

  if opts.library:
    CheckDebugFormatSupport(opts.library, addr2line_binary)

  # Prepare output directory and report guts
  if not os.path.exists(opts.destdir):
    os.makedirs(opts.destdir, 0755)
  nm_out = os.path.join(opts.destdir, 'nm.out')
  if opts.no_nm_out:
    nm_out = None

  # Copy report boilerplate into output directory. This also proves that the
  # output directory is safe for writing, so there should be no problems writing
  # the nm.out file later.
  data_js_file_name = os.path.join(opts.destdir, 'data.js')
  d3_out = os.path.join(opts.destdir, 'd3')
  if not os.path.exists(d3_out):
    os.makedirs(d3_out, 0755)
  d3_src = os.path.join(os.path.dirname(__file__),
                        '..',
                        '..',
                        'third_party', 'd3', 'src')
  template_src = os.path.join(os.path.dirname(__file__),
                              'template')
  shutil.copy(os.path.join(d3_src, 'LICENSE'), d3_out)
  shutil.copy(os.path.join(d3_src, 'd3.js'), d3_out)
  shutil.copy(os.path.join(template_src, 'index.html'), opts.destdir)
  shutil.copy(os.path.join(template_src, 'D3SymbolTreeMap.js'), opts.destdir)

  # Run nm and/or addr2line to gather the data
  symbols = GetNmSymbols(opts.nm_in, nm_out, opts.library,
                         opts.jobs, opts.verbose is True,
                         addr2line_binary, nm_binary,
                         opts.disable_disambiguation is None,
                         opts.source_path)

  # Post-processing
  if opts.pak:
    AddPakData(symbols, opts.pak)
  if opts.library:
    symbol_path_origin_dir = os.path.dirname(os.path.abspath(opts.library))
  else:
    # Just a guess. Hopefully all paths in the input file are absolute.
    symbol_path_origin_dir = os.path.abspath(os.getcwd())
  # Dump JSON for the HTML report.
  DumpCompactTree(symbols, symbol_path_origin_dir, data_js_file_name)
  print 'Report saved to ' + opts.destdir + '/index.html'

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