| Index: src/trusted/validator/x86/testing/enuminsts/xed_tester.c
|
| diff --git a/src/trusted/validator/x86/testing/enuminsts/xed_tester.c b/src/trusted/validator/x86/testing/enuminsts/xed_tester.c
|
| deleted file mode 100644
|
| index 560ada18c491fe612c2edf8276771c458696ef34..0000000000000000000000000000000000000000
|
| --- a/src/trusted/validator/x86/testing/enuminsts/xed_tester.c
|
| +++ /dev/null
|
| @@ -1,256 +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.
|
| - */
|
| -
|
| -/*
|
| - * xed_tester.c
|
| - * Implements a xed decoder that can be used as a NaClEnumeratorDecoder.
|
| - */
|
| -
|
| -#include "native_client/src/trusted/validator/x86/testing/enuminsts/enuminsts.h"
|
| -
|
| -#include <string.h>
|
| -#include "xed-interface.h"
|
| -#include "native_client/src/trusted/validator/types_memory_model.h"
|
| -#include "native_client/src/trusted/validator/x86/ncinstbuffer.h"
|
| -#include "native_client/src/trusted/validator/x86/testing/enuminsts/str_utils.h"
|
| -
|
| -#define kBufferSize 1024
|
| -
|
| -/* Defines the virtual table for the xed decoder. */
|
| -struct {
|
| - /* The virtual table that implements this decoder. */
|
| - NaClEnumeratorDecoder _base;
|
| - /* Defines the xed state to use to parse instructions. */
|
| - xed_state_t _xed_state;
|
| - /* Defines the pc_address to assume when disassembling. */
|
| - int _pc_address;
|
| - /* Defines the disassembled xed instruction. */
|
| - xed_decoded_inst_t _xedd;
|
| - /* Defines the lower-level model of the disassembled xed instruction. */
|
| - xed_inst_t const *_xed_inst;
|
| - /* Defines if there were errors parsing the instruction. */
|
| - xed_error_enum_t _xed_error;
|
| - /* Defines whether we have disassembled the xed instruction. */
|
| - Bool _has_xed_disasm;
|
| - /* If _has_xed_disam is true, the corresponding disassembly. */
|
| - char _xed_disasm[kBufferSize];
|
| - /* If non-empty, the corresponding instruction mnemonic. */
|
| - char _xed_opcode[kBufferSize];
|
| - /* Stores the corresponding operands of the instruction mnemonic. */
|
| - char _xed_operands[kBufferSize];
|
| -} xed_decoder;
|
| -
|
| -
|
| -
|
| -/* Initialize xed state before we try to decode anything. */
|
| -static void XedSetup(void) {
|
| - xed_tables_init();
|
| - xed_state_zero(&xed_decoder._xed_state);
|
| -
|
| - /* dstate.stack_addr_width = XED_ADDRESS_WIDTH_32b; */
|
| -#if (NACL_TARGET_SUBARCH == 32)
|
| - xed_decoder._xed_state.mmode = XED_MACHINE_MODE_LONG_COMPAT_32;
|
| -#endif
|
| -#if (NACL_TARGET_SUBARCH == 64)
|
| - xed_decoder._xed_state.mmode = XED_MACHINE_MODE_LONG_64;
|
| -#endif
|
| -}
|
| -
|
| -/* Defines the function to parse the first instruction. */
|
| -static void ParseInst(const NaClEnumerator* enumerator, const int pc_address) {
|
| - xed_decoder._has_xed_disasm = FALSE;
|
| - xed_decoder._pc_address = pc_address;
|
| - xed_decoder._xed_disasm[0] = 0;
|
| - xed_decoder._xed_opcode[0] = 0;
|
| - xed_decoder._xed_operands[0] = 0;
|
| - xed_decoder._xed_inst = NULL;
|
| - xed_decoded_inst_set_input_chip(&xed_decoder._xedd, XED_CHIP_CORE2);
|
| - xed_decoded_inst_zero_set_mode(&xed_decoder._xedd, &xed_decoder._xed_state);
|
| - xed_decoder._xed_error = xed_decode
|
| - (&xed_decoder._xedd, (const xed_uint8_t*)enumerator->_itext,
|
| - enumerator->_num_bytes);
|
| -}
|
| -
|
| -/* Returns true if the instruction parsed a legal instruction. */
|
| -static Bool IsInstLegal(const NaClEnumerator* enumerator) {
|
| - return (xed_decoder._xedd._decoded_length != 0) &&
|
| - (XED_ERROR_NONE == xed_decoder._xed_error);
|
| -}
|
| -
|
| -/* Returns the disassembled instruction. */
|
| -static const char* Disassemble(const NaClEnumerator* enumerator) {
|
| - if (!xed_decoder._has_xed_disasm) {
|
| - if (xed_decoder._xedd._decoded_length == 0) {
|
| - strcpy(xed_decoder._xed_disasm, "[illegal instruction]");
|
| - }
|
| - xed_format_intel(&xed_decoder._xedd, xed_decoder._xed_disasm,
|
| - kBufferSize, xed_decoder._pc_address);
|
| - xed_decoder._has_xed_disasm = TRUE;
|
| - }
|
| - return xed_decoder._xed_disasm;
|
| -}
|
| -
|
| -/* Returns the mnemonic name for the disassembled instruction. */
|
| -static const char* GetInstMnemonic(const NaClEnumerator* enumerator) {
|
| - char *allocated;
|
| - char *xtmp;
|
| - char *prev_xtmp;
|
| - int char0 = 0;
|
| -
|
| - /* First see if we have cached it. If so, return it. */
|
| - if (xed_decoder._xed_opcode[0] != 0) return xed_decoder._xed_opcode;
|
| -
|
| - /* If reached, we haven't cached it, so find the name from the
|
| - * disassembled instruction, and cache it.
|
| - */
|
| - xtmp = allocated = strdup(Disassemble(enumerator));
|
| -
|
| - /* Remove while prefixes found (i.e. ignore ordering) to get opcode. */
|
| - while (1) {
|
| - xtmp = SkipPrefix(xtmp, "lock");
|
| - xtmp = SkipPrefix(xtmp, "repne");
|
| - xtmp = SkipPrefix(xtmp, "rep");
|
| - xtmp = SkipPrefix(xtmp, "hint-not-taken");
|
| - xtmp = SkipPrefix(xtmp, "hint-taken");
|
| - xtmp = SkipPrefix(xtmp, "addr16");
|
| - xtmp = SkipPrefix(xtmp, "addr32");
|
| - xtmp = SkipPrefix(xtmp, "data16");
|
| - if (xtmp == prev_xtmp) break;
|
| - prev_xtmp = xtmp;
|
| - }
|
| - strncpyto(xed_decoder._xed_opcode, xtmp, kBufferSize - char0, ' ');
|
| -
|
| - /* Cache operand text to be processed before returning. */
|
| - xtmp += strlen(xed_decoder._xed_opcode);
|
| -
|
| - /* Remove uninteresting decorations.
|
| - * NOTE: these patterns need to be ordered from most to least specific
|
| - */
|
| - CleanString(xtmp, "byte ptr ");
|
| - CleanString(xtmp, "dword ptr ");
|
| - CleanString(xtmp, "qword ptr ");
|
| - CleanString(xtmp, "xmmword ptr ");
|
| - CleanString(xtmp, "word ptr ");
|
| - CleanString(xtmp, "ptr ");
|
| - CleanString(xtmp, "far ");
|
| -
|
| - cstrncpy(xed_decoder._xed_operands, strip(xtmp), kBufferSize);
|
| - free(allocated);
|
| - return xed_decoder._xed_opcode;
|
| -}
|
| -
|
| -static const char* GetInstOperandsText(const NaClEnumerator* enumerator) {
|
| - /* Force caching of operands and return. */
|
| - if (xed_decoder._xed_operands[0] == 0) GetInstMnemonic(enumerator);
|
| - return xed_decoder._xed_operands;
|
| -}
|
| -
|
| -/* Prints out the disassembled instruction. */
|
| -static void PrintInst(const NaClEnumerator* enumerator) {
|
| - int i;
|
| - size_t opcode_size;
|
| - NaClPcAddress pc_address = (NaClPcAddress) xed_decoder._pc_address;
|
| - printf(" XED: %"NACL_PRIxNaClPcAddressAll": ", pc_address);
|
| -
|
| - /* Since xed doesn't print out opcode sequence, and it is
|
| - * useful to know, add it to the print out. Note: Use same
|
| - * spacing scheme as nacl decoder, so things line up.
|
| - */
|
| - size_t num_bytes = MAX_INST_LENGTH;
|
| - if (enumerator->_num_bytes > num_bytes)
|
| - num_bytes = enumerator->_num_bytes;
|
| - for (i = 0; i < num_bytes; ++i) {
|
| - if (i < xed_decoder._xedd._decoded_length) {
|
| - printf("%02x ", enumerator->_itext[i]);
|
| - } else {
|
| - printf(" ");
|
| - }
|
| - }
|
| - printf("%s\n", Disassemble(enumerator));
|
| -}
|
| -
|
| -static size_t InstLength(const NaClEnumerator* enumerator) {
|
| - return (size_t) xed_decoder._xedd._decoded_length;
|
| -}
|
| -
|
| -static inline xed_inst_t const* GetXedInst(void) {
|
| - if (xed_decoder._xed_inst == NULL) {
|
| - xed_decoder._xed_inst = xed_decoded_inst_inst(&xed_decoder._xedd);
|
| - }
|
| - return xed_decoder._xed_inst;
|
| -}
|
| -
|
| -static size_t GetNumOperands(const NaClEnumerator* enumerator) {
|
| - return (size_t) xed_inst_noperands(GetXedInst());
|
| -}
|
| -
|
| -#if NACL_TARGET_SUBARCH == 64
|
| -static int IsReservedReg(const xed_reg_enum_t reg) {
|
| - switch (reg) {
|
| - case XED_REG_RSP:
|
| - case XED_REG_RBP:
|
| - case XED_REG_R15:
|
| - return 1;
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -
|
| -static int IsWriteAction(const xed_operand_action_enum_t rw) {
|
| - switch (rw) {
|
| - case XED_OPERAND_ACTION_RW:
|
| - case XED_OPERAND_ACTION_W:
|
| - case XED_OPERAND_ACTION_RCW:
|
| - case XED_OPERAND_ACTION_CW:
|
| - case XED_OPERAND_ACTION_CRW:
|
| - return 1;
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -static Bool WritesToReservedReg(const NaClEnumerator* enumerator,
|
| - const size_t n) {
|
| - xed_inst_t const* xi = GetXedInst();
|
| - xed_operand_t const* op = xed_inst_operand(xi, n);
|
| - xed_operand_enum_t op_name = xed_operand_name(op);
|
| - return xed_operand_is_register(op_name) &&
|
| - IsReservedReg(xed_decoded_inst_get_reg(&xed_decoder._xedd, op_name)) &&
|
| - IsWriteAction(xed_operand_rw(op));
|
| -}
|
| -#elif NACL_TARGET_SUBARCH == 32
|
| -static Bool WritesToReservedReg(const NaClEnumerator* enumerator,
|
| - const size_t n) {
|
| - return FALSE;
|
| -}
|
| -#else
|
| -#error("Bad NACL_TARGET_SUBARCH")
|
| -#endif
|
| -
|
| -static void InstallFlag(const NaClEnumerator* enumerator,
|
| - const char* flag_name,
|
| - const void* flag_address) {
|
| -}
|
| -
|
| -/* Defines the registry function that creates a xed decoder, and returns
|
| - * the decoder to be registered.
|
| - */
|
| -NaClEnumeratorDecoder* RegisterXedDecoder(void) {
|
| - XedSetup();
|
| - xed_decoder._base._id_name = "xed";
|
| - xed_decoder._base._parse_inst_fn = ParseInst;
|
| - xed_decoder._base._inst_length_fn = InstLength;
|
| - xed_decoder._base._print_inst_fn = PrintInst;
|
| - xed_decoder._base._get_inst_mnemonic_fn = GetInstMnemonic;
|
| - xed_decoder._base._get_inst_num_operands_fn = GetNumOperands;
|
| - xed_decoder._base._get_inst_operands_text_fn = GetInstOperandsText;
|
| - xed_decoder._base._writes_to_reserved_reg_fn = WritesToReservedReg;
|
| - xed_decoder._base._is_inst_legal_fn = IsInstLegal;
|
| - xed_decoder._base._maybe_inst_validates_fn = NULL;
|
| - xed_decoder._base._segment_validates_fn = NULL;
|
| - xed_decoder._base._install_flag_fn = InstallFlag;
|
| - xed_decoder._base._usage_message = "Runs xed to decode instructions.";
|
| - return &xed_decoder._base;
|
| -}
|
|
|