summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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'