## 1. ia32 code modification rules

1. Replacement code block must be valid as per regular NaCl ia32 rules with one exception (see below).
2. Boundaries of the instructions must not be changed.
3. Superinstructions (`naclcall`/`nacljmp`) must not be changed.
4. One tiny exception to the rule #1: if instruction is direct jump or direct call and it refers unaligned address outside of the [`dest`, `dest`+`size`) region then it’s allowed as long as it’s not modified.

The exception above exist to support modifications of small pieces of code in a large code block. If code was accepted by the `nacl_dyncode_create` then it means that all the targets in all `jcc`, `jmp`, and `call` instructions are valid WRT their targets — and if `jcc`, `jmp`, or `call` point to unknown (in the `nacl_dyncode_modify`) address everything is fine as long as this address is unmodified: if it was valid once it’s valid always because modifications of instruction boundaries are not allowed.

## 2. amd64 (aka x86-64, aka intel64) code modification rules

1. Replacement code block must be valid as per regular NaCl amd64 rules with one exception (see below).
2. Only instructions in the following list can be modified:
   - `mov`
   - `call`
3. Instructions can only be modified by altering their anyfields (that is: displacements, relative offsets or immediates).
Note: since we don’t allow any modifications to the instructions (except for the anyfields which don’t affect length) instruction boundaries are automatically unchanged in this case, too.
4. One tiny exception to the rule #1: if instruction is direct jump or direct call and it refers unaligned address outside of the [dest, dest+size) region then it’s allowed as long as it’s not modified.

Rationale for the exception in x86-64 case is the same as in ia32 case.

This logic is implemented in `dfa_validate_xxx.c` files. Function `ApplyDfaValidator_x86_xx` implements initial validation (used in `nacl_dyncode_create`) while couple of functions `ValidatorCodeReplacement_x86_xx`/`ValidatorCopy_x86_xx` are used in `nacl_dyncode_modify` (`ValidatorCodeReplacement_x86_xx` determines if the rules above are unbroken and `ValidatorCopy_x86_xx` is used to process instructions one-after-another by `NaClCopyInstructionFunc`). Note: `ValidatorCopy_x86_xx` assumes code was accepted by the `ValidatorCodeReplacement_x86_xx` function. Result for code which is not verified by `ValidatorCodeReplacement_x86_xx` is not defined and `NaClCopyInstructionFunc` is external function passed to `ValidatorCopy_x86_xx` which guarantees safe replacement of a single instruction in a presence of threads.