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)
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
Beispiel #3
0
def GeneratePatchedOrderfile(unpatched_orderfile, native_lib_filename,
                             output_filename):
    """Writes a patched orderfile.

  Args:
    unpatched_orderfile: (str) Path to the unpatched orderfile.
    native_lib_filename: (str) Path to the native library.
    output_filename: (str) Path to the patched orderfile.
  """
    (offset_to_symbol_infos,
     name_to_symbol_infos) = _GroupSymbolInfosFromBinary(native_lib_filename)
    obj_dir = cygprofile_utils.GetObjDir(native_lib_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(unpatched_orderfile))
    expanded_sections = _ExpandSections(profiled_sections,
                                        name_to_symbol_infos,
                                        offset_to_symbol_infos,
                                        section_to_symbols_map,
                                        symbol_to_sections_map, suffixed)

    with open(output_filename, 'w') as f:
        # Make sure the anchor functions are located in the right place, here and
        # after everything else.
        # See the comment in //base/android/library_loader/anchor_functions.cc.
        for prefix in _PREFIXES:
            f.write(prefix + 'dummy_function_to_anchor_text\n')
        for prefix in _PREFIXES:
            f.write(prefix + 'dummy_function_start_of_ordered_text\n')

        for section in expanded_sections:
            f.write(section + '\n')

        for prefix in _PREFIXES:
            f.write(prefix + 'dummy_function_end_of_ordered_text\n')

        # The following is needed otherwise Gold only applies a partial sort.
        f.write('.text\n')  # gets methods not in a section, such as assembly
        f.write('.text.*\n')  # gets everything else

        # Since wildcards are not supported by lld, the "end of text" anchor symbol
        # is not emitted, a different mechanism is used instead. See comments in the
        # file above.
        for prefix in _PREFIXES:
            if prefix:
                f.write(prefix + 'dummy_function_at_the_end_of_text\n')