Пример #1
0
 def testSectionMatchingRules(self):
   symbol_name1 = 'symbol1'
   symbol_name2 = 'symbol2'
   symbol_name3 = 'symbol3'
   section_name1 = '.text.' + symbol_name1
   section_name3 = '.text.foo'
   suffixed = set([section_name3])
   name_to_symbol_infos = {symbol_name1: [
       symbol_extractor.SymbolInfo(symbol_name1, 0x42, 0x12,
                                   section='.text')]}
   offset_to_symbol_infos = {
       0x42: [symbol_extractor.SymbolInfo(symbol_name1, 0x42, 0x12,
                                          section='.text'),
              symbol_extractor.SymbolInfo(symbol_name2, 0x42, 0x12,
                                          section='.text')]}
   section_to_symbols_map = {section_name1: [symbol_name1],
                             section_name3: [symbol_name1, symbol_name3]}
   symbol_to_sections_map = {symbol_name1:
                                 [section_name1, section_name3],
                             symbol_name3: [section_name3]}
   expected = [
       section_name1,
       section_name3,
       section_name3 + '.*',
       '.text.startup.' + symbol_name1,
       '.text.hot.' + symbol_name1,
       '.text.unlikely.' + symbol_name1,
       '.text.startup.symbol2',
       '.text.hot.symbol2',
       '.text.unlikely.symbol2',
       '.text.symbol2']
   self.assertEqual(expected, list(patch_orderfile._SectionMatchingRules(
       section_name1, name_to_symbol_infos, offset_to_symbol_infos,
       section_to_symbols_map, symbol_to_sections_map, suffixed)))
Пример #2
0
 def testExpandSymbols(self):
     symbol_name = "dummySymbol"
     symbol_name2 = "other"
     profiled_symbol_names = [symbol_name, "symbolThatShouldntMatch"]
     name_to_symbol_infos = {
         symbol_name: [
             symbol_extractor.SymbolInfo(symbol_name,
                                         0x42,
                                         0x12,
                                         section='.text')
         ]
     }
     offset_to_symbol_infos = {
         0x42: [
             symbol_extractor.SymbolInfo(symbol_name,
                                         0x42,
                                         0x12,
                                         section='.text'),
             symbol_extractor.SymbolInfo(symbol_name2,
                                         0x42,
                                         0x12,
                                         section='.text')
         ]
     }
     symbol_names = patch_orderfile._ExpandSymbols(profiled_symbol_names,
                                                   name_to_symbol_infos,
                                                   offset_to_symbol_infos)
     self.assertEquals(len(symbol_names), 3)
     self.assertEquals(symbol_names[0], symbol_name)
     self.assertEquals(symbol_names[1], symbol_name2)
     self.assertEquals(symbol_names[2], "symbolThatShouldntMatch")
Пример #3
0
  def testOutputOrderfile(self):
    class FakeOutputFile(object):
      def __init__(self):
        self.writes = []

      def write(self, data):
        self.writes.append(data)

    # One symbol not matched, one with an odd address, one regularly matched
    # And two symbols aliased to the same address
    offsets = [0x12, 0x17]
    offset_to_symbol_infos = {
        0x10: [symbol_extractor.SymbolInfo(
            name='Symbol', offset=0x10, size=0x13, section='dummy')],
        0x12: [symbol_extractor.SymbolInfo(
            name='Symbol2', offset=0x12, size=0x13, section='dummy')],
        0x16: [symbol_extractor.SymbolInfo(
                   name='Symbol3', offset=0x16, size=0x13, section='dummy'),
               symbol_extractor.SymbolInfo(
                   name='Symbol32', offset=0x16, size=0x13, section='dummy'),]}
    symbol_to_sections_map = {
        'Symbol': ['.text.Symbol'],
        'Symbol2': ['.text.Symbol2', '.text.hot.Symbol2'],
        'Symbol3': ['.text.Symbol3'],
        'Symbol32': ['.text.Symbol32']}
    fake_output = FakeOutputFile()
    cyglog_to_orderfile._OutputOrderfile(
        offsets, offset_to_symbol_infos, symbol_to_sections_map, fake_output)
    expected = """.text.Symbol2
.text.hot.Symbol2
.text.Symbol3
.text.Symbol32
"""
    self.assertEquals(expected, ''.join(fake_output.writes))
Пример #4
0
 def testSymbolsWithSameOffset(self):
     symbol_name = "dummySymbol"
     symbol_name2 = "other"
     name_to_symbol_infos = {
         symbol_name: [
             symbol_extractor.SymbolInfo(symbol_name,
                                         0x42,
                                         0x12,
                                         section='.text')
         ]
     }
     offset_to_symbol_infos = {
         0x42: [
             symbol_extractor.SymbolInfo(symbol_name,
                                         0x42,
                                         0x12,
                                         section='.text'),
             symbol_extractor.SymbolInfo(symbol_name2,
                                         0x42,
                                         0x12,
                                         section='.text')
         ]
     }
     symbol_names = patch_orderfile._SymbolsWithSameOffset(
         symbol_name, name_to_symbol_infos, offset_to_symbol_infos)
     self.assertEquals(len(symbol_names), 2)
     self.assertEquals(symbol_names[0], symbol_name)
     self.assertEquals(symbol_names[1], symbol_name2)
     self.assertEquals([],
                       patch_orderfile._SymbolsWithSameOffset(
                           "symbolThatShouldntMatch", name_to_symbol_infos,
                           offset_to_symbol_infos))
 def setUp(self):
     self.symbol_infos = [
         symbol_extractor.SymbolInfo('firstNameAtOffset', 0x42, 42,
                                     '.text'),
         symbol_extractor.SymbolInfo('secondNameAtOffset', 0x42, 42,
                                     '.text'),
         symbol_extractor.SymbolInfo('thirdSymbol', 0x64, 20, '.text')
     ]
Пример #6
0
 def testGroupSymbolsByOffset(self):
   symbol_infos = (
       symbol_extractor.SymbolInfo(name='aSymbol', offset=0x42, size=0x12,
                                   section='.text'),
       symbol_extractor.SymbolInfo(name='anotherSymbol', offset=0x42, size=1,
                                   section='.text'))
   (offset_to_symbol_infos, _) = \
       patch_orderfile._GroupSymbolInfos(symbol_infos)
   self.assertEquals(len(offset_to_symbol_infos), 1)
   self.assertEquals(tuple(offset_to_symbol_infos[0x42]), symbol_infos)
 def testSymbolInfosFromStream(self):
     lines = [
         'Garbage', '', '00c1c05c l     F .text  0000002c first', ''
         'more garbage', '00155 g     F .text  00000012 second'
     ]
     symbol_infos = symbol_extractor._SymbolInfosFromStream(lines)
     self.assertEquals(len(symbol_infos), 2)
     first = symbol_extractor.SymbolInfo('first', 0x00c1c05c, 0x2c, '.text')
     self.assertEquals(first, symbol_infos[0])
     second = symbol_extractor.SymbolInfo('second', 0x00155, 0x12, '.text')
     self.assertEquals(second, symbol_infos[1])
Пример #8
0
 def testAliasClonedSymbols(self):
   symbol_infos = [
       symbol_extractor.SymbolInfo(name='aSymbol', offset=0x42, size=0x12,
                                   section='.text'),
       symbol_extractor.SymbolInfo(name='aSymbol.clone.', offset=8, size=1,
                                   section='.text')]
   (offset_to_symbol_infos, name_to_symbol_infos) = \
       patch_orderfile._GroupSymbolInfos(symbol_infos)
   self.assertEquals(len(offset_to_symbol_infos), 2)
   for i in range(2):
     s = symbol_infos[i]
     matching = offset_to_symbol_infos[s.offset][0]
     self.assertEquals(matching.offset, s.offset)
     self.assertEquals(matching.size, s.size)
   self.assertEquals(len(name_to_symbol_infos), 1)
   self.assertEquals(len(name_to_symbol_infos['aSymbol']), 2)
Пример #9
0
class TestCheckOrderFile(unittest.TestCase):
    _SYMBOL_INFOS = [
        symbol_extractor.SymbolInfo('first', 0x1, 0, ''),
        symbol_extractor.SymbolInfo('second', 0x2, 0, ''),
        symbol_extractor.SymbolInfo('notProfiled', 0x4, 0, ''),
        symbol_extractor.SymbolInfo('third', 0x3, 0, ''),
    ]

    def testVerifySymbolOrder(self):
        self.assertTrue(
            check_orderfile._VerifySymbolOrder(
                ['.second', 'first', 'eighth', 'third'], self._SYMBOL_INFOS,
                0))
        self.assertFalse(
            check_orderfile._VerifySymbolOrder(
                ['second', 'first', 'eighth', 'third'], self._SYMBOL_INFOS, 0))
        self.assertTrue(
            check_orderfile._VerifySymbolOrder(
                ['second', 'first', 'eighth', 'third'], self._SYMBOL_INFOS, 1))
Пример #10
0
 def testFindSymbolInfosAtOffsetNoMatch(self):
     offset_map = {
         0x10: [
             symbol_extractor.SymbolInfo(name='Symbol',
                                         offset=0x10,
                                         size=0x13,
                                         section='.text')
         ]
     }
     self.assertRaises(cyglog_to_orderfile.SymbolNotFoundException,
                       cyglog_to_orderfile._FindSymbolInfosAtOffset,
                       offset_map, 0x12)
Пример #11
0
 def testFindSymbolInfosAtOffsetInexactMatch(self):
     offset_map = {
         0x10: [
             symbol_extractor.SymbolInfo(name='Symbol',
                                         offset=0x10,
                                         size=0x13,
                                         section='.text')
         ]
     }
     functions = cyglog_to_orderfile._FindSymbolInfosAtOffset(
         offset_map, 0x11)
     self.assertEquals(len(functions), 1)
     self.assertEquals(functions[0], offset_map[0x10][0])
Пример #12
0
    def testSymbolCollisions(self):
        symbol_infos_with_collision = list(self.symbol_infos)
        symbol_infos_with_collision.append(
            symbol_extractor.SymbolInfo('secondNameAtOffset', 0x84, 42,
                                        '.text'))

        # The symbol added above should not affect the output.
        name_to_symbol_info = symbol_extractor.CreateNameToSymbolInfo(
            self.symbol_infos)
        self.assertEquals(len(name_to_symbol_info), 3)
        for i in range(3):
            name = self.symbol_infos[i].name
            self.assertIn(name, name_to_symbol_info)
            self.assertEquals(self.symbol_infos[i], name_to_symbol_info[name])
class TestCheckOrderFile(unittest.TestCase):
    _SYMBOL_INFOS = [
        symbol_extractor.SymbolInfo('first', 0x1, 0, ''),
        symbol_extractor.SymbolInfo('second', 0x2, 0, ''),
        symbol_extractor.SymbolInfo('notProfiled', 0x4, 0, ''),
        symbol_extractor.SymbolInfo('third', 0x3, 0, ''),
    ]

    def testMatchesSymbols(self):
        symbols = ['first', 'second', 'third']
        (misordered_pairs_count, matched_count,
         missing_count) = (check_orderfile._CountMisorderedSymbols(
             symbols, self._SYMBOL_INFOS))
        self.assertEquals(
            (misordered_pairs_count, matched_count, missing_count), (0, 3, 0))

    def testMissingMatches(self):
        symbols = ['second', 'third', 'other', 'first']
        (_, matched_count,
         unmatched_count) = (check_orderfile._CountMisorderedSymbols(
             symbols, self._SYMBOL_INFOS))
        self.assertEquals(matched_count, 3)
        self.assertEquals(unmatched_count, 1)

    def testNoUnorderedSymbols(self):
        symbols = ['first', 'other', 'second', 'third', 'noMatchEither']
        (misordered_pairs_count, _,
         _) = (check_orderfile._CountMisorderedSymbols(symbols,
                                                       self._SYMBOL_INFOS))
        self.assertEquals(misordered_pairs_count, 0)

    def testUnorderedSymbols(self):
        symbols = ['first', 'other', 'third', 'second', 'noMatchEither']
        (misordered_pairs_count, _,
         _) = (check_orderfile._CountMisorderedSymbols(symbols,
                                                       self._SYMBOL_INFOS))
        self.assertEquals(misordered_pairs_count, 1)
Пример #14
0
def _CountMisorderedSymbols(symbols, symbol_infos):
    """Count the number of misordered symbols, and log them.

  Args:
    symbols: ordered sequence of symbols from the orderfile
    symbol_infos: ordered list of SymbolInfo from the binary

  Returns:
    (misordered_pairs_count, matched_symbols_count, unmatched_symbols_count)
  """
    name_to_symbol_info = symbol_extractor.CreateNameToSymbolInfo(symbol_infos)
    matched_symbol_infos = []
    missing_count = 0
    misordered_count = 0

    # Find the SymbolInfo matching the orderfile symbols in the binary.
    for symbol in symbols:
        if symbol in name_to_symbol_info:
            matched_symbol_infos.append(name_to_symbol_info[symbol])
        else:
            missing_count += 1
            if missing_count < _MAX_WARNINGS_TO_PRINT:
                logging.warning(
                    'Symbol "%s" is in the orderfile, not in the binary' %
                    symbol)
    logging.info(
        '%d matched symbols, %d un-matched (Only the first %d unmatched'
        ' symbols are shown)' %
        (len(matched_symbol_infos), missing_count, _MAX_WARNINGS_TO_PRINT))

    # In the order of the orderfile, find all the symbols that are at an offset
    # smaller than their immediate predecessor, and record the pair.
    previous_symbol_info = symbol_extractor.SymbolInfo(name='',
                                                       offset=-1,
                                                       size=0,
                                                       section='')
    for symbol_info in matched_symbol_infos:
        if symbol_info.offset < previous_symbol_info.offset and not (
                _IsSameMethod(symbol_info.name, previous_symbol_info.name)):
            logging.warning('Misordered pair: %s - %s' %
                            (str(previous_symbol_info), str(symbol_info)))
            misordered_count += 1
        previous_symbol_info = symbol_info
    return (misordered_count, len(matched_symbol_infos), missing_count)
def _GroupSymbolInfos(symbol_infos):
    """Groups the symbol infos by name and offset.

  Args:
    symbol_infos: an iterable of SymbolInfo

  Returns:
    The same output as _GroupSymbolInfosFromBinary.
  """
    # Map the addresses to symbols.
    offset_to_symbol_infos = collections.defaultdict(list)
    name_to_symbol_infos = collections.defaultdict(list)
    for symbol in symbol_infos:
        symbol = symbol_extractor.SymbolInfo(name=RemoveSuffixes(symbol.name),
                                             offset=symbol.offset,
                                             size=symbol.size,
                                             section=symbol.section)
        offset_to_symbol_infos[symbol.offset].append(symbol)
        name_to_symbol_infos[symbol.name].append(symbol)
    return (dict(offset_to_symbol_infos), dict(name_to_symbol_infos))