diff options
author | tim <tim2.lin@ite.corp-partner.google.com> | 2018-08-20 13:49:17 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-20 07:29:24 -0700 |
commit | 4b490cbb31aa9cb817864cf525fce21bf2943c41 (patch) | |
tree | 83cfe957ac005e49624695bff56de3ad76b27fd6 /extra | |
parent | bffd2b87343bf351781b5a0e441c304b55d0a05f (diff) | |
download | chrome-ec-4b490cbb31aa9cb817864cf525fce21bf2943c41.tar.gz |
stack_analyzer_unittest: Unit test of analyze disassembly for Andes instructionstabilize-10985.B
Write a rough disassembly with Andes instruction in
stack_analyzer_unittest.py which rough disassembly is analyzed
by stack_analyzer.py to get some results. If these results are
the same with expect results, the unit test will pass.
In the rough disassembly, the file format is added in the second
line, because the stack analyzer will be looking for the word of
'arm' or 'nds' in the line, and then get the corresponding Analyzer
class.
BUG=b:111746842
BRANCH=none
TEST=./extra/stack_analyzer/run_tests.sh
Change-Id: I3acbfb199f762a4e89ea95f6254628871a5beb5d
Signed-off-by: tim <tim2.lin@ite.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/1174331
Commit-Ready: Tim2 Lin <tim2.lin@ite.corp-partner.google.com>
Tested-by: Tim2 Lin <tim2.lin@ite.corp-partner.google.com>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'extra')
-rwxr-xr-x | extra/stack_analyzer/stack_analyzer_unittest.py | 102 |
1 files changed, 100 insertions, 2 deletions
diff --git a/extra/stack_analyzer/stack_analyzer_unittest.py b/extra/stack_analyzer/stack_analyzer_unittest.py index d159b2e14a..eb2f69b751 100755 --- a/extra/stack_analyzer/stack_analyzer_unittest.py +++ b/extra/stack_analyzer/stack_analyzer_unittest.py @@ -424,9 +424,46 @@ class StackAnalyzerTest(unittest.TestCase): [funcs[0x2000], funcs[0x4000], funcs[0x2000]], ]) - def testAnalyzeDisassembly(self): + def testAndesAnalyzeDisassembly(self): disasm_text = ( '\n' + 'build/{BOARD}/RW/ec.RW.elf: file format elf32-nds32le' + '\n' + 'Disassembly of section .text:\n' + '\n' + '00000900 <wook_task>:\n' + ' ...\n' + '00001000 <hook_task>:\n' + ' 1000: fc 42\tpush25 $r10, #16 ! {$r6~$r10, $fp, $gp, $lp}\n' + ' 1004: 47 70\t\tmovi55 $r0, #1\n' + ' 1006: b1 13\tbnezs8 100929de <flash_command_write>\n' + ' 1008: 00 01 5c fc\tbne $r6, $r0, 2af6a\n' + '00002000 <console_task>:\n' + ' 2000: fc 00\t\tpush25 $r6, #0 ! {$r6, $fp, $gp, $lp} \n' + ' 2002: f0 0e fc c5\tjal 1000 <hook_task>\n' + ' 2006: f0 0e bd 3b\tj 53968 <get_program_memory_addr>\n' + ' 200a: de ad be ef\tswi.gp $r0, [ + #-11036]\n' + '00004000 <touchpad_calc>:\n' + ' 4000: 47 70\t\tmovi55 $r0, #1\n' + '00010000 <look_task>:' + ) + function_map = self.analyzer.AnalyzeDisassembly(disasm_text) + func_hook_task = sa.Function(0x1000, 'hook_task', 48, [ + sa.Callsite(0x1006, 0x100929de, True, None)]) + expect_funcmap = { + 0x1000: func_hook_task, + 0x2000: sa.Function(0x2000, 'console_task', 16, + [sa.Callsite(0x2002, 0x1000, False, func_hook_task), + sa.Callsite(0x2006, 0x53968, True, None)]), + 0x4000: sa.Function(0x4000, 'touchpad_calc', 0, []), + } + self.assertEqual(function_map, expect_funcmap) + + def testArmAnalyzeDisassembly(self): + disasm_text = ( + '\n' + 'build/{BOARD}/RW/ec.RW.elf: file format elf32-littlearm' + '\n' 'Disassembly of section .text:\n' '\n' '00000900 <wook_task>:\n' @@ -597,9 +634,70 @@ class StackAnalyzerTest(unittest.TestCase): @mock.patch('subprocess.check_output') @mock.patch('stack_analyzer.StackAnalyzer.AddressToLine') - def testAnalyze(self, addrtoline_mock, checkoutput_mock): + def testAndesAnalyze(self, addrtoline_mock, checkoutput_mock): disasm_text = ( '\n' + 'build/{BOARD}/RW/ec.RW.elf: file format elf32-nds32le' + '\n' + 'Disassembly of section .text:\n' + '\n' + '00000900 <wook_task>:\n' + ' ...\n' + '00001000 <hook_task>:\n' + ' 1000: fc 00\t\tpush25 $r10, #16 ! {$r6~$r10, $fp, $gp, $lp}\n' + ' 1002: 47 70\t\tmovi55 $r0, #1\n' + ' 1006: 00 01 5c fc\tbne $r6, $r0, 2af6a\n' + '00002000 <console_task>:\n' + ' 2000: fc 00\t\tpush25 $r6, #0 ! {$r6, $fp, $gp, $lp} \n' + ' 2002: f0 0e fc c5\tjal 1000 <hook_task>\n' + ' 2006: f0 0e bd 3b\tj 53968 <get_program_memory_addr>\n' + ' 200a: 12 34 56 78\tjral5 $r0\n' + ) + + addrtoline_mock.return_value = [('??', '??', 0)] + self.analyzer.annotation = { + 'exception_frame_size': 64, + 'remove': [['fake_func']], + } + + with mock.patch('__builtin__.print') as print_mock: + checkoutput_mock.return_value = disasm_text + self.analyzer.Analyze() + print_mock.assert_has_calls([ + mock.call( + 'Task: HOOKS, Max size: 96 (32 + 64), Allocated size: 2048'), + mock.call('Call Trace:'), + mock.call(' hook_task (32) [??:0] 1000'), + mock.call( + 'Task: CONSOLE, Max size: 112 (48 + 64), Allocated size: 460'), + mock.call('Call Trace:'), + mock.call(' console_task (16) [??:0] 2000'), + mock.call(' -> ??[??:0] 2002'), + mock.call(' hook_task (32) [??:0] 1000'), + mock.call('Unresolved indirect callsites:'), + mock.call(' In function console_task:'), + mock.call(' -> ??[??:0] 200a'), + mock.call('Unresolved annotation signatures:'), + mock.call(' fake_func: function is not found'), + ]) + + with self.assertRaisesRegexp(sa.StackAnalyzerError, + 'Failed to run objdump.'): + checkoutput_mock.side_effect = OSError() + self.analyzer.Analyze() + + with self.assertRaisesRegexp(sa.StackAnalyzerError, + 'objdump failed to disassemble.'): + checkoutput_mock.side_effect = subprocess.CalledProcessError(1, '') + self.analyzer.Analyze() + + @mock.patch('subprocess.check_output') + @mock.patch('stack_analyzer.StackAnalyzer.AddressToLine') + def testArmAnalyze(self, addrtoline_mock, checkoutput_mock): + disasm_text = ( + '\n' + 'build/{BOARD}/RW/ec.RW.elf: file format elf32-littlearm' + '\n' 'Disassembly of section .text:\n' '\n' '00000900 <wook_task>:\n' |