| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* | 7 /* |
| 8 * ncdecode.c - table driven decoder for Native Client | 8 * ncdecode.c - table driven decoder for Native Client |
| 9 * | 9 * |
| 10 * Most x86 decoders I've looked at are big case statements. While | 10 * Most x86 decoders I've looked at are big case statements. While |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 */ | 468 */ |
| 469 static void NCDecoderStateInitFields(NCDecoderState* this) { | 469 static void NCDecoderStateInitFields(NCDecoderState* this) { |
| 470 size_t dbindex; | 470 size_t dbindex; |
| 471 this->error_reporter = &kNCNullErrorReporter; | 471 this->error_reporter = &kNCNullErrorReporter; |
| 472 NCRemainingMemoryInit(this->mbase, this->size, &this->memory); | 472 NCRemainingMemoryInit(this->mbase, this->size, &this->memory); |
| 473 this->memory.error_fn = NCRemainingMemoryInternalError; | 473 this->memory.error_fn = NCRemainingMemoryInternalError; |
| 474 this->memory.error_fn_state = (void*) this; | 474 this->memory.error_fn_state = (void*) this; |
| 475 for (dbindex = 0; dbindex < this->inst_buffer_size; ++dbindex) { | 475 for (dbindex = 0; dbindex < this->inst_buffer_size; ++dbindex) { |
| 476 this->inst_buffer[dbindex].dstate = this; | 476 this->inst_buffer[dbindex].dstate = this; |
| 477 this->inst_buffer[dbindex].inst_index = dbindex; | 477 this->inst_buffer[dbindex].inst_index = dbindex; |
| 478 this->inst_buffer[dbindex].inst_count = 0; | 478 this->inst_buffer[dbindex].inst_count = 1; |
| 479 this->inst_buffer[dbindex].vpc = 0; | 479 this->inst_buffer[dbindex].vpc = 0; |
| 480 this->inst_buffer[dbindex].unchanged = FALSE; |
| 480 NCInstBytesInitMemory(&this->inst_buffer[dbindex].inst.bytes, | 481 NCInstBytesInitMemory(&this->inst_buffer[dbindex].inst.bytes, |
| 481 &this->memory); | 482 &this->memory); |
| 482 NCInstBytesPtrInit((NCInstBytesPtr*) &this->inst_buffer[dbindex].inst_bytes, | 483 NCInstBytesPtrInit((NCInstBytesPtr*) &this->inst_buffer[dbindex].inst_bytes, |
| 483 &this->inst_buffer[dbindex].inst.bytes); | 484 &this->inst_buffer[dbindex].inst.bytes); |
| 484 } | 485 } |
| 485 this->cur_inst_index = 0; | 486 this->cur_inst_index = 0; |
| 486 this->inst_buffer[0].vpc = this->vbase; | 487 this->inst_buffer[0].vpc = this->vbase; |
| 487 } | 488 } |
| 488 | 489 |
| 489 void NCDecoderStateConstruct(NCDecoderState* this, | 490 void NCDecoderStateConstruct(NCDecoderState* this, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 516 * in the ring buffer. Reset the state of that next instruction. | 517 * in the ring buffer. Reset the state of that next instruction. |
| 517 */ | 518 */ |
| 518 static NCDecoderInst* IncrementInst(NCDecoderInst* inst) { | 519 static NCDecoderInst* IncrementInst(NCDecoderInst* inst) { |
| 519 /* giving PreviousInst a positive number will get NextInst | 520 /* giving PreviousInst a positive number will get NextInst |
| 520 * better to keep the buffer switching logic in one place | 521 * better to keep the buffer switching logic in one place |
| 521 */ | 522 */ |
| 522 NCDecoderInst* next_inst = NCGetInstDiff(inst, 1); | 523 NCDecoderInst* next_inst = NCGetInstDiff(inst, 1); |
| 523 next_inst->vpc = inst->vpc + inst->inst.bytes.length; | 524 next_inst->vpc = inst->vpc + inst->inst.bytes.length; |
| 524 next_inst->dstate->cur_inst_index = next_inst->inst_index; | 525 next_inst->dstate->cur_inst_index = next_inst->inst_index; |
| 525 next_inst->inst_count = inst->inst_count + 1; | 526 next_inst->inst_count = inst->inst_count + 1; |
| 527 next_inst->unchanged = FALSE; |
| 526 return next_inst; | 528 return next_inst; |
| 527 } | 529 } |
| 528 | 530 |
| 529 /* Get the i-th byte of the current instruction being parsed. */ | 531 /* Get the i-th byte of the current instruction being parsed. */ |
| 530 static uint8_t GetInstByte(NCDecoderInst* dinst, ssize_t i) { | 532 static uint8_t GetInstByte(NCDecoderInst* dinst, ssize_t i) { |
| 531 if (i < dinst->inst.bytes.length) { | 533 if (i < dinst->inst.bytes.length) { |
| 532 return dinst->inst.bytes.byte[i]; | 534 return dinst->inst.bytes.byte[i]; |
| 533 } else { | 535 } else { |
| 534 return NCRemainingMemoryLookaheadInline(&dinst->dstate->memory, | 536 return NCRemainingMemoryLookaheadInline(&dinst->dstate->memory, |
| 535 i - dinst->inst.bytes.length); | 537 i - dinst->inst.bytes.length); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 (NaClPrintInst) NCNullErrorPrintInst, | 632 (NaClPrintInst) NCNullErrorPrintInst, |
| 631 }; | 633 }; |
| 632 | 634 |
| 633 Bool NCDecoderStateDecode(NCDecoderState* this) { | 635 Bool NCDecoderStateDecode(NCDecoderState* this) { |
| 634 NCDecoderInst* dinst = &this->inst_buffer[this->cur_inst_index]; | 636 NCDecoderInst* dinst = &this->inst_buffer[this->cur_inst_index]; |
| 635 const NaClPcAddress vlimit = this->vbase + this->size; | 637 const NaClPcAddress vlimit = this->vbase + this->size; |
| 636 DEBUG( printf("DecodeSegment(%p[%"NACL_PRIxNaClPcAddress | 638 DEBUG( printf("DecodeSegment(%p[%"NACL_PRIxNaClPcAddress |
| 637 "-%"NACL_PRIxNaClPcAddress"])\n", | 639 "-%"NACL_PRIxNaClPcAddress"])\n", |
| 638 (void*) this->memory.mpc, this->vbase, vlimit) ); | 640 (void*) this->memory.mpc, this->vbase, vlimit) ); |
| 639 NCDecoderStateNewSegment(this); | 641 NCDecoderStateNewSegment(this); |
| 640 dinst->inst_count = 1; | |
| 641 while (dinst->vpc < vlimit) { | 642 while (dinst->vpc < vlimit) { |
| 642 ConsumeNextInstruction(dinst); | 643 ConsumeNextInstruction(dinst); |
| 643 if (this->memory.overflow_count) { | 644 if (this->memory.overflow_count) { |
| 644 NaClPcAddress newpc = dinst->vpc + dinst->inst.bytes.length; | 645 NaClPcAddress newpc = dinst->vpc + dinst->inst.bytes.length; |
| 645 (*this->error_reporter->printf)( | 646 (*this->error_reporter->printf)( |
| 646 this->error_reporter, | 647 this->error_reporter, |
| 647 "%"NACL_PRIxNaClPcAddress" > %"NACL_PRIxNaClPcAddress | 648 "%"NACL_PRIxNaClPcAddress" > %"NACL_PRIxNaClPcAddress |
| 648 " (read overflow of %d bytes)\n", | 649 " (read overflow of %d bytes)\n", |
| 649 newpc, vlimit, this->memory.overflow_count); | 650 newpc, vlimit, this->memory.overflow_count); |
| 650 ErrorSegmentation(dinst); | 651 ErrorSegmentation(dinst); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 if (! (tthis->action_fn)(tthis, old_dinst, new_dinst)) { | 750 if (! (tthis->action_fn)(tthis, old_dinst, new_dinst)) { |
| 750 return FALSE; | 751 return FALSE; |
| 751 } | 752 } |
| 752 | 753 |
| 753 /* Move to next instruction. */ | 754 /* Move to next instruction. */ |
| 754 old_dinst = IncrementInst(old_dinst); | 755 old_dinst = IncrementInst(old_dinst); |
| 755 new_dinst = IncrementInst(new_dinst); | 756 new_dinst = IncrementInst(new_dinst); |
| 756 } | 757 } |
| 757 return TRUE; | 758 return TRUE; |
| 758 } | 759 } |
| OLD | NEW |