def test_trailing_nops(self): old, new = self.read_anon_namespace_files() FNNAME = 'loops_state_set(unsigned int)' oldfn = old.functions[FNNAME] newfn = new.functions[FNNAME] self.assertEqual(oldfn.padding, []) self.assertEqual(newfn.padding, [Instruction(0x353, [144], 'nop')]) self.assertTrue(fn_equal(oldfn, newfn))
def test_adding_anon_namespace(self): old, new = self.read_anon_namespace_files() peers = FunctionMatchupSet(old, new) self.assertEqual(peers.gone, []) self.assertEqual(peers.appeared, []) oldfn = old.get_demangled_function( 'tracer_state::find_trace(basic_block_def*, basic_block_def**)') self.assertIn(oldfn, peers.old_to_new) newfn = peers.old_to_new[oldfn] self.assertEqual( newfn.demangled, '(anonymous namespace)::tracer_state::find_trace(basic_block_def*, basic_block_def**)') oldfn = old.functions['gate_tracer()'] newfn = new.functions['gate_tracer()'] self.assertTrue(fn_equal(oldfn, newfn)) # Some functions move from their own sections to the .text section: oldfn = old.get_demangled_function( 'tracer_state::bb_seen_p(basic_block_def*)') self.assertIn(oldfn, peers.old_to_new) newfn = peers.old_to_new[oldfn] self.assertEqual( newfn.demangled, '(anonymous namespace)::tracer_state::bb_seen_p(basic_block_def*)') self.assertEqual(oldfn.section.name, '.text._ZN12tracer_state9bb_seen_pEP15basic_block_def') self.assertEqual(oldfn.offset, 0x0) self.assertEqual(newfn.section.name, '.text') self.assertEqual(newfn.offset, 0x3b6) # Currently bb_seen_p is reported as having changed, purely due to # the following 5-byte instruction: # # FN+0x1f: Old: callq THIS_FN+0x24 # : New: callq <bitmap_bit_p(simple_bitmap_def const*, int)> # Old: e8 00 00 00 00 # New: e8 c8 fd ff ff # In the old function, bitmap_bit_p is in a different section, # whereas in the new they are both in the .text section. # Presumably in the old object this call gets patched based on where # the callee ends up # Ultimately we need "objdump -r" to see the relocations old_callq = oldfn.get_instr_at_relative_offset(0x1f) new_callq = newfn.get_instr_at_relative_offset(0x1f) self.assertEqual(old_callq.disasm, 'callq THIS_FN+0x24') self.assertEqual(new_callq.disasm, 'callq <bitmap_bit_p(simple_bitmap_def const*, int)>') out = self.get_diff(old, new) self.assertIn('Old: tracer.o\n', out) self.assertIn('New: tracer.o\n', out) self.assertIn(' Unchanged function: ei_container(edge_iterator)\n', out) self.assertIn(('\n' ' Unchanged function: gate_tracer()\n' ' (moved offset within .text from 0x11a8 to 0x1236)\n'), out) self.assertIn(('\n' ' Unchanged function: tracer_state::find_best_successor(basic_block_def*)\n' ' (renamed to (anonymous namespace)::tracer_state::find_best_successor(basic_block_def*))\n' ' (moved offset within .text from 0x560 to 0x5ee)\n'), out) # tracer_state::bb_seen_p(basic_block_def*): self.assertIn(' (moved from .text._ZN12tracer_state9bb_seen_pEP15basic_block_def+0x0 to .text+0x3b6)', out)
def test_adding_anon_namespace(self): old, new = self.read_anon_namespace_files() peers = FunctionMatchupSet(old, new) self.assertEqual(peers.gone, []) self.assertEqual(peers.appeared, []) oldfn = old.get_demangled_function( 'tracer_state::find_trace(basic_block_def*, basic_block_def**)') self.assertIn(oldfn, peers.old_to_new) newfn = peers.old_to_new[oldfn] self.assertEqual( newfn.demangled, '(anonymous namespace)::tracer_state::find_trace(basic_block_def*, basic_block_def**)' ) oldfn = old.functions['gate_tracer()'] newfn = new.functions['gate_tracer()'] self.assertTrue(fn_equal(oldfn, newfn)) # Some functions move from their own sections to the .text section: oldfn = old.get_demangled_function( 'tracer_state::bb_seen_p(basic_block_def*)') self.assertIn(oldfn, peers.old_to_new) newfn = peers.old_to_new[oldfn] self.assertEqual( newfn.demangled, '(anonymous namespace)::tracer_state::bb_seen_p(basic_block_def*)') self.assertEqual( oldfn.section.name, '.text._ZN12tracer_state9bb_seen_pEP15basic_block_def') self.assertEqual(oldfn.offset, 0x0) self.assertEqual(newfn.section.name, '.text') self.assertEqual(newfn.offset, 0x3b6) # Currently bb_seen_p is reported as having changed, purely due to # the following 5-byte instruction: # # FN+0x1f: Old: callq THIS_FN+0x24 # : New: callq <bitmap_bit_p(simple_bitmap_def const*, int)> # Old: e8 00 00 00 00 # New: e8 c8 fd ff ff # In the old function, bitmap_bit_p is in a different section, # whereas in the new they are both in the .text section. # Presumably in the old object this call gets patched based on where # the callee ends up # Ultimately we need "objdump -r" to see the relocations old_callq = oldfn.get_instr_at_relative_offset(0x1f) new_callq = newfn.get_instr_at_relative_offset(0x1f) self.assertEqual(old_callq.disasm, 'callq THIS_FN+0x24') self.assertEqual( new_callq.disasm, 'callq <bitmap_bit_p(simple_bitmap_def const*, int)>') out = self.get_diff(old, new) self.assertIn('Old: tracer.o\n', out) self.assertIn('New: tracer.o\n', out) self.assertIn(' Unchanged function: ei_container(edge_iterator)\n', out) self.assertIn( ('\n' ' Unchanged function: gate_tracer()\n' ' (moved offset within .text from 0x11a8 to 0x1236)\n'), out) self.assertIn(( '\n' ' Unchanged function: tracer_state::find_best_successor(basic_block_def*)\n' ' (renamed to (anonymous namespace)::tracer_state::find_best_successor(basic_block_def*))\n' ' (moved offset within .text from 0x560 to 0x5ee)\n'), out) # tracer_state::bb_seen_p(basic_block_def*): self.assertIn( ' (moved from .text._ZN12tracer_state9bb_seen_pEP15basic_block_def+0x0 to .text+0x3b6)', out)