コード例 #1
0
ファイル: cpu_x86_test.c プロジェクト: rzr/Tizen_Crosswalk
int main(void) {
    NaClCPUFeaturesX86 fv;
    NaClCPUData cpu_data;
    int feature_id;
    NaClCPUDataGet(&cpu_data);

    NaClGetCurrentCPUFeaturesX86((NaClCPUFeatures *) &fv);
    if (NaClArchSupportedX86(&fv)) {
        printf("This is a native client %d-bit %s compatible computer\n",
               NACL_TARGET_SUBARCH, GetCPUIDString(&cpu_data));
    } else {
        if (!NaClGetCPUFeatureX86(&fv, NaClCPUFeatureX86_CPUIDSupported)) {
            printf("Computer doesn't support CPUID\n");
        }
        if (!NaClGetCPUFeatureX86(&fv, NaClCPUFeatureX86_CPUSupported)) {
            printf("Computer id %s is not supported\n", GetCPUIDString(&cpu_data));
        }
    }

    printf("This processor has:\n");
    for (feature_id = 0; feature_id < NaClCPUFeatureX86_Max; ++feature_id) {
        if (NaClGetCPUFeatureX86(&fv, feature_id))
            printf("        %s\n", NaClGetCPUFeatureX86Name(feature_id));
    }
    return 0;
}
コード例 #2
0
void NaClInitSwitchToApp(struct NaClApp *nap) {
  /* TODO(jfb) Use a safe cast here. */
  NaClCPUFeaturesX86 *features = (NaClCPUFeaturesX86 *) nap->cpu_features;
  if (NaClGetCPUFeatureX86(features, NaClCPUFeatureX86_AVX)) {
    NaClSwitch = NaClSwitchAVX;
  } else if (NaClGetCPUFeatureX86(features, NaClCPUFeatureX86_SSE)) {
    NaClSwitch = NaClSwitchSSE;
  } else {
    NaClSwitch = NaClSwitchNoSSE;
  }
}
コード例 #3
0
/* Helper function to report unsupported features */
static INLINE void NaClCheckFeature(NaClCPUFeatureX86ID feature,
                                    struct NaClValidatorState* vstate,
                                    Bool* squash_me) {
  if (!NaClGetCPUFeatureX86(&vstate->cpu_features, feature)) {
    if (!NaClGetCPUFeatureX86(&vstate->cpu_checks.cpu_features, feature)) {
      NaClValidatorInstMessage(
          LOG_WARNING, vstate, vstate->cur_inst_state,
          "CPU model does not support %s instructions.\n",
          NaClGetCPUFeatureX86Name(feature));
      NaClSetCPUFeatureX86(&vstate->cpu_checks.cpu_features, feature, TRUE);
    }
    *squash_me = TRUE;
  }
}
コード例 #4
0
/* It returns 0 if the current instruction is implemented, and 1 if not.  */
static int ValidateSFenceClFlush(const NCDecoderInst *dinst) {
  NCValidatorState* vstate = NCVALIDATOR_STATE_DOWNCAST(dinst->dstate);
  uint8_t mrm = NCInstBytesByteInline(&dinst->inst_bytes, 2);

  if (modrm_modInline(mrm) == 3) {
    /* this is an sfence */
    if (NaClGetCPUFeatureX86(&vstate->cpufeatures, NaClCPUFeatureX86_FXSR))
      return 0;
    return 1;
  } else {
    /* this is an clflush */
    if (NaClGetCPUFeatureX86(&vstate->cpufeatures, NaClCPUFeatureX86_CLFLUSH))
      return 0;
    return 1;
  }
}
コード例 #5
0
static int32_t TestSyscall(struct NaClAppThread *natp) {
  /* TODO(mcgrathr): Use a safe cast here. */
  NaClCPUFeaturesX86 *features = (NaClCPUFeaturesX86 *) natp->nap->cpu_features;
  if (NaClGetCPUFeatureX86(features, NaClCPUFeatureX86_SSE)) {
    g_nacl_syscall_thread_capture_fault_addr =
        (uintptr_t) &NaClSyscallThreadCaptureFaultSSE;
  } else {
    g_nacl_syscall_thread_capture_fault_addr =
        (uintptr_t) &NaClSyscallThreadCaptureFaultNoSSE;
  }

  natp->user.gs = natp->user.trusted_gs;

  return 0;
}
コード例 #6
0
static Bool ValidateInst(const NCDecoderInst *dinst) {
  NaClCPUFeaturesX86 *cpufeatures;
  int squashme = 0;
  NCValidatorState* vstate;
  if (dinst == NULL) return TRUE;
  vstate = NCVALIDATOR_STATE_DOWNCAST(dinst->dstate);

  OpcodeHisto(NCInstBytesByteInline(&dinst->inst_bytes,
                                    dinst->inst.prefixbytes),
              vstate);
  /* For testing only, this mode disables inter-instruction checks. */
  if (!NACL_FLAG_unsafe_single_inst32_mode) {
    RememberInstructionBoundary(dinst, vstate);
  }

  cpufeatures = &vstate->cpufeatures;

  if (!ValidatePrefixes(dinst)) {
    NCBadInstructionError(dinst, "Bad prefix usage");
    NCStatsBadPrefix(vstate);
  }

  if ((dinst->opinfo->insttype != NACLi_NOP) &&
      ((size_t) (dinst->inst.bytes.length - dinst->inst.prefixbytes)
       > kMaxValidInstLength)) {
    NCBadInstructionError(dinst, "Instruction too long");
    NCStatsBadInstLength(vstate);
  }

  switch (dinst->opinfo->insttype) {
    case NACLi_NOP:
    case NACLi_386:
    case NACLi_386L:
    case NACLi_386R:
    case NACLi_386RE:
      break;
    case NACLi_JMP8:
      ValidateJmp8(dinst);
      break;
    case NACLi_JMPZ:
      ValidateJmpz(dinst);
      break;
    case NACLi_INDIRECT:
      ValidateIndirect5(dinst);
      break;
    case NACLi_X87:
    case NACLi_X87_FSINCOS:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_x87);
      break;
    case NACLi_SFENCE_CLFLUSH:
      squashme = ValidateSFenceClFlush(dinst);
      break;
    case NACLi_CMPXCHG8B:
      /* Only allow if the modrm mod field accesses memory.
       * This stops us from accepting f00f on multiple bytes.
       * http://en.wikipedia.org/wiki/Pentium_F00F_bug
       */
      if (modrm_modInline(dinst->inst.mrm)
          == kModRmModFieldDefinesRegisterRef) {
        NCBadInstructionError(dinst, "Illegal instruction");
        NCStatsIllegalInst(vstate);
      }
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_CX8);
      break;
    case NACLi_CMOV:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_CMOV);
      break;
    case NACLi_FCMOV:
      squashme = !(NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_CMOV) &&
                   NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_x87));
      break;
    case NACLi_RDTSC:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_TSC);
      break;
    case NACLi_MMX:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_MMX);
      break;
    case NACLi_MMXSSE2:
      /* Note: We accept these instructions if either MMX or SSE2 bits */
      /* are set, in case MMX instructions go away someday...          */
      squashme = !(NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_MMX) ||
                   NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSE2));
      break;
    case NACLi_SSE:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSE);
      break;
    case NACLi_SSE2:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSE2);
      break;
    case NACLi_SSE3:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSE3);
      break;
    case NACLi_SSE4A:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSE4A);
      break;
    case NACLi_SSE41:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSE41);
      break;
    case NACLi_SSE42:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSE42);
      break;
    case NACLi_MOVBE:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_MOVBE);
      break;
    case NACLi_POPCNT:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_POPCNT);
      break;
    case NACLi_LZCNT:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_LZCNT);
      break;
    case NACLi_SSSE3:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSSE3);
      break;
    case NACLi_3DNOW:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_3DNOW);
      break;
    case NACLi_E3DNOW:
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_E3DNOW);
      break;
    case NACLi_SSE2x:
      /* This case requires CPUID checking code */
      /* Note: DATA16 prefix required. The generated table
       * for group 14 (which the only 2 SSE2x instructions are in),
       * allows instructions with and without a 66 prefix. However,
       * the SSE2x instructions psrldq and pslldq are only allowed
       * with the 66 prefix. Hence, this code has been added to
       * do this check.
       */
      if (!(dinst->inst.opcode_prefixmask & kPrefixDATA16)) {
        NCBadInstructionError(dinst, "Bad prefix usage");
        NCStatsBadPrefix(vstate);
      }
      squashme = !NaClGetCPUFeatureX86(cpufeatures, NaClCPUFeatureX86_SSE2);
      break;

    case NACLi_RETURN:
      NCBadInstructionError(dinst, "ret instruction (not allowed)");
      NCStatsReturn(vstate);
      /* ... and fall through to illegal instruction code */
    case NACLi_EMMX:
      /* EMMX needs to be supported someday but isn't ready yet. */
    case NACLi_INVALID:
    case NACLi_ILLEGAL:
    case NACLi_SYSTEM:
    case NACLi_RDMSR:
    case NACLi_RDTSCP:
    case NACLi_SYSCALL:
    case NACLi_SYSENTER:
    case NACLi_LONGMODE:
    case NACLi_SVM:
    case NACLi_OPINMRM:
    case NACLi_3BYTE:
    case NACLi_CMPXCHG16B: {
        NCBadInstructionError(dinst, "Illegal instruction");
        NCStatsIllegalInst(vstate);
        break;
      }
    case NACLi_UNDEFINED: {
        NCBadInstructionError(dinst, "Undefined instruction");
        NCStatsIllegalInst(vstate);
        NCStatsInternalError(vstate);
        break;
      }
    default:
      NCBadInstructionError(dinst, "Undefined instruction type");
      NCStatsInternalError(vstate);
      break;
  }
  if (squashme) {
    if (vstate->readonly_text) {
      NCBadInstructionError(dinst,
                            "Illegal instruction for fixed-feature CPU mode");
      NCStatsIllegalInst(vstate);
    } else {
      NCStubOutMem(vstate, dinst->dstate->memory.mpc,
                   dinst->dstate->memory.read_length);
    }
  }
  return TRUE;
}
コード例 #7
0
void NaClCpuCheck(struct NaClValidatorState* state,
                  struct NaClInstIter* iter) {
  Bool squash_me = FALSE;
  switch (state->cur_inst->insttype) {
    case NACLi_X87:
    case NACLi_X87_FSINCOS:
      NaClCheckFeature(NaClCPUFeatureX86_x87, state, &squash_me);
      break;
    case NACLi_SFENCE_CLFLUSH:
      /* TODO(bradchen): distinguish between SFENCE and CLFLUSH */
      NaClCheckFeature(NaClCPUFeatureX86_CLFLUSH, state, &squash_me);
      NaClCheckFeature(NaClCPUFeatureX86_FXSR, state, &squash_me);
      break;
    case NACLi_CMPXCHG8B:
      NaClCheckFeature(NaClCPUFeatureX86_CX8, state, &squash_me);
      break;
    case NACLi_CMPXCHG16B:
      NaClCheckFeature(NaClCPUFeatureX86_CX16, state, &squash_me);
      break;
    case NACLi_CMOV:
      NaClCheckFeature(NaClCPUFeatureX86_CMOV, state, &squash_me);
      break;
    case NACLi_FCMOV:
      if (!(NaClGetCPUFeatureX86(&state->cpu_features,
                                 NaClCPUFeatureX86_CMOV) &&
            NaClGetCPUFeatureX86(&state->cpu_features,
                                 NaClCPUFeatureX86_x87))) {
        if (!state->cpu_checks.f_CMOV_and_x87) {
          NaClValidatorInstMessage(
              LOG_WARNING, state, state->cur_inst_state,
              "CPU model does not support CMOV and x87 instructions.\n");
          state->cpu_checks.f_CMOV_and_x87 = TRUE;
        }
        squash_me = TRUE;
      }
      break;
    case NACLi_RDTSC:
      NaClCheckFeature(NaClCPUFeatureX86_TSC, state, &squash_me);
      break;
    case NACLi_MMX:
      NaClCheckFeature(NaClCPUFeatureX86_MMX, state, &squash_me);
      break;
    case NACLi_MMXSSE2:
      /* Note: We accept these instructions if either MMX or SSE2 bits */
      /* are set, in case MMX instructions go away someday...          */
      if (!(NaClGetCPUFeatureX86(&state->cpu_features,
                                 NaClCPUFeatureX86_MMX) ||
            NaClGetCPUFeatureX86(&state->cpu_features,
                                 NaClCPUFeatureX86_SSE2))) {
        if (!state->cpu_checks.f_MMX_or_SSE2) {
          NaClValidatorInstMessage(
              LOG_WARNING, state, state->cur_inst_state,
              "CPU model does not support MMX or SSE2 instructions.\n");
          state->cpu_checks.f_MMX_or_SSE2 = TRUE;
        }
      }
      squash_me = TRUE;
      break;
    case NACLi_SSE:
      NaClCheckFeature(NaClCPUFeatureX86_SSE, state, &squash_me);
      break;
    case NACLi_SSE2:
      NaClCheckFeature(NaClCPUFeatureX86_SSE2, state, &squash_me);
      break;
    case NACLi_SSE3:
      NaClCheckFeature(NaClCPUFeatureX86_SSE3, state, &squash_me);
      break;
    case NACLi_SSE4A:
      NaClCheckFeature(NaClCPUFeatureX86_SSE4A, state, &squash_me);
      break;
    case NACLi_SSE41:
      NaClCheckFeature(NaClCPUFeatureX86_SSE41, state, &squash_me);
      break;
    case NACLi_SSE42:
      NaClCheckFeature(NaClCPUFeatureX86_SSE42, state, &squash_me);
      break;
    case NACLi_MOVBE:
      NaClCheckFeature(NaClCPUFeatureX86_MOVBE, state, &squash_me);
      break;
    case NACLi_POPCNT:
      NaClCheckFeature(NaClCPUFeatureX86_POPCNT, state, &squash_me);
      break;
    case NACLi_LZCNT:
      NaClCheckFeature(NaClCPUFeatureX86_LZCNT, state, &squash_me);
      break;
    case NACLi_SSSE3:
      NaClCheckFeature(NaClCPUFeatureX86_SSSE3, state, &squash_me);
      break;
    case NACLi_3DNOW:
      NaClCheckFeature(NaClCPUFeatureX86_3DNOW, state, &squash_me);
      break;
    case NACLi_E3DNOW:
      NaClCheckFeature(NaClCPUFeatureX86_E3DNOW, state, &squash_me);
      break;
    case NACLi_LONGMODE:
      /* TODO(karl): Remove this when NACLi_LONGMODE is no longer needed */
      NaClCheckFeature(NaClCPUFeatureX86_LM, state, &squash_me);
      break;
    case NACLi_SSE2x:
      /* This case requires CPUID checking code */
      /* DATA16 prefix required */
      if (!(state->cur_inst_state->prefix_mask & kPrefixDATA16)) {
        NaClValidatorInstMessage(
            LOG_ERROR, state, state->cur_inst_state,
            "SSEx instruction must use prefix 0x66.\n");
      }
      NaClCheckFeature(NaClCPUFeatureX86_SSE2, state, &squash_me);
      break;
    default:
      /* This instruction could be either legal or illegal, but if we
       * get here it is not CPU-dependent.
       */
      break;
  }
  if (state->cur_inst->flags & NACL_IFLAG(LongMode)) {
    NaClCheckFeature(NaClCPUFeatureX86_LM, state, &squash_me);
  }
  if (squash_me) {
    if (state->readonly_text) {
      NaClValidatorInstMessage(
          LOG_ERROR, state, state->cur_inst_state,
          "Read-only text: cannot squash unsupported instruction.\n");
    } else {
      /* Replace all bytes of the instruction with the HLT instruction. */
      NCStubOutMem(state, NaClInstIterGetInstMemoryInline(iter),
                   NaClInstStateLength(state->cur_inst_state));
    }
  }
}