| Index: tools/binary_size/run_binary_size_analysis.py
|
| diff --git a/tools/binary_size/run_binary_size_analysis.py b/tools/binary_size/run_binary_size_analysis.py
|
| index f2c95b104fe042b38901da1732d22c39de4565a4..23869e0f64cbdfe659eebd310633d990e0cc96c9 100755
|
| --- a/tools/binary_size/run_binary_size_analysis.py
|
| +++ b/tools/binary_size/run_binary_size_analysis.py
|
| @@ -18,6 +18,7 @@ import optparse
|
| import os
|
| import re
|
| import shutil
|
| +import struct
|
| import subprocess
|
| import sys
|
| import tempfile
|
| @@ -654,6 +655,72 @@ def GetNmSymbols(nm_infile, outfile, library, jobs, verbose,
|
| 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."""
|
| @@ -726,6 +793,9 @@ def main():
|
| 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 '
|
| @@ -796,6 +866,9 @@ def main():
|
| 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)
|
|
|
| @@ -806,6 +879,10 @@ def main():
|
| addr2line_binary, nm_binary,
|
| opts.disable_disambiguation is None,
|
| opts.source_path)
|
| +
|
| + if opts.pak:
|
| + AddPakData(symbols, opts.pak)
|
| +
|
| if not os.path.exists(opts.destdir):
|
| os.makedirs(opts.destdir, 0755)
|
|
|
|
|