Diff for /np2/i386c/ia32/disasm.c between versions 1.5 and 1.10

version 1.5, 2004/02/19 03:04:01 version 1.10, 2011/01/15 17:17:23
Line 1 Line 1
 /*      $Id$    */  
   
 /*  /*
  * Copyright (c) 2004 NONAKA Kimihiro   * Copyright (c) 2004 NONAKA Kimihiro
  * All rights reserved.   * All rights reserved.
Line 12 Line 10
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. The name of the author may not be used to endorse or promote products  
  *    derived from this software without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Line 82  static const char *opcode_1byte[2][256]  Line 78  static const char *opcode_1byte[2][256] 
 /*b0*/  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",    /*b0*/  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  
         "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  "movw",            "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  
 /*c0*/  NULL,    NULL,    "ret",   "ret",   "les",   "lds",   "movb",  "movw",  /*c0*/  NULL,    NULL,    "ret",   "ret",   "les",   "lds",   "movb",  "movw",
         "enter", "leave", "ret",   "ret",   "int3",  "int",   "into",  "iret",          "enter", "leave", "retf",  "retf",  "int3",  "int",   "into",  "iret",
 /*d0*/  NULL,    NULL,    NULL,    NULL,    "aam",   "aad",   "salc",  "xlat",  /*d0*/  NULL,    NULL,    NULL,    NULL,    "aam",   "aad",   "salc",  "xlat",
         "esc0",  "esc1",  "esc2",  "esc3",  "esc4",  "esc5",  "esc6",  "esc7",          "esc0",  "esc1",  "esc2",  "esc3",  "esc4",  "esc5",  "esc6",  "esc7",
 /*e0*/  "loopne","loope", "loop",  "jcxz",  "inb",   "inw",   "outb",  "outw",  /*e0*/  "loopne","loope", "loop",  "jcxz",  "inb",   "inw",   "outb",  "outw",
Line 117  static const char *opcode_1byte[2][256]  Line 113  static const char *opcode_1byte[2][256] 
 /*b0*/  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",    /*b0*/  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  
         "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  "movl",            "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  
 /*c0*/  NULL,    NULL,    "ret",   "ret",   "les",   "lds",   "movb",  "movl",  /*c0*/  NULL,    NULL,    "ret",   "ret",   "les",   "lds",   "movb",  "movl",
         "enter", "leave", "ret",   "ret",   "int3",  "int",   "into",  "iretd",          "enter", "leave", "retf",  "retf",  "int3",  "int",   "into",  "iretd",
 /*d0*/  NULL,    NULL,    NULL,    NULL,    "aam",   "aad",   "salc",  "xlat",  /*d0*/  NULL,    NULL,    NULL,    NULL,    "aam",   "aad",   "salc",  "xlat",
         "esc0",  "esc1",  "esc2",  "esc3",  "esc4",  "esc5",  "esc6",  "esc7",          "esc0",  "esc1",  "esc2",  "esc3",  "esc4",  "esc5",  "esc6",  "esc7",
 /*e0*/  "loopne","loope", "loop",  "jecxz", "inb",   "inl",   "outb",  "outl",  /*e0*/  "loopne","loope", "loop",  "jecxz", "inb",   "inl",   "outb",  "outl",
Line 332  static const char *opcode2_g9[8] = { Line 328  static const char *opcode2_g9[8] = {
         NULL, "cmpxchg8b", NULL, NULL, NULL, NULL, NULL, NULL          NULL, "cmpxchg8b", NULL, NULL, NULL, NULL, NULL, NULL
 };  };
   
   #if 0
 static const char *sep[2] = { " ", ", " };  static const char *sep[2] = { " ", ", " };
   #endif
   
 /*  
  * context  
  */  
 typedef struct {  
         DWORD val;  
   
         DWORD eip;  
         BOOL op32;  
         BOOL as32;  
   
         DWORD baseaddr;  
         DWORD opcode[3];  
         DWORD modrm;  
         DWORD sib;  
   
         BOOL useseg;  
         int seg;  
   
         BYTE opbyte[32];  
         int nopbyte;  
   
         char str[256];  
         size_t remain;  
   
         char *next;  
         char *prefix;  
         char *op;  
         char *arg[3];  
         int narg;  
   
         char pad;  
 } disasm_context_t;  
   
   
 /*  /*
Line 375  typedef struct { Line 339  typedef struct {
 static int  static int
 convert_address(disasm_context_t *ctx)  convert_address(disasm_context_t *ctx)
 {  {
         DWORD pde_addr; /* page directory entry address */          UINT32 pde_addr;        /* page directory entry address */
         DWORD pde;      /* page directory entry */          UINT32 pde;             /* page directory entry */
         DWORD pte_addr; /* page table entry address */          UINT32 pte_addr;        /* page table entry address */
         DWORD pte;      /* page table entry */          UINT32 pte;             /* page table entry */
         DWORD addr;          UINT32 addr;
   
         if (CPU_STAT_SREG(CPU_CS_INDEX).valid) {          if (CPU_STAT_SREG(CPU_CS_INDEX).valid) {
                 addr = CPU_STAT_SREGBASE(CPU_CS_INDEX) + ctx->eip;                  addr = CPU_STAT_SREGBASE(CPU_CS_INDEX) + ctx->eip;
                 if (CPU_STAT_PAGING) {                  if (CPU_STAT_PAGING) {
                         pde_addr = CPU_STAT_PDE_BASE + ((addr >> 20) & 0xffc);                          pde_addr = CPU_STAT_PDE_BASE + ((addr >> 20) & 0xffc);
                         pde = cpu_memoryread_d(pde_addr);                          pde = cpu_memoryread_d(pde_addr);
                           /* XXX: check */
                         pte_addr = (pde & CPU_PDE_BASEADDR_MASK) + ((addr >> 10) & 0xffc);                          pte_addr = (pde & CPU_PDE_BASEADDR_MASK) + ((addr >> 10) & 0xffc);
                         pte = cpu_memoryread_d(pte_addr);                          pte = cpu_memoryread_d(pte_addr);
                           /* XXX: check */
                         addr = (pte & CPU_PTE_BASEADDR_MASK) + (addr & 0x00000fff);                          addr = (pte & CPU_PTE_BASEADDR_MASK) + (addr & 0x00000fff);
                 }                  }
                 ctx->val = addr;                  ctx->val = addr;
Line 399  convert_address(disasm_context_t *ctx) Line 365  convert_address(disasm_context_t *ctx)
 static int  static int
 disasm_codefetch_1(disasm_context_t *ctx)  disasm_codefetch_1(disasm_context_t *ctx)
 {  {
         BYTE val;          UINT8 val;
         int rv;          int rv;
   
         rv = convert_address(ctx);          rv = convert_address(ctx);
Line 409  disasm_codefetch_1(disasm_context_t *ctx Line 375  disasm_codefetch_1(disasm_context_t *ctx
         val = cpu_memoryread(ctx->val);          val = cpu_memoryread(ctx->val);
         ctx->val = val;          ctx->val = val;
   
         ctx->opbyte[ctx->nopbyte++] = (BYTE)ctx->val;          ctx->opbyte[ctx->nopbytes++] = (UINT8)ctx->val;
         ctx->eip++;          ctx->eip++;
   
         return 0;          return 0;
 }  }
   
   #if 0
 static int  static int
 disasm_codefetch_2(disasm_context_t *ctx)  disasm_codefetch_2(disasm_context_t *ctx)
 {  {
         WORD val;          UINT16 val;
         int rv;          int rv;
   
         rv = disasm_codefetch_1(ctx);          rv = disasm_codefetch_1(ctx);
         if (rv)          if (rv)
                 return rv;                  return rv;
         val = (WORD)(ctx->val & 0xff);          val = (UINT16)(ctx->val & 0xff);
         rv = disasm_codefetch_1(ctx);          rv = disasm_codefetch_1(ctx);
         if (rv)          if (rv)
                 return rv;                  return rv;
         val |= (WORD)(ctx->val & 0xff) << 8;          val |= (UINT16)(ctx->val & 0xff) << 8;
   
         ctx->val = val;          ctx->val = val;
         return 0;          return 0;
Line 437  disasm_codefetch_2(disasm_context_t *ctx Line 404  disasm_codefetch_2(disasm_context_t *ctx
 static int  static int
 disasm_codefetch_4(disasm_context_t *ctx)  disasm_codefetch_4(disasm_context_t *ctx)
 {  {
         DWORD val;          UINT32 val;
         int rv;          int rv;
   
         rv = disasm_codefetch_1(ctx);          rv = disasm_codefetch_1(ctx);
Line 447  disasm_codefetch_4(disasm_context_t *ctx Line 414  disasm_codefetch_4(disasm_context_t *ctx
         rv = disasm_codefetch_1(ctx);          rv = disasm_codefetch_1(ctx);
         if (rv)          if (rv)
                 return rv;                  return rv;
         val |= (DWORD)(ctx->val & 0xff) << 8;          val |= (UINT32)(ctx->val & 0xff) << 8;
         rv = disasm_codefetch_1(ctx);          rv = disasm_codefetch_1(ctx);
         if (rv)          if (rv)
                 return rv;                  return rv;
         val |= (DWORD)(ctx->val & 0xff) << 16;          val |= (UINT32)(ctx->val & 0xff) << 16;
         rv = disasm_codefetch_1(ctx);          rv = disasm_codefetch_1(ctx);
         if (rv)          if (rv)
                 return rv;                  return rv;
         val |= (DWORD)(ctx->val & 0xff) << 24;          val |= (UINT32)(ctx->val & 0xff) << 24;
   
         ctx->val = val;          ctx->val = val;
         return 0;          return 0;
Line 472  ea16(disasm_context_t *ctx, char *buf, s Line 439  ea16(disasm_context_t *ctx, char *buf, s
                 "bx + si", "bx + di", "bp + si", "bp + di",                  "bx + si", "bx + di", "bp + si", "bp + di",
                 "si", "di", "bp", "bx"                  "si", "di", "bp", "bx"
         };          };
 //      char tmp[32];          UINT32 val;
         DWORD mod, rm;          UINT mod, rm;
         DWORD val;  
         int rv;          int rv;
   
         mod = (ctx->modrm >> 6) & 3;          mod = (ctx->modrm >> 6) & 3;
Line 487  ea16(disasm_context_t *ctx, char *buf, s Line 453  ea16(disasm_context_t *ctx, char *buf, s
                         if (rv)                          if (rv)
                                 return rv;                                  return rv;
   
                         snprintf(buf, size, "[0x%04lx]", ctx->val);                          snprintf(buf, size, "[0x%04x]", ctx->val);
                 } else {                  } else {
                         snprintf(buf, size, "[%s]", ea16_str[rm]);                          snprintf(buf, size, "[%s]", ea16_str[rm]);
                 }                  }
Line 510  ea16(disasm_context_t *ctx, char *buf, s Line 476  ea16(disasm_context_t *ctx, char *buf, s
   
                         val = ctx->val;                          val = ctx->val;
                 }                  }
                 snprintf(buf, size, "[%s + 0x%04lx]", ea16_str[rm], val);                  snprintf(buf, size, "[%s + 0x%04x]", ea16_str[rm], val);
         }          }
   
         return 0;          return 0;
Line 520  static int Line 486  static int
 ea32(disasm_context_t *ctx, char *buf, size_t size)  ea32(disasm_context_t *ctx, char *buf, size_t size)
 {  {
         char tmp[32];          char tmp[32];
         DWORD count[9];          UINT count[9];
         DWORD mod, rm;          UINT32 val;
         DWORD sib;          UINT mod, rm;
         DWORD scale;          UINT sib;
         DWORD idx;          UINT scale;
         DWORD base;          UINT idx;
         DWORD val;          UINT base;
         int rv;          int rv;
         int i, n;          int i, n;
   
Line 604  ea32(disasm_context_t *ctx, char *buf, s Line 570  ea32(disasm_context_t *ctx, char *buf, s
                                 milstr_ncat(buf, " + ", size);                                  milstr_ncat(buf, " + ", size);
                         }                          }
                         if (count[i] > 1) {                          if (count[i] > 1) {
                                 snprintf(tmp, size, "%s * %ld",                                  snprintf(tmp, size, "%s * %d",
                                     reg32_str[i], count[i]);                                      reg32_str[i], count[i]);
                         } else {                          } else {
                                 milstr_ncpy(tmp, reg32_str[i], sizeof(tmp));                                  milstr_ncpy(tmp, reg32_str[i], sizeof(tmp));
Line 617  ea32(disasm_context_t *ctx, char *buf, s Line 583  ea32(disasm_context_t *ctx, char *buf, s
                 if (n > 0) {                  if (n > 0) {
                         milstr_ncat(buf, " + ", size);                          milstr_ncat(buf, " + ", size);
                 }                  }
                 snprintf(tmp, sizeof(tmp), "0x%08lx", count[8]);                  snprintf(tmp, sizeof(tmp), "0x%08x", count[8]);
                 milstr_ncat(buf, tmp, size);                  milstr_ncat(buf, tmp, size);
         }          }
         milstr_ncat(buf, "]", size);          milstr_ncat(buf, "]", size);
Line 665  ea(disasm_context_t *ctx) Line 631  ea(disasm_context_t *ctx)
   
         return 0;          return 0;
 }  }
   #endif
   
 /*  /*
  * get opcode   * get opcode
Line 673  static int Line 640  static int
 op(disasm_context_t *ctx)  op(disasm_context_t *ctx)
 {  {
         const char *opcode;          const char *opcode;
 //      DWORD type;          UINT8 op[3];
         BYTE op[3];  
         int prefix;          int prefix;
         int len;          size_t len;
         int rv;          int rv;
         int i;          int i;
   
Line 685  op(disasm_context_t *ctx) Line 651  op(disasm_context_t *ctx)
                 if (rv)                  if (rv)
                         return rv;                          return rv;
   
                 op[0] = (BYTE)(ctx->val & 0xff);                  op[0] = (UINT8)(ctx->val & 0xff);
                 if (insttable_info[op[0]] & INST_PREFIX) {                  if (insttable_info[op[0]] & INST_PREFIX) {
                         if (ctx->prefix == 0)                          if (ctx->prefix == 0)
                                 ctx->prefix = ctx->next;                                  ctx->prefix = ctx->next;
Line 729  op(disasm_context_t *ctx) Line 695  op(disasm_context_t *ctx)
                         }                          }
                 }                  }
                 len = strlen(ctx->next);                  len = strlen(ctx->next);
                 len = (len < (int)ctx->remain) ? len : ctx->remain;                  len = (len < ctx->remain) ? len : ctx->remain;
                 ctx->next += len;                  ctx->next += len;
                 ctx->remain -= len;                  ctx->remain -= len;
         }          }
Line 741  op(disasm_context_t *ctx) Line 707  op(disasm_context_t *ctx)
                 if (rv)                  if (rv)
                         return rv;                          return rv;
   
                 op[1] = (BYTE)(ctx->val & 0xff);                  op[1] = (UINT8)(ctx->val & 0xff);
                 ctx->opcode[1] = op[1];                  ctx->opcode[1] = op[1];
   
                 switch (op[0]) {                  switch (op[0]) {
Line 752  op(disasm_context_t *ctx) Line 718  op(disasm_context_t *ctx)
                                 if (rv)                                  if (rv)
                                         return rv;                                          return rv;
   
                                 op[2] = (BYTE)(ctx->val & 0xff);                                  op[2] = (UINT8)(ctx->val & 0xff);
                                 ctx->opcode[2] = op[2];                                  ctx->opcode[2] = op[2];
   
                                 switch (op[1]) {                                  switch (op[1]) {
Line 813  op(disasm_context_t *ctx) Line 779  op(disasm_context_t *ctx)
  * interface   * interface
  */   */
 int  int
 disasm(DWORD *eip, char *buf, size_t size)  disasm(UINT32 *eip, disasm_context_t *ctx)
 {  {
         disasm_context_t ctx;  
         int rv;          int rv;
   
         memset(&ctx, 0, sizeof(ctx));          memset(ctx, 0, sizeof(disasm_context_t));
         ctx.remain = sizeof(ctx.str) - 1;          ctx->remain = sizeof(ctx->str) - 1;
         ctx.next = ctx.str;          ctx->next = ctx->str;
         ctx.prefix = 0;          ctx->prefix = 0;
         ctx.op = 0;          ctx->op = 0;
         ctx.arg[0] = 0;          ctx->arg[0] = 0;
         ctx.arg[1] = 0;          ctx->arg[1] = 0;
         ctx.arg[2] = 0;          ctx->arg[2] = 0;
   
         ctx.eip = *eip;          ctx->eip = *eip;
         ctx.op32 = CPU_INST_OP32;          ctx->op32 = CPU_INST_OP32;
         ctx.as32 = CPU_INST_AS32;          ctx->as32 = CPU_INST_AS32;
         ctx.seg = -1;          ctx->seg = -1;
   
         ctx.baseaddr = ctx.eip;          ctx->baseaddr = ctx->eip;
         ctx.pad = ' ';          ctx->pad = ' ';
   
         rv = op(&ctx);          rv = op(ctx);
         if (rv) {          if (rv) {
                 memset(&ctx, 0, sizeof(ctx));                  memset(ctx, 0, sizeof(disasm_context_t));
                 return rv;                  return rv;
         }          }
           *eip = ctx->eip;
   
         *eip = ctx.eip;  
         milstr_ncpy(buf, ctx.str, size);  
         return 0;          return 0;
 }  }

Removed from v.1.5  
changed lines
  Added in v.1.10


RetroPC.NET-CVS <cvs@retropc.net>