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

Unified Diff: src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.c

Issue 625923004: Delete old x86 validator. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: rebase master Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.c
diff --git a/src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.c b/src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.c
deleted file mode 100644
index d3a800e0172e14e0a3004746e574cb5139c8fc77..0000000000000000000000000000000000000000
--- a/src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (c) 2012 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.
- */
-
-/* Validator to check that instructions are in the legal subset. */
-
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.h"
-
-#include "native_client/src/shared/platform/nacl_log.h"
-#include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h"
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h"
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal.h"
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.h"
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_internal.h"
-#include "native_client/src/trusted/validator/x86/decoder/generator/gen/nacl_disallows.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"
-
-/* Message to use if we don't have a more precise reason why the instruction
- * is illegal.
- */
-static const char* kNaClGenericReasonDisallowed =
- "Illegal native client instruction";
-
-/* This function returns a printable description of the reason an instruction
- * is disallowed, or NULL if the reason is not understood.
- */
-static const char* NaClReasonWhyDisallowed(NaClDisallowsFlag flag) {
- switch (flag) {
- case NaClTooManyPrefixBytes:
- return "More than one (non-REX) prefix byte specified";
- case NaClMarkedIllegal:
- return "This instruction has been marked illegal by Native Client";
- case NaClMarkedInvalid:
- return "Opcode sequence doesn't define a valid x86 instruction";
- case NaClMarkedSystem:
- return "System instructions are not allowed by Native Client";
- case NaClHasBadSegmentPrefix:
- return "Uses a segment prefix byte not allowed by Native Client";
- case NaClCantUsePrefix67:
- return "Use of 67 (ADDR16) prefix not allowed by Native Client";
- case NaClMultipleRexPrefix:
- return "Multiple use of REX prefix not allowed";
- case NaClRepDisallowed:
- return
- "Use of REP (F3) prefix for instruction not allowed by "
- "Native Client";
- case NaClRepneDisallowed:
- return
- "Use of REPNE (F2) prefix for instruction not allowed by "
- "Native Client";
- case NaClData16Disallowed:
- return
- "Use of DATA16 (66) prefix for instruction not allowed by "
- "Native Client";
- case NaClHasDuplicatePrefix:
- return
- "Duplicating a prefix byte is not allowed by Native Client";
- case NaClHasAmbigSegmentPrefixes:
- return
- "Specifying different segment registers using prefix bytes "
- "is not allowed by Native Client";
- case NaClRexPrefixNotLast:
- return "REX prefix byte must appear last";
- default:
- return NULL;
- }
-}
-
-/* Same as NaClReasonWhyDisallowed, except that the unknown value (NULL)
- * is replaced by a useful print error message.
- */
-static const char* NaClGetReasonWhyDisallowed(NaClDisallowsFlag flag) {
- const char* why = NaClReasonWhyDisallowed(flag);
- if (NULL == why) {
- /* If reached, we don't understand the flag. Non the less, we should
- * return a message explaining that the instruction is illegal, so
- * that an appropriate error message can be printed.
- */
- why = kNaClGenericReasonDisallowed;
- }
- return why;
-}
-
-/* A mask of possible segment prefixes. */
-static const uint32_t kNaClSegmentPrefixMask =
- kPrefixSEGES | kPrefixSEGFS | kPrefixSEGGS | kPrefixSEGSS |
- kPrefixSEGCS | kPrefixSEGDS;
-
-/*
- * A mask for prefixes that can't appear with any jump instruction.
- * Note: We rule these out because of Intel's Software Developer's
- * Manual (volume 2a) documents in section 2.1.1 that such uses may
- * cause unpredictable behaviour.
- */
-static const uint32_t kNaClUnsafeJumpPrefixes =
- kPrefixSEGES | kPrefixSEGFS | kPrefixSEGGS | kPrefixSEGSS;
-
-/*
- * A mask for prefixes that can only appear with conditional jump
- * instructions with branch hints.
- */
-static const uint32_t kNaClBranchHintJumpPrefixes =
- kPrefixSEGCS | kPrefixSEGDS;
-
-/* This function checks properties about segment registers on an
- * instruction, reporting issues not allowed by native client.
- */
-static void NaClCheckSegmentPrefixes(NaClValidatorState* state,
- Bool* is_legal,
- NaClDisallowsFlags* disallows_flags) {
- NaClInstState* inst_state = state->cur_inst_state;
- Bool segment_prefixes_ok = TRUE;
-
- if (0 == (inst_state->prefix_mask & kNaClSegmentPrefixMask)) return;
-
- if (state->cur_inst->flags &
- (NACL_IFLAG(JumpInstruction) | NACL_IFLAG(ConditionalJump))) {
- if (inst_state->prefix_mask & kNaClUnsafeJumpPrefixes) {
- segment_prefixes_ok = FALSE;
- }
- if (NaClExcludesBit(state->cur_inst->flags, NACL_IFLAG(BranchHints)) &&
- NaClHasBit(inst_state->prefix_mask, kNaClBranchHintJumpPrefixes)) {
- segment_prefixes_ok = FALSE;
- }
- } else {
- /* We don't allow any prefix masks on data accesses. */
- segment_prefixes_ok = FALSE;
- }
-
- if (!segment_prefixes_ok) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClHasBadSegmentPrefix);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClHasBadSegmentPrefix)));
- }
-
- /* Don't allow ambiguous prefix forms. */
- if (inst_state->has_ambig_segment_prefixes) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClHasAmbigSegmentPrefixes);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClHasAmbigSegmentPrefixes)));
- }
-
-}
-
-/* This function checks properties of prefix bytes on an instruction,
- * reporting issues not allowed by native client.
- *
- * Parameters are:
- * state : The current validator state to check.
- * is_legal: Flag set to FALSE if any prefix problems are found.
- * disallows_flags : Set of flags, describing the reason(s) the
- * current instruction in the validator state is not
- * legal in native client. Updated as appropriate.
- */
-static void NaClCheckForPrefixIssues(NaClValidatorState* state,
- Bool* is_legal,
- NaClDisallowsFlags* disallows_flags) {
- NaClInstState* inst_state = state->cur_inst_state;
- const NaClInst* inst = state->cur_inst;
- /* Don't allow more than one (non-REX) prefix. */
- int num_prefix_bytes = inst_state->num_prefix_bytes;
- if (inst_state->rexprefix) --num_prefix_bytes;
-
- /* Don't allow an invalid instruction. */
- if (!NaClInstStateIsValid(inst_state)) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClMarkedInvalid);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClMarkedInvalid)));
- }
-
- /* If there aren't prefix bytes, there isn't anything to check. */
- if (num_prefix_bytes == 0) return;
-
- /* Don't allow multiple prefix bytes, except for the special
- * case of the pair DATA16 and LOCK (allowed so that one can
- * lock short integers).
- *
- * Note: Explicit NOP sequences that use multiple 66 values are
- * recognized as special cases, and need not be processed here.
- */
- if (num_prefix_bytes > 1) {
- if ((num_prefix_bytes == 2) &&
- (inst_state->prefix_mask & kPrefixDATA16) &&
- (inst_state->prefix_mask & kPrefixLOCK)) {
- /* Allow data prefix if lock prefix also given. */
- } else {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClTooManyPrefixBytes);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClTooManyPrefixBytes)));
- }
- }
-
- /* Only allow REP/REPE/REPZ (F3) prefix if flag specifies it is allowed. */
- if ((inst_state->prefix_mask & kPrefixREP) &&
- (NACL_EMPTY_IFLAGS == (inst->flags & NACL_IFLAG(OpcodeAllowsRep)))) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClRepDisallowed);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClRepDisallowed)));
- }
-
- /* Only allow REPNE/REPNZ (F2) prefix if flag specifies it is allowed. */
- if ((inst_state->prefix_mask & kPrefixREPNE) &&
- (NACL_EMPTY_IFLAGS == (inst->flags & NACL_IFLAG(OpcodeAllowsRepne)))) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClRepneDisallowed);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClRepneDisallowed)));
- }
-
- /* Only allow Data16 (66) prefix if flag specifies it is allowed. */
- if ((inst_state->prefix_mask & kPrefixDATA16) &&
- (NACL_EMPTY_IFLAGS == (inst->flags & NACL_IFLAG(OpcodeAllowsData16)))) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClData16Disallowed);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClData16Disallowed)));
- }
-
- /* Don't allow more than one REX prefix. */
- if (inst_state->num_rex_prefixes > 1) {
- /* NOTE: does not apply to NOP, since they are parsed using
- * special handling (i.e. explicit byte sequence matches) that
- * doesn't explicitly define prefix bytes.
- *
- * NOTE: We don't disallow this while decoding, since xed doesn't
- * disallow this, and we want to be able to compare our tool
- * to xed.
- */
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClMultipleRexPrefix);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClMultipleRexPrefix)));
- }
-
- /* Don't allow shortened address sizes. That is prefix ADDR16. */
- if (inst_state->prefix_mask & kPrefixADDR16) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClCantUsePrefix67);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClCantUsePrefix67)));
- }
-
- NaClCheckSegmentPrefixes(state, is_legal, disallows_flags);
-
- /* Don't allow duplicated prefixes. Note: Don't report if multiple
- * REX prefixes has been reported, since we don't know what duplicates
- * caused the problem, and an error has already been reported.
- */
- if (inst_state->has_prefix_duplicates &&
- (NACL_EMPTY_DISALLOWS_FLAGS ==
- (*disallows_flags & NACL_DISALLOWS_FLAG(NaClMultipleRexPrefix)))) {
- /* NOTE: does not apply to NOP, since they are parsed using
- * special handling (i.e. explicit byte sequence matches) that
- * doesn't explicitly define prefix bytes.
- *
- * NOTE: We don't disallow this while decoding, since xed doesn't
- * disallow this, and we want to be able to compare our tool
- * to xed.
- */
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClHasDuplicatePrefix);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClHasDuplicatePrefix)));
- }
-
- /* Check the location of the REX prefix, if one is specified.. */
- if (inst_state->prefix_mask & kPrefixREX) {
- /* First find the locations of the REX prefix. */
- int i;
- int rex_index = -1;
- for (i = 0; i < inst_state->num_prefix_bytes; ++i) {
- char prefix = inst_state->bytes.byte[i];
- switch (prefix) {
- case 0x40:
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x44:
- case 0x45:
- case 0x46:
- case 0x47:
- case 0x48:
- case 0x49:
- case 0x4a:
- case 0x4b:
- case 0x4c:
- case 0x4d:
- case 0x4e:
- case 0x4f:
- rex_index = i;
- break;
- default:
- break;
- }
- }
- /* NOTE: REX prefix must be last, unless FO exists. If FO
- * exists, it must be after REX (Intel Manual).
- *
- * NOTE: (karl) It appears that this constraint is violated
- * with compiled code of /bin/ld_static. According to AMD,
- * the rex prefix must be last.
- *
- * For now, we will follow the convention of gcc, which places
- * the LOCK byte in front of the REX byte.
- */
- if (rex_index >= 0) {
- if ((rex_index + 1) != inst_state->num_prefix_bytes) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClRexPrefixNotLast);
- }
- }
- }
-}
-
-/* Checks instruction details of the current instruction to see if there
- * are any red flags that make the instruction illegal.
- *
- * Parameters are:
- * state : The current validator state to check.
- * is_legal: Flag set to FALSE if any prefix problems are found.
- * disallows_flags : Set of flags, describing the reason(s) the
- * current instruction in the validator state is not
- * legal in native client. Updated as appropriate.
- */
-static void NaClCheckIfMarkedIllegal(NaClValidatorState* state,
- Bool* is_legal,
- NaClDisallowsFlags* disallows_flags) {
- if (NACL_IFLAG(NaClIllegal) & state->cur_inst->flags) {
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClMarkedIllegal);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClMarkedIllegal)));
- }
-
- /* Check other forms to disallow.
- * TODO(karl): Move these checks into the model generator, setting the
- * NaClIllegal flag. Once that is completed, this switch statement can
- * can be removed.
- */
- switch (state->cur_inst->insttype) {
- case NACLi_RETURN:
- case NACLi_EMMX:
- /* EMMX needs to be supported someday but isn't ready yet. */
- case NACLi_ILLEGAL:
- case NACLi_SYSTEM:
- case NACLi_RDMSR:
- case NACLi_RDTSCP:
- case NACLi_LONGMODE:
- case NACLi_SVM:
- case NACLi_3BYTE:
- case NACLi_UNDEFINED:
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClMarkedIllegal);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClMarkedIllegal)));
- break;
- case NACLi_INVALID:
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClMarkedInvalid);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClMarkedInvalid)));
- break;
- case NACLi_SYSCALL:
- case NACLi_SYSENTER:
- *is_legal = FALSE;
- *disallows_flags |= NACL_DISALLOWS_FLAG(NaClMarkedSystem);
- DEBUG(NaClLog(LOG_INFO, "%s\n",
- NaClGetReasonWhyDisallowed(NaClMarkedSystem)));
- break;
- default:
- break;
- }
-}
-
-/* Prints out error messages describing why the current instruction
- * in the given validator state is not legal in native client.
- *
- * Parameters are:
- * state : The current validator state to check.
- * disallows_flags : Set of flags, describing the reason(s) the
- * current instruction in the validator state is not
- * legal in native client. Updated as appropriate.
- */
-static void NaClReportWhyNaClIllegal(NaClValidatorState* state,
- NaClDisallowsFlags disallows_flags) {
- if (NACL_EMPTY_DISALLOWS_FLAGS != disallows_flags) {
- int i;
- Bool printed_reason = FALSE;
- NaClInstState* inst_state = state->cur_inst_state;
- /* Print out error message for each reason the instruction is disallowed. */
- for (i = 0; i < NaClDisallowsFlagEnumSize; ++i) {
- if (disallows_flags & NACL_DISALLOWS_FLAG(i)) {
- const char* why_disallowed = NaClReasonWhyDisallowed(i);
- if (NULL != why_disallowed) {
- printed_reason = TRUE;
- NaClValidatorInstMessage(
- LOG_ERROR, state, inst_state, "%s\n", why_disallowed);
- }
- }
- /* Stop looking if we should quit reporting errors. */
- if (state->quit) break;
- }
- /* Be sure we print a reason (in case the switch isn't complete). */
- if (!printed_reason) {
- disallows_flags = NACL_EMPTY_DISALLOWS_FLAGS;
- }
- }
- if (NACL_EMPTY_DISALLOWS_FLAGS == disallows_flags) {
- /* No known reason was recorded, but the instruction was recorded as illegal.
- * Report that the instruction is not acceptable.
- */
- NaClValidatorInstMessage(LOG_ERROR, state, state->cur_inst_state,
- "%s\n", kNaClGenericReasonDisallowed);
- }
-}
-
-void NaClValidateInstructionLegal(NaClValidatorState* state) {
- Bool is_legal = TRUE;
- NaClDisallowsFlags disallows_flags = NACL_EMPTY_DISALLOWS_FLAGS;
- DEBUG_OR_ERASE({
- struct Gio* g = NaClLogGetGio();
- NaClLog(LOG_INFO, "->NaClValidateInstructionLegal\n");
- NaClInstPrint(g, state->decoder_tables,
- NaClInstStateInst(state->cur_inst_state));
- NaClExpVectorPrint(g, state);
- });
- NaClCheckForPrefixIssues(state, &is_legal, &disallows_flags);
- NaClCheckIfMarkedIllegal(state, &is_legal, &disallows_flags);
- if (!is_legal) {
- NaClReportWhyNaClIllegal(state, disallows_flags);
- }
- DEBUG(NaClLog(LOG_INFO,
- "<-NaClValidateInstructionLegal: is_legal = %"NACL_PRIdBool"\n",
- is_legal));
-}
« no previous file with comments | « src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.h ('k') | src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698