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

Side by Side Diff: src/trusted/validator/x86/testing/tf/val_runner.py

Issue 10908137: (abandoned) Validator tests: convert hexes to TFs and run on bots (for prod. validator only) (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: fix for windows (temp files and crlf) Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 import collections
6 import os
7 import re
8 import subprocess
9
10 import utils
11
12
13 VALIDATORS = ['nc', 'dfa']
14
15
16 scons_out = '../../../../../../scons-out'
17 ncval32 = os.path.join(scons_out, 'opt-linux-x86-32/staging/ncval')
Mark Seaborn 2012/09/10 19:38:06 You shouldn't hard-code Scons output filenames lik
Vlad Shcherbina 2012/09/11 14:26:00 I was using it to run locally (on bots paths are a
18 ncval64 = os.path.join(scons_out, 'opt-linux-x86-64/staging/ncval')
19 rdfaval = os.path.join(scons_out, 'opt-linux-x86-32/staging/validator_test')
20
21
22 def AddValidatorsOptions(option_parser):
23 option_parser.add_option('--ncval32', dest='ncval32', type='string')
24 option_parser.add_option('--ncval64', dest='ncval64', type='string')
25 option_parser.add_option('--rdfaval', dest='rdfaval', type='string')
26
27
28 def ProcessValidatorsOptions(options):
29 global ncval32
Mark Seaborn 2012/09/10 19:38:06 It would be cleaner if you didn't modify global va
Vlad Shcherbina 2012/09/11 14:26:00 Well, I don't like it because it would mean passin
30 global ncval64
31 global rdfaval
32
33 if options.ncval32 is not None:
34 ncval32 = options.ncval32
35
36 if options.ncval64 is not None:
37 ncval64 = options.ncval64
38
39 if options.rdfaval is not None:
40 rdfaval = options.rdfaval
41
42
43 def SplitToLines(content):
44 return [line.rstrip() for line in content.rstrip().split('\n')]
45
46
47 def RunNcVal32(hex_name):
48 args = [
49 '--hex_text=-',
50 '--max_errors=-1',
51 '--detailed=false',
52 '--cpuid-all'
53 ]
54
55 with open(hex_name) as input:
56 result = utils.CheckOutput([ncval32] + args, stdin=input)
57
58 return SplitToLines(result)
59
60
61 def RunNcVal64(hex_name):
62 args = [
63 '--hex_text=-',
64 '--max_errors=-1',
65 '--readwrite_sfi',
66 '--annotate=false',
67 '--cpuid-all',
68 '--detailed=false',
69 ]
70
71 with open(hex_name) as input:
72 result = utils.CheckOutput([ncval64] + args, stdin=input)
73
74 return SplitToLines(result)
75
76
77 def ParseNcValVerdict(last_line):
78 m = re.match(r'\*\*\* <input> (is safe|IS UNSAFE) \*\*\*$', last_line)
79 assert m is not None, 'unexpected ncval output "%s"' % last_line
80 return m.group(1) == 'is safe'
81
82
83 def ParseNcVal32(lines):
84 assert len(lines) > 0, 'ncval output is empty'
85
86 errors = []
87 for line in lines[:-1]:
88 line = line.strip()
89 if line == '':
90 continue
91 if re.match(r'.+ > .+ \(read overflow of .+ bytes\)', line):
Mark Seaborn 2012/09/10 19:38:06 Why are you dropping this line of output?
Vlad Shcherbina 2012/09/11 14:26:00 Right, this should not happen anyway. It's somethi
92 continue
93 if line == 'ErrorSegmentation':
Mark Seaborn 2012/09/10 19:38:06 Ditto: why drop this?
Vlad Shcherbina 2012/09/11 14:26:00 Same.
94 continue
95 # Parse error message of the form
96 # VALIDATOR: 4: Bad prefix usage
97 m = re.match(r'VALIDATOR: ([0-9a-f]+): (.*)$', line, re.IGNORECASE)
98 offset = int(m.group(1), 16)
99 message = m.group(2)
100 errors.append((offset, message))
101 safe = ParseNcValVerdict(lines[-1])
102 return safe, errors
103
104
105 def ParseNcVal64(lines):
106 assert len(lines) > 0, 'ncval output is empty'
107
108 errors = []
109 for i, line in enumerate(lines[:-1]):
110 #print line
Mark Seaborn 2012/09/10 19:38:06 Please remove commented-out code
Vlad Shcherbina 2012/09/11 14:26:00 Done.
111 #if 'Bad basic' in line:
112 # print 'z'*10
113 # print line
114 # raw_input()
115
116 if line.startswith('VALIDATOR: Checking jump targets:'):
117 continue
118 if line.startswith('VALIDATOR: Checking that basic blocks are aligned'):
119 continue
120
121 # Skip disassembler output of the form
122 # VALIDATOR: 0000000000000003: 49 89 14 07 mov [%r15+%rax*1], %rdx
123 m = re.match(r'VALIDATOR: ([0-9a-f]+):', line, re.IGNORECASE)
124 if m is not None:
125 continue
126
127 # Parse error message of the form
128 # VALIDATOR: ERROR: 20: Bad basic block alignment.
129 m = re.match(r'VALIDATOR: ERROR: ([0-9a-f]+): (.*)', line, re.IGNORECASE)
130 if m is not None:
131 offset = int(m.group(1), 16)
132 errors.append((offset, m.group(2)))
133 continue
134
135 # Parse two-line error messages of the form
136 # VALIDATOR: 0000000000000003: 49 89 14 07 mov [%r15+%rax*1], %rdx
137 # VALIDATOR: ERROR: Invalid index register in memory offset
138 m = re.match(r'VALIDATOR: ((?:ERROR|WARNING): .*)$', line, re.IGNORECASE)
139 if m is not None:
140 m2 = re.match(r'VALIDATOR: ([0-9a-f]+):', lines[i-1], re.IGNORECASE)
141 assert m2 is not None, "can't parse line '%s' preceding line '%s'" % (
142 lines[i-1],
143 line
144 )
145 offset = int(m2.group(1), 16)
146 errors.append((offset, m.group(1)))
147 continue
148
149 assert False, "can't parse line '%s'" % line
Mark Seaborn 2012/09/10 19:38:06 Better style would be: raise AssertionError("can
Vlad Shcherbina 2012/09/11 14:26:00 Done.
150
151 safe = ParseNcValVerdict(lines[-1])
152 return safe, errors
153
154
155 def MakeElf(bits, data, elf_filename):
156 assert bits in [32, 64]
157
158 with utils.TempFile(mode='w') as asm_file:
159 for c in data:
160 asm_file.write('.byte %d\n' % ord(c))
161 asm_file.flush()
162
163 subprocess.check_call([
164 'as', '--%s' % bits, asm_file.name, '-o', elf_filename])
165
166
167 def RunDfa(bits, data):
168 with utils.TempFile(mode='w') as elf_file:
169 with utils.TempFile(mode='w+') as out_file:
170 MakeElf(bits, data, elf_file.name)
171
172 result = subprocess.call([rdfaval, elf_file.name], stdout=out_file)
173 out_file.seek(0)
174 lines = SplitToLines(out_file.read())
175
176 return result, lines
177
178
179 def ParseDfa(lines):
Mark Seaborn 2012/09/10 19:38:06 Please can you take out all of the DFA-validator r
Vlad Shcherbina 2012/09/11 14:26:00 Done.
180 errors = []
181 for line in lines:
182 if re.match(r"file '.*' can not be fully validated$", line):
183 continue
184 m = re.match(r'bad jump to around 0x([0-9a-f]+)$', line, re.IGNORECASE)
185 if m is not None:
186 offset = int(m.group(1), 16)
187 errors.append((offset, 'bad jump to around'))
188 continue
189
190 m = re.match(r'offset 0x([0-9a-f]+): (.*)$', line, re.IGNORECASE)
191 offset = int(m.group(1), 16)
192 message = m.group(2)
193 errors.append((offset, message))
194
195 return errors
196
197
198 ValidationResults = collections.namedtuple('ValidationResults', 'safe, errors')
199
200
201 def RunValidator(validator, bits, data):
202 assert validator in VALIDATORS
203 assert bits in [32, 64]
204 assert len(data) % 32 == 0
205
206 if validator == 'nc':
207 with utils.TempFile(mode='w') as hex_file:
208 hex_file.write('%s\n' % utils.DataToReadableHex(data))
209 hex_file.flush()
210
211 if bits == 32:
212 safe, errors = ParseNcVal32(RunNcVal32(hex_file.name))
213 elif bits == 64:
214 safe, errors = ParseNcVal64(RunNcVal64(hex_file.name))
215
216 elif validator == 'dfa':
217 code, output = RunDfa(bits, data)
218 safe = (code == 0)
219 errors = ParseDfa(output)
220
221 return ValidationResults(safe=safe, errors=errors)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698