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

Side by Side Diff: src/trusted/validator_ragel/build.scons

Issue 10826182: Validator_ragel: move checkdecoder test from Makefile to scons (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 8 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- python -*- 1 # -*- python -*-
2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 from SCons.Errors import UserError 6 from SCons.Errors import UserError
7 7
8 Import('env') 8 Import('env')
9 9
10 # 10 #
(...skipping 12 matching lines...) Expand all
23 23
24 INST_DEFS = [ 24 INST_DEFS = [
25 'unreviewed/general_purpose_instructions.def', 25 'unreviewed/general_purpose_instructions.def',
26 'unreviewed/system_instructions.def', 26 'unreviewed/system_instructions.def',
27 'unreviewed/x87_instructions.def', 27 'unreviewed/x87_instructions.def',
28 'unreviewed/mmx_instructions.def', 28 'unreviewed/mmx_instructions.def',
29 'unreviewed/xmm_instructions.def', 29 'unreviewed/xmm_instructions.def',
30 'unreviewed/nops.def' 30 'unreviewed/nops.def'
31 ] 31 ]
32 32
33
34
35
36 # Generate 32 and 64 bit versions of decoders and validators. Both libraries
37 # are used for command-line decoder and validator those detect specific
38 # architecture of the ELF file provided.
39 env.ComponentLibrary('dfa_validate_x86_32',
40 ['gen/validator_x86_32.c'])
41 env.ComponentLibrary('dfa_validate_x86_64',
42 ['gen/validator_x86_64.c'])
43 env.ComponentLibrary('dfa_decode_x86_32',
44 ['gen/decoder_x86_32.c'])
45 env.ComponentLibrary('dfa_decode_x86_64',
46 ['gen/decoder_x86_64.c'])
47
48 # Glue library called from service runtime. The source file depends on the
49 # target architecture.
50 caller_lib_bits = None
51 if env.Bit('target_x86_32'):
52 caller_lib_bits = '32'
53 if env.Bit('target_x86_64'):
54 caller_lib_bits = '64'
55 if caller_lib_bits:
56 caller_lib = 'dfa_validate_caller_x86_%s' % caller_lib_bits
57 env.ComponentLibrary(caller_lib,
58 ['unreviewed/dfa_validate_%s.c' % caller_lib_bits])
59
60 # Command-line decoder.
61 decoder_test = env.ComponentProgram(
62 'decoder_test',
63 ['unreviewed/decoder_test.c'],
64 EXTRA_LIBS=['dfa_decode_x86_32', 'dfa_decode_x86_64'])
65
66 # Command-line validator.
67 validator_test_exe = env.ComponentProgram(
68 'validator_test',
69 ['unreviewed/validator_test.c'],
70 EXTRA_LIBS=['dfa_validate_x86_32', 'dfa_validate_x86_64'])
71
72 # Python-based regression test. TODO(pasko): remove it when validator_tests are
73 # migrated to be able to run with the new validator.
74 if env.Bit('validator_ragel'):
75 test_node = env.CommandTest('validator_test_py.out',
76 command=['${PYTHON}',
77 env.File('unreviewed/validator_test.py'),
78 validator_test_exe])
79 env.AddNodeToTestSuite(test_node, ['small_tests'], 'run_validator_test_py')
80
81
33 # Source generation: 82 # Source generation:
34 # 83 #
35 # dfagen : Regenerate any autogenerated source files. 84 # dfagen : Regenerate any autogenerated source files.
36 85
37 generate = False 86 dfa_aliases = 'dfagen', 'dfaclean', 'dfacheckdecoder'
38 if 'dfagen' in COMMAND_LINE_TARGETS or 'dfaclean' in COMMAND_LINE_TARGETS: 87
39 generate = True 88 generate = any(a in COMMAND_LINE_TARGETS for a in dfa_aliases)
40 89
41 if generate: 90 if generate:
42 if not env.Bit('host_linux'): 91 if not env.Bit('host_linux'):
43 raise UserError('Right now DFA generation is only supported on Linux') 92 raise UserError('Right now DFA generation is only supported on Linux')
44 93
45 # Source generation step 1: Build generator of ragel files. 94 # Source generation step 1: Build generator of ragel files.
46 # 95 #
47 # We have generator which reads .def files and produced automaton definition. 96 # We have generator which reads .def files and produced automaton definition.
48 # 97 #
49 # Ragel is included in most Linux distributions, but it's not standard tool 98 # Ragel is included in most Linux distributions, but it's not standard tool
50 # on MacOS/Windows thus we only support gneration of automata under Linux. 99 # on MacOS/Windows thus we only support gneration of automata under Linux.
51 # This also means that we don't need to make sure gen_dfa.cc is portable to 100 # This also means that we don't need to make sure gen_dfa.cc is portable to
52 # non-POSIX platforms (in particular it's not Windows compatible). 101 # non-POSIX platforms (in particular it's not Windows compatible).
53 102
54 env_gen_dfa = env.Clone() 103 env_gen_dfa = env.Clone()
55 env_gen_dfa.Append(CCFLAGS=['-std=c++0x', '-DNACL_TRUSTED_BUT_NOT_TCB']) 104 env_gen_dfa.Append(CCFLAGS=['-std=c++0x', '-DNACL_TRUSTED_BUT_NOT_TCB'])
56 105
57 gen_dfa = env_gen_dfa.ComponentProgram( 106 gen_dfa = env_gen_dfa.ComponentProgram(
58 'gen_dfa', 107 'gen_dfa',
59 ['unreviewed/gen_dfa.cc']) 108 ['unreviewed/gen_dfa.cc'])
60 109
61 # Source generation step 2: Generate decoder automatas. 110 # Source generation step 2: Generate decoder automata.
62 # 111 #
63 # Now we are back to conditionally defining the large automata generated 112 # Now we are back to conditionally defining the large automata generated
64 # by gen_dfa. 113 # by gen_dfa.
65 114
66 def MakeAutomaton(bits, automaton, dfa_gen_actions, ragel_flags): 115 def MakeAutomaton(bits, automaton, dfa_gen_actions, ragel_flags):
67 rl_file = '%s_x86_%s_instruction.rl' % (automaton, bits) 116 rl_file = '%s_x86_%s_instruction.rl' % (automaton, bits)
68 117
69 # We are cheating here: there are two autogenerated files: 118 # We are cheating here: there are two autogenerated files:
70 # .rl and _consts.c, but we only track .rl one. This is safe because 119 # .rl and _consts.c, but we only track .rl one. This is safe because
71 # _consts.c file includes constants referenced by .rl file and if .rl 120 # _consts.c file includes constants referenced by .rl file and if .rl
72 # file is not changed _consts.c is guaranteed to be the same (reverse 121 # file is not changed _consts.c is guaranteed to be the same (reverse
73 # is not true). 122 # is not true).
123
74 const_file = '%s/%s_x86_%s_instruction_consts.c' % ( 124 const_file = '%s/%s_x86_%s_instruction_consts.c' % (
75 val_src_dir, automaton, bits) 125 val_src_dir, automaton, bits)
76 126
77 exe_path = '${STAGING_DIR}/${PROGPREFIX}gen_dfa${PROGSUFFIX}'
78 env.Command( 127 env.Command(
79 target=rl_file, 128 target=rl_file,
80 source=[exe_path] + INST_DEFS, 129 source=[gen_dfa] + INST_DEFS,
81 action=( 130 action=(
82 '${SOURCES[0]} -o ${TARGET} -c %s -m %s -d %s %s') % ( 131 '${SOURCES[0]} -o ${TARGET} -c %s -m %s -d %s %s') % (
83 # Const file (-c): not tracked by SCONS (see above) 132 # Const file (-c): not tracked by SCONS (see above)
84 const_file, 133 const_file,
85 # Argument for CPU type (-m): either "ia32" or "amd64". 134 # Argument for CPU type (-m): either "ia32" or "amd64".
86 {'32': 'ia32', '64': 'amd64'}[bits], 135 {'32': 'ia32', '64': 'amd64'}[bits],
87 # (-d): 136 # (-d):
88 dfa_gen_actions, 137 dfa_gen_actions,
89 # pass inst defs as remaining parameters 138 # pass inst defs as remaining parameters
90 ' '.join('${SOURCES[%d]}' % (i+1) 139 ' '.join('${SOURCES[%d]}' % (i+1)
91 for i in range(len(INST_DEFS))) 140 for i in range(len(INST_DEFS)))
92 ) 141 )
93 ) 142 )
94 c_file = '%s_x86_%s.c' % (automaton, bits) 143 c_file = '%s_x86_%s.c' % (automaton, bits)
95 c_full_filename = '%s/%s' % (val_src_dir, c_file) 144 c_full_filename = '%s/%s' % (val_src_dir, c_file)
96 env.Command( 145 env.Command(
97 target=c_file, 146 target=c_file,
98 source=['unreviewed/%s_x86_%s.rl' % (automaton, bits), rl_file], 147 source=['unreviewed/%s_x86_%s.rl' % (automaton, bits), rl_file],
99 action=['%s %s -LL -I%s ${SOURCES[0]} -o ${TARGET}' % ( 148 action=['%s %s -LL -I%s ${SOURCES[0]} -o ${TARGET}' % (
100 ragel_binary, ragel_flags, rl_src_dir)] 149 ragel_binary, ragel_flags, rl_src_dir)]
101 ) 150 )
102 151
103 def InjectGeneratedFileHeader(target, source, env): 152 def InjectGeneratedFileHeader(target, source, env):
104 source_filename = source[0].get_abspath() 153 source_filename = source[0].get_abspath()
105 target_filename = target[0].get_abspath() 154 target_filename = target[0].get_abspath()
106 architecture = {'x86_32': 'ia32', 155 architecture = {'x86_32': 'ia32',
107 'x86_64': 'x86-64'}[target_filename[-8:-2]] 156 'x86_64': 'x86-64'}[target_filename[-8:-2]]
157
108 with open(source_filename, 'r') as source_file: 158 with open(source_filename, 'r') as source_file:
109 with open(target_filename, 'w') as target_file: 159 comment, sep, rest = source_file.read().partition('*/')
110 target_file.write( 160 if sep == '':
111 """/* native_client/%s 161 raise UserError('Generated file %s does not have '
112 * THIS FILE IS AUTO-GENERATED. DO NOT EDIT. 162 'header comment block' % source_filename)
113 * Compiled for %s mode.
114 */""" % (target_filename, architecture))
115 163
116 comment, sep, rest = source_file.read().partition('*/') 164 with open(target_filename, 'w') as target_file:
117 if sep == '': 165 target_file.write(
118 raise UserError('Generated file %s does not have ' 166 ('/* native_client/%s\n'
119 'header comment block' % source_filename) 167 ' * THIS FILE IS AUTO-GENERATED. DO NOT EDIT.\n'
120 target_file.write(rest) 168 ' * Compiled for %s mode.\n'
169 ' */') % (target_filename, architecture))
121 170
171 target_file.write(rest)
172
173 # inject comments and place files to appropriate dir
122 env.Command( 174 env.Command(
123 target=c_full_filename, 175 target=c_full_filename,
124 source=['%s/%s' % (rl_src_dir, c_file)], 176 source=['%s/%s' % (rl_src_dir, c_file)],
125 action=InjectGeneratedFileHeader 177 action=InjectGeneratedFileHeader
126 ) 178 )
127 179
128 return rl_file, c_file, c_full_filename 180 return rl_file, c_file, c_full_filename
129 181
130 decoder32 = MakeAutomaton( 182 decoder32 = MakeAutomaton(
131 '32', 'decoder', 183 '32', 'decoder',
132 'check_access,opcode,parse_operands_states,mark_data_fields', 184 'check_access,opcode,parse_operands_states,mark_data_fields',
133 '-T0') 185 '-T0')
134 validator32 = MakeAutomaton( 186 validator32 = MakeAutomaton(
135 '32', 'validator', 187 '32', 'validator',
136 ('check_access,opcode,parse_operands,parse_operands_states,' 188 ('check_access,opcode,parse_operands,parse_operands_states,'
137 'instruction_name,mark_data_fields,nacl-forbidden,' 189 'instruction_name,mark_data_fields,nacl-forbidden,'
138 'imm_operand_action,rel_operand_action'), 190 'imm_operand_action,rel_operand_action'),
139 '-G2') 191 '-G2')
140 decoder64 = MakeAutomaton( 192 decoder64 = MakeAutomaton(
141 '64', 'decoder', 193 '64', 'decoder',
142 'check_access,opcode,parse_operands_states,mark_data_fields', 194 'check_access,opcode,parse_operands_states,mark_data_fields',
143 '-T0') 195 '-T0')
144 validator64 = MakeAutomaton( 196 validator64 = MakeAutomaton(
145 '64', 'validator', 197 '64', 'validator',
146 ('opcode,instruction_name,mark_data_fields,imm_operand_action,' 198 ('opcode,instruction_name,mark_data_fields,imm_operand_action,'
147 'rel_operand_action,nacl-forbidden,parse_nonwrite_registers,' 199 'rel_operand_action,nacl-forbidden,parse_nonwrite_registers,'
148 'parse_x87_operands,parse_mmx_operands,parse_xmm_operands,' 200 'parse_x87_operands,parse_mmx_operands,parse_xmm_operands,'
149 'parse_ymm_operands,parse_relative_operands,' 201 'parse_ymm_operands,parse_relative_operands,'
150 'parse_immediate_operands,parse_operands_states,' 202 'parse_immediate_operands,parse_operands_states,'
151 'parse_operand_positions'), 203 'parse_operand_positions'),
152 '-GT2') 204 '-GT2')
153 205
154 automata = list(decoder32 + validator32 + decoder64 + validator64) 206 automata = list(decoder32 + validator32 + decoder64 + validator64)
155 207
208
209 # Generate checkdecoder test
210
211 test_env = env.Clone()
212 test_env.Append(
213 CCFLAGS=['-g', '-Wno-unused-function'],
214 LINKFLAGS='-g',
215 CPPPATH='unreviewed')
216
217 test_dfa_object = test_env.Object('unreviewed/test_dfa.c')
218
219 check_decoders = []
220
221 for bits in ('32', '64'):
222 (one_valid_instr_rl,) = env.Command(
223 target='one_valid_instruction_x86_%s.rl'%bits,
224 source=[gen_dfa]+INST_DEFS,
225 action=('${SOURCES[0]} -o ${TARGET} %s '
226 '-d check_access,rex_prefix,vex_prefix,opcode '
227 '-d parse_operands_states,parse_operands,instruction_name '
228 '%s')%(
229 ' '.join('${SOURCES[%d]}'%(i+1) for i in range(len(INST_DEFS))),
230 {'32': '', '64': '-m amd64'}[bits])
khim 2012/08/07 09:24:22 Please add explicit "-m ia32"
Vlad Shcherbina 2012/08/07 11:01:57 Done.
231 )
232
233 include_dir = one_valid_instr_rl.dir.get_abspath()
234
235 (one_instr_dot,) = env.Command(
236 target='one_instruction_x86_%s.dot'%bits,
237 source=['unreviewed/one_instruction_x86_%s.rl'%bits, one_valid_instr_rl] ,
khim 2012/08/07 09:24:22 Long line
Vlad Shcherbina 2012/08/07 11:01:57 Done.
238 action=[
239 '%s -V -I%s ${SOURCES[0]} -o ${TARGET}'%
240 (ragel_binary, include_dir)]
241 )
242
243 test_dfa_transitions = test_env.Command(
244 target='test_dfa_transitions_x86_%s.c'%bits,
245 source=['unreviewed/parse_dfa.py', one_instr_dot],
246 action='python ${SOURCES[0]} <"${SOURCES[1]}" >"${TARGET}"'
247 )
248
249 unoptimized_env = test_env.Clone()
250 unoptimized_env.Append(CFLAGS='-O0') # does it make any difference?
khim 2012/08/07 09:24:22 I don't think it's big deal, really. The whole te
Vlad Shcherbina 2012/08/07 11:01:57 Then I remove it to make config simpler.
251 test_dfa_transitions_object = unoptimized_env.Object(test_dfa_transitions)
252
253 test_dfa = test_env.ComponentProgram(
254 'test_dfa_x86_%s'%bits,
255 [test_dfa_object, test_dfa_transitions_object])
256
257 gas =File("#/../third_party/binutils/as-new")
khim 2012/08/07 09:24:22 Please rename it to as.linux as-new is some wart
Vlad Shcherbina 2012/08/07 11:01:57 Done.
258 objdump =File("#/../third_party/binutils/objdump")
khim 2012/08/07 09:24:22 This should be objdump.linux
Vlad Shcherbina 2012/08/07 11:01:57 Done.
259
260 fast_temp_for_test = '/dev/shm'
261
262 (check_decoder,) = env.Command(
263 target='objdump_test_fake_file_%s'%bits,
264 source=[
265 'unreviewed/run_objdump_test.py',
266 decoder_test,
267 'unreviewed/decoder_test_one_file.sh',
268 test_dfa,
269 ],
270 action=[(
271 'python ${SOURCES[0]} '
272 '--gas="%s --%s" '
273 '--objdump="%s" '
274 '--decoder="${SOURCES[1]}" '
275 '--tester="${SOURCES[2]}" '
276 '--nthreads=`cat /proc/cpuinfo | grep processor | wc -l` ' #TODO: re move
khim 2012/08/07 09:24:22 Long line
Vlad Shcherbina 2012/08/07 11:01:57 Done.
277 '-- '
278 '"${SOURCES[3]}" "%s"'
279 )%(gas, bits, objdump, fast_temp_for_test),
280 ])
281 check_decoders.append(check_decoder)
282
283 SideEffect(fast_temp_for_test, check_decoders)
284
156 env.AlwaysBuild(env.Alias('dfagen', automata)) 285 env.AlwaysBuild(env.Alias('dfagen', automata))
157 env.AlwaysBuild(env.Alias('dfaclean', action=map(Delete, automata))) 286 env.AlwaysBuild(env.Alias('dfaclean', action=map(Delete, automata)))
158 287 env.AlwaysBuild(env.Alias('dfacheckdecoder', check_decoders))
159 # Generate 32 and 64 bit versions of decoders and validators. Both libraries
160 # are used for command-line decoder and validator those detect specific
161 # architecture of the ELF file provided.
162 env.ComponentLibrary('dfa_validate_x86_32',
163 ['gen/validator_x86_32.c'])
164 env.ComponentLibrary('dfa_validate_x86_64',
165 ['gen/validator_x86_64.c'])
166 env.ComponentLibrary('dfa_decode_x86_32',
167 ['gen/decoder_x86_32.c'])
168 env.ComponentLibrary('dfa_decode_x86_64',
169 ['gen/decoder_x86_64.c'])
170
171 # Glue library called from service runtime. The source file depends on the
172 # target architecture.
173 caller_lib_bits = None
174 if env.Bit('target_x86_32'):
175 caller_lib_bits = '32'
176 if env.Bit('target_x86_64'):
177 caller_lib_bits = '64'
178 if caller_lib_bits:
179 caller_lib = 'dfa_validate_caller_x86_%s' % caller_lib_bits
180 env.ComponentLibrary(caller_lib,
181 ['unreviewed/dfa_validate_%s.c' % caller_lib_bits])
182
183 # Command-line decoder.
184 env.ComponentProgram(
185 'decoder_test',
186 ['unreviewed/decoder_test.c'],
187 EXTRA_LIBS=['dfa_decode_x86_32', 'dfa_decode_x86_64'])
188
189 # Command-line validator.
190 validator_test_exe = env.ComponentProgram(
191 'validator_test',
192 ['unreviewed/validator_test.c'],
193 EXTRA_LIBS=['dfa_validate_x86_32', 'dfa_validate_x86_64'])
194
195 # Python-based regression test. TODO(pasko): remove it when validator_tests are
196 # migrated to be able to run with the new validator.
197 if env.Bit('validator_ragel'):
198 test_node = env.CommandTest('validator_test_py.out',
199 command=['${PYTHON}',
200 env.File('unreviewed/validator_test.py'),
201 validator_test_exe])
202 env.AddNodeToTestSuite(test_node, ['small_tests'], 'run_validator_test_py')
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698