Index: src/trusted/validator/x86/decoder/generator/ncval_simplify.c |
diff --git a/src/trusted/validator/x86/decoder/generator/ncval_simplify.c b/src/trusted/validator/x86/decoder/generator/ncval_simplify.c |
deleted file mode 100644 |
index b71ae504bc1c06e565ff3fdfc2f77cbd055eec45..0000000000000000000000000000000000000000 |
--- a/src/trusted/validator/x86/decoder/generator/ncval_simplify.c |
+++ /dev/null |
@@ -1,277 +0,0 @@ |
-/* |
- * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-/* |
- * Simplifies instruction set to what is needed for the |
- * (x86-64) ncval_reg_sfi validator. |
- * |
- * There are two parts to this story. First, the decoder used by the |
- * ncval_reg_sfi validator use the decoder in: |
- * native_client/src/trusted/validator/x86/decoder |
- * |
- * This decoder is based on instruction flags. If the instruction flags |
- * are not changed, the same sequence of bytes will be parsed, independent |
- * of the instruction mnemonic. Therefore, it is safe to change the |
- * instruction mnemonic to a "don't care" name unless it is explicitly |
- * used in some rule of the validator. The static validator validator_names |
- * in function NaClNcvalSimplifyMnemonic lists all instruction mnemonics that |
- * are currently used by the validator. |
- * |
- * Secondly, the ncval_reg_sfi validator checks general purpose registers, |
- * segment registers, and memory references to make sure that data and |
- * branching have been sandboxed properly. Hence, any argument to an x86 |
- * instruction that can be shown that it will never access one of these |
- * forms can be omitted without breaking the validator. Hence, this code |
- * removes all such arguments. See function NaClNcvalKeepOperand for details |
- * on what arguments are removed. |
- * |
- * Finally, for pragmatic reasons (i.e. readability), if an instruction is |
- * modified by this simplification, it is marked as a "partial instruction", |
- * so that the corresponding (ncdis) disassembler can correctly communicate |
- * that a partial match (rather than an actual instruction decoding) was applied |
- * to the given bits. The printed partial match communicates what was kept for |
- * validation purposes. |
- */ |
- |
-#ifndef NACL_TRUSTED_BUT_NOT_TCB |
-#error("This file is not meant for use in the TCB") |
-#endif |
- |
-#include "native_client/src/trusted/validator/x86/decoder/generator/ncval_simplify.h" |
- |
-#include <string.h> |
-#include "native_client/src/include/nacl_macros.h" |
-#include "native_client/src/trusted/validator/x86/x86_insts.h" |
-#include "native_client/src/trusted/validator/x86/decoder/generator/nc_compress.h" |
- |
-/* To turn on debugging of instruction decoding, change value of |
- * DEBUGGING to 1. |
- */ |
-#define DEBUGGING 0 |
- |
-#include "native_client/src/shared/utils/debugging.h" |
- |
-/* Returns true if the data extracted by the operand may be needed |
- * for register sfi sandboxing. |
- */ |
-static Bool NaClNcvalKeepOperand(NaClOp *operand) { |
- /* Operands in the ncval_seg_sfi (x86-64) validator are not inspected |
- * by the validator, unless they are general purpose register, segment |
- * registers, or memory references. The following list are all operand |
- * specifiers that can't contain any of the above, and hence, are not |
- * used by the validator. This list is used to safely determine if |
- * an operand can be removed. |
- */ |
- static NaClOpKind unnecessary_opkinds[] = { |
- RegDR0, /* Debug registers. */ |
- RegDR1, |
- RegDR2, |
- RegDR3, |
- RegDR4, |
- RegDR5, |
- RegDR6, |
- RegDR7, |
- RegDR8, |
- RegDR9, |
- RegDR10, |
- RegDR11, |
- RegDR12, |
- RegDR13, |
- RegDR14, |
- RegDR15, |
- RegEFLAGS, /* Program status and control registers. */ |
- RegRFLAGS, |
- St_Operand, /* Floating point stack registers. */ |
- RegST0, |
- RegST1, |
- RegST2, |
- RegST3, |
- RegST4, |
- RegST5, |
- RegST6, |
- RegST7, |
- Mmx_G_Operand, /* Mxx registers. */ |
- Mmx_Gd_Operand, |
- RegMMX0, |
- RegMMX1, |
- RegMMX2, |
- RegMMX3, |
- RegMMX4, |
- RegMMX5, |
- RegMMX6, |
- RegMMX7, |
- Xmm_G_Operand, /* Xmm registers. */ |
- Xmm_Go_Operand, |
- RegXMM0, |
- RegXMM1, |
- RegXMM2, |
- RegXMM3, |
- RegXMM4, |
- RegXMM5, |
- RegXMM6, |
- RegXMM7, |
- RegXMM8, |
- RegXMM9, |
- RegXMM10, |
- RegXMM11, |
- RegXMM12, |
- RegXMM13, |
- RegXMM14, |
- RegXMM15, |
- }; |
- size_t i; |
- for (i = 0; i < NACL_ARRAY_SIZE(unnecessary_opkinds); ++i) { |
- if (operand->kind == unnecessary_opkinds[i]) return FALSE; |
- } |
- return TRUE; |
-} |
- |
-/* Returns the instruction mnemonic to use for an instruction. The |
- * mnemonic is changed only if the (x86-64) ncval_reg_sfi validator |
- * doesn't need to know the corresponding instruction mnemonic. |
- */ |
-static NaClMnemonic NaClNcvalSimplifyMnemonic(NaClModeledInst *inst) { |
- /* List of white listed names that must be kept for the validator, |
- * since they are used as part of the pattern checking of the validator. |
- */ |
- static NaClMnemonic validator_names[] = { |
- InstAnd, |
- InstAdd, |
- InstCall, |
- InstInvalid, |
- InstLea, |
- InstMov, |
- InstOr, |
- InstPop, |
- InstPush, |
- InstSub |
- }; |
- NaClMnemonic name = inst->name; |
- size_t i; |
- for (i = 0; i < NACL_ARRAY_SIZE(validator_names); ++i) { |
- if (name == validator_names[i]) return name; |
- } |
- /* If not white listed, change to dont care. */ |
- if (NaClHasBit(inst->flags, NACL_IFLAG(ConditionalJump))) { |
- return InstDontCareCondJump; |
- } |
- if (NaClHasBit(inst->flags, NACL_IFLAG(JumpInstruction))) { |
- return InstDontCareJump; |
- } |
- return InstDontCare; |
-} |
- |
-/* Fixes format strings used to define the instruction operand |
- * to its simplified form, by removing any implicit braces used |
- * when defining the operand for the instruction. |
- */ |
-static const char* RemoveImplicitFromFormat(const char* str) { |
- size_t str_len = strlen(str); |
- if ((str_len > 0) && (str[0] == '{') && (str[str_len-1] == '}')) { |
- char* simp_str = (char*) malloc(str_len-1); |
- if (NULL == simp_str) return str; /* This should not happen. */ |
- strncpy(simp_str, str+1, str_len-1); |
- simp_str[str_len-2] = '\0'; |
- return simp_str; |
- } |
- return str; |
-} |
- |
-/* Simplify the given instruction and return the simplified instruction, |
- * based on expectations of the (x86-64) ncval_reg_sfi validator. |
- */ |
-static void NaClNcvalSimplifyInst(NaClInstTables *inst_tables, |
- NaClModeledInst *inst) { |
- size_t i; |
- NaClMnemonic simplified_name; |
- size_t fill = 0; |
- Bool is_partial = FALSE; |
- |
- if (NULL == inst) return; |
- |
- /* First simplify additional rules associated with the given instruction. */ |
- NaClNcvalSimplifyInst(inst_tables, inst->next_rule); |
- |
- /* Ignore invalid instructions. */ |
- if (NACLi_INVALID == inst->insttype) return; |
- |
- /* Remove unnecessary operands. */ |
- if (NaClHasBit(inst->flags, NACL_IFLAG(NaClIllegal))) { |
- /* Remove all arguments. We don't need to process arguments. |
- * Validation will fail regardless. |
- */ |
- inst->num_operands = 0; |
- inst->name = InstDontCare; |
- is_partial = TRUE; |
- } else { |
- /* Simplify the instruction mnemonic. */ |
- simplified_name = NaClNcvalSimplifyMnemonic(inst); |
- if (simplified_name != inst->name) { |
- uint8_t num_operands; |
- inst->name = simplified_name; |
- is_partial = TRUE; |
- |
- /* We have simplified the modeled instruction, and hence |
- * the modeled instruction is now a pattern, rather than' |
- * an x86 instruction. Remove operands that aren't needed, |
- * because the operand is never going to be used by the validator. |
- */ |
- num_operands = inst->num_operands; |
- for (i = 0; i < num_operands; i++) { |
- if (NaClNcvalKeepOperand(&inst->operands[i])) { |
- inst->operands[fill++] = inst->operands[i]; |
- } else { |
- inst->num_operands--; |
- is_partial = TRUE; |
- } |
- } |
- } |
- } |
- |
- /* Check if we modified anything. If so, we need to clean |
- * up the instruction so that (all) useful information is printed |
- * by the decoder print functions (i.e. as a pattern rather than |
- * an x86 instruction). |
- */ |
- if (is_partial) { |
- uint8_t num_operands = inst->num_operands; |
- NaClAddBits(inst->flags, NACL_IFLAG(PartialInstruction)); |
- for (i = 0; i < num_operands; i++) { |
- if (NaClHasBit(inst->operands[i].flags, NACL_OPFLAG(OpImplicit))) { |
- NaClRemoveBits(inst->operands[i].flags, NACL_OPFLAG(OpImplicit)); |
- inst->operands[i].format_string = |
- RemoveImplicitFromFormat(inst->operands[i].format_string); |
- } |
- } |
- } |
-} |
- |
-/* Simplify instructions in the given trie node. */ |
-static void NaClNcvalSimplifyNode(NaClInstTables *inst_tables, |
- NaClModeledInstNode* node) { |
- if (NULL == node) return; |
- NaClNcvalSimplifyInst(inst_tables, node->matching_inst); |
- NaClNcvalSimplifyNode(inst_tables, node->success); |
- NaClNcvalSimplifyNode(inst_tables, node->fail); |
-} |
- |
-void NaClNcvalInstSimplify(NaClInstTables* inst_tables) { |
- int i; |
- NaClInstPrefix prefix; |
- |
- /* Simplify the undefined instruction. */ |
- NaClNcvalSimplifyInst(inst_tables, inst_tables->undefined_inst); |
- |
- /* Simplify all instructions in the instruction opcode table. */ |
- for (prefix = NoPrefix; prefix < NaClInstPrefixEnumSize; ++prefix) { |
- for (i = 0; i < NCDTABLESIZE; ++i) { |
- NaClNcvalSimplifyInst(inst_tables, inst_tables->inst_table[i][prefix]); |
- } |
- } |
- |
- /* Simplify instructions in the instruction trie. */ |
- NaClNcvalSimplifyNode(inst_tables, inst_tables->inst_node_root); |
-} |