| 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);
 | 
| -}
 | 
| 
 |