| Index: src/trusted/validator/x86/ncval_seg_sfi/ncdecode_verbose.c
 | 
| diff --git a/src/trusted/validator/x86/ncval_seg_sfi/ncdecode_verbose.c b/src/trusted/validator/x86/ncval_seg_sfi/ncdecode_verbose.c
 | 
| deleted file mode 100644
 | 
| index 0aa8c1b51dd138a2480943dcce9d50390b985a36..0000000000000000000000000000000000000000
 | 
| --- a/src/trusted/validator/x86/ncval_seg_sfi/ncdecode_verbose.c
 | 
| +++ /dev/null
 | 
| @@ -1,618 +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.
 | 
| - */
 | 
| -
 | 
| -/*
 | 
| - * ncdecode_verbose.c - Print routines for validator that are
 | 
| - * not to be loaded into sel_ldr.
 | 
| - */
 | 
| -
 | 
| -#include "native_client/src/trusted/validator/x86/ncval_seg_sfi/ncdecode_verbose.h"
 | 
| -
 | 
| -#include <stdio.h>
 | 
| -#include <stdlib.h>
 | 
| -#include <string.h>
 | 
| -
 | 
| -#include "native_client/src/shared/gio/gio.h"
 | 
| -#include "native_client/src/shared/platform/nacl_log.h"
 | 
| -#include "native_client/src/trusted/validator/x86/ncval_seg_sfi/ncdecode.h"
 | 
| -
 | 
| -#include "native_client/src/trusted/validator/x86/x86_insts_inl.c"
 | 
| -
 | 
| -#if NACL_TARGET_SUBARCH == 64
 | 
| -#include "native_client/src/trusted/validator/x86/ncval_seg_sfi/gen/ncdisasmtab_64.h"
 | 
| -#else
 | 
| -#include "native_client/src/trusted/validator/x86/ncval_seg_sfi/gen/ncdisasmtab_32.h"
 | 
| -#endif
 | 
| -
 | 
| -/* To turn on debugging of instruction decoding, change value of
 | 
| - * DEBUGGING to 1.
 | 
| - */
 | 
| -#define DEBUGGING 0
 | 
| -
 | 
| -#include "native_client/src/shared/utils/debugging.h"
 | 
| -
 | 
| -/* The following are conditionally added since they only have meaning
 | 
| - * if we are processing 64-bit instructions.
 | 
| - */
 | 
| -#if NACL_TARGET_SUBARCH == 64
 | 
| -
 | 
| -/* Returns true if REX.W is defined in the REX prefix byte. */
 | 
| -static INLINE uint8_t GetRexPrefixW(const NCDecoderInst* dinst) {
 | 
| -  /* Note: the field rexprefix is non-zero only if a rexprefix was found. */
 | 
| -  return 0 != NaClRexW(dinst->inst.rexprefix);
 | 
| -}
 | 
| -
 | 
| -/* Returns true if REX.R is defined in the REX prefix byte. */
 | 
| -static INLINE uint8_t GetRexPrefixR(const NCDecoderInst* dinst) {
 | 
| -  /* Note: the field rexprefix is non-zero only if a rexprefix was found. */
 | 
| -  return 0 != NaClRexR(dinst->inst.rexprefix);
 | 
| -}
 | 
| -
 | 
| -#endif
 | 
| -
 | 
| -/* Returns the index into the general purpose registers based on the
 | 
| - * value in the modrm.rm field of the instruction (taking into account
 | 
| - * the REX prefix if it appears).
 | 
| - */
 | 
| -static INLINE uint32_t state_modrm_reg(const NCDecoderInst* dinst) {
 | 
| -  /* TODO(karl) This is no where near close to being correct. Currently,
 | 
| -   * It only models r/m64 entry for instructions in the Intel documentation,
 | 
| -   * which requires the W bit to be set (r/m32 entries do not use REX.w,
 | 
| -   * and a different set of registers).
 | 
| -   */
 | 
| -  uint32_t index = modrm_regInline(dinst->inst.mrm);
 | 
| -#if NACL_TARGET_SUBARCH == 64
 | 
| -  if (GetRexPrefixW(dinst) && GetRexPrefixR(dinst)) {
 | 
| -    index += 8;
 | 
| -  }
 | 
| -#endif
 | 
| -  return index;
 | 
| -}
 | 
| -
 | 
| -/* Returns the index for the first instruction opcode byte. */
 | 
| -static INLINE int NCOpcodeOffset(const NCDecoderInst* dinst) {
 | 
| -  return dinst->inst.prefixbytes;
 | 
| -}
 | 
| -
 | 
| -/* Returns the index for the modrm byte. */
 | 
| -static INLINE int NCMrmOffset(const NCDecoderInst* dinst) {
 | 
| -  return NCOpcodeOffset(dinst) + dinst->inst.num_opbytes;
 | 
| -}
 | 
| -
 | 
| -/* Returns the index of the sib byte (if it has one). */
 | 
| -static INLINE int NCSibOffset(const NCDecoderInst* dinst) {
 | 
| -  /* Note: The sib byte follows the mrm byte. */
 | 
| -  return NCMrmOffset(dinst) + 1;
 | 
| -}
 | 
| -
 | 
| -/* Returns the beginning index for the displacement (if it has one). */
 | 
| -static int NCDispOffset(const NCDecoderInst* dinst) {
 | 
| -  if (dinst->opinfo->hasmrmbyte) {
 | 
| -    if (dinst->inst.hassibbyte) {
 | 
| -      return NCSibOffset(dinst) + 1;
 | 
| -    } else {
 | 
| -      return NCMrmOffset(dinst) + 1;
 | 
| -    }
 | 
| -  } else {
 | 
| -    return NCOpcodeOffset(dinst) + dinst->inst.num_opbytes;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -/* Returns the beginning index for the immediate value. */
 | 
| -static INLINE int NCImmedOffset(const NCDecoderInst* dinst) {
 | 
| -  return NCDispOffset(dinst) + dinst->inst.dispbytes;
 | 
| -}
 | 
| -
 | 
| -/* later this will make decoding x87 instructions a bit more concise. */
 | 
| -static const char** kDisasmX87Op[8] = {kDisasm87D8,
 | 
| -                                       kDisasm87D9,
 | 
| -                                       kDisasm87DA,
 | 
| -                                       kDisasm87DB,
 | 
| -                                       kDisasm87DC,
 | 
| -                                       kDisasm87DD,
 | 
| -                                       kDisasm87DE,
 | 
| -                                       kDisasm87DF};
 | 
| -
 | 
| -const char** kDummyUsesToAvoidCompilerWarning[] = {kDisasm660F38Op,
 | 
| -                                                   kDisasmF20F38Op,
 | 
| -                                                   kDisasm660F3AOp};
 | 
| -
 | 
| -/* disassembler stuff */
 | 
| -static const char* DisFmt(const NCDecoderInst *dinst) {
 | 
| -  NCInstBytesPtr opbyte;
 | 
| -  uint8_t opbyte0;
 | 
| -  uint8_t opbyte1;
 | 
| -  uint8_t pm = dinst->inst.opcode_prefixmask;
 | 
| -  NCInstBytesPtrInitInc(&opbyte, &dinst->inst_bytes, NCOpcodeOffset(dinst));
 | 
| -  opbyte0 = NCInstBytesByte(&opbyte, 0);
 | 
| -
 | 
| -  if (dinst->opinfo->insttype == NACLi_X87 ||
 | 
| -      dinst->opinfo->insttype == NACLi_X87_FSINCOS) {
 | 
| -    if (opbyte0 != kWAITOp) {
 | 
| -      return kDisasmX87Op[opbyte0 - kFirstX87Opcode][dinst->inst.mrm];
 | 
| -    }
 | 
| -  }
 | 
| -  if (dinst->opinfo->insttype == NACLi_FCMOV) {
 | 
| -    return kDisasmX87Op[opbyte0 - kFirstX87Opcode][dinst->inst.mrm];
 | 
| -  }
 | 
| -  if (dinst->opinfo->insttype == NACLi_NOP) return "nop";
 | 
| -  if (opbyte0 != kTwoByteOpcodeByte1) return kDisasm1ByteOp[opbyte0];
 | 
| -  opbyte1 = NCInstBytesByte(&opbyte, 1);
 | 
| -  if (opbyte1 == 0x0f) {
 | 
| -    return kDisasm0F0FOp[
 | 
| -        NCInstBytesByte(&opbyte, dinst->inst.bytes.length - 1)];
 | 
| -  }
 | 
| -  if (opbyte1 == 0x38) {
 | 
| -    return kDisasm0F38Op[NCInstBytesByte(&opbyte, 2)];
 | 
| -  }
 | 
| -  if (opbyte1 == 0x3A) {
 | 
| -    return kDisasm0F3AOp[NCInstBytesByte(&opbyte, 2)];
 | 
| -  }
 | 
| -  if (! (pm & (kPrefixDATA16 | kPrefixREPNE | kPrefixREP))) {
 | 
| -    return kDisasm0FXXOp[opbyte1];
 | 
| -  }
 | 
| -  if (pm & kPrefixDATA16) return kDisasm660FXXOp[opbyte1];
 | 
| -  if (pm & kPrefixREPNE)  return kDisasmF20FXXOp[opbyte1];
 | 
| -  if (pm & kPrefixREP)    return kDisasmF30FXXOp[opbyte1];
 | 
| -
 | 
| -  /* no update; should be invalid */
 | 
| -  return "internal error";
 | 
| -}
 | 
| -
 | 
| -/* Returns the (sign extended) 32-bit integer immediate value. */
 | 
| -static int32_t ImmedValue32(const NCDecoderInst* dinst) {
 | 
| -  NCInstBytesPtr addr;
 | 
| -  NCInstBytesPtrInitInc(&addr, &dinst->inst_bytes,
 | 
| -                        NCImmedOffset(dinst));
 | 
| -  return NCInstBytesInt32(&addr, dinst->inst.immbytes);
 | 
| -}
 | 
| -
 | 
| -/* Returns the (sign extended) 64-bit integer immediate value. */
 | 
| -static int64_t ImmedValue64(const NCDecoderInst* dinst) {
 | 
| -  NCInstBytesPtr addr;
 | 
| -  NCInstBytesPtrInitInc(&addr, &dinst->inst_bytes,
 | 
| -                        NCImmedOffset(dinst));
 | 
| -  return NCInstBytesInt64(&addr, dinst->inst.immbytes);
 | 
| -}
 | 
| -
 | 
| -/* Returns the (sign extended) 32-bit integer displacement value. */
 | 
| -static int32_t DispValue32(const NCDecoderInst* dinst) {
 | 
| -  NCInstBytesPtr addr;
 | 
| -  NCInstBytesPtrInitInc(&addr, &dinst->inst_bytes,
 | 
| -                        NCDispOffset(dinst));
 | 
| -  return NCInstBytesInt32(&addr, dinst->inst.dispbytes);
 | 
| -}
 | 
| -
 | 
| -/* Defines the set of available general purpose registers. */
 | 
| -static const char* gp_regs[] = {
 | 
| -#if NACL_TARGET_SUBARCH == 64
 | 
| -  /* TODO(karl) - Depending on whether the instruction uses r/m32
 | 
| -   * of r/m64 forms (according to the Intel document), the list of
 | 
| -   * (16) registers is different. Currently, we are only handling
 | 
| -   * the r/m64 case.
 | 
| -   */
 | 
| -  "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
 | 
| -  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
 | 
| -#else
 | 
| -  "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
 | 
| -#endif
 | 
| -};
 | 
| -
 | 
| -
 | 
| -static const char* mmx_regs[] = {
 | 
| -  "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
 | 
| -};
 | 
| -
 | 
| -static const char* xmm_regs[] = {
 | 
| -  "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7"
 | 
| -};
 | 
| -
 | 
| -static const char* seg_regs[] = {
 | 
| -  "%es", "%cs", "%ss", "%ds", "%fs", "%gs"
 | 
| -};
 | 
| -
 | 
| -/* Print out the sib byte of the parsed instruction in the given decoder state
 | 
| - * to the given file.
 | 
| - */
 | 
| -static void SibPrint(const NCDecoderInst* dinst, struct Gio* fp) {
 | 
| -  uint8_t sib = NCInstBytesByte(&dinst->inst_bytes, NCSibOffset(dinst));
 | 
| -
 | 
| -  if (!dinst->inst.hassibbyte) {
 | 
| -    /* This should not happen. */
 | 
| -    gprintf(fp, "?");
 | 
| -  } else if (sib_ss(sib) == 0) {
 | 
| -    if (sib_base(sib) == 5) {
 | 
| -      /* This code is JUST WRONG!. However, I am not fixing since
 | 
| -       * the decoder printer is broken in so many other ways!. See tables
 | 
| -       * 2-1 and 2-2 of "Intel 64 and IA-32 Architectures Software Developer's
 | 
| -       * Manual" for details of what should be done (there are
 | 
| -       * 3 cases, depending on the value of the mod field of the modrm
 | 
| -       * byte).
 | 
| -       * Note: While the changes here are not correct, they at least make
 | 
| -       * sure that we process bytes that are actually in the instruction.
 | 
| -       * That is, the code doesn't accidentally walk off the end of the
 | 
| -       * parsed instruction.
 | 
| -       */
 | 
| -      gprintf(fp, "[0x%x]", DispValue32(dinst));
 | 
| -    } else {
 | 
| -      /* Has a base register */
 | 
| -      if (sib_index(sib) == 4) {
 | 
| -        /* No index */
 | 
| -        gprintf(fp, "[%s]", gp_regs[sib_base(sib)]);
 | 
| -      } else {
 | 
| -        gprintf(fp, "[%s + %s]",
 | 
| -                gp_regs[sib_base(sib)],
 | 
| -                gp_regs[sib_index(sib)]);
 | 
| -      }
 | 
| -    }
 | 
| -  } else {
 | 
| -    if (sib_index(sib) == 4) {
 | 
| -      /* No index */
 | 
| -      gprintf(fp, "[%s]", gp_regs[sib_base(sib)]);
 | 
| -    } else {
 | 
| -      gprintf(fp, "[%s + %d * %s]",
 | 
| -              gp_regs[sib_base(sib)],
 | 
| -              1 << sib_ss(sib),
 | 
| -              gp_regs[sib_index(sib)]);
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -static void SegPrefixPrint(const NCDecoderInst *dinst, struct Gio* fp) {
 | 
| -  uint8_t pm = dinst->inst.prefixmask;
 | 
| -  if (pm & kPrefixSEGCS) {
 | 
| -    gprintf(fp, "cs:");
 | 
| -  } else if (pm & kPrefixSEGSS) {
 | 
| -    gprintf(fp, "ss:");
 | 
| -  } else if (pm & kPrefixSEGFS) {
 | 
| -    gprintf(fp, "fs:");
 | 
| -  } else if (pm & kPrefixSEGGS) {
 | 
| -    gprintf(fp, "gs:");
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -/* Append that we don't bother to translate the instruction argument,
 | 
| - * since it is NaCl illegal. Used to handle cases where we don't implement
 | 
| - * 16-bit modrm effective addresses.
 | 
| - */
 | 
| -static INLINE void NaClIllegalOp(struct Gio* fp) {
 | 
| -  gprintf(fp, "*NaClIllegal*");
 | 
| -}
 | 
| -
 | 
| -/* Print out the register (from the list of register names),
 | 
| - * that is referenced by the decoded instruction in the
 | 
| - * decoder state. If is_gp_regs is true, the register names
 | 
| - * correspond to general purpose register names. Otherwise,
 | 
| - * they are some other set, such as MMX or XMM.
 | 
| - */
 | 
| -static void RegMemPrint(const NCDecoderInst *dinst,
 | 
| -                        const char* reg_names[],
 | 
| -                        const uint8_t is_gp_regs,
 | 
| -                        struct Gio* fp) {
 | 
| -  DEBUG( printf(
 | 
| -             "reg mem print: sib_offset = %d, "
 | 
| -             "disp_offset = %d, mrm.mod = %02x\n",
 | 
| -             NCSibOffset(dinst), (int) NCDispOffset(dinst),
 | 
| -             modrm_modInline(dinst->inst.mrm)) );
 | 
| -  switch (modrm_modInline(dinst->inst.mrm)) {
 | 
| -    case 0:
 | 
| -      SegPrefixPrint(dinst, fp);
 | 
| -      if (NaClHasBit(dinst->inst.prefixmask, kPrefixADDR16)) {
 | 
| -        NaClIllegalOp(fp);
 | 
| -      } else {
 | 
| -        if (4 == modrm_rmInline(dinst->inst.mrm)) {
 | 
| -          SibPrint(dinst, fp);
 | 
| -        } else if (5 == modrm_rmInline(dinst->inst.mrm)) {
 | 
| -          gprintf(fp, "[0x%x]", DispValue32(dinst));
 | 
| -        } else {
 | 
| -          gprintf(fp, "[%s]", gp_regs[modrm_rmInline(dinst->inst.mrm)]);
 | 
| -        }
 | 
| -      }
 | 
| -      break;
 | 
| -    case 1:
 | 
| -      SegPrefixPrint(dinst, fp);
 | 
| -      if (NaClHasBit(dinst->inst.prefixmask, kPrefixADDR16)) {
 | 
| -        NaClIllegalOp(fp);
 | 
| -      } else {
 | 
| -        gprintf(fp, "0x%x", DispValue32(dinst));
 | 
| -        if (4 == modrm_rmInline(dinst->inst.mrm)) {
 | 
| -          SibPrint(dinst, fp);
 | 
| -        } else {
 | 
| -          gprintf(fp, "[%s]", gp_regs[modrm_rmInline(dinst->inst.mrm)]);
 | 
| -        }
 | 
| -      }
 | 
| -      break;
 | 
| -    case 2:
 | 
| -      SegPrefixPrint(dinst, fp);
 | 
| -      if (NaClHasBit(dinst->inst.prefixmask, kPrefixADDR16)) {
 | 
| -        NaClIllegalOp(fp);
 | 
| -      } else {
 | 
| -        gprintf(fp, "0x%x", DispValue32(dinst));
 | 
| -        if (4 == modrm_rmInline(dinst->inst.mrm)) {
 | 
| -          SibPrint(dinst, fp);
 | 
| -        } else {
 | 
| -          gprintf(fp, "[%s]", gp_regs[modrm_rmInline(dinst->inst.mrm)]);
 | 
| -        }
 | 
| -      }
 | 
| -      break;
 | 
| -    case 3:
 | 
| -      if (is_gp_regs) {
 | 
| -        gprintf(fp, "%s", reg_names[state_modrm_reg(dinst)]);
 | 
| -      } else {
 | 
| -        gprintf(fp, "%s", reg_names[modrm_rmInline(dinst->inst.mrm)]);
 | 
| -      }
 | 
| -      break;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -/* Parses the group name in token. Returns NOGROUP(0) if unable to parse. */
 | 
| -static NaClMRMGroups ParseGroupName(const char* token) {
 | 
| -  if (!strncmp(token, "group", 5)) {
 | 
| -    /* Matched group name prefix, recognize last two characters explicitly.*/
 | 
| -    const char* suffix = token + 5;
 | 
| -    switch (strlen(suffix)) {
 | 
| -      case 1:
 | 
| -        switch (suffix[0]) {
 | 
| -          case '1':
 | 
| -            return GROUP1;
 | 
| -          case '2':
 | 
| -            return GROUP2;
 | 
| -          case '3':
 | 
| -            return GROUP3;
 | 
| -          case '4':
 | 
| -            return GROUP4;
 | 
| -          case '5':
 | 
| -            return GROUP5;
 | 
| -          case '6':
 | 
| -            return GROUP6;
 | 
| -          case '7':
 | 
| -            return GROUP7;
 | 
| -          case '8':
 | 
| -            return GROUP8;
 | 
| -          case '9':
 | 
| -            return GROUP9;
 | 
| -          case 'p':
 | 
| -            return GROUPP;
 | 
| -          default:
 | 
| -            break;
 | 
| -        }
 | 
| -        break;
 | 
| -      case 2:
 | 
| -        if (suffix[0] == '1') {
 | 
| -          switch(suffix[1]) {
 | 
| -            case '0':
 | 
| -              return GROUP10;
 | 
| -            case '1':
 | 
| -              return GROUP11;
 | 
| -            case '2':
 | 
| -              return GROUP12;
 | 
| -            case '3':
 | 
| -              return GROUP13;
 | 
| -            case '4':
 | 
| -              return GROUP14;
 | 
| -            case '5':
 | 
| -              return GROUP15;
 | 
| -            case '6':
 | 
| -              return GROUP16;
 | 
| -            case '7':
 | 
| -              return GROUP17;
 | 
| -            case 'a':
 | 
| -              return GROUP1A;
 | 
| -            default:
 | 
| -              break;
 | 
| -          }
 | 
| -        }
 | 
| -        break;
 | 
| -      default:
 | 
| -        break;
 | 
| -    }
 | 
| -  }
 | 
| -  return 0;
 | 
| -}
 | 
| -
 | 
| -static void InstFormat(const char* format,
 | 
| -                       const NCDecoderInst *dinst,
 | 
| -                       struct Gio* fp) {
 | 
| -  char token_buf[128];
 | 
| -  char* fmt = token_buf;
 | 
| -  int pos = 0;
 | 
| -
 | 
| -  strncpy(token_buf, format, sizeof(token_buf));
 | 
| -
 | 
| -  while (1) {
 | 
| -    char* token = strtok(fmt, " ,\n");
 | 
| -    DEBUG( printf("\ntoken = '%s'\n", token) );
 | 
| -    if (NULL == token) {
 | 
| -      break;
 | 
| -    }
 | 
| -    if (pos > 1) {
 | 
| -      gprintf(fp, ", ");
 | 
| -    } else if (pos > 0) {
 | 
| -      gprintf(fp, " ");
 | 
| -    }
 | 
| -    if ('$' == token[0]) {
 | 
| -      NaClMRMGroups group = ParseGroupName(token+1);
 | 
| -      if (NOGROUP != group) {
 | 
| -        int mrm = modrm_regInline(dinst->inst.mrm);
 | 
| -        const char* opname = kDisasmModRMOp[group][mrm];
 | 
| -        DEBUG( printf("case: group %d, opname = %s\n", group, opname) );
 | 
| -        gprintf(fp, "%s", opname);
 | 
| -      } else {
 | 
| -        /* Tokens starting with a $ but not $group need formatting */
 | 
| -        DEBUG( printf("case: $ and not group\n") );
 | 
| -        switch (token[1]) {
 | 
| -          case 'A':
 | 
| -            gprintf(fp, "$A");
 | 
| -            break;
 | 
| -          case 'C':
 | 
| -            gprintf(fp, "%%cr%d", modrm_regInline(dinst->inst.mrm));
 | 
| -            break;
 | 
| -          case 'D':
 | 
| -            gprintf(fp, "%%dr%d", modrm_regInline(dinst->inst.mrm));
 | 
| -            break;
 | 
| -          case 'E':
 | 
| -          case 'M': /* mod should never be 3 for 'M' */
 | 
| -            /* TODO(sehr): byte and word accesses */
 | 
| -            RegMemPrint(dinst, gp_regs, 1, fp);
 | 
| -            break;
 | 
| -          case 'F':
 | 
| -            gprintf(fp, "eflags");
 | 
| -            break;
 | 
| -          case 'G':
 | 
| -            gprintf(fp, "%s", gp_regs[modrm_regInline(dinst->inst.mrm)]);
 | 
| -            break;
 | 
| -          case 'I':
 | 
| -            gprintf(fp, "0x%"NACL_PRIx64, ImmedValue64(dinst));
 | 
| -            break;
 | 
| -          case 'J':
 | 
| -            gprintf(fp, "0x%"NACL_PRIxNaClPcAddress,
 | 
| -                    NCPrintableInstructionAddress(dinst)
 | 
| -                    + dinst->inst.bytes.length
 | 
| -                    + ImmedValue32(dinst));
 | 
| -            break;
 | 
| -          case 'O':
 | 
| -            gprintf(fp, "[0x%"NACL_PRIx64"]", ImmedValue64(dinst));
 | 
| -            break;
 | 
| -          case 'P':
 | 
| -            if ('R' == token[2]) {
 | 
| -              gprintf(fp, "%%mm%d", modrm_rmInline(dinst->inst.mrm));
 | 
| -            } else {
 | 
| -              gprintf(fp, "%%mm%d", modrm_regInline(dinst->inst.mrm));
 | 
| -            }
 | 
| -            break;
 | 
| -          case 'Q':
 | 
| -            RegMemPrint(dinst, mmx_regs, 0, fp);
 | 
| -            break;
 | 
| -          case 'R':
 | 
| -            gprintf(fp, "%s", gp_regs[modrm_rmInline(dinst->inst.mrm)]);
 | 
| -            break;
 | 
| -          case 'S':
 | 
| -            gprintf(fp, "%s", seg_regs[modrm_regInline(dinst->inst.mrm)]);
 | 
| -            break;
 | 
| -          case 'V':
 | 
| -            if ('R' == token[2]) {
 | 
| -              gprintf(fp, "%%xmm%d", modrm_rmInline(dinst->inst.mrm));
 | 
| -            } else {
 | 
| -              gprintf(fp, "%%xmm%d", modrm_regInline(dinst->inst.mrm));
 | 
| -            }
 | 
| -            break;
 | 
| -          case 'W':
 | 
| -            RegMemPrint(dinst, xmm_regs, 0, fp);
 | 
| -            break;
 | 
| -          case 'X':
 | 
| -            gprintf(fp, "ds:[esi]");
 | 
| -            break;
 | 
| -          case 'Y':
 | 
| -            gprintf(fp, "es:[edi]");
 | 
| -            break;
 | 
| -          default:
 | 
| -            gprintf(fp, "token('%s')", token);
 | 
| -            break;
 | 
| -        }
 | 
| -      }
 | 
| -    } else {
 | 
| -      /* Print the token as is */
 | 
| -      gprintf(fp, "%s", token);
 | 
| -    }
 | 
| -    fmt = NULL;
 | 
| -    ++pos;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -static void NCPrintInstTextUsingFormat(const char* format,
 | 
| -                                       const NCDecoderInst *dinst,
 | 
| -                                       struct Gio* fp) {
 | 
| -  InstFormat(format, dinst, fp);
 | 
| -  gprintf(fp, "\n");
 | 
| -}
 | 
| -
 | 
| -void NCPrintInstWithoutHex(const NCDecoderInst *dinst, struct Gio* fp) {
 | 
| -  DEBUG( printf("use format: %s\n", DisFmt(dinst)) );
 | 
| -  NCPrintInstTextUsingFormat(DisFmt(dinst), dinst, fp);
 | 
| -}
 | 
| -
 | 
| -void NCPrintInstWithHex(const NCDecoderInst *dinst, struct Gio *fp) {
 | 
| -  int i;
 | 
| -  DEBUG( printf("use format: %s\n", DisFmt(dinst)) );
 | 
| -  gprintf(fp, " %"NACL_PRIxNaClPcAddress":\t%02x",
 | 
| -          NCPrintableInstructionAddress(dinst),
 | 
| -          NCInstBytesByte(&dinst->inst_bytes, 0));
 | 
| -  for (i = 1; i < dinst->inst.bytes.length; i++) {
 | 
| -    gprintf(fp, " %02x", NCInstBytesByte(&dinst->inst_bytes, i));
 | 
| -  }
 | 
| -  for (i = dinst->inst.bytes.length; i < 7; i++) gprintf(fp, "   ");
 | 
| -  gprintf(fp, "\t");
 | 
| -  NCPrintInstWithoutHex(dinst, fp);
 | 
| -}
 | 
| -
 | 
| -static Bool PrintInstLogGio(const NCDecoderInst *dinst) {
 | 
| -  NCPrintInstWithHex(dinst, NaClLogGetGio());
 | 
| -  return TRUE;
 | 
| -}
 | 
| -
 | 
| -/* Defines a buffer size big enough to hold an instruction. */
 | 
| -#define MAX_INST_TEXT_SIZE 256
 | 
| -
 | 
| -/* Defines an instruction print function. */
 | 
| -typedef void (*inst_print_fn)(const struct NCDecoderInst* inst,
 | 
| -                              struct Gio *file);
 | 
| -
 | 
| -/* Print out the given instruction, using the given instruction print function,
 | 
| - * and return the printed text as a (malloc allocated) string.
 | 
| - */
 | 
| -static char* InstToStringConvert(const NCDecoderInst* dinst,
 | 
| -                                 inst_print_fn print_fn) {
 | 
| -  /* Print to a memory buffer, and then duplicate. */
 | 
| -  struct GioMemoryFile filemem;
 | 
| -  struct Gio *file = (struct Gio*) &filemem;
 | 
| -  char buffer[MAX_INST_TEXT_SIZE];
 | 
| -  char* result;
 | 
| -
 | 
| -  /* Note: Be sure to leave an extra byte to add the null character to
 | 
| -   * the end of the string.
 | 
| -   */
 | 
| -  GioMemoryFileCtor(&filemem, buffer, MAX_INST_TEXT_SIZE - 1);
 | 
| -  print_fn(dinst, file);
 | 
| -  buffer[filemem.curpos < MAX_INST_TEXT_SIZE
 | 
| -         ? filemem.curpos : MAX_INST_TEXT_SIZE] ='\0';
 | 
| -  result = strdup(buffer);
 | 
| -  GioMemoryFileDtor(file);
 | 
| -  return result;
 | 
| -}
 | 
| -
 | 
| -char* NCInstWithHexToString(const NCDecoderInst* dinst) {
 | 
| -  return InstToStringConvert(dinst, NCPrintInstWithHex);
 | 
| -}
 | 
| -
 | 
| -char* NCInstWithoutHexToString(const NCDecoderInst* dinst) {
 | 
| -  return InstToStringConvert(dinst, NCPrintInstWithoutHex);
 | 
| -}
 | 
| -
 | 
| -void NCDecodeSegment(uint8_t* mbase, NaClPcAddress vbase,
 | 
| -                     NaClMemorySize size) {
 | 
| -  NCDecoderInst inst;
 | 
| -  NCDecoderState dstate;
 | 
| -  NCDecoderStateConstruct(&dstate, mbase, vbase, size, &inst, 1);
 | 
| -  NCDecoderStateSetErrorReporter(&dstate, &kNCVerboseErrorReporter);
 | 
| -  /* TODO(karl): Fix this so that we don't need to override the
 | 
| -   * action function.
 | 
| -   */
 | 
| -  dstate.action_fn = PrintInstLogGio;
 | 
| -  NCDecoderStateDecode(&dstate);
 | 
| -  NCDecoderStateDestruct(&dstate);
 | 
| -}
 | 
| -
 | 
| -static void NCVerboseErrorPrintInst(NaClErrorReporter* self,
 | 
| -                                    NCDecoderInst* dinst) {
 | 
| -  PrintInstLogGio(dinst);
 | 
| -}
 | 
| -
 | 
| -NaClErrorReporter kNCVerboseErrorReporter = {
 | 
| -  NCDecoderInstErrorReporter,
 | 
| -  NaClVerboseErrorPrintf,
 | 
| -  NaClVerboseErrorPrintfV,
 | 
| -  (NaClPrintInst) NCVerboseErrorPrintInst
 | 
| -};
 | 
| 
 |