def testInvertMapping(self): inputMap = {'1': ['2', '3'], '4': ['2', '5']} self.assertEqual(cygprofile_utils.InvertMapping(inputMap), { '2': ['1', '4'], '3': ['1'], '5': ['4'] })
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 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.ObjectFileProcessor( obj_dir).GetSymbolToSectionsMap() 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. # # __cxx_global_var_init is one of the largest symbols (~38kB as of May # 2018), called extremely early, and not instrumented. first_sections = ('dummy_function_start_of_ordered_text', '__cxx_global_var_init') for section in first_sections: for prefix in _PREFIXES: f.write(prefix + section + '\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')
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