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

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: following Mark's suggestion, obtain binutils from gerrit repo instead of deps/third-party 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
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 # Generate 32 and 64 bit versions of decoders and validators. Both libraries
34 # are used for command-line decoder and validator those detect specific
35 # architecture of the ELF file provided.
36 env.ComponentLibrary('dfa_validate_x86_32',
37 ['gen/validator_x86_32.c'])
38 env.ComponentLibrary('dfa_validate_x86_64',
39 ['gen/validator_x86_64.c'])
40 env.ComponentLibrary('dfa_decode_x86_32',
41 ['gen/decoder_x86_32.c'])
42 env.ComponentLibrary('dfa_decode_x86_64',
43 ['gen/decoder_x86_64.c'])
44
45 # Glue library called from service runtime. The source file depends on the
46 # target architecture.
47 caller_lib_bits = None
48 if env.Bit('target_x86_32'):
49 caller_lib_bits = '32'
50 if env.Bit('target_x86_64'):
51 caller_lib_bits = '64'
52 if caller_lib_bits:
53 # TODO(shcherbina):
54 # interpolate env.get('TARGET_FULLARCH') / env.get('TARGET_SUBARCH') instead
55 caller_lib = 'dfa_validate_caller_x86_%s' % caller_lib_bits
56 env.ComponentLibrary(caller_lib,
57 ['unreviewed/dfa_validate_%s.c' % caller_lib_bits])
58
59 # Command-line decoder.
60 decoder_test = env.ComponentProgram(
61 'decoder_test',
62 ['unreviewed/decoder_test.c'],
63 EXTRA_LIBS=['dfa_decode_x86_32', 'dfa_decode_x86_64'])
64
65 # Command-line validator.
66 validator_test_exe = env.ComponentProgram(
67 'validator_test',
68 ['unreviewed/validator_test.c'],
69 EXTRA_LIBS=['dfa_validate_x86_32', 'dfa_validate_x86_64'])
70
71 # Python-based regression test. TODO(pasko): remove it when validator_tests are
72 # migrated to be able to run with the new validator.
73 if env.Bit('validator_ragel'):
74 test_node = env.CommandTest('validator_test_py.out',
75 command=['${PYTHON}',
76 env.File('unreviewed/validator_test.py'),
77 validator_test_exe])
78 env.AddNodeToTestSuite(test_node, ['small_tests'], 'run_validator_test_py')
79
33 # Source generation: 80 # Source generation:
34 # 81 #
35 # dfagen : Regenerate any autogenerated source files. 82 # dfagen : Regenerate any autogenerated source files.
36 83
37 generate = False 84 dfa_aliases = 'dfagen', 'dfaclean', 'dfacheckdecoder'
38 if 'dfagen' in COMMAND_LINE_TARGETS or 'dfaclean' in COMMAND_LINE_TARGETS: 85
39 generate = True 86 generate = any(a in COMMAND_LINE_TARGETS for a in dfa_aliases)
40 87
41 if generate: 88 if generate:
42 if not env.Bit('host_linux'): 89 if not env.Bit('host_linux'):
43 raise UserError('Right now DFA generation is only supported on Linux') 90 raise UserError('Right now DFA generation is only supported on Linux')
44 91
45 # Source generation step 1: Build generator of ragel files. 92 # Source generation step 1: Build generator of ragel files.
46 # 93 #
47 # We have generator which reads .def files and produced automaton definition. 94 # We have generator which reads .def files and produced automaton definition.
48 # 95 #
49 # Ragel is included in most Linux distributions, but it's not standard tool 96 # 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. 97 # 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 98 # 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). 99 # non-POSIX platforms (in particular it's not Windows compatible).
53 100
54 env_gen_dfa = env.Clone() 101 env_gen_dfa = env.Clone()
55 env_gen_dfa.Append(CCFLAGS=['-std=c++0x', '-DNACL_TRUSTED_BUT_NOT_TCB']) 102 env_gen_dfa.Append(CCFLAGS=['-std=c++0x', '-DNACL_TRUSTED_BUT_NOT_TCB'])
56 103
57 gen_dfa = env_gen_dfa.ComponentProgram( 104 gen_dfa = env_gen_dfa.ComponentProgram(
58 'gen_dfa', 105 'gen_dfa',
59 ['unreviewed/gen_dfa.cc']) 106 ['unreviewed/gen_dfa.cc'])
60 107
61 # Source generation step 2: Generate decoder automatas. 108 # Source generation step 2: Generate decoder automata.
62 # 109 #
63 # Now we are back to conditionally defining the large automata generated 110 # Now we are back to conditionally defining the large automata generated
64 # by gen_dfa. 111 # by gen_dfa.
65 112
66 def MakeAutomaton(bits, automaton, dfa_gen_actions, ragel_flags): 113 def MakeAutomaton(bits, automaton, dfa_gen_actions, ragel_flags):
67 rl_file = '%s_x86_%s_instruction.rl' % (automaton, bits) 114 rl_file = '%s_x86_%s_instruction.rl' % (automaton, bits)
68 115
69 # We are cheating here: there are two autogenerated files: 116 # We are cheating here: there are two autogenerated files:
70 # .rl and _consts.c, but we only track .rl one. This is safe because 117 # .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 118 # _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 119 # file is not changed _consts.c is guaranteed to be the same (reverse
73 # is not true). 120 # is not true).
121
74 const_file = '%s/%s_x86_%s_instruction_consts.c' % ( 122 const_file = '%s/%s_x86_%s_instruction_consts.c' % (
75 val_src_dir, automaton, bits) 123 val_src_dir, automaton, bits)
76 124
77 exe_path = '${STAGING_DIR}/${PROGPREFIX}gen_dfa${PROGSUFFIX}'
78 env.Command( 125 env.Command(
79 target=rl_file, 126 target=rl_file,
80 source=[exe_path] + INST_DEFS, 127 source=[gen_dfa] + INST_DEFS,
81 action=( 128 action=(
82 '${SOURCES[0]} -o ${TARGET} -c %s -m %s -d %s %s') % ( 129 '${SOURCES[0]} -o ${TARGET} -c %s -m %s -d %s %s') % (
83 # Const file (-c): not tracked by SCONS (see above) 130 # Const file (-c): not tracked by SCONS (see above)
84 const_file, 131 const_file,
85 # Argument for CPU type (-m): either "ia32" or "amd64". 132 # Argument for CPU type (-m): either "ia32" or "amd64".
86 {'32': 'ia32', '64': 'amd64'}[bits], 133 {'32': 'ia32', '64': 'amd64'}[bits],
87 # (-d): 134 # (-d):
88 dfa_gen_actions, 135 dfa_gen_actions,
89 # pass inst defs as remaining parameters 136 # pass inst defs as remaining parameters
90 ' '.join('${SOURCES[%d]}' % (i+1) 137 ' '.join('${SOURCES[%d]}' % (i + 1)
91 for i in range(len(INST_DEFS))) 138 for i in range(len(INST_DEFS)))
92 ) 139 )
93 ) 140 )
94 c_file = '%s_x86_%s.c' % (automaton, bits) 141 c_file = '%s_x86_%s.c' % (automaton, bits)
95 c_full_filename = '%s/%s' % (val_src_dir, c_file) 142 c_full_filename = '%s/%s' % (val_src_dir, c_file)
96 env.Command( 143 env.Command(
97 target=c_file, 144 target=c_file,
98 source=['unreviewed/%s_x86_%s.rl' % (automaton, bits), rl_file], 145 source=['unreviewed/%s_x86_%s.rl' % (automaton, bits), rl_file],
99 action=['%s %s -LL -I%s ${SOURCES[0]} -o ${TARGET}' % ( 146 action=['%s %s -LL -I%s ${SOURCES[0]} -o ${TARGET}' % (
100 ragel_binary, ragel_flags, rl_src_dir)] 147 ragel_binary, ragel_flags, rl_src_dir)]
101 ) 148 )
102 149
103 def InjectGeneratedFileHeader(target, source, env): 150 def InjectGeneratedFileHeader(target, source, env):
104 source_filename = source[0].get_abspath() 151 source_filename = source[0].get_abspath()
105 target_filename = target[0].get_abspath() 152 target_filename = target[0].get_abspath()
106 architecture = {'x86_32': 'ia32', 153 architecture = {'x86_32': 'ia32',
107 'x86_64': 'x86-64'}[target_filename[-8:-2]] 154 'x86_64': 'x86-64'}[target_filename[-8:-2]]
155
108 with open(source_filename, 'r') as source_file: 156 with open(source_filename, 'r') as source_file:
109 with open(target_filename, 'w') as target_file: 157 comment, sep, rest = source_file.read().partition('*/')
110 target_file.write( 158 if sep == '':
111 """/* native_client/%s 159 raise UserError('Generated file %s does not have '
112 * THIS FILE IS AUTO-GENERATED. DO NOT EDIT. 160 'header comment block' % source_filename)
113 * Compiled for %s mode.
114 */""" % (target_filename, architecture))
115 161
116 comment, sep, rest = source_file.read().partition('*/') 162 with open(target_filename, 'w') as target_file:
117 if sep == '': 163 target_file.write(
118 raise UserError('Generated file %s does not have ' 164 ('/* native_client/%s\n'
119 'header comment block' % source_filename) 165 ' * THIS FILE IS AUTO-GENERATED. DO NOT EDIT.\n'
120 target_file.write(rest) 166 ' * Compiled for %s mode.\n'
167 ' */') % (target_filename, architecture))
121 168
169 target_file.write(rest)
170
171 # inject comments and place files to appropriate dir
122 env.Command( 172 env.Command(
123 target=c_full_filename, 173 target=c_full_filename,
124 source=['%s/%s' % (rl_src_dir, c_file)], 174 source=['%s/%s' % (rl_src_dir, c_file)],
125 action=InjectGeneratedFileHeader 175 action=InjectGeneratedFileHeader
126 ) 176 )
127 177
128 return rl_file, c_file, c_full_filename 178 return rl_file, c_file, c_full_filename
129 179
130 decoder32 = MakeAutomaton( 180 decoder32 = MakeAutomaton(
131 '32', 'decoder', 181 '32', 'decoder',
132 'check_access,opcode,parse_operands_states,mark_data_fields', 182 'check_access,opcode,parse_operands_states,mark_data_fields',
133 '-T0') 183 '-T0')
134 validator32 = MakeAutomaton( 184 validator32 = MakeAutomaton(
135 '32', 'validator', 185 '32', 'validator',
136 ('check_access,opcode,parse_operands,parse_operands_states,' 186 ('check_access,opcode,parse_operands,parse_operands_states,'
137 'instruction_name,mark_data_fields,nacl-forbidden,' 187 'instruction_name,mark_data_fields,nacl-forbidden,'
138 'imm_operand_action,rel_operand_action'), 188 'imm_operand_action,rel_operand_action'),
139 '-G2') 189 '-G2')
140 decoder64 = MakeAutomaton( 190 decoder64 = MakeAutomaton(
141 '64', 'decoder', 191 '64', 'decoder',
142 'check_access,opcode,parse_operands_states,mark_data_fields', 192 'check_access,opcode,parse_operands_states,mark_data_fields',
143 '-T0') 193 '-T0')
144 validator64 = MakeAutomaton( 194 validator64 = MakeAutomaton(
145 '64', 'validator', 195 '64', 'validator',
146 ('opcode,instruction_name,mark_data_fields,imm_operand_action,' 196 ('opcode,instruction_name,mark_data_fields,imm_operand_action,'
147 'rel_operand_action,nacl-forbidden,parse_nonwrite_registers,' 197 'rel_operand_action,nacl-forbidden,parse_nonwrite_registers,'
148 'parse_x87_operands,parse_mmx_operands,parse_xmm_operands,' 198 'parse_x87_operands,parse_mmx_operands,parse_xmm_operands,'
149 'parse_ymm_operands,parse_relative_operands,' 199 'parse_ymm_operands,parse_relative_operands,'
150 'parse_immediate_operands,parse_operands_states,' 200 'parse_immediate_operands,parse_operands_states,'
151 'parse_operand_positions'), 201 'parse_operand_positions'),
152 '-GT2') 202 '-GT2')
153 203
154 automata = list(decoder32 + validator32 + decoder64 + validator64) 204 automata = list(decoder32 + validator32 + decoder64 + validator64)
155 205
206 # Generate checkdecoder test
207
208 test_env = env.Clone()
209 test_env.Append(
210 CCFLAGS=['-g', '-Wno-unused-function'],
211 LINKFLAGS='-g',
212 CPPPATH='unreviewed')
213
214 test_dfa_object = test_env.Object('unreviewed/test_dfa.c')
215
216 objdump, gas = env.Command(
217 target=['objdump', 'gas'],
218 source=['obtain_binutils.py'],
219 action='python ${SOURCES[0]} ${TARGETS[0]} ${TARGETS[1]}'
220 )
221
222 check_decoders = []
223
224 for bits in ('32', '64'):
225 (one_valid_instr_rl,) = env.Command(
226 target='one_valid_instruction_x86_%s.rl' % bits,
227 source=[gen_dfa] + INST_DEFS,
228 action=('${SOURCES[0]} -o ${TARGET} %s '
229 '-d check_access,rex_prefix,vex_prefix,opcode '
230 '-d parse_operands_states,parse_operands,instruction_name '
231 '-m %s') % (
232 ' '.join('${SOURCES[%d]}' % (i + 1)
233 for i in range(len(INST_DEFS))),
234 {'32': 'ia32', '64': 'amd64'}[bits])
235 )
236
237 include_dir = one_valid_instr_rl.dir.get_abspath()
238
239 (one_instr_dot,) = env.Command(
240 target='one_instruction_x86_%s.dot' % bits,
241 source=[
242 'unreviewed/one_instruction_x86_%s.rl' % bits,
243 one_valid_instr_rl],
244 action=[
245 '%s -V -I%s ${SOURCES[0]} -o ${TARGET}' %
246 (ragel_binary, include_dir)]
247 )
248
249 test_dfa_transitions = test_env.Command(
250 target='test_dfa_transitions_x86_%s.c' % bits,
251 source=['unreviewed/parse_dfa.py', one_instr_dot],
252 action='python ${SOURCES[0]} <"${SOURCES[1]}" >"${TARGET}"'
253 )
254
255 test_dfa_transitions_object = test_env.Object(test_dfa_transitions)
256
257 test_dfa = test_env.ComponentProgram(
258 'test_dfa_x86_%s' % bits,
259 [test_dfa_object, test_dfa_transitions_object])
260
261 fast_temp_for_test = '/dev/shm'
262
263 (check_decoder,) = env.Command(
264 target='objdump_test_fake_file_%s' % bits,
265 source=[
266 'unreviewed/run_objdump_test.py',
267 gas,
268 objdump,
269 decoder_test,
270 'unreviewed/decoder_test_one_file.sh',
271 test_dfa,
272 ],
273 action=[(
274 'python ${SOURCES[0]} '
275 '--gas="${SOURCES[1]} --%s" '
276 '--objdump="${SOURCES[2]}" '
277 '--decoder="${SOURCES[3]}" '
278 '--tester="${SOURCES[4]}" '
279 '-- '
280 '"${SOURCES[5]}" "%s"'
281 ) % (bits, fast_temp_for_test),
282 ])
283 check_decoders.append(check_decoder)
284
285 SideEffect(fast_temp_for_test, check_decoders)
286
156 env.AlwaysBuild(env.Alias('dfagen', automata)) 287 env.AlwaysBuild(env.Alias('dfagen', automata))
157 env.AlwaysBuild(env.Alias('dfaclean', action=map(Delete, automata))) 288 env.AlwaysBuild(env.Alias('dfaclean', action=map(Delete, automata)))
158 289 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 | src/trusted/validator_ragel/obtain_binutils.py » ('j') | src/trusted/validator_ragel/obtain_binutils.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698