summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortim <tim2.lin@ite.corp-partner.google.com>2018-08-20 13:49:17 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-08-20 07:29:24 -0700
commit4b490cbb31aa9cb817864cf525fce21bf2943c41 (patch)
tree83cfe957ac005e49624695bff56de3ad76b27fd6
parentbffd2b87343bf351781b5a0e441c304b55d0a05f (diff)
downloadchrome-ec-stabilize-10985.B.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>
-rwxr-xr-xextra/stack_analyzer/stack_analyzer_unittest.py102
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'