Index: src/trusted/validator_x86/nccopycode.c |
=================================================================== |
--- src/trusted/validator_x86/nccopycode.c (revision 3655) |
+++ src/trusted/validator_x86/nccopycode.c (working copy) |
@@ -23,9 +23,17 @@ |
#include <errno.h> |
#include <string.h> |
#include <assert.h> |
+#include "native_client/src/shared/platform/nacl_check.h" |
+#if NACL_TARGET_SUBARCH == 32 |
#include "native_client/src/trusted/validator_x86/ncdecode.h" |
#include "native_client/src/trusted/validator_x86/ncvalidate.h" |
-#include "native_client/src/shared/platform/nacl_check.h" |
+#elif NACL_TARGET_SUBARCH == 64 |
+#include "native_client/src/trusted/validator_x86/nc_inst_iter.h" |
+#include "native_client/src/trusted/validator_x86/nc_segment.h" |
+#include "native_client/src/trusted/validator_x86/nc_inst_state_internal.h" |
+#else |
+#error "Unknown Platform" |
+#endif |
/* x86 HALT opcode */ |
static const uint8_t kNaClFullStop = 0xf4; |
@@ -158,13 +166,11 @@ |
* Copy a single instruction, avoiding the possibility of other threads |
* executing a partially changed instruction. |
*/ |
-void CopyInstruction(const struct NCDecoderState *mstate_old, |
- const struct NCDecoderState *mstate_new) { |
- uint8_t* dst = mstate_old->inst.maddr; |
- uint8_t* src = mstate_new->inst.maddr; |
- int sz = mstate_old->inst.length; |
+void CopyInstructionInternal(uint8_t *dst, |
+ uint8_t *src, |
+ uint8_t sz) { |
intptr_t offset = 0; |
- CHECK(mstate_new->inst.length == mstate_old->inst.length); |
+ uint8_t *firstbyte_p = dst; |
while (sz > 0 && dst[0] == src[0]) { |
/* scroll to first changed byte */ |
@@ -196,13 +202,13 @@ |
onestore_memmove8(dst-offset, tmp); |
} else { |
/* the slow path, first flip first byte to halt*/ |
- uint8_t firstbyte = mstate_old->inst.maddr[0]; |
- mstate_old->inst.maddr[0] = kNaClFullStop; |
+ uint8_t firstbyte = firstbyte_p[0]; |
+ firstbyte_p[0] = kNaClFullStop; |
SerializeAllProcessors(); |
/* copy the rest of instruction */ |
- if (dst == mstate_old->inst.maddr) { |
+ if (dst == firstbyte_p) { |
/* but not the first byte! */ |
firstbyte = *src; |
dst++, src++, sz--; |
@@ -212,10 +218,25 @@ |
SerializeAllProcessors(); |
/* flip first byte back */ |
- mstate_old->inst.maddr[0] = firstbyte; |
+ firstbyte_p[0] = firstbyte; |
} |
} |
+#if NACL_TARGET_SUBARCH == 32 |
+ |
+/* |
+ * Copy a single instruction, avoiding the possibility of other threads |
+ * executing a partially changed instruction. |
+ */ |
+void CopyInstruction(const struct NCDecoderState *mstate_old, |
+ const struct NCDecoderState *mstate_new) { |
+ CHECK(mstate_new->inst.length == mstate_old->inst.length); |
+ |
+ CopyInstructionInternal(mstate_old->inst.maddr, |
+ mstate_new->inst.maddr, |
+ mstate_old->inst.length); |
+} |
+ |
int NCCopyCode(uint8_t *dst, uint8_t *src, NaClPcAddress vbase, |
size_t sz, int bundle_size) { |
struct NCValidatorState *vstate; |
@@ -226,3 +247,44 @@ |
return 0; |
} |
+#elif NACL_TARGET_SUBARCH == 64 |
+ |
+int NaClCopyCodeIter(uint8_t *dst, uint8_t *src, |
+ NaClPcAddress vbase, size_t size) { |
+ NaClSegment segment_old, segment_new; |
+ NaClInstIter *iter_old, *iter_new; |
+ NaClInstState *istate_old, *istate_new; |
+ |
+ NaClSegmentInitialize(dst, vbase, size, &segment_old); |
+ NaClSegmentInitialize(src, vbase, size, &segment_new); |
+ |
+ iter_old = NaClInstIterCreate(&segment_old); |
+ iter_new = NaClInstIterCreate(&segment_new); |
+ while (NaClInstIterHasNext(iter_old) && |
+ NaClInstIterHasNext(iter_new)) { |
+ istate_old = NaClInstIterGetState(iter_old); |
+ istate_new = NaClInstIterGetState(iter_new); |
+ if (istate_old->length != istate_new->length || |
+ istate_new->vpc != istate_old->vpc) { |
+ NaClLog(LOG_INFO, |
bsy
2010/11/11 21:27:21
if i understand what you said earlier, this should
petr
2010/11/12 18:11:06
This can occur if you run sel_ldr with -c. We shou
|
+ "Segment replacement: copied instructions misaligned\n"); |
+ return 1; |
+ } |
+ CopyInstructionInternal(istate_old->mpc, |
+ istate_new->mpc, |
+ istate_old->length); |
+ NaClInstIterAdvance(iter_old); |
+ NaClInstIterAdvance(iter_new); |
+ } |
+ |
+ CHECK(!NaClInstIterHasNext(iter_old) && !NaClInstIterHasNext(iter_new)); |
+ |
+ NaClInstIterDestroy(iter_old); |
+ NaClInstIterDestroy(iter_new); |
+ return 0; |
+} |
+ |
+#else |
+#error "Unknown Platform" |
+#endif |
+ |