Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Side by Side Diff: tests/debug_stub/debug_stub_test.py

Issue 107313005: [MIPS] Add support for debug stub test (Closed) Base URL: http://git.chromium.org/native_client/src/native_client.git@master
Patch Set: Minor code style update. Created 6 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/debug_stub/debugger_test.c » ('j') | tests/debug_stub/debugger_test.c » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Native Client Authors. All rights reserved. 1 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import re 5 import re
6 import struct 6 import struct
7 import subprocess 7 import subprocess
8 import sys 8 import sys
9 import unittest 9 import unittest
10 import xml.etree.ElementTree 10 import xml.etree.ElementTree
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 ('es', 'I'), 82 ('es', 'I'),
83 ('fs', 'I'), 83 ('fs', 'I'),
84 ('gs', 'I'), 84 ('gs', 'I'),
85 ] 85 ]
86 86
87 87
88 ARM_REG_DEFS = ([('r%d' % regno, 'I') for regno in xrange(16)] 88 ARM_REG_DEFS = ([('r%d' % regno, 'I') for regno in xrange(16)]
89 + [('cpsr', 'I')]) 89 + [('cpsr', 'I')])
90 90
91 91
92 MIPS_REG_DEFS = [
93 ('zero', 'I'),
94 ('at', 'I'),
95 ('v0', 'I'),
96 ('v1', 'I'),
97 ('a0', 'I'),
98 ('a1', 'I'),
99 ('a2', 'I'),
100 ('a3', 'I'),
101 ('t0', 'I'),
102 ('t1', 'I'),
103 ('t2', 'I'),
104 ('t3', 'I'),
105 ('t4', 'I'),
106 ('t5', 'I'),
107 ('t6', 'I'),
108 ('t7', 'I'),
109 ('s0', 'I'),
110 ('s1', 'I'),
111 ('s2', 'I'),
112 ('s3', 'I'),
113 ('s4', 'I'),
114 ('s5', 'I'),
115 ('s6', 'I'),
116 ('s7', 'I'),
117 ('t8', 'I'),
118 ('t9', 'I'),
119 ('k0', 'I'),
120 ('k1', 'I'),
121 ('global_ptr', 'I'),
122 ('stack_ptr', 'I'),
123 ('frame_ptr', 'I'),
124 ('return_addr', 'I'),
125 ('prog_ctr', 'I'),
126 ]
127
128
92 REG_DEFS = { 129 REG_DEFS = {
93 'x86-32': X86_32_REG_DEFS, 130 'x86-32': X86_32_REG_DEFS,
94 'x86-64': X86_64_REG_DEFS, 131 'x86-64': X86_64_REG_DEFS,
95 'arm': ARM_REG_DEFS, 132 'arm': ARM_REG_DEFS,
133 'mips32': MIPS_REG_DEFS,
96 } 134 }
97 135
98 136
99 SP_REG = { 137 SP_REG = {
100 'x86-32': 'esp', 138 'x86-32': 'esp',
101 'x86-64': 'rsp', 139 'x86-64': 'rsp',
102 'arm': 'r13', 140 'arm': 'r13',
141 'mips32': 'stack_ptr',
103 } 142 }
104 143
105 144
106 IP_REG = { 145 IP_REG = {
107 'x86-32': 'eip', 146 'x86-32': 'eip',
108 'x86-64': 'rip', 147 'x86-64': 'rip',
109 'arm': 'r15', 148 'arm': 'r15',
149 'mips32': 'prog_ctr',
110 } 150 }
111 151
112 152
113 X86_TRAP_FLAG = 1 << 8 153 X86_TRAP_FLAG = 1 << 8
114 154
115 # RESET_X86_FLAGS_VALUE is what ASM_WITH_REGS() resets the x86 flags 155 # RESET_X86_FLAGS_VALUE is what ASM_WITH_REGS() resets the x86 flags
116 # to. Copied from tests/common/register_set.h. 156 # to. Copied from tests/common/register_set.h.
117 RESET_X86_FLAGS_VALUE = (1 << 2) | (1 << 6) 157 RESET_X86_FLAGS_VALUE = (1 << 2) | (1 << 6)
118 KNOWN_X86_FLAGS_MASK = (1<<0) | (1<<2) | (1<<6) | (1<<7) | (1<<11) | (1<<8) 158 KNOWN_X86_FLAGS_MASK = (1<<0) | (1<<2) | (1<<6) | (1<<7) | (1<<11) | (1<<8)
119 159
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 self.assertEquals(registers['r8'], 0x80000009) 321 self.assertEquals(registers['r8'], 0x80000009)
282 # Skip r9 because it is not supposed to be settable or readable 322 # Skip r9 because it is not supposed to be settable or readable
283 # by untrusted code. 323 # by untrusted code.
284 self.assertEquals(registers['r10'], 0xa000000b) 324 self.assertEquals(registers['r10'], 0xa000000b)
285 self.assertEquals(registers['r11'], 0xb000000c) 325 self.assertEquals(registers['r11'], 0xb000000c)
286 self.assertEquals(registers['r12'], 0xc000000d) 326 self.assertEquals(registers['r12'], 0xc000000d)
287 self.assertEquals(registers['r13'], 0x12345678) 327 self.assertEquals(registers['r13'], 0x12345678)
288 self.assertEquals(registers['r14'], 0xe000000f) 328 self.assertEquals(registers['r14'], 0xe000000f)
289 self.assertEquals(registers['cpsr'] & ARM_USER_CPSR_FLAGS_MASK, 329 self.assertEquals(registers['cpsr'] & ARM_USER_CPSR_FLAGS_MASK,
290 (1 << 29) | (1 << 27)) 330 (1 << 29) | (1 << 27))
331 elif ARCH == 'mips32':
332 # We skip zero register because it can not be set.
Mark Seaborn 2013/12/26 17:01:13 Nit: 'cannot' is one word
petarj 2013/12/26 18:36:24 'can not' is also correct and acceptable from the
333 self.assertEquals(registers['at'], 0x11000220)
334 self.assertEquals(registers['v0'], 0x22000330)
335 self.assertEquals(registers['v1'], 0x33000440)
336 self.assertEquals(registers['a0'], 0x44000550)
337 self.assertEquals(registers['a1'], 0x55000660)
338 self.assertEquals(registers['a2'], 0x66000770)
339 self.assertEquals(registers['a3'], 0x77000880)
340 self.assertEquals(registers['t0'], 0x88000990)
341 self.assertEquals(registers['t1'], 0x99000AA0)
Mark Seaborn 2013/12/26 17:01:13 Nit: use lower-case hex to match code above
petarj 2013/12/26 18:36:24 Done.
342 self.assertEquals(registers['t2'], 0xAA000BB0)
343 self.assertEquals(registers['t3'], 0xBB000CC0)
344 self.assertEquals(registers['t4'], 0xCC000DD0)
345 self.assertEquals(registers['t5'], 0xDD000EE0)
346 self.assertEquals(registers['t6'], 0x0FFFFFF0)
347 self.assertEquals(registers['t7'], 0x3FFFFFFF)
348 # Skip t8 because it can not be set by untrusted code.
349 self.assertEquals(registers['s0'], 0x11100222)
350 self.assertEquals(registers['s1'], 0x22200333)
351 self.assertEquals(registers['s2'], 0x33300444)
352 self.assertEquals(registers['s3'], 0x44400555)
353 self.assertEquals(registers['s4'], 0x55500666)
354 self.assertEquals(registers['s5'], 0x66600777)
355 self.assertEquals(registers['s6'], 0x77700888)
356 self.assertEquals(registers['s7'], 0x88800999)
357 self.assertEquals(registers['t9'], 0xAAA00BBB)
358 # Skip k0 and k1 registers, since they can be changed by kernel.
Mark Seaborn 2013/12/26 17:01:13 Do you mean "can only"?
petarj 2013/12/26 18:36:24 No, application can change it too, but it makes no
359 self.assertEquals(registers['global_ptr'], 0xDDD00EEE)
360 self.assertEquals(registers['stack_ptr'], 0x2EE00FFF)
361 self.assertEquals(registers['frame_ptr'], 0xFFF00000)
362 self.assertEquals(registers['return_addr'], 0x0A0A0A0A)
291 else: 363 else:
292 raise AssertionError('Unknown architecture') 364 raise AssertionError('Unknown architecture')
293 365
294 expected_fault_addr = GetSymbols()['fault_addr'] 366 expected_fault_addr = GetSymbols()['fault_addr']
295 if ARCH == 'x86-64': 367 if ARCH == 'x86-64':
296 expected_fault_addr += registers['r15'] 368 expected_fault_addr += registers['r15']
297 self.assertEquals(registers[IP_REG[ARCH]], expected_fault_addr) 369 self.assertEquals(registers[IP_REG[ARCH]], expected_fault_addr)
298 370
299 # Test that we can write registers. 371 # Test that we can write registers.
300 def CheckWriteRegisters(self, connection): 372 def CheckWriteRegisters(self, connection):
301 if ARCH == 'x86-32': 373 if ARCH == 'x86-32':
302 reg_name = 'edx' 374 reg_name = 'edx'
303 elif ARCH == 'x86-64': 375 elif ARCH == 'x86-64':
304 reg_name = 'rdx' 376 reg_name = 'rdx'
305 elif ARCH == 'arm': 377 elif ARCH == 'arm':
306 reg_name = 'r0' 378 reg_name = 'r0'
379 elif ARCH == 'mips32':
380 reg_name = 'a0'
307 else: 381 else:
308 raise AssertionError('Unknown architecture') 382 raise AssertionError('Unknown architecture')
309 383
310 # Read registers. 384 # Read registers.
311 regs = DecodeRegs(connection.RspRequest('g')) 385 regs = DecodeRegs(connection.RspRequest('g'))
312 386
313 # Change a register. 387 # Change a register.
314 regs[reg_name] += 1 388 regs[reg_name] += 1
315 new_value = regs[reg_name] 389 new_value = regs[reg_name]
316 390
317 # Write registers. 391 # Write registers.
318 self.assertEquals(connection.RspRequest('G' + EncodeRegs(regs)), 'OK') 392 self.assertEquals(connection.RspRequest('G' + EncodeRegs(regs)), 'OK')
319 393
320 # Read registers. Check for a new value. 394 # Read registers. Check for a new value.
321 regs = DecodeRegs(connection.RspRequest('g')) 395 regs = DecodeRegs(connection.RspRequest('g'))
322 self.assertEquals(regs[reg_name], new_value) 396 self.assertEquals(regs[reg_name], new_value)
323 397
324 # TODO: Resume execution and check that changing the registers really 398 # TODO: Resume execution and check that changing the registers really
325 # influenced the program's execution. This would require changing 399 # influenced the program's execution. This would require changing
326 # debugger_test.c. 400 # debugger_test.c.
327 401
328 def CheckReadOnlyRegisters(self, connection): 402 def CheckReadOnlyRegisters(self, connection):
329 if ARCH == 'x86-32': 403 if ARCH == 'x86-32':
330 sample_read_only_regs = ['cs', 'ds'] 404 sample_read_only_regs = ['cs', 'ds']
331 elif ARCH == 'x86-64': 405 elif ARCH == 'x86-64':
332 sample_read_only_regs = ['r15', 'cs', 'ds'] 406 sample_read_only_regs = ['r15', 'cs', 'ds']
333 elif ARCH == 'arm': 407 elif ARCH == 'arm':
334 sample_read_only_regs = [] 408 sample_read_only_regs = []
409 elif ARCH == 'mips32':
410 sample_read_only_regs = ['zero']
335 else: 411 else:
336 raise AssertionError('Unknown architecture') 412 raise AssertionError('Unknown architecture')
337 413
338 for reg_name in sample_read_only_regs: 414 for reg_name in sample_read_only_regs:
339 # Read registers. 415 # Read registers.
340 regs = DecodeRegs(connection.RspRequest('g')) 416 regs = DecodeRegs(connection.RspRequest('g'))
341 417
342 # Change a register. 418 # Change a register.
343 old_value = regs[reg_name] 419 old_value = regs[reg_name]
344 regs[reg_name] += 1 420 regs[reg_name] += 1
(...skipping 15 matching lines...) Expand all
360 mem_addr = 0xffff 436 mem_addr = 0xffff
361 resut = connection.RspRequest('m%x,%x' % (mem_addr, 1)) 437 resut = connection.RspRequest('m%x,%x' % (mem_addr, 1))
362 self.assertEquals(result, 'E03') 438 self.assertEquals(result, 'E03')
363 439
364 # Run tests on debugger_test.c binary. 440 # Run tests on debugger_test.c binary.
365 def test_debugger_test(self): 441 def test_debugger_test(self):
366 with LaunchDebugStub('test_getting_registers') as connection: 442 with LaunchDebugStub('test_getting_registers') as connection:
367 # Tell the process to continue, because it starts at the 443 # Tell the process to continue, because it starts at the
368 # breakpoint set at its start address. 444 # breakpoint set at its start address.
369 reply = connection.RspRequest('c') 445 reply = connection.RspRequest('c')
370 if ARCH == 'arm': 446 if ARCH == 'arm' or ARCH == 'mips32':
Mark Seaborn 2013/12/26 17:01:13 To reduce duplication, can you factor out this che
petarj 2013/12/26 18:36:24 Not applicable here, but done elsewhere.
371 # The process should have stopped on a BKPT instruction. 447 # The process should have stopped on a BKPT instruction.
372 AssertReplySignal(reply, NACL_SIGTRAP) 448 AssertReplySignal(reply, NACL_SIGTRAP)
373 else: 449 else:
374 # The process should have stopped on a HLT instruction. 450 # The process should have stopped on a HLT instruction.
375 AssertReplySignal(reply, NACL_SIGSEGV) 451 AssertReplySignal(reply, NACL_SIGSEGV)
376 452
377 self.CheckTargetXml(connection) 453 self.CheckTargetXml(connection)
378 self.CheckReadRegisters(connection) 454 self.CheckReadRegisters(connection)
379 self.CheckWriteRegisters(connection) 455 self.CheckWriteRegisters(connection)
380 self.CheckReadOnlyRegisters(connection) 456 self.CheckReadOnlyRegisters(connection)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 reply = connection.RspRequest(step_command) 520 reply = connection.RspRequest(step_command)
445 AssertReplySignal(reply, NACL_SIGTRAP) 521 AssertReplySignal(reply, NACL_SIGTRAP)
446 self.assertEquals(ParseThreadStopReply(reply)['thread_id'], thread_id) 522 self.assertEquals(ParseThreadStopReply(reply)['thread_id'], thread_id)
447 ip += size 523 ip += size
448 regs = DecodeRegs(connection.RspRequest('g')) 524 regs = DecodeRegs(connection.RspRequest('g'))
449 self.assertEqual(regs[IP_REG[ARCH]], ip) 525 self.assertEqual(regs[IP_REG[ARCH]], ip)
450 # The trap flag should be reported as unset. 526 # The trap flag should be reported as unset.
451 self.assertEqual(regs['eflags'] & X86_TRAP_FLAG, 0) 527 self.assertEqual(regs['eflags'] & X86_TRAP_FLAG, 0)
452 528
453 def test_single_step(self): 529 def test_single_step(self):
454 if ARCH == 'arm': 530 if ARCH == 'arm' or ARCH == 'mips32':
455 # Skip this test because single-stepping is not supported on ARM. 531 # Skip this test because single-stepping is not supported on ARM/MIPS.
456 # TODO(eaeltsin): 532 # TODO(eaeltsin):
457 # http://code.google.com/p/nativeclient/issues/detail?id=2911 533 # http://code.google.com/p/nativeclient/issues/detail?id=2911
458 return 534 return
459 with LaunchDebugStub('test_single_step') as connection: 535 with LaunchDebugStub('test_single_step') as connection:
460 # We expect test_single_step() to stop at a HLT instruction. 536 # We expect test_single_step() to stop at a HLT instruction.
461 reply = connection.RspRequest('c') 537 reply = connection.RspRequest('c')
462 AssertReplySignal(reply, NACL_SIGSEGV) 538 AssertReplySignal(reply, NACL_SIGSEGV)
463 tid = ParseThreadStopReply(reply)['thread_id'] 539 tid = ParseThreadStopReply(reply)['thread_id']
464 # Skip past the single-byte HLT instruction. 540 # Skip past the single-byte HLT instruction.
465 regs = DecodeRegs(connection.RspRequest('g')) 541 regs = DecodeRegs(connection.RspRequest('g'))
466 regs[IP_REG[ARCH]] += 1 542 regs[IP_REG[ARCH]] += 1
467 AssertEquals(connection.RspRequest('G' + EncodeRegs(regs)), 'OK') 543 AssertEquals(connection.RspRequest('G' + EncodeRegs(regs)), 'OK')
468 544
469 self.CheckSingleStep(connection, 's', tid) 545 self.CheckSingleStep(connection, 's', tid)
470 # Check that we can continue after single-stepping. 546 # Check that we can continue after single-stepping.
471 reply = connection.RspRequest('c') 547 reply = connection.RspRequest('c')
472 self.assertEquals(reply, 'W00') 548 self.assertEquals(reply, 'W00')
473 549
474 def test_vCont(self): 550 def test_vCont(self):
475 # Basically repeat test_single_step, but using vCont commands. 551 # Basically repeat test_single_step, but using vCont commands.
476 if ARCH == 'arm': 552 if ARCH == 'arm' or ARCH == 'mips32':
477 # Skip this test because single-stepping is not supported on ARM. 553 # Skip this test because single-stepping is not supported on ARM/MIPS.
478 # TODO(eaeltsin): 554 # TODO(eaeltsin):
479 # http://code.google.com/p/nativeclient/issues/detail?id=2911 555 # http://code.google.com/p/nativeclient/issues/detail?id=2911
480 return 556 return
481 with LaunchDebugStub('test_single_step') as connection: 557 with LaunchDebugStub('test_single_step') as connection:
482 # Test if vCont is supported. 558 # Test if vCont is supported.
483 reply = connection.RspRequest('vCont?') 559 reply = connection.RspRequest('vCont?')
484 self.assertEqual(reply, 'vCont;s;S;c;C') 560 self.assertEqual(reply, 'vCont;s;S;c;C')
485 561
486 # Continue using vCont. 562 # Continue using vCont.
487 # We expect test_single_step() to stop at a HLT instruction. 563 # We expect test_single_step() to stop at a HLT instruction.
(...skipping 20 matching lines...) Expand all
508 584
509 # Try to single-step wrong thread. 585 # Try to single-step wrong thread.
510 reply = connection.RspRequest('vCont;s:%x' % (tid + 2)) 586 reply = connection.RspRequest('vCont;s:%x' % (tid + 2))
511 self.assertTrue(reply.startswith('E')) 587 self.assertTrue(reply.startswith('E'))
512 588
513 # Try to single-step all threads. 589 # Try to single-step all threads.
514 reply = connection.RspRequest('vCont;s') 590 reply = connection.RspRequest('vCont;s')
515 self.assertTrue(reply.startswith('E')) 591 self.assertTrue(reply.startswith('E'))
516 592
517 def test_interrupt(self): 593 def test_interrupt(self):
518 if ARCH == 'arm': 594 if ARCH == 'arm' or ARCH == 'mips32':
519 # Skip this test because single-stepping is not supported on ARM. 595 # Skip this test because single-stepping is not supported on ARM/MIPS.
520 # TODO(eaeltsin): 596 # TODO(eaeltsin):
521 # http://code.google.com/p/nativeclient/issues/detail?id=2911 597 # http://code.google.com/p/nativeclient/issues/detail?id=2911
522 return 598 return
523 func_addr = GetSymbols()['test_interrupt'] 599 func_addr = GetSymbols()['test_interrupt']
524 with LaunchDebugStub('test_interrupt') as connection: 600 with LaunchDebugStub('test_interrupt') as connection:
525 # Single stepping inside syscalls doesn't work. So we need to reach 601 # Single stepping inside syscalls doesn't work. So we need to reach
526 # a point where interrupt will not catch the program inside syscall. 602 # a point where interrupt will not catch the program inside syscall.
527 reply = connection.RspRequest('Z0,%x,0' % func_addr) 603 reply = connection.RspRequest('Z0,%x,0' % func_addr)
528 self.assertEquals(reply, 'OK') 604 self.assertEquals(reply, 'OK')
529 reply = connection.RspRequest('c') 605 reply = connection.RspRequest('c')
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 regs = DecodeRegs(connection.RspRequest('g')) 716 regs = DecodeRegs(connection.RspRequest('g'))
641 if ARCH in ('x86-32', 'x86-64'): 717 if ARCH in ('x86-32', 'x86-64'):
642 AssertReplySignal(stop_reply, NACL_SIGSEGV) 718 AssertReplySignal(stop_reply, NACL_SIGSEGV)
643 # Skip past the single-byte HLT instruction. 719 # Skip past the single-byte HLT instruction.
644 regs[IP_REG[ARCH]] += 1 720 regs[IP_REG[ARCH]] += 1
645 elif ARCH == 'arm': 721 elif ARCH == 'arm':
646 AssertReplySignal(stop_reply, NACL_SIGTRAP) 722 AssertReplySignal(stop_reply, NACL_SIGTRAP)
647 bundle_size = 16 723 bundle_size = 16
648 assert regs['r15'] % bundle_size == 0, regs['r15'] 724 assert regs['r15'] % bundle_size == 0, regs['r15']
649 regs['r15'] += bundle_size 725 regs['r15'] += bundle_size
726 elif ARCH == 'mips32':
727 AssertReplySignal(stop_reply, NACL_SIGTRAP)
728 bundle_size = 16
729 assert regs['prog_ctr'] % bundle_size == 0, regs['prog_ctr']
730 regs['prog_ctr'] += bundle_size
650 else: 731 else:
651 raise AssertionError('Unknown architecture') 732 raise AssertionError('Unknown architecture')
652 AssertEquals(connection.RspRequest('G' + EncodeRegs(regs)), 'OK') 733 AssertEquals(connection.RspRequest('G' + EncodeRegs(regs)), 'OK')
653 734
654 def WaitForTestThreadsToStart(self, connection, symbols): 735 def WaitForTestThreadsToStart(self, connection, symbols):
655 # Wait until: 736 # Wait until:
656 # * The main thread starts to modify g_main_thread_var. 737 # * The main thread starts to modify g_main_thread_var.
657 # * The child thread executes a breakpoint. 738 # * The child thread executes a breakpoint.
658 old_value = ReadUint32(connection, symbols['g_main_thread_var']) 739 old_value = ReadUint32(connection, symbols['g_main_thread_var'])
659 while True: 740 while True:
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 global NM_TOOL 815 global NM_TOOL
735 global SEL_LDR_COMMAND 816 global SEL_LDR_COMMAND
736 ARCH = args.pop(0) 817 ARCH = args.pop(0)
737 NM_TOOL = args.pop(0) 818 NM_TOOL = args.pop(0)
738 SEL_LDR_COMMAND = args 819 SEL_LDR_COMMAND = args
739 unittest.main() 820 unittest.main()
740 821
741 822
742 if __name__ == '__main__': 823 if __name__ == '__main__':
743 Main() 824 Main()
OLDNEW
« no previous file with comments | « no previous file | tests/debug_stub/debugger_test.c » ('j') | tests/debug_stub/debugger_test.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698