#!/usr/bin/env python3
# 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 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
import elf_symbolizer

# 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.items():
            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.items():
                for symbol_name, value in symbol_bucket[
                        NODE_CHILDREN_KEY].items():
                    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].values():
            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 binary_line in nm_output_lines:
            line = binary_line.decode()
            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 binary_line in nm_output_lines:
            line = binary_line.decode()
            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 open(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']).decode()
    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('WARNING: --nm-out is deprecated and has no effect.',
              file=sys.stderr)
    if (opts.nm_in):
        if opts.jobs:
            print('WARNING: --jobs has no effect when used with --nm-in',
                  file=sys.stderr)
    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, 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, 0o755)
    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, 0o755)
    d3_src = os.path.join(os.path.dirname(__file__), '..', '..', '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())
