Initial megacommit.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2008-07-12 17:40:22 +00:00
parent a3be5d89ae
commit 775dc8a9c0
1920 changed files with 734652 additions and 0 deletions

View File

@ -0,0 +1,509 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="Bochs_disasm"
ProjectGUID="{29C2ABC1-ADA5-42CD-A5FC-96022D52A510}"
RootNamespace="Bochs_disasm"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="2"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="DebugFast|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="DebugFast|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="2"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath=".\config.h"
>
</File>
<File
RelativePath=".\dis_decode.cpp"
>
</File>
<File
RelativePath=".\dis_groups.cpp"
>
</File>
<File
RelativePath=".\dis_tables.h"
>
</File>
<File
RelativePath=".\dis_tables.inl"
>
</File>
<File
RelativePath=".\disasm.h"
>
</File>
<File
RelativePath=".\opcodes.inl"
>
</File>
<File
RelativePath=".\PowerPCDisasm.cpp"
>
</File>
<File
RelativePath=".\PowerPCDisasm.h"
>
</File>
<File
RelativePath=".\resolve.cpp"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="DebugFast|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="DebugFast|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\stdafx.h"
>
</File>
<File
RelativePath=".\syntax.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

2247
Externals/Bochs_disasm/PowerPCDisasm.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

28
Externals/Bochs_disasm/PowerPCDisasm.h vendored Normal file
View File

@ -0,0 +1,28 @@
/* $VER: ppc_disasm V0.1 (23.05.1998)
*
* Disassembler module for the PowerPC microprocessor family
* Copyright (c) 1998-2000 Frank Wille
*
* ppc_disasm.c is freeware and may be freely redistributed as long as
* no modifications are made and nothing is charged for it.
* Non-commercial usage is allowed without any restrictions.
* EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
* SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
*
*
* v0.1 (23.05.1998) phx
* First version, which implements all PowerPC instructions.
* v0.0 (09.05.1998) phx
* File created.
*/
// Yeah, this does not really belong in bochs_disasm, but hey, it's a disasm and it needed a common location...
#ifndef _POWERPC_DISASM
#define _POWERPC_DISASM
const char *DisassembleGekko(unsigned int opcode, unsigned int curInstAddr);
const char *GetGRPName(unsigned int index);
#endif

11
Externals/Bochs_disasm/SConscript vendored Normal file
View File

@ -0,0 +1,11 @@
Import('env')
files = ["dis_decode.cpp",
"dis_groups.cpp",
"resolve.cpp",
"syntax.cpp",
"PowerPCDisasm.cpp",
]
env_bochs = env.Copy(CXXFLAGS = " -fPIC ")
env_bochs.StaticLibrary("bdisasm", files)

41
Externals/Bochs_disasm/config.h vendored Normal file
View File

@ -0,0 +1,41 @@
#ifndef _BOCHS_CONFIG_H
#define _BOCHS_CONFIG_H
#ifdef _WIN32
typedef signed __int8 Bit8s;
typedef signed __int16 Bit16s;
typedef signed __int32 Bit32s;
typedef signed __int64 Bit64s;
typedef unsigned __int8 Bit8u;
typedef unsigned __int16 Bit16u;
typedef unsigned __int32 Bit32u;
typedef unsigned __int64 Bit64u;
typedef bool bx_bool;
typedef Bit64u bx_address;
#define BX_CPP_INLINE inline
#else
#include <stdint.h>
typedef int8_t Bit8s;
typedef int16_t Bit16s;
typedef int32_t Bit32s;
typedef int64_t Bit64s;
typedef uint8_t Bit8u;
typedef uint16_t Bit16u;
typedef uint32_t Bit32u;
typedef uint64_t Bit64u;
typedef bool bx_bool;
typedef Bit64u bx_address;
#define BX_CPP_INLINE inline
#endif
#endif

328
Externals/Bochs_disasm/dis_decode.cpp vendored Normal file
View File

@ -0,0 +1,328 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dis_decode.cc,v 1.32 2006/05/12 17:04:19 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "disasm.h"
#include "dis_tables.h"
#define OPCODE(entry) ((BxDisasmOpcodeInfo_t*) entry->OpcodeInfo)
#define OPCODE_TABLE(entry) ((BxDisasmOpcodeTable_t*) entry->OpcodeInfo)
#ifndef NULL
#define NULL 0
#endif
static const unsigned char instruction_has_modrm[512] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/* ------------------------------- */
/* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
/* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
/* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
/* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
/* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
/* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
/* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* A0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* B0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* C0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
/* D0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
/* E0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* F0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/* ------------------------------- */
1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0F 00 */
1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 0F 10 */
1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 0F 20 */
0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 0F 30 */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 40 */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 50 */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 60 */
1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 0F 70 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0F 80 */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 90 */
0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* 0F A0 */
1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* 0F B0 */
1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 0F C0 */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F D0 */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F E0 */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* 0F F0 */
/* ------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{
x86_insn insn = decode(is_32, is_64, base, ip, instr, disbuf);
return insn.ilen;
}
x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{
x86_insn insn(is_32, is_64);
const Bit8u *instruction_begin = instruction = instr;
resolve_modrm = NULL;
unsigned b3 = 0;
db_eip = ip;
db_base = base; // cs linear base (base for PM & cs<<4 for RM & VM)
disbufptr = disbuf; // start sprintf()'ing into beginning of buffer
#define SSE_PREFIX_NONE 0
#define SSE_PREFIX_66 1
#define SSE_PREFIX_F2 2
#define SSE_PREFIX_F3 3 /* only one SSE prefix could be used */
unsigned sse_prefix = SSE_PREFIX_NONE;
for(;;)
{
insn.b1 = fetch_byte();
insn.prefixes++;
switch(insn.b1) {
case 0x40: // rex
case 0x41:
case 0x42:
case 0x43:
case 0x44:
case 0x45:
case 0x46:
case 0x47:
case 0x48:
case 0x49:
case 0x4A:
case 0x4B:
case 0x4C:
case 0x4D:
case 0x4E:
case 0x4F:
if (! is_64) break;
insn.extend8b = 1;
if (insn.b1 & 0x8) {
insn.os_64 = 1;
insn.os_32 = 1;
}
if (insn.b1 & 0x4) insn.rex_r = 8;
if (insn.b1 & 0x2) insn.rex_x = 8;
if (insn.b1 & 0x1) insn.rex_b = 8;
continue;
case 0x26: // ES:
if (! is_64) insn.seg_override = ES_REG;
continue;
case 0x2e: // CS:
if (! is_64) insn.seg_override = CS_REG;
continue;
case 0x36: // SS:
if (! is_64) insn.seg_override = SS_REG;
continue;
case 0x3e: // DS:
if (! is_64) insn.seg_override = DS_REG;
continue;
case 0x64: // FS:
insn.seg_override = FS_REG;
continue;
case 0x65: // GS:
insn.seg_override = GS_REG;
continue;
case 0x66: // operand size override
if (!insn.os_64) insn.os_32 = !is_32;
if (!sse_prefix) sse_prefix = SSE_PREFIX_66;
continue;
case 0x67: // address size override
if (!is_64) insn.as_32 = !is_32;
insn.as_64 = 0;
continue;
case 0xf0: // lock
continue;
case 0xf2: // repne
if (!sse_prefix) sse_prefix = SSE_PREFIX_F2;
continue;
case 0xf3: // rep
if (!sse_prefix) sse_prefix = SSE_PREFIX_F3;
continue;
// no more prefixes
default:
break;
}
insn.prefixes--;
break;
}
if (insn.b1 == 0x0f)
{
insn.b1 = 0x100 | fetch_byte();
}
const BxDisasmOpcodeTable_t *opcode_table, *entry;
if (is_64) {
if (insn.os_64)
opcode_table = BxDisasmOpcodes64q;
else if (insn.os_32)
opcode_table = BxDisasmOpcodes64d;
else
opcode_table = BxDisasmOpcodes64w;
} else {
if (insn.os_32)
opcode_table = BxDisasmOpcodes32;
else
opcode_table = BxDisasmOpcodes16;
}
entry = opcode_table + insn.b1;
// will require 3rd byte for 3-byte opcode
if (entry->Attr & _GRP3BTAB) b3 = fetch_byte();
if (instruction_has_modrm[insn.b1])
{
decode_modrm(&insn);
}
int attr = entry->Attr;
while(attr)
{
switch(attr) {
case _GROUPN:
entry = &(OPCODE_TABLE(entry)[insn.nnn]);
break;
case _GRPSSE:
if(sse_prefix) insn.prefixes--;
/* For SSE opcodes, look into another 4 entries table
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3) */
entry = &(OPCODE_TABLE(entry)[sse_prefix]);
break;
case _SPLIT11B:
entry = &(OPCODE_TABLE(entry)[insn.mod != 3]); /* REG/MEM */
break;
case _GRPRM:
entry = &(OPCODE_TABLE(entry)[insn.rm]);
break;
case _GRPFP:
if(insn.mod != 3)
{
entry = &(OPCODE_TABLE(entry)[insn.nnn]);
} else {
int index = (insn.b1-0xD8)*64 + (insn.modrm & 0x3f);
entry = &(BxDisasmOpcodeInfoFP[index]);
}
break;
case _GRP3DNOW:
entry = &(BxDisasm3DNowGroup[peek_byte()]);
break;
case _GRP3BTAB:
entry = &(OPCODE_TABLE(entry)[b3 >> 4]);
break;
case _GRP3BOP:
entry = &(OPCODE_TABLE(entry)[b3 & 15]);
break;
default:
printf("Internal disassembler error - unknown attribute !\n");
return x86_insn(is_32, is_64);
}
/* get additional attributes from group table */
attr = entry->Attr;
}
#define BRANCH_NOT_TAKEN 0x2E
#define BRANCH_TAKEN 0x3E
unsigned branch_hint = 0;
// print prefixes
for(unsigned i=0;i<insn.prefixes;i++)
{
Bit8u prefix_byte = *(instr+i);
if (prefix_byte == 0xF3 || prefix_byte == 0xF2 || prefix_byte == 0xF0)
{
const BxDisasmOpcodeTable_t *prefix = &(opcode_table[prefix_byte]);
dis_sprintf("%s ", OPCODE(prefix)->IntelOpcode);
}
// branch hint for jcc instructions
if ((insn.b1 >= 0x070 && insn.b1 <= 0x07F) ||
(insn.b1 >= 0x180 && insn.b1 <= 0x18F))
{
if (prefix_byte == BRANCH_NOT_TAKEN || prefix_byte == BRANCH_TAKEN)
branch_hint = prefix_byte;
}
}
const BxDisasmOpcodeInfo_t *opcode = OPCODE(entry);
// patch jecx opcode
if (insn.b1 == 0xE3 && insn.as_32 && !insn.as_64)
opcode = &Ia_jecxz_Jb;
// fix nop opcode
if (insn.b1 == 0x90 && !insn.rex_b) {
opcode = &Ia_nop;
}
// print instruction disassembly
if (intel_mode)
print_disassembly_intel(&insn, opcode);
else
print_disassembly_att (&insn, opcode);
if (branch_hint == BRANCH_NOT_TAKEN)
{
dis_sprintf(", not taken");
}
else if (branch_hint == BRANCH_TAKEN)
{
dis_sprintf(", taken");
}
insn.ilen = (unsigned)(instruction - instruction_begin);
return insn;
}
void disassembler::dis_sprintf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsprintf(disbufptr, fmt, ap);
va_end(ap);
disbufptr += strlen(disbufptr);
}
void disassembler::dis_putc(char symbol)
{
*disbufptr++ = symbol;
*disbufptr = 0;
}

607
Externals/Bochs_disasm/dis_groups.cpp vendored Normal file
View File

@ -0,0 +1,607 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dis_groups.cc,v 1.33 2006/08/13 09:40:07 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <assert.h>
#include "disasm.h"
/*
#if BX_DEBUGGER
#include "../bx_debug/debug.h"
#endif
*/
void disassembler::Apw(const x86_insn *insn)
{
Bit16u imm16 = fetch_word();
Bit16u cs_selector = fetch_word();
dis_sprintf("%04x:%04x", (unsigned) cs_selector, (unsigned) imm16);
}
void disassembler::Apd(const x86_insn *insn)
{
Bit32u imm32 = fetch_dword();
Bit16u cs_selector = fetch_word();
dis_sprintf("%04x:%08x", (unsigned) cs_selector, (unsigned) imm32);
}
// 8-bit general purpose registers
void disassembler::AL(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rAX_REG]); }
void disassembler::CL(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rCX_REG]); }
// 16-bit general purpose registers
void disassembler::AX(const x86_insn *insn) {
dis_sprintf("%s", general_16bit_regname[rAX_REG]);
}
void disassembler::DX(const x86_insn *insn) {
dis_sprintf("%s", general_16bit_regname[rDX_REG]);
}
// 32-bit general purpose registers
void disassembler::EAX(const x86_insn *insn)
{
dis_sprintf("%s", general_32bit_regname[rAX_REG]);
}
// 64-bit general purpose registers
void disassembler::RAX(const x86_insn *insn)
{
dis_sprintf("%s", general_64bit_regname[rAX_REG]);
}
// segment registers
void disassembler::CS(const x86_insn *insn) { dis_sprintf("%s", segment_name[CS_REG]); }
void disassembler::DS(const x86_insn *insn) { dis_sprintf("%s", segment_name[DS_REG]); }
void disassembler::ES(const x86_insn *insn) { dis_sprintf("%s", segment_name[ES_REG]); }
void disassembler::SS(const x86_insn *insn) { dis_sprintf("%s", segment_name[SS_REG]); }
void disassembler::FS(const x86_insn *insn) { dis_sprintf("%s", segment_name[FS_REG]); }
void disassembler::GS(const x86_insn *insn) { dis_sprintf("%s", segment_name[GS_REG]); }
void disassembler::Sw(const x86_insn *insn) { dis_sprintf("%s", segment_name[insn->nnn]); }
// test registers
void disassembler::Td(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("tr%d", insn->nnn);
else
dis_sprintf("%%tr%d", insn->nnn);
}
// control register
void disassembler::Cd(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("cr%d", insn->nnn);
else
dis_sprintf("%%cr%d", insn->nnn);
}
void disassembler::Cq(const x86_insn *insn) { Cd(insn); }
// debug register
void disassembler::Dd(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("db%d", insn->nnn);
else
dis_sprintf("%%db%d", insn->nnn);
}
void disassembler::Dq(const x86_insn *insn) { Dd(insn); }
// 8-bit general purpose register
void disassembler::R8(const x86_insn *insn)
{
unsigned reg = (insn->b1 & 7) | insn->rex_b;
if (reg < 4 || insn->extend8b)
dis_sprintf("%s", general_8bit_regname_rex[reg]);
else
dis_sprintf("%s", general_8bit_regname[reg]);
}
// 16-bit general purpose register
void disassembler::RX(const x86_insn *insn)
{
dis_sprintf("%s", general_16bit_regname[(insn->b1 & 7) | insn->rex_b]);
}
// 32-bit general purpose register
void disassembler::ERX(const x86_insn *insn)
{
dis_sprintf("%s", general_32bit_regname[(insn->b1 & 7) | insn->rex_b]);
}
// 64-bit general purpose register
void disassembler::RRX(const x86_insn *insn)
{
dis_sprintf("%s", general_64bit_regname[(insn->b1 & 7) | insn->rex_b]);
}
// general purpose register or memory operand
void disassembler::Eb(const x86_insn *insn)
{
if (insn->mod == 3) {
if (insn->rm < 4 || insn->extend8b)
dis_sprintf("%s", general_8bit_regname_rex[insn->rm]);
else
dis_sprintf("%s", general_8bit_regname[insn->rm]);
}
else
(this->*resolve_modrm)(insn, B_SIZE);
}
void disassembler::Ew(const x86_insn *insn)
{
if (insn->mod == 3)
dis_sprintf("%s", general_16bit_regname[insn->rm]);
else
(this->*resolve_modrm)(insn, W_SIZE);
}
void disassembler::Ed(const x86_insn *insn)
{
if (insn->mod == 3)
dis_sprintf("%s", general_32bit_regname[insn->rm]);
else
(this->*resolve_modrm)(insn, D_SIZE);
}
void disassembler::Eq(const x86_insn *insn)
{
if (insn->mod == 3)
dis_sprintf("%s", general_64bit_regname[insn->rm]);
else
(this->*resolve_modrm)(insn, Q_SIZE);
}
// general purpose register
void disassembler::Gb(const x86_insn *insn)
{
if (insn->nnn < 4 || insn->extend8b)
dis_sprintf("%s", general_8bit_regname_rex[insn->nnn]);
else
dis_sprintf("%s", general_8bit_regname[insn->nnn]);
}
void disassembler::Gw(const x86_insn *insn)
{
dis_sprintf("%s", general_16bit_regname[insn->nnn]);
}
void disassembler::Gd(const x86_insn *insn)
{
dis_sprintf("%s", general_32bit_regname[insn->nnn]);
}
void disassembler::Gq(const x86_insn *insn)
{
dis_sprintf("%s", general_64bit_regname[insn->nnn]);
}
// immediate
void disassembler::I1(const x86_insn *insn)
{
if (! intel_mode) dis_putc('$');
dis_putc ('1');
}
void disassembler::Ib(const x86_insn *insn)
{
if (! intel_mode) dis_putc('$');
dis_sprintf("0x%02x", (unsigned) fetch_byte());
}
void disassembler::Iw(const x86_insn *insn)
{
if (! intel_mode) dis_putc('$');
dis_sprintf("0x%04x", (unsigned) fetch_word());
}
void disassembler::IwIb(const x86_insn *insn)
{
Bit16u iw = fetch_word();
Bit8u ib = fetch_byte();
if (intel_mode) {
dis_sprintf("0x%04x, 0x%02x", iw, ib);
}
else {
dis_sprintf("$0x%02x, $0x%04x", ib, iw);
}
}
void disassembler::Id(const x86_insn *insn)
{
if (! intel_mode) dis_putc('$');
dis_sprintf("0x%08x", (unsigned) fetch_dword());
}
void disassembler::Iq(const x86_insn *insn)
{
Bit64u value = fetch_qword();
if (! intel_mode) dis_putc('$');
dis_sprintf("0x%08x%08x",
(unsigned)(value>>32), (unsigned)(value & 0xffffffff));
}
// sign extended immediate
void disassembler::sIbw(const x86_insn *insn)
{
if (! intel_mode) dis_putc('$');
Bit16u imm16 = (Bit8s) fetch_byte();
dis_sprintf("0x%04x", (unsigned) imm16);
}
// sign extended immediate
void disassembler::sIbd(const x86_insn *insn)
{
if (! intel_mode) dis_putc('$');
Bit32u imm32 = (Bit8s) fetch_byte();
dis_sprintf ("0x%08x", (unsigned) imm32);
}
// sign extended immediate
void disassembler::sIbq(const x86_insn *insn)
{
if (! intel_mode) dis_putc('$');
Bit64u imm64 = (Bit8s) fetch_byte();
dis_sprintf ("0x%08x%08x",
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
}
// sign extended immediate
void disassembler::sIdq(const x86_insn *insn)
{
if (! intel_mode) dis_putc('$');
Bit64u imm64 = (Bit32s) fetch_dword();
dis_sprintf ("0x%08x%08x",
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
}
// floating point
void disassembler::ST0(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("st(0)");
else
dis_sprintf("%%st(0)");
}
void disassembler::STi(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("st(%d)", insn->rm);
else
dis_sprintf("%%st(%d)", insn->rm);
}
// 16-bit general purpose register
void disassembler::Rw(const x86_insn *insn)
{
dis_sprintf("%s", general_16bit_regname[insn->rm]);
}
// 32-bit general purpose register
void disassembler::Rd(const x86_insn *insn)
{
dis_sprintf("%s", general_32bit_regname[insn->rm]);
}
// 64-bit general purpose register
void disassembler::Rq(const x86_insn *insn)
{
dis_sprintf("%s", general_64bit_regname[insn->rm]);
}
// mmx register
void disassembler::Pq(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("mm%d", insn->nnn);
else
dis_sprintf("%%mm%d", insn->nnn);
}
void disassembler::Nq(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("mm%d", insn->rm);
else
dis_sprintf("%%mm%d", insn->rm);
}
void disassembler::Qd(const x86_insn *insn)
{
if (insn->mod == 3)
{
if (intel_mode)
dis_sprintf ("mm%d", insn->rm);
else
dis_sprintf("%%mm%d", insn->rm);
}
else
(this->*resolve_modrm)(insn, D_SIZE);
}
void disassembler::Qq(const x86_insn *insn)
{
if (insn->mod == 3)
{
if (intel_mode)
dis_sprintf ("mm%d", insn->rm);
else
dis_sprintf("%%mm%d", insn->rm);
}
else
(this->*resolve_modrm)(insn, Q_SIZE);
}
// xmm register
void disassembler::Udq(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("xmm%d", insn->rm);
else
dis_sprintf("%%xmm%d", insn->rm);
}
void disassembler::Vq(const x86_insn *insn)
{
if (intel_mode)
dis_sprintf ("xmm%d", insn->nnn);
else
dis_sprintf("%%xmm%d", insn->nnn);
}
void disassembler::Vdq(const x86_insn *insn) { Vq(insn); }
void disassembler::Vss(const x86_insn *insn) { Vq(insn); }
void disassembler::Vsd(const x86_insn *insn) { Vq(insn); }
void disassembler::Vps(const x86_insn *insn) { Vq(insn); }
void disassembler::Vpd(const x86_insn *insn) { Vq(insn); }
void disassembler::Wq(const x86_insn *insn)
{
if (insn->mod == 3)
{
if (intel_mode)
dis_sprintf ("xmm%d", insn->rm);
else
dis_sprintf("%%xmm%d", insn->rm);
}
else
(this->*resolve_modrm)(insn, Q_SIZE);
}
void disassembler::Wdq(const x86_insn *insn)
{
if (insn->mod == 3)
{
if (intel_mode)
dis_sprintf ("xmm%d", insn->rm);
else
dis_sprintf("%%xmm%d", insn->rm);
}
else
(this->*resolve_modrm)(insn, O_SIZE);
}
void disassembler::Wsd(const x86_insn *insn) { Wq(insn); }
void disassembler::Wss(const x86_insn *insn)
{
if (insn->mod == 3)
{
if (intel_mode)
dis_sprintf ("xmm%d", insn->rm);
else
dis_sprintf("%%xmm%d", insn->rm);
}
else
(this->*resolve_modrm)(insn, D_SIZE);
}
void disassembler::Wpd(const x86_insn *insn) { Wdq(insn); }
void disassembler::Wps(const x86_insn *insn) { Wdq(insn); }
// direct memory access
void disassembler::OP_O(const x86_insn *insn, unsigned size)
{
const char *seg;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = segment_name[DS_REG];
print_datasize(size);
if (insn->as_64) {
Bit64u imm64 = fetch_qword();
dis_sprintf("%s:0x%08x%08x", seg,
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
}
else if (insn->as_32) {
Bit32u imm32 = fetch_dword();
dis_sprintf("%s:0x%x", seg, (unsigned) imm32);
}
else {
Bit16u imm16 = fetch_word();
dis_sprintf("%s:0x%x", seg, (unsigned) imm16);
}
}
void disassembler::Ob(const x86_insn *insn) { OP_O(insn, B_SIZE); }
void disassembler::Ow(const x86_insn *insn) { OP_O(insn, W_SIZE); }
void disassembler::Od(const x86_insn *insn) { OP_O(insn, D_SIZE); }
void disassembler::Oq(const x86_insn *insn) { OP_O(insn, Q_SIZE); }
// memory operand
void disassembler::OP_M(const x86_insn *insn, unsigned size)
{
if(insn->mod == 3)
dis_sprintf("(bad)");
else
(this->*resolve_modrm)(insn, size);
}
void disassembler::Ma(const x86_insn *insn) { OP_M(insn, X_SIZE); }
void disassembler::Mp(const x86_insn *insn) { OP_M(insn, X_SIZE); }
void disassembler::Ms(const x86_insn *insn) { OP_M(insn, X_SIZE); }
void disassembler::Mx(const x86_insn *insn) { OP_M(insn, X_SIZE); }
void disassembler::Mb(const x86_insn *insn) { OP_M(insn, B_SIZE); }
void disassembler::Mw(const x86_insn *insn) { OP_M(insn, W_SIZE); }
void disassembler::Md(const x86_insn *insn) { OP_M(insn, D_SIZE); }
void disassembler::Mq(const x86_insn *insn) { OP_M(insn, Q_SIZE); }
void disassembler::Mt(const x86_insn *insn) { OP_M(insn, T_SIZE); }
void disassembler::Mdq(const x86_insn *insn) { OP_M(insn, O_SIZE); }
void disassembler::Mps(const x86_insn *insn) { OP_M(insn, O_SIZE); }
void disassembler::Mpd(const x86_insn *insn) { OP_M(insn, O_SIZE); }
// string instructions
void disassembler::OP_X(const x86_insn *insn, unsigned size)
{
const char *rsi, *seg;
if (insn->as_64) {
rsi = general_64bit_regname[rSI_REG];
}
else {
if (insn->as_32)
rsi = general_32bit_regname[rSI_REG];
else
rsi = general_16bit_regname[rSI_REG];
}
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = segment_name[DS_REG];
print_datasize(size);
if (intel_mode)
dis_sprintf("%s:[%s]", seg, rsi);
else
dis_sprintf("%s:(%s)", seg, rsi);
}
void disassembler::Xb(const x86_insn *insn) { OP_X(insn, B_SIZE); }
void disassembler::Xw(const x86_insn *insn) { OP_X(insn, W_SIZE); }
void disassembler::Xd(const x86_insn *insn) { OP_X(insn, D_SIZE); }
void disassembler::Xq(const x86_insn *insn) { OP_X(insn, Q_SIZE); }
void disassembler::OP_Y(const x86_insn *insn, unsigned size)
{
const char *rdi;
if (insn->as_64) {
rdi = general_64bit_regname[rDI_REG];
}
else {
if (insn->as_32)
rdi = general_32bit_regname[rDI_REG];
else
rdi = general_16bit_regname[rDI_REG];
}
print_datasize(size);
if (intel_mode)
dis_sprintf("%s:[%s]", segment_name[ES_REG], rdi);
else
dis_sprintf("%s:(%s)", segment_name[ES_REG], rdi);
}
void disassembler::Yb(const x86_insn *insn) { OP_Y(insn, B_SIZE); }
void disassembler::Yw(const x86_insn *insn) { OP_Y(insn, W_SIZE); }
void disassembler::Yd(const x86_insn *insn) { OP_Y(insn, D_SIZE); }
void disassembler::Yq(const x86_insn *insn) { OP_Y(insn, Q_SIZE); }
#define BX_JUMP_TARGET_NOT_REQ ((bx_address)(-1))
// jump offset
void disassembler::Jb(const x86_insn *insn)
{
Bit8s imm8 = (Bit8s) fetch_byte();
if (insn->is_64) {
Bit64u imm64 = (Bit64s) imm8;
dis_sprintf(".+0x%08x%08x",
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
Bit64u target = db_eip + (Bit64s) imm64; target += db_base;
dis_sprintf(" (0x%08x%08x)",
(unsigned)(target>>32), (unsigned)(target & 0xffffffff));
}
return;
}
if (insn->os_32) {
Bit32u imm32 = (Bit32s) imm8;
dis_sprintf(".+0x%08x", (unsigned) imm32);
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
Bit32u target = db_eip + (Bit32s) imm32; target += db_base;
dis_sprintf(" (0x%08x)", target);
}
}
else {
Bit16u imm16 = (Bit16s) imm8;
dis_sprintf(".+0x%04x", (unsigned) imm16);
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
Bit16u target = (db_eip + (Bit16s) imm16) & 0xffff;
dis_sprintf(" (0x%08x)", target + db_base);
}
}
}
void disassembler::Jw(const x86_insn *insn)
{
// Jw supported in 16-bit mode only
assert(! insn->is_64);
assert(! insn->is_32);
Bit16u imm16 = (Bit16s) fetch_word();
dis_sprintf(".+0x%04x", (unsigned) imm16);
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
Bit16u target = (db_eip + (Bit16s) imm16) & 0xffff;
dis_sprintf(" (0x%08x)", target + db_base);
}
}
void disassembler::Jd(const x86_insn *insn)
{
Bit32s imm32 = (Bit32s) fetch_dword();
if (insn->is_64) {
Bit64u imm64 = (Bit64s) imm32;
dis_sprintf(".+0x%08x%08x",
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
Bit64u target = db_eip + (Bit64s) imm64; target += db_base;
dis_sprintf(" (0x%08x%08x)",
(unsigned)(target>>32), (unsigned)(target & 0xffffffff));
}
return;
}
dis_sprintf(".+0x%08x", (unsigned) imm32);
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
Bit32u target = db_eip + (Bit32s) imm32; target += db_base;
dis_sprintf(" (0x%08x)", target);
}
}

152
Externals/Bochs_disasm/dis_tables.h vendored Normal file
View File

@ -0,0 +1,152 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dis_tables.h,v 1.29 2006/04/27 15:11:45 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
#ifndef _BX_DISASM_TABLES_
#define _BX_DISASM_TABLES_
// opcode table attributes
#define _GROUPN 1
#define _SPLIT11B 2
#define _GRPFP 3
#define _GRP3DNOW 4
#define _GRPSSE 5
#define _GRPRM 6
#define _GRP3BOP 7
#define _GRP3BTAB 8
/* ************************************************************************ */
#define GRPSSE(n) _GRPSSE, BxDisasmGroupSSE_##n
#define GRPN(n) _GROUPN, BxDisasmGroup##n
#define GRPRM(n) _GRPRM, BxDisasmGroupRm##n
#define GRPMOD(n) _SPLIT11B, BxDisasmGroupMod##n
#define GRPFP(n) _GRPFP, BxDisasmFPGroup##n
#define GRP3DNOW _GRP3DNOW, BxDisasm3DNowGroup
#define GR3BOP(n) _GRP3BOP, BxDisasm3ByteOp##n
#define GR3BTAB(n) _GRP3BTAB, BxDisasm3ByteTable##n
/* ************************************************************************ */
#define Apw &disassembler::Apw
#define Apd &disassembler::Apd
#define AL &disassembler::AL
#define CL &disassembler::CL
#define AX &disassembler::AX
#define DX &disassembler::DX
#define EAX &disassembler::EAX
#define RAX &disassembler::RAX
#define CS &disassembler::CS
#define DS &disassembler::DS
#define ES &disassembler::ES
#define SS &disassembler::SS
#define FS &disassembler::FS
#define GS &disassembler::GS
#define Sw &disassembler::Sw
#define Td &disassembler::Td
#define Cd &disassembler::Cd
#define Cq &disassembler::Cq
#define Dd &disassembler::Dd
#define Dq &disassembler::Dq
#define R8 &disassembler::R8
#define RX &disassembler::RX
#define ERX &disassembler::ERX
#define RRX &disassembler::RRX
#define Eb &disassembler::Eb
#define Ew &disassembler::Ew
#define Ed &disassembler::Ed
#define Eq &disassembler::Eq
#define Gb &disassembler::Gb
#define Gw &disassembler::Gw
#define Gd &disassembler::Gd
#define Gq &disassembler::Gq
#define I1 &disassembler::I1
#define Ib &disassembler::Ib
#define Iw &disassembler::Iw
#define Id &disassembler::Id
#define Iq &disassembler::Iq
#define IwIb &disassembler::IwIb
#define sIbw &disassembler::sIbw
#define sIbd &disassembler::sIbd
#define sIbq &disassembler::sIbq
#define sIdq &disassembler::sIdq
#define ST0 &disassembler::ST0
#define STi &disassembler::STi
#define Rw &disassembler::Rw
#define Rd &disassembler::Rd
#define Rq &disassembler::Rq
#define Pq &disassembler::Pq
#define Qd &disassembler::Qd
#define Qq &disassembler::Qq
#define Nq &disassembler::Nq
#define Vq &disassembler::Vq
#define Vdq &disassembler::Vdq
#define Vss &disassembler::Vss
#define Vsd &disassembler::Vsd
#define Vps &disassembler::Vps
#define Vpd &disassembler::Vpd
#define Udq &disassembler::Udq
#define Wq &disassembler::Wq
#define Wdq &disassembler::Wdq
#define Wss &disassembler::Wss
#define Wsd &disassembler::Wsd
#define Wps &disassembler::Wps
#define Wpd &disassembler::Wpd
#define Ob &disassembler::Ob
#define Ow &disassembler::Ow
#define Od &disassembler::Od
#define Oq &disassembler::Oq
#define Ma &disassembler::Ma
#define Mp &disassembler::Mp
#define Ms &disassembler::Ms
#define Mx &disassembler::Mx
#define Mb &disassembler::Mb
#define Mw &disassembler::Mw
#define Md &disassembler::Md
#define Mq &disassembler::Mq
#define Mt &disassembler::Mt
#define Mdq &disassembler::Mdq
#define Mps &disassembler::Mps
#define Mpd &disassembler::Mpd
#define Xb &disassembler::Xb
#define Xw &disassembler::Xw
#define Xd &disassembler::Xd
#define Xq &disassembler::Xq
#define Yb &disassembler::Yb
#define Yw &disassembler::Yw
#define Yd &disassembler::Yd
#define Yq &disassembler::Yq
#define Jb &disassembler::Jb
#define Jw &disassembler::Jw
#define Jd &disassembler::Jd
#define XX 0
const struct BxDisasmOpcodeInfo_t
#include "opcodes.inl"
#include "dis_tables.inl"
#undef XX
#endif

5081
Externals/Bochs_disasm/dis_tables.inl vendored Normal file

File diff suppressed because it is too large Load Diff

508
Externals/Bochs_disasm/disasm.h vendored Normal file
View File

@ -0,0 +1,508 @@
#ifndef _BX_DISASM_H_
#define _BX_DISASM_H_
#include "config.h"
#define BX_DECODE_MODRM(modrm_byte, mod, opcode, rm) { \
mod = (modrm_byte >> 6) & 0x03; \
opcode = (modrm_byte >> 3) & 0x07; \
rm = modrm_byte & 0x07; \
}
#define BX_DECODE_SIB(sib_byte, scale, index, base) { \
scale = sib_byte >> 6; \
index = (sib_byte >> 3) & 0x07; \
base = sib_byte & 0x07; \
}
// will be used in future
#define IA_286 0x00000001 /* 286+ instruction */
#define IA_386 0x00000002 /* 386+ instruction */
#define IA_486 0x00000004 /* 486+ instruction */
#define IA_PENTIUM 0x00000008 /* Pentium+ instruction */
#define IA_P6 0x00000010 /* P6 new instruction */
#define IA_SYSTEM 0x00000020 /* system instruction (require CPL=0) */
#define IA_LEGACY 0x00000040 /* legacy instruction */
#define IA_X87 0x00000080 /* FPU (X87) instruction */
#define IA_MMX 0x00000100 /* MMX instruction */
#define IA_3DNOW 0x00000200 /* 3DNow! instruction */
#define IA_PREFETCH 0x00000400 /* Prefetch instruction */
#define IA_SSE 0x00000800 /* SSE instruction */
#define IA_SSE2 0x00001000 /* SSE2 instruction */
#define IA_SSE3 0x00002000 /* SSE3 instruction */
#define IA_SSE4 0x00004000 /* SSE4 instruction */
#define IA_X86_64 0x00008000 /* x86-64 instruction */
/* general purpose bit register */
enum {
rAX_REG,
rCX_REG,
rDX_REG,
rBX_REG,
rSP_REG,
rBP_REG,
rSI_REG,
rDI_REG
};
/* segment register */
enum {
ES_REG,
CS_REG,
SS_REG,
DS_REG,
FS_REG,
GS_REG,
INVALID_SEG1,
INVALID_SEG2
};
class disassembler;
struct x86_insn;
typedef void (disassembler::*BxDisasmPtr_t)(const x86_insn *insn);
typedef void (disassembler::*BxDisasmResolveModrmPtr_t)(const x86_insn *insn, unsigned attr);
struct BxDisasmOpcodeInfo_t
{
const char *IntelOpcode;
const char *AttOpcode;
BxDisasmPtr_t Operand1;
BxDisasmPtr_t Operand2;
BxDisasmPtr_t Operand3;
};
struct BxDisasmOpcodeTable_t
{
Bit32u Attr;
const void *OpcodeInfo;
};
// segment override not used
#define NO_SEG_OVERRIDE 0xFF
// datasize attributes
#define X_SIZE 0x0000
#define B_SIZE 0x0100
#define W_SIZE 0x0200
#define D_SIZE 0x0300
#define Q_SIZE 0x0400
#define Z_SIZE 0x0500
#define V_SIZE 0x0600
#define O_SIZE 0x0700
#define T_SIZE 0x0800
#define P_SIZE 0x0900
// branch hint attribute
#define BRANCH_HINT 0x1000
struct x86_insn
{
public:
x86_insn(bx_bool is32, bx_bool is64);
bx_bool is_seg_override() const {
return (seg_override != NO_SEG_OVERRIDE);
}
public:
bx_bool is_32, is_64;
bx_bool as_32, as_64;
bx_bool os_32, os_64;
Bit8u extend8b;
Bit8u rex_r, rex_x, rex_b;
Bit8u seg_override;
unsigned b1, prefixes;
unsigned ilen;
Bit8u modrm, mod, nnn, rm;
Bit8u sib, scale, index, base;
union {
Bit16u displ16;
Bit32u displ32;
} displacement;
};
BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
{
is_32 = is32;
is_64 = is64;
if (is_64) {
os_64 = 0;
as_64 = 1;
os_32 = 1;
as_32 = 1;
}
else {
os_64 = 0;
as_64 = 0;
os_32 = is_32;
as_32 = is_32;
}
extend8b = 0;
rex_r = rex_b = rex_x = 0;
seg_override = NO_SEG_OVERRIDE;
prefixes = 0;
ilen = 0;
b1 = 0;
modrm = mod = nnn = rm = 0;
sib = scale = index = base = 0;
displacement.displ32 = 0;
}
class disassembler {
public:
disassembler() { set_syntax_intel(); }
unsigned disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf);
unsigned disasm16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return disasm(0, 0, base, ip, instr, disbuf); }
unsigned disasm32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return disasm(1, 0, base, ip, instr, disbuf); }
unsigned disasm64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return disasm(1, 1, base, ip, instr, disbuf); }
x86_insn decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf);
x86_insn decode16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return decode(0, 0, base, ip, instr, disbuf); }
x86_insn decode32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return decode(1, 0, base, ip, instr, disbuf); }
x86_insn decode64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return decode(1, 1, base, ip, instr, disbuf); }
void set_syntax_intel();
void set_syntax_att ();
void toggle_syntax_mode();
private:
bx_bool intel_mode;
const char **general_16bit_regname;
const char **general_8bit_regname;
const char **general_32bit_regname;
const char **general_8bit_regname_rex;
const char **general_64bit_regname;
const char **segment_name;
const char **index16;
const char *sreg_mod01or10_rm32[8];
const char *sreg_mod00_base32[8];
const char *sreg_mod01or10_base32[8];
const char *sreg_mod00_rm16[8];
const char *sreg_mod01or10_rm16[8];
private:
bx_address db_eip, db_base;
const Bit8u *instruction; // for fetching of next byte of instruction
char *disbufptr;
BxDisasmResolveModrmPtr_t resolve_modrm;
BX_CPP_INLINE Bit8u fetch_byte() {
db_eip++;
return(*instruction++);
};
BX_CPP_INLINE Bit8u peek_byte() {
return(*instruction);
};
BX_CPP_INLINE Bit16u fetch_word() {
Bit8u b0 = * (Bit8u *) instruction++;
Bit8u b1 = * (Bit8u *) instruction++;
Bit16u ret16 = (b1<<8) | b0;
db_eip += 2;
return(ret16);
};
BX_CPP_INLINE Bit32u fetch_dword() {
Bit8u b0 = * (Bit8u *) instruction++;
Bit8u b1 = * (Bit8u *) instruction++;
Bit8u b2 = * (Bit8u *) instruction++;
Bit8u b3 = * (Bit8u *) instruction++;
Bit32u ret32 = (b3<<24) | (b2<<16) | (b1<<8) | b0;
db_eip += 4;
return(ret32);
};
BX_CPP_INLINE Bit64u fetch_qword() {
Bit64u d0 = fetch_dword();
Bit64u d1 = fetch_dword();
Bit64u ret64 = (d1<<32) | d0;
return(ret64);
};
void dis_putc(char symbol);
void dis_sprintf(const char *fmt, ...);
void decode_modrm(x86_insn *insn);
void resolve16_mod0 (const x86_insn *insn, unsigned mode);
void resolve16_mod1or2(const x86_insn *insn, unsigned mode);
void resolve32_mod0 (const x86_insn *insn, unsigned mode);
void resolve32_mod1or2(const x86_insn *insn, unsigned mode);
void resolve32_mod0_rm4 (const x86_insn *insn, unsigned mode);
void resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode);
void resolve64_mod0 (const x86_insn *insn, unsigned mode);
void resolve64_mod1or2(const x86_insn *insn, unsigned mode);
void resolve64_mod0_rm4 (const x86_insn *insn, unsigned mode);
void resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode);
void initialize_modrm_segregs();
void print_datasize (unsigned mode);
void print_memory_access16(int datasize,
const char *seg, const char *index, Bit16u disp);
void print_memory_access (int datasize,
const char *seg, const char *base, const char *index, int scale, Bit32u disp);
void print_disassembly_intel(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
void print_disassembly_att (const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
public:
/*
* Codes for Addressing Method:
* ---------------------------
* A - Direct address. The instruction has no ModR/M byte; the address
* of the operand is encoded in the instruction; and no base register,
* index register, or scaling factor can be applied.
* C - The reg field of the ModR/M byte selects a control register.
* D - The reg field of the ModR/M byte selects a debug register.
* E - A ModR/M byte follows the opcode and specifies the operand. The
* operand is either a general-purpose register or a memory address.
* If it is a memory address, the address is computed from a segment
* register and any of the following values: a base register, an
* index register, a scaling factor, a displacement.
* F - Flags Register.
* G - The reg field of the ModR/M byte selects a general register.
* I - Immediate data. The operand value is encoded in subsequent bytes of
* the instruction.
* J - The instruction contains a relative offset to be added to the
* instruction pointer register.
* M - The ModR/M byte may refer only to memory.
* N - The R/M field of the ModR/M byte selects a packed-quadword MMX
technology register.
* O - The instruction has no ModR/M byte; the offset of the operand is
* coded as a word or double word (depending on address size attribute)
* in the instruction. No base register, index register, or scaling
* factor can be applied.
* P - The reg field of the ModR/M byte selects a packed quadword MMX
* technology register.
* Q - A ModR/M byte follows the opcode and specifies the operand. The
* operand is either an MMX technology register or a memory address.
* If it is a memory address, the address is computed from a segment
* register and any of the following values: a base register, an
* index register, a scaling factor, and a displacement.
* R - The mod field of the ModR/M byte may refer only to a general register.
* S - The reg field of the ModR/M byte selects a segment register.
* U - The R/M field of the ModR/M byte selects a 128-bit XMM register.
* T - The reg field of the ModR/M byte selects a test register.
* V - The reg field of the ModR/M byte selects a 128-bit XMM register.
* W - A ModR/M byte follows the opcode and specifies the operand. The
* operand is either a 128-bit XMM register or a memory address. If
* it is a memory address, the address is computed from a segment
* register and any of the following values: a base register, an
* index register, a scaling factor, and a displacement.
* X - Memory addressed by the DS:rSI register pair.
* Y - Memory addressed by the ES:rDI register pair.
*/
/*
* Codes for Operand Type:
* ----------------------
* a - Two one-word operands in memory or two double-word operands in
* memory, depending on operand-size attribute (used only by the BOUND
* instruction).
* b - Byte, regardless of operand-size attribute.
* d - Doubleword, regardless of operand-size attribute.
* dq - Double-quadword, regardless of operand-size attribute.
* p - 32-bit or 48-bit pointer, depending on operand-size attribute.
* pd - 128-bit packed double-precision floating-point data.
* pi - Quadword MMX technology register (packed integer)
* ps - 128-bit packed single-precision floating-point data.
* q - Quadword, regardless of operand-size attribute.
* s - 6-byte or 10-byte pseudo-descriptor.
* si - Doubleword integer register (scalar integer)
* ss - Scalar element of a 128-bit packed single-precision floating data.
* sd - Scalar element of a 128-bit packed double-precision floating data.
* v - Word, doubleword or quadword, depending on operand-size attribute.
* w - Word, regardless of operand-size attr.
*/
// far call/jmp
void Apw(const x86_insn *insn);
void Apd(const x86_insn *insn);
// 8-bit general purpose registers
void AL(const x86_insn *insn);
void CL(const x86_insn *insn);
// 16-bit general purpose registers
void AX(const x86_insn *insn);
void DX(const x86_insn *insn);
// 32-bit general purpose registers
void EAX(const x86_insn *insn);
// 64-bit general purpose registers
void RAX(const x86_insn *insn);
// segment registers
void CS(const x86_insn *insn);
void DS(const x86_insn *insn);
void ES(const x86_insn *insn);
void SS(const x86_insn *insn);
void FS(const x86_insn *insn);
void GS(const x86_insn *insn);
// segment registers
void Sw(const x86_insn *insn);
// test registers
void Td(const x86_insn *insn);
// control register
void Cd(const x86_insn *insn);
void Cq(const x86_insn *insn);
// debug register
void Dd(const x86_insn *insn);
void Dq(const x86_insn *insn);
// 8-bit general purpose register
void R8(const x86_insn *insn);
// 16-bit general purpose register
void RX(const x86_insn *insn);
// 32-bit general purpose register
void ERX(const x86_insn *insn);
// 64-bit general purpose register
void RRX(const x86_insn *insn);
// general purpose register or memory operand
void Eb(const x86_insn *insn);
void Ew(const x86_insn *insn);
void Ed(const x86_insn *insn);
void Eq(const x86_insn *insn);
// general purpose register
void Gb(const x86_insn *insn);
void Gw(const x86_insn *insn);
void Gd(const x86_insn *insn);
void Gq(const x86_insn *insn);
// immediate
void I1(const x86_insn *insn);
void Ib(const x86_insn *insn);
void Iw(const x86_insn *insn);
void Id(const x86_insn *insn);
void Iq(const x86_insn *insn);
// two immediates Iw/Ib
void IwIb(const x86_insn *insn);
// sign extended immediate
void sIbw(const x86_insn *insn);
void sIbd(const x86_insn *insn);
void sIbq(const x86_insn *insn);
void sIdq(const x86_insn *insn);
// floating point
void ST0(const x86_insn *insn);
void STi(const x86_insn *insn);
// general purpose register
void Rw(const x86_insn *insn);
void Rd(const x86_insn *insn);
void Rq(const x86_insn *insn);
// mmx register
void Pq(const x86_insn *insn);
// mmx register or memory operand
void Qd(const x86_insn *insn);
void Qq(const x86_insn *insn);
void Vq(const x86_insn *insn);
void Nq(const x86_insn *insn);
// xmm register
void Udq(const x86_insn *insn);
void Vdq(const x86_insn *insn);
void Vss(const x86_insn *insn);
void Vsd(const x86_insn *insn);
void Vps(const x86_insn *insn);
void Vpd(const x86_insn *insn);
// xmm register or memory operand
void Wq(const x86_insn *insn);
void Wdq(const x86_insn *insn);
void Wss(const x86_insn *insn);
void Wsd(const x86_insn *insn);
void Wps(const x86_insn *insn);
void Wpd(const x86_insn *insn);
// direct memory access
void OP_O(const x86_insn *insn, unsigned size);
void Ob(const x86_insn *insn);
void Ow(const x86_insn *insn);
void Od(const x86_insn *insn);
void Oq(const x86_insn *insn);
// memory operand
void OP_M(const x86_insn *insn, unsigned size);
void Ma(const x86_insn *insn);
void Mp(const x86_insn *insn);
void Ms(const x86_insn *insn);
void Mx(const x86_insn *insn);
void Mb(const x86_insn *insn);
void Mw(const x86_insn *insn);
void Md(const x86_insn *insn);
void Mq(const x86_insn *insn);
void Mt(const x86_insn *insn);
void Mdq(const x86_insn *insn);
void Mps(const x86_insn *insn);
void Mpd(const x86_insn *insn);
// string instructions
void OP_X(const x86_insn *insn, unsigned size);
void Xb(const x86_insn *insn);
void Xw(const x86_insn *insn);
void Xd(const x86_insn *insn);
void Xq(const x86_insn *insn);
// string instructions
void OP_Y(const x86_insn *insn, unsigned size);
void Yb(const x86_insn *insn);
void Yw(const x86_insn *insn);
void Yd(const x86_insn *insn);
void Yq(const x86_insn *insn);
// jump offset
void Jb(const x86_insn *insn);
void Jw(const x86_insn *insn);
void Jd(const x86_insn *insn);
};
#endif

1230
Externals/Bochs_disasm/opcodes.inl vendored Normal file

File diff suppressed because it is too large Load Diff

460
Externals/Bochs_disasm/resolve.cpp vendored Normal file
View File

@ -0,0 +1,460 @@
/////////////////////////////////////////////////////////////////////////
// $Id: resolve.cc,v 1.13 2006/08/11 17:22:43 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <assert.h>
#include "disasm.h"
void disassembler::decode_modrm(x86_insn *insn)
{
insn->modrm = fetch_byte();
BX_DECODE_MODRM(insn->modrm, insn->mod, insn->nnn, insn->rm);
// MOVs with CRx and DRx always use register ops and ignore the mod field.
if ((insn->b1 & ~3) == 0x120) insn->mod = 3;
insn->nnn |= insn->rex_r;
if (insn->mod == 3) {
/* mod, reg, reg */
insn->rm |= insn->rex_b;
return;
}
if (insn->as_64)
{
if (insn->rm != 4) { /* rm != 100b, no s-i-b byte */
insn->rm |= insn->rex_b;
// one byte modrm
switch (insn->mod) {
case 0:
resolve_modrm = &disassembler::resolve64_mod0;
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
insn->displacement.displ32 = fetch_dword();
break;
case 1:
/* reg, 8-bit displacement, sign extend */
resolve_modrm = &disassembler::resolve64_mod1or2;
insn->displacement.displ32 = (Bit8s) fetch_byte();
break;
case 2:
/* reg, 32-bit displacement */
resolve_modrm = &disassembler::resolve64_mod1or2;
insn->displacement.displ32 = fetch_dword();
break;
} /* switch (mod) */
} /* if (rm != 4) */
else { /* rm == 4, s-i-b byte follows */
insn->sib = fetch_byte();
BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
insn->base |= insn->rex_b;
insn->index |= insn->rex_x;
switch (insn->mod) {
case 0:
resolve_modrm = &disassembler::resolve64_mod0_rm4;
if ((insn->base & 7) == 5)
insn->displacement.displ32 = fetch_dword();
break;
case 1:
resolve_modrm = &disassembler::resolve64_mod1or2_rm4;
insn->displacement.displ32 = (Bit8s) fetch_byte();
break;
case 2:
resolve_modrm = &disassembler::resolve64_mod1or2_rm4;
insn->displacement.displ32 = fetch_dword();
break;
}
} /* s-i-b byte follows */
}
else
{
if (insn->as_32)
{
if (insn->rm != 4) { /* rm != 100b, no s-i-b byte */
insn->rm |= insn->rex_b;
// one byte modrm
switch (insn->mod) {
case 0:
resolve_modrm = &disassembler::resolve32_mod0;
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
insn->displacement.displ32 = fetch_dword();
break;
case 1:
/* reg, 8-bit displacement, sign extend */
resolve_modrm = &disassembler::resolve32_mod1or2;
insn->displacement.displ32 = (Bit8s) fetch_byte();
break;
case 2:
/* reg, 32-bit displacement */
resolve_modrm = &disassembler::resolve32_mod1or2;
insn->displacement.displ32 = fetch_dword();
break;
} /* switch (mod) */
} /* if (rm != 4) */
else { /* rm == 4, s-i-b byte follows */
insn->sib = fetch_byte();
BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
insn->base |= insn->rex_b;
insn->index |= insn->rex_x;
switch (insn->mod) {
case 0:
resolve_modrm = &disassembler::resolve32_mod0_rm4;
if ((insn->base & 7) == 5)
insn->displacement.displ32 = fetch_dword();
break;
case 1:
resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
insn->displacement.displ32 = (Bit8s) fetch_byte();
break;
case 2:
resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
insn->displacement.displ32 = fetch_dword();
break;
}
} /* s-i-b byte follows */
}
else {
assert(insn->rex_b == 0);
assert(insn->rex_x == 0);
assert(insn->rex_r == 0);
/* 16 bit addressing modes. */
switch (insn->mod) {
case 0:
resolve_modrm = &disassembler::resolve16_mod0;
if(insn->rm == 6)
insn->displacement.displ16 = fetch_word();
break;
case 1:
/* reg, 8-bit displacement, sign extend */
resolve_modrm = &disassembler::resolve16_mod1or2;
insn->displacement.displ16 = (Bit8s) fetch_byte();
break;
case 2:
resolve_modrm = &disassembler::resolve16_mod1or2;
insn->displacement.displ16 = fetch_word();
break;
} /* switch (mod) ... */
}
}
}
void disassembler::resolve16_mod0(const x86_insn *insn, unsigned mode)
{
const char *seg;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = sreg_mod00_rm16[insn->rm];
if(insn->rm == 6)
print_memory_access16(mode, seg, NULL, insn->displacement.displ16);
else
print_memory_access16(mode, seg, index16[insn->rm], 0);
}
void disassembler::resolve16_mod1or2(const x86_insn *insn, unsigned mode)
{
const char *seg;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = sreg_mod01or10_rm16[insn->rm];
print_memory_access16(mode, seg, index16[insn->rm], insn->displacement.displ16);
}
void disassembler::resolve32_mod0(const x86_insn *insn, unsigned mode)
{
const char *seg;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = segment_name[DS_REG];
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
print_memory_access(mode, seg, NULL, NULL, 0, insn->displacement.displ32);
else
print_memory_access(mode, seg, general_32bit_regname[insn->rm], NULL, 0, 0);
}
void disassembler::resolve32_mod1or2(const x86_insn *insn, unsigned mode)
{
const char *seg;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = sreg_mod01or10_rm32[insn->rm];
print_memory_access(mode, seg,
general_32bit_regname[insn->rm], NULL, 0, insn->displacement.displ32);
}
void disassembler::resolve32_mod0_rm4(const x86_insn *insn, unsigned mode)
{
const char *seg, *base = NULL, *index = NULL;
Bit32u disp32 = 0;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = sreg_mod00_base32[insn->base];
if ((insn->base & 7) != 5)
base = general_32bit_regname[insn->base];
else
disp32 = insn->displacement.displ32;
if (insn->index != 4)
index = general_32bit_regname[insn->index];
print_memory_access(mode, seg, base, index, insn->scale, disp32);
}
void disassembler::resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode)
{
const char *seg, *index = NULL;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = sreg_mod01or10_base32[insn->base];
if (insn->index != 4)
index = general_32bit_regname[insn->index];
print_memory_access(mode, seg,
general_32bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
}
void disassembler::resolve64_mod0(const x86_insn *insn, unsigned mode)
{
const char *seg, *rip_regname;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = segment_name[DS_REG];
if (intel_mode) rip_regname = "rip";
else rip_regname = "%rip";
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
print_memory_access(mode, seg, rip_regname, NULL, 0, insn->displacement.displ32);
else
print_memory_access(mode, seg, general_64bit_regname[insn->rm], NULL, 0, 0);
}
void disassembler::resolve64_mod1or2(const x86_insn *insn, unsigned mode)
{
const char *seg;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = sreg_mod01or10_rm32[insn->rm];
print_memory_access(mode, seg,
general_64bit_regname[insn->rm], NULL, 0, insn->displacement.displ32);
}
void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned mode)
{
const char *seg, *base = NULL, *index = NULL;
Bit32u disp32 = 0;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = sreg_mod00_base32[insn->base];
if ((insn->base & 7) != 5)
base = general_64bit_regname[insn->base];
else
disp32 = insn->displacement.displ32;
if (insn->index != 4)
index = general_64bit_regname[insn->index];
print_memory_access(mode, seg, base, index, insn->scale, disp32);
}
void disassembler::resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode)
{
const char *seg, *index = NULL;
if (insn->is_seg_override())
seg = segment_name[insn->seg_override];
else
seg = sreg_mod01or10_base32[insn->base];
if (insn->index != 4)
index = general_64bit_regname[insn->index];
print_memory_access(mode, seg,
general_64bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
}
void disassembler::print_datasize(unsigned size)
{
if (!intel_mode) return;
switch(size)
{
case B_SIZE:
dis_sprintf("byte ptr ");
break;
case W_SIZE:
dis_sprintf("word ptr ");
break;
case D_SIZE:
dis_sprintf("dword ptr ");
break;
case Q_SIZE:
dis_sprintf("qword ptr ");
break;
case O_SIZE:
dis_sprintf("dqword ptr ");
break;
case T_SIZE:
dis_sprintf("tbyte ptr ");
break;
case P_SIZE:
break;
case X_SIZE:
break;
};
}
void disassembler::print_memory_access16(int datasize,
const char *seg, const char *index, Bit16u disp)
{
print_datasize(datasize);
if (intel_mode)
{
if (index == NULL)
{
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
}
else
{
if (disp != 0)
dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp);
else
dis_sprintf("%s:[%s]", seg, index);
}
}
else
{
if (index == NULL)
{
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
}
else
{
if (disp != 0)
dis_sprintf("%s:0x%x(%s,1)", seg, (unsigned) disp, index);
else
dis_sprintf("%s:(%s,1)", seg, index);
}
}
}
void disassembler::print_memory_access(int datasize,
const char *seg, const char *base, const char *index, int scale, Bit32u disp)
{
print_datasize(datasize);
if (intel_mode)
{
if (base == NULL)
{
if (index == NULL)
{
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
}
else
{
if (scale != 0)
{
if (disp != 0)
dis_sprintf("%s:[%s*%d+0x%x]", seg, index, 1<<scale, (unsigned) disp);
else
dis_sprintf("%s:[%s*%d]", seg, index, 1<<scale);
}
else
{
if (disp != 0)
dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp);
else
dis_sprintf("%s:[%s]", seg, index);
}
}
}
else
{
if (index == NULL)
{
if (disp != 0)
dis_sprintf("%s:[%s+0x%x]", seg, base, (unsigned) disp);
else
dis_sprintf("%s:[%s]", seg, base);
}
else
{
if (scale != 0)
{
if (disp != 0)
dis_sprintf("%s:[%s+%s*%d+0x%x]", seg, base, index, 1<<scale, (unsigned) disp);
else
dis_sprintf("%s:[%s+%s*%d]", seg, base, index, 1<<scale);
}
else
{
if (disp != 0)
dis_sprintf("%s:[%s+%s+0x%x]", seg, base, index, (unsigned) disp);
else
dis_sprintf("%s:[%s+%s]", seg, base, index);
}
}
}
}
else
{
if (base == NULL)
{
if (index == NULL)
{
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
}
else
{
if (disp != 0)
dis_sprintf("%s:0x%x(,%s,%d)", seg, (unsigned) disp, index, 1<<scale);
else
dis_sprintf("%s:(,%s,%d)", seg, index, 1<<scale);
}
}
else
{
if (index == NULL)
{
if (disp != 0)
dis_sprintf("%s:0x%x(%s)", seg, (unsigned) disp, base);
else
dis_sprintf("%s:(%s)", seg, base);
}
else
{
if (disp != 0)
dis_sprintf("%s:0x%x(%s,%s,%d)", seg, (unsigned) disp, base, index, 1<<scale);
else
dis_sprintf("%s:(%s,%s,%d)", seg, base, index, 1<<scale);
}
}
}
}

8
Externals/Bochs_disasm/stdafx.cpp vendored Normal file
View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// Bochs_disasm.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

18
Externals/Bochs_disasm/stdafx.h vendored Normal file
View File

@ -0,0 +1,18 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE 1
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
// TODO: reference additional headers your program requires here

254
Externals/Bochs_disasm/syntax.cpp vendored Normal file
View File

@ -0,0 +1,254 @@
/////////////////////////////////////////////////////////////////////////
// $Id: syntax.cc,v 1.10 2006/04/27 15:11:45 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "disasm.h"
//////////////////
// Intel STYLE
//////////////////
#define BX_DISASM_SUPPORT_X86_64
#ifdef BX_DISASM_SUPPORT_X86_64
static const char *intel_general_16bit_regname[16] = {
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
};
static const char *intel_general_32bit_regname[16] = {
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
};
static const char *intel_general_64bit_regname[16] = {
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
};
static const char *intel_general_8bit_regname_rex[16] = {
"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
};
#else
static const char *intel_general_16bit_regname[8] = {
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
};
static const char *intel_general_32bit_regname[8] = {
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
};
#endif
static const char *intel_general_8bit_regname[8] = {
"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
};
static const char *intel_segment_name[8] = {
"es", "cs", "ss", "ds", "fs", "gs", "??", "??"
};
static const char *intel_index16[8] = {
"bx+si",
"bx+di",
"bp+si",
"bp+di",
"si",
"di",
"bp",
"bx"
};
//////////////////
// AT&T STYLE
//////////////////
#ifdef BX_DISASM_SUPPORT_X86_64
static const char *att_general_16bit_regname[16] = {
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
};
static const char *att_general_32bit_regname[16] = {
"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
};
static const char *att_general_64bit_regname[16] = {
"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
};
static const char *att_general_8bit_regname_rex[16] = {
"%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
};
#else
static const char *att_general_16bit_regname[8] = {
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di"
};
static const char *att_general_32bit_regname[8] = {
"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
};
#endif
static const char *att_general_8bit_regname[8] = {
"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh"
};
static const char *att_segment_name[8] = {
"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%??", "%??"
};
static const char *att_index16[8] = {
"%bx, %si",
"%bx, %di",
"%bp, %si",
"%bp, %di",
"%si",
"%di",
"%bp",
"%bx"
};
#define NULL_SEGMENT_REGISTER 7
void disassembler::initialize_modrm_segregs()
{
sreg_mod00_rm16[0] = segment_name[DS_REG];
sreg_mod00_rm16[1] = segment_name[DS_REG];
sreg_mod00_rm16[2] = segment_name[SS_REG];
sreg_mod00_rm16[3] = segment_name[SS_REG];
sreg_mod00_rm16[4] = segment_name[DS_REG];
sreg_mod00_rm16[5] = segment_name[DS_REG];
sreg_mod00_rm16[6] = segment_name[DS_REG];
sreg_mod00_rm16[7] = segment_name[DS_REG];
sreg_mod01or10_rm16[0] = segment_name[DS_REG];
sreg_mod01or10_rm16[1] = segment_name[DS_REG];
sreg_mod01or10_rm16[2] = segment_name[SS_REG];
sreg_mod01or10_rm16[3] = segment_name[SS_REG];
sreg_mod01or10_rm16[4] = segment_name[DS_REG];
sreg_mod01or10_rm16[5] = segment_name[DS_REG];
sreg_mod01or10_rm16[6] = segment_name[SS_REG];
sreg_mod01or10_rm16[7] = segment_name[DS_REG];
sreg_mod01or10_rm32[0] = segment_name[DS_REG];
sreg_mod01or10_rm32[1] = segment_name[DS_REG];
sreg_mod01or10_rm32[2] = segment_name[DS_REG];
sreg_mod01or10_rm32[3] = segment_name[DS_REG];
sreg_mod01or10_rm32[4] = segment_name[NULL_SEGMENT_REGISTER];
sreg_mod01or10_rm32[5] = segment_name[SS_REG];
sreg_mod01or10_rm32[6] = segment_name[DS_REG];
sreg_mod01or10_rm32[7] = segment_name[DS_REG];
sreg_mod00_base32[0] = segment_name[DS_REG];
sreg_mod00_base32[1] = segment_name[DS_REG];
sreg_mod00_base32[2] = segment_name[DS_REG];
sreg_mod00_base32[3] = segment_name[DS_REG];
sreg_mod00_base32[4] = segment_name[SS_REG];
sreg_mod00_base32[5] = segment_name[DS_REG];
sreg_mod00_base32[6] = segment_name[DS_REG];
sreg_mod00_base32[7] = segment_name[DS_REG];
sreg_mod01or10_base32[0] = segment_name[DS_REG];
sreg_mod01or10_base32[1] = segment_name[DS_REG];
sreg_mod01or10_base32[2] = segment_name[DS_REG];
sreg_mod01or10_base32[3] = segment_name[DS_REG];
sreg_mod01or10_base32[4] = segment_name[SS_REG];
sreg_mod01or10_base32[5] = segment_name[SS_REG];
sreg_mod01or10_base32[6] = segment_name[DS_REG];
sreg_mod01or10_base32[7] = segment_name[DS_REG];
}
//////////////////
// Intel STYLE
//////////////////
void disassembler::set_syntax_intel()
{
intel_mode = 1;
general_16bit_regname = intel_general_16bit_regname;
general_8bit_regname = intel_general_8bit_regname;
general_32bit_regname = intel_general_32bit_regname;
general_8bit_regname_rex = intel_general_8bit_regname_rex;
general_64bit_regname = intel_general_64bit_regname;
segment_name = intel_segment_name;
index16 = intel_index16;
initialize_modrm_segregs();
}
void disassembler::print_disassembly_intel(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry)
{
// print opcode
dis_sprintf("%s ", entry->IntelOpcode);
if (entry->Operand1) {
(this->*entry->Operand1)(insn);
}
if (entry->Operand2) {
dis_sprintf(", ");
(this->*entry->Operand2)(insn);
}
if (entry->Operand3) {
dis_sprintf(", ");
(this->*entry->Operand3)(insn);
}
}
//////////////////
// AT&T STYLE
//////////////////
void disassembler::set_syntax_att()
{
intel_mode = 0;
general_16bit_regname = att_general_16bit_regname;
general_8bit_regname = att_general_8bit_regname;
general_32bit_regname = att_general_32bit_regname;
general_8bit_regname_rex = att_general_8bit_regname_rex;
general_64bit_regname = att_general_64bit_regname;
segment_name = att_segment_name;
index16 = att_index16;
initialize_modrm_segregs();
}
void disassembler::toggle_syntax_mode()
{
if (intel_mode) set_syntax_att();
else set_syntax_intel();
}
void disassembler::print_disassembly_att(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry)
{
// print opcode
dis_sprintf("%s ", entry->AttOpcode);
if (entry->Operand3) {
(this->*entry->Operand3)(insn);
dis_sprintf(", ");
}
if (entry->Operand2) {
(this->*entry->Operand2)(insn);
dis_sprintf(", ");
}
if (entry->Operand1) {
(this->*entry->Operand1)(insn);
}
}