OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/python | |
2 # | |
3 # Copyright (c) 2012 The Native Client Authors. All rights reserved. | |
4 # Use of this source code is governed by a BSD-style license that can be | |
5 # found in the LICENSE file. | |
6 # | |
7 | |
8 | |
Nick Bray (chromium)
2012/04/27 19:41:33
One newline here.
| |
9 import sys | |
10 import textwrap | |
11 from subprocess import Popen, PIPE | |
12 | |
13 _OBJDUMP = 'mips-linux-gnu-objdump' | |
14 | |
Nick Bray (chromium)
2012/04/27 19:41:33
Two newlines around functions and classes at modul
| |
15 def _objdump(binary, vaddr, ctx_before, ctx_after): | |
16 args = [ | |
17 _OBJDUMP, | |
18 '-d', | |
19 '-G', | |
20 binary, | |
21 '--start-address=0x%08X' % (vaddr - (4 * ctx_before)), | |
22 '--stop-address=0x%08X' % (vaddr + 4 + (4 * ctx_after))] | |
23 highlight = ctx_before | |
24 lines = 0 | |
25 for line in Popen(args, stdout=PIPE).stdout.read().split('\n'): | |
26 if line.startswith(' '): | |
27 if highlight == 0: | |
28 print '--> ', line | |
29 else: | |
30 print ' ', line | |
31 highlight -= 1 | |
32 lines += 1 | |
33 if not lines: | |
34 print ' (not found)' | |
35 | |
36 def _problem_info(code): | |
37 return { | |
38 'kProblemUnsafe': ['Instruction is unsafe', 0, 0], | |
39 'kProblemBranchSplitsPattern': ['The destination of this branch is ' | |
40 'at middle of an pseudo-instruction that must be executed in full', | |
41 0, 0], | |
42 'kProblemPatternCrossesBundle': ['This instruction is part of a ' | |
43 'sequence that must execute in full, but it spans a bundle edge ' | |
44 '-- so an indirect branch may target it', | |
45 1, 1], | |
46 'kProblemBranchInvalidDest': ['This branch targets a location that is ' | |
47 'outside of the application\'s executable code, over 256 MB', | |
48 0, 0], | |
49 'kProblemUnsafeLoadStore': ['This load/store instruction is not ' | |
50 'preceded by a valid store mask instruction', | |
51 1, 0], | |
52 'kProblemUnsafeJumpRegister': ['This indirect jump instruction is not ' | |
53 'preceded by a valid jump mask instruction', | |
54 1, 0], | |
55 'kProblemUnsafeDataWrite': ['This instruction affects a register that ' | |
56 'must contain a valid data-region address (sp), but is not ' | |
57 'followed by a valid store mask instruction', | |
58 0, 1], | |
59 'kProblemReadOnlyRegister': ['This instruction changes the contents of' | |
60 ' read-only register', | |
61 0, 0], | |
62 'kProblemMisalignedCall': ['This linking branch/jump instruction is ' | |
63 'not at the bundle offset +8, so when its RA result is masked, the' | |
64 ' caller will not return to the next instruction (start of next ' | |
65 'bundle)', | |
66 0, 0], | |
67 'kProblemUnalignedJumpToTrampoline':['The destination of this ' | |
68 'jump/branch instruction is in trampoline code section but ' | |
69 'address is not bundle aligned', | |
70 0, 0], | |
71 'kProblemDataRegInDelaySlot':['This instruction changes value of a ' | |
72 'stack pointer but is located in the delay slot of jump/branch', | |
73 1, 0], | |
74 }[code] | |
75 | |
76 def _safety_msg(val): | |
77 return { | |
78 0: 'UNKNOWN', # Should not appear | |
79 1: 'is undefined', | |
80 2: 'has unpredictable effects', | |
81 3: 'is deprecated', | |
82 4: 'is forbidden', | |
83 5: 'uses forbidden operands', | |
84 }[val] | |
85 | |
86 def _explain_problem(binary, vaddr, safety, code, ref_vaddr): | |
87 msg, ctx_before, ctx_after = _problem_info(code) | |
88 if safety == 6: | |
89 msg = "At %08X: %s:" % (vaddr, msg) | |
90 else: | |
91 msg = ("At %08X: %s (%s):" | |
92 % (vaddr, msg, _safety_msg(safety))) | |
93 print '\n'.join(textwrap.wrap(msg, 70, subsequent_indent=' ')) | |
94 _objdump(binary, vaddr, ctx_before, ctx_after) | |
95 if ref_vaddr: | |
96 print "Destination address %08X:" % ref_vaddr | |
97 _objdump(binary, ref_vaddr, 1, 1) | |
98 | |
99 def _parse_report(line): | |
100 vaddr_hex, safety, code, ref_vaddr_hex = line.split() | |
101 return (int(vaddr_hex, 16), int(safety), code, int(ref_vaddr_hex, 16)) | |
102 | |
103 for line in sys.stdin: | |
Nick Bray (chromium)
2012/04/27 19:41:33
Nit: Wrap inside a main() function, prevents the c
| |
104 if line.startswith('ncval: '): | |
105 line = line[7:].strip() | |
106 _explain_problem(sys.argv[1], *_parse_report(line)) | |
Nick Bray (chromium)
2012/04/27 19:41:33
Nit: A little input validation here (len(sys.argv)
| |
OLD | NEW |