示例#1
0
def main():
  parser = optparse.OptionParser(usage=
      'usage: %prog [options] <binary> <orderfile>')
  parser.add_option('--target-arch', action='store', dest='arch',
                    choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
                    help='The target architecture for the binary.')
  parser.add_option('--threshold', action='store', dest='threshold', default=1,
                    help='The maximum allowed number of out-of-order symbols.')
  options, argv = parser.parse_args(sys.argv)
  if not options.arch:
    options.arch = cygprofile_utils.DetectArchitecture()
  if len(argv) != 3:
    parser.print_help()
    return 1
  (binary_filename, orderfile_filename) = argv[1:]

  symbol_extractor.SetArchitecture(options.arch)
  obj_dir = cygprofile_utils.GetObjDir(binary_filename)
  symbol_to_sections_map = \
      cyglog_to_orderfile.GetSymbolToSectionsMapFromObjectFiles(obj_dir)
  section_to_symbols_map = cygprofile_utils.InvertMapping(
      symbol_to_sections_map)
  symbols = patch_orderfile.GetSymbolsFromOrderfile(orderfile_filename,
                                                    section_to_symbols_map)
  symbol_infos = symbol_extractor.SymbolInfosFromBinary(binary_filename)
  # Missing symbols is not an error since some of them can be eliminated through
  # inlining.
  (misordered_pairs_count, matched_symbols, _) = _CountMisorderedSymbols(
      symbols, symbol_infos)
  return (misordered_pairs_count > options.threshold) or (matched_symbols == 0)
示例#2
0
def main():
    parser = _CreateArgumentParser()
    options = parser.parse_args()
    symbol_extractor.SetArchitecture(options.target_arch)
    GeneratePatchedOrderfile(options.unpatched_orderfile,
                             options.native_library, options.output_file)
    return 0
示例#3
0
def main():
    parser = CreateArgumentParser()
    args = parser.parse_args()
    logging.basicConfig(level=logging.INFO)

    symbol_extractor.SetArchitecture(args.arch)
    logging.info('Parsing object files in %s', args.build_directory)
    object_files_symbols = _GetSymbolNameToFilename(args.build_directory)
    native_lib_filename = os.path.join(args.build_directory, 'lib.unstripped',
                                       args.native_library)
    if not os.path.exists(native_lib_filename):
        logging.error('Native library not found. Did you build the APK?')
        return 1

    offset = 0
    if args.residency:
        with open(args.residency) as f:
            residency = json.load(f)
            offset = residency['offset']

    logging.info('Extracting symbols from %s', native_lib_filename)
    native_lib_symbols = symbol_extractor.SymbolInfosFromBinary(
        native_lib_filename)
    logging.info('%d Symbols found', len(native_lib_symbols))
    logging.info('Mapping symbols and object files to code pages')
    page_to_symbols = CodePagesToMangledSymbols(native_lib_symbols, offset)
    page_to_object_files = CodePagesToObjectFiles(object_files_symbols,
                                                  page_to_symbols)

    if args.reached_symbols_file:
        logging.info('Mapping reached symbols to code pages')
        reached_symbol_names = ReadReachedSymbols(args.reached_symbols_file)
        reached_data = CodePagesToReachedSize(reached_symbol_names,
                                              page_to_symbols)
        WriteReachedData(os.path.join(args.output_directory, 'reached.json'),
                         reached_data)

    if not os.path.exists(args.output_directory):
        os.makedirs(args.output_directory)
    text_output_filename = os.path.join(args.output_directory, 'map.txt')
    json_output_filename = os.path.join(args.output_directory, 'map.json')
    WriteCodePageAttribution(page_to_object_files, text_output_filename,
                             json_output_filename)
    directory = os.path.dirname(__file__)

    for filename in ['visualize.html', 'visualize.js', 'visualize.css']:
        if args.residency:
            shutil.copy(args.residency,
                        os.path.join(args.output_directory, 'residency.json'))
        shutil.copy(os.path.join(directory, filename),
                    os.path.join(args.output_directory, filename))

    if args.start_server:
        os.chdir(args.output_directory)
        httpd = SocketServer.TCPServer(
            ('', args.port), SimpleHTTPServer.SimpleHTTPRequestHandler)
        logging.warning('Serving on port %d', args.port)
        httpd.serve_forever()

    return 0
示例#4
0
def main():
    parser = optparse.OptionParser(
        usage='usage: %prog [options] <binary> <orderfile>')
    parser.add_option('--target-arch',
                      action='store',
                      dest='arch',
                      choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
                      help='The target architecture for the binary.')
    parser.add_option(
        '--threshold',
        action='store',
        dest='threshold',
        default=20,
        type=int,
        help='The maximum allowed number of out-of-order symbols.')
    options, argv = parser.parse_args(sys.argv)
    if not options.arch:
        options.arch = cygprofile_utils.DetectArchitecture()
    if len(argv) != 3:
        parser.print_help()
        return 1
    (binary_filename, orderfile_filename) = argv[1:]

    symbol_extractor.SetArchitecture(options.arch)
    symbol_infos = symbol_extractor.SymbolInfosFromBinary(binary_filename)

    if not _VerifySymbolOrder(
        [sym.strip() for sym in file(orderfile_filename)], symbol_infos,
            options.threshold):
        return 1
示例#5
0
    def __init__(self, options, orderfile_updater_class):
        self._options = options

        self._instrumented_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_instrumented_out')
        self._uninstrumented_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_uninstrumented_out')

        if options.profile:
            output_directory = os.path.join(self._instrumented_out_dir,
                                            'Release')
            host_profile_dir = os.path.join(output_directory, 'profile_data')
            urls = [profile_android_startup.AndroidProfileTool.TEST_URL]
            use_wpr = True
            simulate_user = False
            urls = options.urls
            use_wpr = not options.no_wpr
            simulate_user = options.simulate_user
            self._profiler = profile_android_startup.AndroidProfileTool(
                output_directory, host_profile_dir, use_wpr, urls,
                simulate_user)

        self._output_data = {}
        self._step_recorder = StepRecorder(options.buildbot)
        self._compiler = None
        assert issubclass(orderfile_updater_class, OrderfileUpdater)
        self._orderfile_updater = orderfile_updater_class(
            self._CLANK_REPO, self._step_recorder, options.branch,
            options.netrc)
        assert os.path.isdir(
            constants.DIR_SOURCE_ROOT), 'No src directory found'
        symbol_extractor.SetArchitecture(options.arch)
示例#6
0
def main(argv):
  parser = optparse.OptionParser(usage=
      'usage: %prog [options] <unpatched_orderfile> <library>')
  parser.add_option('--target-arch', action='store', dest='arch',
                    choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
                    help='The target architecture for the library.')
  options, argv = parser.parse_args(argv)
  if not options.arch:
    options.arch = cygprofile_utils.DetectArchitecture()
  if len(argv) != 3:
    parser.print_help()
    return 1
  orderfile_filename = argv[1]
  binary_filename = argv[2]
  symbol_extractor.SetArchitecture(options.arch)
  (offset_to_symbol_infos, name_to_symbol_infos) = _GroupSymbolInfosFromBinary(
      binary_filename)
  profiled_symbols = GetSymbolsFromOrderfile(orderfile_filename)
  expanded_symbols = _ExpandSymbols(
      profiled_symbols, name_to_symbol_infos, offset_to_symbol_infos)
  _PrintSymbolsWithPrefixes(expanded_symbols, sys.stdout)
  # The following is needed otherwise Gold only applies a partial sort.
  print '.text'    # gets methods not in a section, such as assembly
  print '.text.*'  # gets everything else
  return 0
    def __init__(self, options, orderfile_updater_class):
        self._options = options
        self._instrumented_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_instrumented_out')
        if self._options.use_call_graph:
            self._instrumented_out_dir += '_call_graph'

        self._uninstrumented_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_uninstrumented_out')
        self._no_orderfile_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_no_orderfile_out')

        self._PrepareOrderfilePaths()

        if options.profile:
            output_directory = os.path.join(self._instrumented_out_dir,
                                            'Release')
            host_profile_dir = os.path.join(output_directory, 'profile_data')
            urls = [profile_android_startup.AndroidProfileTool.TEST_URL]
            use_wpr = True
            simulate_user = False
            urls = options.urls
            use_wpr = not options.no_wpr
            simulate_user = options.simulate_user
            device = self._SetDevice()
            self._profiler = profile_android_startup.AndroidProfileTool(
                output_directory,
                host_profile_dir,
                use_wpr,
                urls,
                simulate_user,
                device,
                debug=self._options.streamline_for_debugging)
            if options.pregenerated_profiles:
                self._profiler.SetPregeneratedProfiles(
                    glob.glob(options.pregenerated_profiles))
        else:
            assert not options.pregenerated_profiles, (
                '--pregenerated-profiles cannot be used with --skip-profile')
            assert not options.profile_save_dir, (
                '--profile-save-dir cannot be used with --skip-profile')
            self._monochrome = not self._options.use_legacy_chrome_apk

        # Outlined function handling enabled by default for all architectures.
        self._order_outlined_functions = not options.noorder_outlined_functions

        self._output_data = {}
        self._step_recorder = StepRecorder(options.buildbot)
        self._compiler = None
        if orderfile_updater_class is None:
            if options.public:
                orderfile_updater_class = OrderfileNoopUpdater
            else:
                orderfile_updater_class = OrderfileUpdater
        assert issubclass(orderfile_updater_class, OrderfileUpdater)
        self._orderfile_updater = orderfile_updater_class(
            self._clank_dir, self._step_recorder)
        assert os.path.isdir(
            constants.DIR_SOURCE_ROOT), 'No src directory found'
        symbol_extractor.SetArchitecture(options.arch)
示例#8
0
def main():
  parser = _CreateArgumentParser()
  args = parser.parse_args()

  if not args.target_arch:
    args.arch = cygprofile_utils.DetectArchitecture()
  symbol_extractor.SetArchitecture(args.target_arch)

  offsets = _ReadReachedOffsets(args.reached_offsets)
  assert offsets
  _WarnAboutDuplicates(offsets)

  processor = process_profiles.SymbolOffsetProcessor(args.native_library)
  ordered_symbols = processor.GetOrderedSymbols(offsets)
  if ordered_symbols is None:
    return 1

  success = False
  temp_filename = None
  output_file = None
  try:
    (fd, temp_filename) = tempfile.mkstemp(dir=os.path.dirname(args.output))
    output_file = os.fdopen(fd, 'w')
    output_file.write('\n'.join(ordered_symbols))
    output_file.close()
    os.rename(temp_filename, args.output)
    temp_filename = None
    success = True
  finally:
    if output_file:
      output_file.close()
    if temp_filename:
      os.remove(temp_filename)

  return 0 if success else 1
示例#9
0
def main(argv):
    parser = optparse.OptionParser(
        usage='usage: %prog [options] <unpatched_orderfile> <library>')
    parser.add_option('--target-arch',
                      action='store',
                      dest='arch',
                      choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
                      help='The target architecture for the library.')
    options, argv = parser.parse_args(argv)
    if not options.arch:
        options.arch = cygprofile_utils.DetectArchitecture()
    if len(argv) != 3:
        parser.print_help()
        return 1
    orderfile_filename = argv[1]
    binary_filename = argv[2]
    symbol_extractor.SetArchitecture(options.arch)
    (offset_to_symbol_infos,
     name_to_symbol_infos) = _GroupSymbolInfosFromBinary(binary_filename)
    obj_dir = cygprofile_utils.GetObjDir(binary_filename)
    raw_symbol_map = cyglog_to_orderfile.GetSymbolToSectionsMapFromObjectFiles(
        obj_dir)
    suffixed = _SectionsWithSuffixes(raw_symbol_map)
    symbol_to_sections_map = _CombineSectionListsByPrimaryName(raw_symbol_map)
    section_to_symbols_map = cygprofile_utils.InvertMapping(
        symbol_to_sections_map)
    profiled_sections = _StripSuffixes(
        GetSectionsFromOrderfile(orderfile_filename))
    expanded_sections = _ExpandSections(profiled_sections,
                                        name_to_symbol_infos,
                                        offset_to_symbol_infos,
                                        section_to_symbols_map,
                                        symbol_to_sections_map, suffixed)

    # Make sure the anchor functions are located in the right place, here and
    # after everything else.
    # See the comment in //tools/cygprofile/lightweight_cyrprofile.cc.
    # The linker ignores sections it doesn't see, so this can stay for all builds.
    for prefix in _PREFIXES:
        print prefix + 'dummy_function_to_anchor_text'

    for section in expanded_sections:
        print section
    # The following is needed otherwise Gold only applies a partial sort.
    print '.text'  # gets methods not in a section, such as assembly
    for prefix in _PREFIXES:
        print prefix + '*'  # gets everything else

    for prefix in _PREFIXES:
        print prefix + 'dummy_function_at_the_end_of_text'

    return 0
示例#10
0
def _CreateNewOrderfile(native_library_filename, output_orderfile, arch):
    """Creates a new reordered orderfile.

  Args:
    native_library_filename: (str) Native library filename.
    output_orderfile: (str) Path to the output orderfile.
    arch: (str) Architecture
  """
    symbol_extractor.SetArchitecture(arch)
    symbol_infos = _ExtractAndProcessSymbols(native_library_filename)
    reordered = _ReorderSymbols(symbol_infos)
    with open(output_orderfile, 'w') as f:
        for s in reordered:
            f.write('%s\n' % s)
示例#11
0
def main():
    parser = _CreateArgumentParser()
    args = parser.parse_args()

    assert bool(args.merged_cyglog) ^ bool(args.reached_offsets)

    if not args.target_arch:
        args.arch = cygprofile_utils.DetectArchitecture()
    symbol_extractor.SetArchitecture(args.target_arch)

    obj_dir = cygprofile_utils.GetObjDir(args.native_library)

    offsets = []
    if args.merged_cyglog:
        log_file_lines = map(string.rstrip,
                             open(args.merged_cyglog).readlines())
        offsets = _ParseLogLines(log_file_lines)
    else:
        offsets = _ReadReachedOffsets(args.reached_offsets)
    assert offsets
    _WarnAboutDuplicates(offsets)

    generator = OffsetOrderfileGenerator(
        process_profiles.SymbolOffsetProcessor(args.native_library),
        ObjectFileProcessor(obj_dir))

    ordered_sections = generator.GetOrderedSections(offsets)
    if ordered_sections is None:
        return 1

    success = False
    temp_filename = None
    output_file = None
    try:
        (fd,
         temp_filename) = tempfile.mkstemp(dir=os.path.dirname(args.output))
        output_file = os.fdopen(fd, 'w')
        output_file.write('\n'.join(ordered_sections))
        output_file.close()
        os.rename(temp_filename, args.output)
        temp_filename = None
        success = True
    finally:
        if output_file:
            output_file.close()
        if temp_filename:
            os.remove(temp_filename)

    return 0 if success else 1
示例#12
0
def main():
    parser = optparse.OptionParser(
        usage=
        'usage: %prog [options] <merged_cyglog> <library> <output_filename>')
    parser.add_option('--target-arch',
                      action='store',
                      dest='arch',
                      choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
                      help='The target architecture for libchrome.so')
    options, argv = parser.parse_args(sys.argv)
    if not options.arch:
        options.arch = cygprofile_utils.DetectArchitecture()
    if len(argv) != 4:
        parser.print_help()
        return 1
    (log_filename, lib_filename, output_filename) = argv[1:]
    symbol_extractor.SetArchitecture(options.arch)

    obj_dir = os.path.abspath(
        os.path.join(os.path.dirname(lib_filename), '../obj'))

    log_file_lines = map(string.rstrip, open(log_filename).readlines())
    offsets = _ParseLogLines(log_file_lines)
    _WarnAboutDuplicates(offsets)

    offset_to_symbol_infos = _GroupLibrarySymbolInfosByOffset(lib_filename)
    symbol_to_section_map = _GetSymbolToSectionMapFromObjectFiles(obj_dir)

    success = False
    temp_filename = None
    output_file = None
    try:
        (fd, temp_filename) = tempfile.mkstemp(
            dir=os.path.dirname(output_filename))
        output_file = os.fdopen(fd, 'w')
        ok = _OutputOrderfile(offsets, offset_to_symbol_infos,
                              symbol_to_section_map, output_file)
        output_file.close()
        os.rename(temp_filename, output_filename)
        temp_filename = None
        success = ok
    finally:
        if output_file:
            output_file.close()
        if temp_filename:
            os.remove(temp_filename)

    return 0 if success else 1
示例#13
0
    def __init__(self, options, orderfile_updater_class):
        self._options = options

        self._instrumented_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_instrumented_out')
        self._uninstrumented_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_uninstrumented_out')

        if options.profile:
            output_directory = os.path.join(self._instrumented_out_dir,
                                            'Release')
            host_profile_dir = os.path.join(output_directory, 'profile_data')
            urls = [profile_android_startup.AndroidProfileTool.TEST_URL]
            use_wpr = True
            simulate_user = False
            urls = options.urls
            use_wpr = not options.no_wpr
            simulate_user = options.simulate_user
            self._profiler = profile_android_startup.AndroidProfileTool(
                output_directory,
                host_profile_dir,
                use_wpr,
                urls,
                simulate_user,
                device=options.device)
            if options.pregenerated_profiles:
                self._profiler.SetPregeneratedProfiles(
                    glob.glob(options.pregenerated_profiles))
        else:
            assert not options.pregenerated_profiles, (
                '--pregenerated-profiles cannot be used with --skip-profile')
            assert not options.profile_save_dir, (
                '--profile-save-dir cannot be used with --skip-profile')

        # Outlined function handling enabled by default for all architectures.
        self._order_outlined_functions = not options.noorder_outlined_functions

        self._output_data = {}
        self._step_recorder = StepRecorder(options.buildbot)
        self._compiler = None
        assert issubclass(orderfile_updater_class, OrderfileUpdater)
        self._orderfile_updater = orderfile_updater_class(
            self._CLANK_REPO, self._step_recorder, options.branch,
            options.netrc)
        assert os.path.isdir(
            constants.DIR_SOURCE_ROOT), 'No src directory found'
        symbol_extractor.SetArchitecture(options.arch)
示例#14
0
def main():
    parser = CreateArgumentParser()
    args = parser.parse_args()

    assert bool(args.merged_cyglog) ^ bool(args.reached_offsets)

    if not args.target_arch:
        args.arch = cygprofile_utils.DetectArchitecture()
    symbol_extractor.SetArchitecture(args.target_arch)

    obj_dir = cygprofile_utils.GetObjDir(args.native_library)

    offsets = []
    if args.merged_cyglog:
        log_file_lines = map(string.rstrip,
                             open(args.merged_cyglog).readlines())
        offsets = _ParseLogLines(log_file_lines)
    else:
        offsets = ReadReachedOffsets(args.reached_offsets)
    assert offsets
    _WarnAboutDuplicates(offsets)

    offset_to_symbol_infos = _GroupLibrarySymbolInfosByOffset(
        args.native_library)
    symbol_to_sections_map = GetSymbolToSectionsMapFromObjectFiles(obj_dir)

    success = False
    temp_filename = None
    output_file = None
    try:
        (fd,
         temp_filename) = tempfile.mkstemp(dir=os.path.dirname(args.output))
        output_file = os.fdopen(fd, 'w')
        ok = _OutputOrderfile(offsets, offset_to_symbol_infos,
                              symbol_to_sections_map, output_file)
        output_file.close()
        os.rename(temp_filename, args.output)
        temp_filename = None
        success = ok
    finally:
        if output_file:
            output_file.close()
        if temp_filename:
            os.remove(temp_filename)

    return 0 if success else 1
    def __init__(self, options, orderfile_updater_class):
        self._options = options

        self._instrumented_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_instrumented_out')
        self._uninstrumented_out_dir = os.path.join(
            self._BUILD_ROOT, self._options.arch + '_uninstrumented_out')

        if options.profile:
            output_directory = os.path.join(self._instrumented_out_dir,
                                            'Release')
            host_cyglog_dir = os.path.join(output_directory, 'cyglog_data')
            # Only override the defaults when using lightweight instrumentation,
            # as the regular profiling code is likely too slow for these.
            urls = [profile_android_startup.AndroidProfileTool.TEST_URL]
            use_wpr = True
            simulate_user = False
            if options.simulate_user and not options.lightweight_instrumentation:
                logging.error(
                    '--simulate-user required --lightweight-instrumentation, ignoring.'
                )
            if options.lightweight_instrumentation:
                urls = options.urls
                use_wpr = not options.no_wpr
                simulate_user = options.simulate_user
            self._profiler = profile_android_startup.AndroidProfileTool(
                output_directory, host_cyglog_dir, use_wpr, urls,
                simulate_user)

        self._output_data = {}
        self._step_recorder = StepRecorder(options.buildbot)
        self._compiler = None
        assert issubclass(orderfile_updater_class, OrderfileUpdater)
        self._orderfile_updater = orderfile_updater_class(
            self._CLANK_REPO, self._step_recorder, options.branch,
            options.netrc)
        assert os.path.isdir(
            constants.DIR_SOURCE_ROOT), 'No src directory found'
        symbol_extractor.SetArchitecture(options.arch)