Index: src/trusted/validator/x86/64/ncvalidate.c |
diff --git a/src/trusted/validator/x86/64/ncvalidate.c b/src/trusted/validator/x86/64/ncvalidate.c |
deleted file mode 100644 |
index 9811f7b5bda5c34bc18d2a81121a1ba75b1d9506..0000000000000000000000000000000000000000 |
--- a/src/trusted/validator/x86/64/ncvalidate.c |
+++ /dev/null |
@@ -1,244 +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. |
- */ |
- |
-/* Implement the ApplyValidator API for the x86-64 architecture. */ |
-#include <assert.h> |
-#include "native_client/src/shared/platform/nacl_log.h" |
-#include "native_client/src/trusted/validator/ncvalidate.h" |
-#include "native_client/src/trusted/validator/validation_cache.h" |
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h" |
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal.h" |
-#include "native_client/src/trusted/cpu_features/arch/x86/cpu_x86.h" |
-#include "native_client/src/trusted/validator/x86/nc_segment.h" |
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncval_decode_tables.h" |
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.h" |
- |
-/* Be sure the correct compile flags are defined for this. */ |
-#if NACL_ARCH(NACL_TARGET_ARCH) != NACL_x86 |
-# error("Can't compile, target is for x86-64") |
-#else |
-# if NACL_TARGET_SUBARCH != 64 |
-# error("Can't compile, target is for x86-64") |
-# endif |
-#endif |
- |
-NaClValidationStatus NaClValidatorSetup_x86_64( |
- intptr_t guest_addr, |
- size_t size, |
- int readonly_text, |
- const NaClCPUFeaturesX86 *cpu_features, |
- struct NaClValidatorState** vstate_ptr) { |
- *vstate_ptr = NaClValidatorStateCreate(guest_addr, size, RegR15, |
- readonly_text, cpu_features); |
- return (*vstate_ptr == NULL) |
- ? NaClValidationFailedOutOfMemory |
- : NaClValidationSucceeded; /* or at least to this point! */ |
-} |
- |
-static NaClValidationStatus ApplyValidator_x86_64( |
- uintptr_t guest_addr, |
- uint8_t *data, |
- size_t size, |
- int stubout_mode, |
- int readonly_text, |
- const NaClCPUFeatures *f, |
- const struct NaClValidationMetadata *metadata, |
- struct NaClValidationCache *cache) { |
- /* TODO(jfb) Use a safe cast here. */ |
- const NaClCPUFeaturesX86 *cpu_features = (NaClCPUFeaturesX86 *) f; |
- struct NaClValidatorState *vstate; |
- NaClValidationStatus status; |
- void *query = NULL; |
- |
- /* Check that the given parameter values are supported. */ |
- if (stubout_mode && readonly_text) |
- return NaClValidationFailedNotImplemented; |
- |
- if (!NaClArchSupportedX86(cpu_features)) |
- return NaClValidationFailedCpuNotSupported; |
- |
- /* Don't cache in stubout mode. */ |
- if (stubout_mode) |
- cache = NULL; |
- |
- /* If the validation caching interface is available, perform a query. */ |
- if (cache != NULL) |
- query = cache->CreateQuery(cache->handle); |
- if (query != NULL) { |
- const char validator_id[] = "x86-64"; |
- cache->AddData(query, (uint8_t *) validator_id, sizeof(validator_id)); |
- cache->AddData(query, (uint8_t *) cpu_features, sizeof(*cpu_features)); |
- NaClAddCodeIdentity(data, size, metadata, cache, query); |
- if (cache->QueryKnownToValidate(query)) { |
- cache->DestroyQuery(query); |
- return NaClValidationSucceeded; |
- } |
- } |
- |
- /* Init then validator state. */ |
- status = NaClValidatorSetup_x86_64( |
- guest_addr, size, readonly_text, cpu_features, &vstate); |
- if (status != NaClValidationSucceeded) { |
- if (query != NULL) |
- cache->DestroyQuery(query); |
- return status; |
- } |
- NaClValidatorStateSetLogVerbosity(vstate, LOG_ERROR); |
- NaClValidatorStateSetDoStubOut(vstate, stubout_mode); |
- |
- /* Validate. */ |
- NaClValidateSegment(data, guest_addr, size, vstate); |
- status = (NaClValidatesOk(vstate) || stubout_mode) ? |
- NaClValidationSucceeded : NaClValidationFailed; |
- |
- /* Cache the result if validation succeded and the code was not modified. */ |
- if (query != NULL) { |
- /* Don't cache the result if the code is modified. */ |
- if (status == NaClValidationSucceeded && !NaClValidatorDidStubOut(vstate)) |
- cache->SetKnownToValidate(query); |
- cache->DestroyQuery(query); |
- } |
- |
- NaClValidatorStateDestroy(vstate); |
- return status; |
-} |
- |
-static NaClValidationStatus ApplyValidatorCodeReplacement_x86_64( |
- uintptr_t guest_addr, |
- uint8_t *data_old, |
- uint8_t *data_new, |
- size_t size, |
- const NaClCPUFeatures *f) { |
- /* TODO(jfb) Use a safe cast here. */ |
- const NaClCPUFeaturesX86 *cpu_features = (NaClCPUFeaturesX86 *) f; |
- NaClValidationStatus status; |
- struct NaClValidatorState *vstate; |
- |
- /* Check that the given parameter values are supported. */ |
- if (!NaClArchSupportedX86(cpu_features)) |
- return NaClValidationFailedCpuNotSupported; |
- |
- /* Init then validator state. */ |
- status = NaClValidatorSetup_x86_64(guest_addr, size, FALSE, |
- cpu_features, &vstate); |
- if (status != NaClValidationSucceeded) |
- return status; |
- NaClValidatorStateSetLogVerbosity(vstate, LOG_ERROR); |
- |
- /* Validate. */ |
- NaClValidateSegmentPair(data_old, data_new, guest_addr, size, vstate); |
- status = NaClValidatesOk(vstate) ? |
- NaClValidationSucceeded : NaClValidationFailed; |
- |
- NaClValidatorStateDestroy(vstate); |
- return status; |
-} |
- |
-/* Copies code from src to dest in a thread safe way, returns 1 on success, |
- * returns 0 on error. This will likely assert on error to avoid partially |
- * copied code or undefined state. |
- */ |
-static int CopyCodeIter(uint8_t *dst, uint8_t *src, |
- NaClPcAddress vbase, size_t size, |
- NaClCopyInstructionFunc copy_func) { |
- NaClSegment segment_old; |
- NaClSegment segment_new; |
- NaClInstIter *iter_old; |
- NaClInstIter *iter_new; |
- NaClInstState *istate_old; |
- NaClInstState *istate_new; |
- int still_good = 1; |
- |
- NaClSegmentInitialize(dst, vbase, size, &segment_old); |
- NaClSegmentInitialize(src, vbase, size, &segment_new); |
- |
- iter_old = NaClInstIterCreate(kNaClValDecoderTables, &segment_old); |
- if (NULL == iter_old) return 0; |
- iter_new = NaClInstIterCreate(kNaClValDecoderTables, &segment_new); |
- if (NULL == iter_new) { |
- NaClInstIterDestroy(iter_old); |
- return 0; |
- } |
- while (1) { |
- /* March over every instruction, which means NaCl pseudo-instructions are |
- * treated as multiple instructions. Checks in NaClValidateCodeReplacement |
- * guarantee that only valid replacements will happen, and no pseudo- |
- * instructions should be touched. |
- */ |
- if (!(NaClInstIterHasNext(iter_old) && NaClInstIterHasNext(iter_new))) { |
- if (NaClInstIterHasNext(iter_old) || NaClInstIterHasNext(iter_new)) { |
- NaClLog(LOG_ERROR, |
- "Segment replacement: copy failed: iterators " |
- "length mismatch\n"); |
- still_good = 0; |
- } |
- break; |
- } |
- istate_old = NaClInstIterGetState(iter_old); |
- istate_new = NaClInstIterGetState(iter_new); |
- if (istate_old->bytes.length != istate_new->bytes.length || |
- iter_old->memory.read_length != iter_new->memory.read_length || |
- istate_new->inst_addr != istate_old->inst_addr) { |
- /* Sanity check: this should never happen based on checks in |
- * NaClValidateInstReplacement. |
- */ |
- NaClLog(LOG_ERROR, |
- "Segment replacement: copied instructions misaligned\n"); |
- still_good = 0; |
- break; |
- } |
- /* Replacing all modified instructions at once could yield a speedup here |
- * as every time we modify instructions we must serialize all processors |
- * twice. Re-evaluate if code modification performance is an issue. |
- */ |
- if (!copy_func(iter_old->memory.mpc, iter_new->memory.mpc, |
- iter_old->memory.read_length)) { |
- NaClLog(LOG_ERROR, |
- "Segment replacement: copy failed: unable to copy instruction\n"); |
- still_good = 0; |
- break; |
- } |
- NaClInstIterAdvance(iter_old); |
- NaClInstIterAdvance(iter_new); |
- } |
- |
- NaClInstIterDestroy(iter_old); |
- NaClInstIterDestroy(iter_new); |
- return still_good; |
-} |
- |
-static NaClValidationStatus ApplyValidatorCopy_x86_64( |
- uintptr_t guest_addr, |
- uint8_t *data_old, |
- uint8_t *data_new, |
- size_t size, |
- const NaClCPUFeatures *f, |
- NaClCopyInstructionFunc copy_func) { |
- /* TODO(jfb) Use a safe cast here. */ |
- const NaClCPUFeaturesX86 *cpu_features = (NaClCPUFeaturesX86 *) f; |
- if (!NaClArchSupportedX86(cpu_features)) |
- return NaClValidationFailedCpuNotSupported; |
- |
- return (0 == CopyCodeIter(data_old, data_new, guest_addr, size, copy_func)) |
- ? NaClValidationFailed : NaClValidationSucceeded; |
-} |
- |
-static const struct NaClValidatorInterface validator = { |
- TRUE, /* Optional stubout_mode is implemented. */ |
- TRUE, /* Optional readonly_text is implemented. */ |
- TRUE, /* Optional code replacement functions are implemented. */ |
- ApplyValidator_x86_64, |
- ApplyValidatorCopy_x86_64, |
- ApplyValidatorCodeReplacement_x86_64, |
- sizeof(NaClCPUFeaturesX86), |
- NaClSetAllCPUFeaturesX86, |
- NaClGetCurrentCPUFeaturesX86, |
- NaClFixCPUFeaturesX86, |
-}; |
- |
-const struct NaClValidatorInterface *NaClValidatorCreate_x86_64(void) { |
- return &validator; |
-} |