1 This directory contains the code for the native client register based
2 (R15) solution for x86-64 validation. R15 is used to convert 32-bit
3 addresses to the corresponding 64-bit address for memory accesses.
5 Note: Although the current builds generate 32-bit versions, they do
6 not make any sense, since pointers are 32-bits in x86-32.
11 Defines code that checks if the CPUID allows each
12 instruction. If not, it replaces the instruction with HALTs
17 Defines code that checks each instruction to see if it meets
18 basic requirements for native client. This includes the
21 - More than one (non-REX) prefix byte is not specified (we do
22 allow lock (f0) and DATA 16 (66) prefixes if the instruction
23 has been specified to accept both).
25 - The instruction has not been marked as illegal (see "Modeled
28 - The prefix/opcode sequence of the instruction has not been
29 marked as invalid (see "Modeled Instructions" below).
31 - The is not marked as a system instruction (see "Modeled
34 - Segment prefixes (except those used for jump prediction on
35 conditional jumps) are not allowed.
37 - The ADDR 16 (67) prefix has been used for the instruction,
38 but native client doesn't allow it (see "Modeled
41 - No more than one REX prefix has been specified for the
44 - The REP (f3) prefix is not allowed for the instruction (see
45 "Modeled Instructions" below).
47 - The REPNE (f2) prefix is not allowed for the instruction
48 (see "Modeled Instructions" below).
50 - The DATA 16 (66) prefix is not allowed for the instruction
51 (see "Modeled Instructions" below).
53 - A prefix byte was not duplicated (we allow 66 to be
54 duplicated for special cases of the NOP instructions that
55 are commonly generated by compilers, see "Modeled
56 Instructions" for more information on these hard-coded
59 - Multiple, ambigious segment prefixes are not allowed for an
62 - The REX prefix does not appear last in the sequence of
67 Defines code to check jump instructions. In general, explicit
68 jumps must jump to an instruction in the same segment if it is
69 explicitly specified using a constant. All other jumps should
70 be indirect and use a pre-approved pattern that adds R15 to a
71 corresponding 32-bit address.
73 nc_memory_protect.{c,h}
75 Checks that memory references use an appropriate pattern that
76 converts a 32-bit data address (using R15) to a corresponding
77 64-bit memory reference.
79 nc_opcode_histogram.{c,h}
81 Simple histogram tracker of the frequency that each opcode is
82 used. Not needed to validate but provides useful test
87 Checks that the instruction doesn't improperly modify one of
88 the base registers RSP, RBP, and R15. Also checks LEA
89 instructions to see if they calculate an address of the form
93 and put the results into an appropriate 32-bit register.
97 Defines an iterator that iterates over the instructions in a
98 memory segment. Keeps track of the previous 2 instructions
99 during this iteration so that one can check multiple
100 instruction patterns. It also define
104 Defines the API to the iterator defined in ncvalidate_iter.c.
106 ncvalidate_iter_internal.h
108 Defines internal methods and data structures used to implement
109 the iterator defined in ncvalidate_iter.c
111 ncvalidate_iter_verbose.c
113 Defines a verbose error reporter that works for the
114 instructions iterated over using the API methods in
117 ncvalidate_utils.{c,h}
119 Defines various common checking routines for instructions.
121 ncvalidate_registry.{c,h}
123 Defines a registry of validator checking methods, that get
124 applied to validate instruction.
129 Textual version(s) of the instructions understood by the validator can
130 be found in the following files.
132 native_client/src/trusted/validator_x86/testdata/64/modeled_insts.txt
134 Defines the set of instructions understood by the (full)
135 decoder. This is the most human readable form of the generated
136 decoder tables used by the validator.
138 native_client/src/trusted/validator_x86/testdata/64/ncval_reg_sfi_modeled_insts.txt
140 Defines the set of (partial) isntructions understood by the
141 validator decoder. This file is the same as modeled_insts.txt
142 above except that it shows how the modeled instructions have
143 been simplified, based on the needs of the validator in this
144 directory. In particular, most instruction mnemonics are
145 simplified to a "don't care" name since the mnemonic name is not
146 needed by the validator. In addition, most implicit arguments of
147 the instruction are made explicit, and arguments that can't be
148 used to compute memory addresses have been removed.
150 For more information on the contents of these files, see
152 native_client/src/trusted/validator/x86/decoder/README
154 Pre/Post condition testing
155 --------------------------
157 The code in this directory is set up to allow instructions to be
158 validated individually. When run in this mode, pre/post conditions
159 are generated rather than looking accross instructions to verify the
160 conditions. This is intentional, and is intended for testing multiple
161 validators. In such contexts, the pre/post conditions define what must
162 be checked by a compatible validator.
164 To generate these condition tests, one must compile the source using
167 .> ./scons --mode=opt-linux platform=x86-64 ncval_testing=1
169 Note: --mode=opt-linux is not necessary. Any applicable mode will
172 When native_client/src/trusted/validator_x86/ncval.c is compiled with
173 the above scons command, the corresponding executable will generate
176 Code to generate pre/post conditions is conditionalized in the source
177 (under '#ifdef NCVAL_TESTING') so that it is only added when scons
178 option ncval_testing=1 is defined.
180 The default error reportor is used by the validator. This is done so
181 that only pre/post conditions will be printed. Hence, if you are to
182 add debugging code within NCVAL_TESTING, be sure to not redirect the
183 output to the validator's error reporter. Rather, redirect using calls
184 to NaClLog or printf. To override this presumption and see other
185 debugging messages, change the line
189 in native_client/src/trusted/validator_x86/ncval.c to be
193 This will cause the validator to use the verbose error reporter within
196 To run unit tests for the pre/post conditions, run the following scons
199 .> ./scons --mode=opt-linux platform=x86-64 ncval_testing=1 \
202 Note: To see how to test scons builds with ncval_testing=1, see
203 native_client/src/trusted/validator_x86/build.scons and look for the
204 text 'test_env.Bit('ncval_testing')'.
209 Many of the source files contain #define DEBUGGING flags. When
210 DEBUGGING is set to 1, additional debugging print messages are
211 compiled into the code. Unfortunately, by default, these message
212 frequently call routines that are not compiled into corresponding
213 executables (such as ncval and ncdis). To add the additional routines,
216 native_client/site_scons/site_tools/library_deps.py
218 For x86-32, edit lines
220 # When turning on the DEBUGGING flag in the x86-32 validator
221 # or decoder, add the following:
222 #'nc_opcode_modeling_verbose_x86_32',
226 # When turning on the DEBUGGING flag in the x86-32 validator
227 # or decoder, add the following:
228 'nc_opcode_modeling_verbose_x86_32',
230 For x86-64, edit lines
232 # When turning on the DEBUGGING flag in the x86-64 validator
233 # or decoder, add the following:
234 # 'nc_opcode_modeling_verbose_x86_64',
238 # When turning on the DEBUGGING flag in the x86-64 validator
239 # or decoder, add the following:
240 'nc_opcode_modeling_verbose_x86_64',
242 These changes will make sure that the corresponding print routines are
243 added to the executables during link time.