#include <x86dasm.h>
Public Methods | |
InstructionDecoder (const RelocationInfos &r) | |
int | Decode (Instruction &instruction, ObjectModule::DataReader &reader) |
Protected Attributes | |
const RelocationInfos & | reloc |
ObjectModule::DataReader * | reader |
Private Types | |
typedef int(* | DecodeProc )(InstructionDecoder *, uchar, int, Instruction &) |
Private Methods | |
void | CheckTables () |
bool | get_checkc (uint32_t *offset) |
uint32_t | ReadVar (int flag) |
bool | getv_rel (Param ¶m, int flag) |
int | do_sib (uchar *base, Param ¶m) |
int | mod0 (int sib_offset, uchar r_m, bool *size_known, Param ¶m) |
int | mod1 (int sib_offset, uchar r_m, Param ¶m) |
int | mod2 (int sib_offset, uchar r_m, bool *size_known, Param ¶m) |
int | do_mod_rm (uchar mod, uchar r_m, int reg_size, Param::MemoryTypes memType, bool size_needed, Param ¶m) |
int | check_forward (const InstTable *inst_table, Instruction &instruction) |
int | mod_reg2 (uchar opcode, int special, int mod_reg, Instruction &instruction) |
INSTPROCDECL (stub) | |
INSTPROCDECL (unimpl) | |
INSTPROCDECL (conv_byte) | |
INSTPROCDECL (one_byte) | |
INSTPROCDECL (two_byte) | |
INSTPROCDECL (two_sbyte) | |
INSTPROCDECL (three_byte) | |
INSTPROCDECL (five_byte) | |
INSTPROCDECL (one_a) | |
INSTPROCDECL (two_a) | |
INSTPROCDECL (three_a) | |
INSTPROCDECL (in_out) | |
INSTPROCDECL (string_byte) | |
INSTPROCDECL (enter) | |
INSTPROCDECL (two_bcd) | |
INSTPROCDECL (disp8) | |
INSTPROCDECL (disp16) | |
INSTPROCDECL (wait) | |
INSTPROCDECL (prefix) | |
INSTPROCDECL (prefixf3) | |
INSTPROCDECL (seg_over) | |
INSTPROCDECL (opsize_over) | |
INSTPROCDECL (adrsize_over) | |
INSTPROCDECL (mod_reg) | |
INSTPROCDECL (mod_xmm) | |
INSTPROCDECL (mod_reg_p3) | |
INSTPROCDECL (seg_reg) | |
INSTPROCDECL (group1) | |
INSTPROCDECL (group2) | |
INSTPROCDECL (group3) | |
INSTPROCDECL (group4) | |
INSTPROCDECL (group5) | |
INSTPROCDECL (group6) | |
INSTPROCDECL (group7) | |
INSTPROCDECL (group8) | |
INSTPROCDECL (group9) | |
INSTPROCDECL (groupA) | |
INSTPROCDECL (group15) | |
INSTPROCDECL (group16) | |
INSTPROCDECL (mov_special) | |
INSTPROCDECL (mov_creg) | |
INSTPROCDECL (esc) | |
INSTPROCDECL (extra) | |
INSTPROCDECL (one_byte_k63d) | |
INSTPROCDECL (k6_3dnow) | |
INSTPROCDECL (prefetch_k63d) | |
Static Private Attributes | |
const InstTable | instrTable [] |
const InstTable | exInstrTable [] |
|
|
|
Definition at line 56 of file x86dasm.h.
00056 : 00057 reloc(r),reader(NULL) 00058 {}; int Decode(Instruction& instruction,ObjectModule::DataReader& reader); |
|
Definition at line 1963 of file x86dasm.cpp. References byte, get_checkc(), InstructionDecoder::InstTable::instruction, Instruction::instruction, InstructionDecoder::InstTable::rtn, and uchar.
01964 { 01965 uint32_t byte; 01966 int data; 01967 int valid; 01968 01969 // !!! too different ?? 01970 // the next byte must be a valid instruction 01971 if ( get_checkc( &byte ) ) 01972 return 0; 01973 data = (uchar)byte; 01974 01975 instruction.instruction = inst_table[data].instruction; 01976 valid = inst_table[data].rtn( 01977 this, 01978 (uchar)data, 01979 inst_table[data].special, 01980 instruction ); 01981 01982 return valid; 01983 } |
|
Definition at line 576 of file x86table.cpp. References COMPILE_CHECK, exInstrTable, and instrTable.
00577 { 00578 // produce a warning on some compiler, ignore it 00579 COMPILE_CHECK(instrLenCheck, 00580 (sizeof(InstructionDecoder::instrTable) == (sizeof(InstructionDecoder::instrTable[0])*256)) 00581 && (sizeof(InstructionDecoder::exInstrTable) == (sizeof(InstructionDecoder::exInstrTable[0])*256)) 00582 ); 00583 } |
|
Definition at line 2000 of file x86dasm.cpp. References _PRG_ASSERT, addr_bytes, addr_large, Instruction::Args, get_checkc(), Param::GetMemSize(), instrTable, InstructionDecoder::InstTable::instruction, Instruction::instruction, Instruction::numArg, over_seg, Param::relocation, InstructionDecoder::InstTable::rtn, size_bytes, size_large, Param::t_memory, Param::type, and uchar. Referenced by GetInstruction(), CodeParser::ScanCode(), and CodeParser::WriteCode().
02001 { 02002 this->reader = &reader; 02003 #ifdef DEBUG 02004 // marca istruzione con valori invalidi 02005 instruction.instruction = num_instructions; 02006 instruction.numArg = 20; 02007 // testa valori 02008 for(int i = 0; i<3; ++i) 02009 { 02010 _PRG_ASSERT(instruction.Args[i].relocation == NULL); 02011 instruction.Args[i].InitInvalid(); 02012 } 02013 #endif 02014 try 02015 { 02016 int result; 02017 uint32_t c; 02018 if ( get_checkc( &c ) ) 02019 return 0; 02020 instruction.instruction = instrTable[c].instruction; 02021 result = 02022 instrTable[c].rtn( this, (uchar)c,instrTable[c].special,instruction); 02023 #ifdef DEBUG 02024 // testa valori 02025 if (result != 0 ) 02026 { 02027 _PRG_ASSERT(instruction.instruction>=0); 02028 _PRG_ASSERT(instruction.instruction<num_instructions); 02029 _PRG_ASSERT(instruction.numArg != 20); 02030 for(int i = 0; i<instruction.numArg; ++i) 02031 { 02032 instruction.Args[i].CheckValid(); 02033 if ( instruction.Args[i].type == Param::t_memory ) 02034 { 02035 if (instruction.instruction != istr_lea && instruction.instruction != istr_invlpg) 02036 _PRG_ASSERT(instruction.Args[i].GetMemSize() != 0); 02037 } 02038 } 02039 } 02040 #endif 02041 return result; 02042 } 02043 catch(const ObjectModule::OutOfAddress&) 02044 { 02045 /* reset to default */ 02046 over_seg = -1; 02047 if (over_opsize) 02048 { 02049 size_large = !size_large; 02050 size_bytes = 6 - size_bytes; 02051 } 02052 if (over_adrsize) 02053 { 02054 addr_large = !addr_large; 02055 addr_bytes = 6 - addr_bytes; 02056 } 02057 return 0; 02058 } 02059 } |
|
Definition at line 961 of file x86dasm.cpp. References _PRG_ASSERT, do_sib(), Param::factor, Param::mem_reg2, Param::MemoryTypes, mod0(), mod1(), mod2(), mod3(), null_reg, Param::SetMemType(), and uchar. Referenced by mod_reg2().
00962 { 00963 bool size_known; 00964 int sib_offset; 00965 int result; 00966 00967 _PRG_ASSERT(reg_size != 3 || mmx); 00968 _PRG_ASSERT(reg_size != 4 || xmm); 00969 00970 if (mod == 3) // registry case 00971 { 00972 return mod3( r_m, reg_size, param ); 00973 } 00974 00975 size_known = false; 00976 00977 sib_offset = 0; 00978 00979 if ( addr_large ) 00980 { 00981 // set default value for sib 00982 param.mem_reg2 = null_reg; 00983 param.factor = 1; 00984 if ( r_m == 4 && mod != 3 ) { 00985 /* Get result and new r_m */ 00986 sib_offset = do_sib( &r_m, param ); 00987 if ( sib_offset == -1 ) { 00988 return( -1 ); 00989 } 00990 } 00991 } 00992 switch( mod ) { 00993 case 0: result = mod0( sib_offset, r_m, &size_known, param ); 00994 break; 00995 case 1: result = mod1( sib_offset, r_m, param ); 00996 size_known = true; 00997 break; 00998 default: 00999 // no warning and a bit optimized 01000 _PRG_ASSERT(0); 01001 case 2: result = mod2( sib_offset, r_m, &size_known, param ); 01002 break; 01003 } 01004 01005 if ( result != -1 ) { 01006 /* 01007 ** If the size is already known, then we don't need 'xxxx' ptr text 01008 */ 01009 // if ( !size_known || size_needed ) 01010 { 01011 param.SetMemType( memType, size_needed ); 01012 } 01013 } 01014 return( result ); 01015 } |
|
Definition at line 858 of file x86dasm.cpp. References Param::factor, get_checkc(), GETREGS, Param::mem_reg2, ss, and uchar. Referenced by do_mod_rm().
00859 { 00860 uint32_t sib_byte; 00861 int ss; 00862 int idx; 00863 00864 if ( get_checkc ( &sib_byte ) ) 00865 return( -1 ); 00866 ss = (int)(sib_byte & 0xC0L) >> 6; 00867 idx = (int)(sib_byte & 0x38L) >> 3; 00868 *base = (uchar)(sib_byte & 0x07L); 00869 if ( idx == 0x04 ) { /* For special [ESP] */ 00870 // assume codifica fissa, tolto 00871 // if ( ss != 0 ) { 00872 // return( -1 ); 00873 // } else { 00874 // strcpy( text, "" ); 00875 // } 00876 } else 00877 { 00878 param.mem_reg2 = GETREGS(2,idx); 00879 param.factor = (uchar)(1<<ss); 00880 } 00881 return 1; 00882 } |
|
Definition at line 202 of file x86dasm.cpp. References IsRelocation, ObjectModule::DataReader::ReadByte(), reader, and ObjectModule::DataReader::Tell(). Referenced by check_forward(), Decode(), do_sib(), mod1(), and mod_reg2().
00203 { 00204 if ( IsRelocation( reader->Tell() ) ) 00205 return true; // Must be no labels or fixups 00206 *offset = reader->ReadByte(); 00207 return false; 00208 } |
|
Definition at line 217 of file x86dasm.cpp. References RelocationInfos::GetRelocation(), Param::literal, ObjectModule::DataReader::ReadDword(), reader, ObjectModule::DataReader::ReadWord(), RelocationInfos::relError, reloc, Param::relocation, and ObjectModule::DataReader::Tell(). Referenced by mod0(), mod2(), and mod_reg2().
00218 { 00219 uint32_t value; 00220 const Relocation *rel; 00221 if (flag) 00222 { 00223 rel = reloc.GetRelocation(reader->Tell(),4); 00224 if (rel == &RelocationInfos::relError) 00225 return true; 00226 value = reader->ReadDword(); 00227 } 00228 else 00229 { 00230 rel = reloc.GetRelocation(reader->Tell(),2); 00231 if (rel == &RelocationInfos::relError) 00232 return true; 00233 value = reader->ReadWord(); 00234 } 00235 param.relocation = rel; 00236 param.literal = value; 00237 return false; 00238 } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 885 of file x86dasm.cpp. References addr_bytes, addr_large, addr_mode2, Param::factor, GETREGS, getv_rel(), Param::mem_reg2, Param::Memory, null_reg, and uchar. Referenced by do_mod_rm().
00886 { 00887 int result; 00888 00889 if ( (r_m == 6 && !addr_large) || (r_m == 5 && addr_large) ) { 00890 00891 // !!! segmento mettere in instruction 00892 param = Param(Param::Memory,null_reg,param.mem_reg2,0,param.factor); 00893 if ( getv_rel( param, addr_large ) ) 00894 return -1; 00895 00896 result = addr_bytes+sib_offset; 00897 *size_known = false; 00898 return( result ); 00899 } 00900 if ( addr_large ) { 00901 param = Param(Param::Memory,GETREGS(2,r_m),param.mem_reg2,0,param.factor); 00902 } else { 00903 param = Param(Param::Memory,addr_mode2[r_m][0],addr_mode2[r_m][1],0,1 ); 00904 } 00905 result = sib_offset; 00906 *size_known = true; 00907 return( result ); 00908 } |
|
Definition at line 910 of file x86dasm.cpp. References addr_mode2, Param::factor, get_checkc(), GETREGS, Param::mem_reg2, Param::Memory, U8TOI, and uchar. Referenced by do_mod_rm().
00911 { 00912 uint32_t offset; 00913 int result; 00914 00915 // read no relocation byte 00916 if ( get_checkc( &offset ) ) 00917 return -1; 00918 00919 // byte to dword 00920 offset = U8TOI(offset); 00921 00922 if ( addr_large ) { 00923 param = Param(Param::Memory,GETREGS(2,r_m),param.mem_reg2,offset,param.factor); 00924 } else { 00925 param = Param(Param::Memory,addr_mode2[r_m][0],addr_mode2[r_m][1],offset,1 ); 00926 } 00927 00928 result = 1 + sib_offset; 00929 return( result ); 00930 } |
|
Definition at line 932 of file x86dasm.cpp. References addr_bytes, addr_large, addr_mode2, Param::factor, GETREGS, getv_rel(), Param::mem_reg2, Param::Memory, and uchar. Referenced by do_mod_rm().
00933 { 00934 int result; 00935 00936 // e chi se ne importa se l'assembler non e' ottimizzato ? 00937 // if ( offset == 0x00000000L ) { 00938 // return( -1 ); /* Assembler should have optimized */ 00939 // } 00940 if ( addr_large ) { 00941 param = Param(Param::Memory,GETREGS(2,r_m),param.mem_reg2,0,param.factor); 00942 } else { 00943 param = Param(Param::Memory,addr_mode2[r_m][0],addr_mode2[r_m][1],0,1 ); 00944 } 00945 if ( getv_rel( param, addr_large ) ) 00946 return -1; 00947 result = addr_bytes+sib_offset; 00948 *size_known = true; 00949 return( result ); 00950 } |
|
Definition at line 1020 of file x86dasm.cpp. References _PRG_ASSERT, Instruction::Args, COMPILE_CHECK, do_mod_rm(), get_checkc(), GETREGS, getv_rel(), Instruction::instruction, Param::Literal, Param::memDescriptor, Param::memFarPointer16, Param::memFPFloat32, Param::memInt8, Param::memMmx, Param::memNone, Param::MemoryTypes, Param::memXmm, modreg1, modregCL, modregIsb, modregIub, modregIv, modregMem, modregMem2FPacket, modregMem4FPacket, modregMemBound, modregMemByte, modregMemDescriptor, modregMemDword, modregMemFPacket, modregMemNone, modregMemPacket, modregMemPacketDword, modregMemPointer, modregMemQword, modregMemReg, modregMemType, modregMemWord, modregMmx, modregReg, modregRegMem, modregSize, modregThird, modregType, modregVar, modregXmm, Instruction::numArg, over_seg, REG, Param::Registry, RegSizeToMemType(), rm_size_invalid, Instruction::segOver, size_bytes, size_large, U8TOI, and uchar.
01021 { 01022 uchar mod; 01023 uchar r_m; 01024 uchar reg; 01025 int reg_size; 01026 int rm_size; 01027 int additional = 0; 01028 Param *reg_param; 01029 Param *mem_param; 01030 Param::MemoryTypes memType; 01031 01032 mod = (uchar)((mod_reg & 0xC0) >> 6); 01033 reg = (uchar)((mod_reg & 0x38) >> 3); 01034 r_m = (uchar)((mod_reg & 0x07) >> 0); 01035 01036 reg_size = special & modregSize; 01037 COMPILE_CHECK(varTypes,(modregVar == 1) && (modregMmx == 3) && (modregXmm == 4)); 01038 if (reg_size == modregVar && size_large ) 01039 reg_size = 2; 01040 #ifdef DEBUG 01041 _PRG_ASSERT(mmx == 0 && xmm == 0); 01042 if (reg_size == modregMmx) 01043 ::mmx = 1; 01044 if (reg_size == modregXmm) 01045 ::xmm = 1; 01046 #endif 01047 01048 // !!! se size_needed e punta a registro errore (es LDS) 01049 bool size_needed = false; 01050 01051 if ( (special&modregMemType) == 0 ) 01052 { 01053 rm_size = reg_size; 01054 memType = RegSizeToMemType(reg_size); 01055 } 01056 else 01057 { 01058 size_needed = true; 01059 switch (special&modregMemType) 01060 { 01061 case modregMemByte: 01062 rm_size = 0; 01063 memType = Param::memInt8; 01064 break; 01065 case modregMemWord: 01066 rm_size = 1; 01067 memType = Param::memInt16; 01068 break; 01069 case modregMemDword: 01070 _PRG_ASSERT( (::mmx && reg_size == modregMmx) 01071 || (::xmm && reg_size == modregXmm) ); 01072 rm_size = 2; 01073 memType = Param::memInt32; 01074 break; 01075 case modregMemQword: 01076 _PRG_ASSERT(::xmm == 0); 01077 _PRG_ASSERT(instruction.instruction==istr_cmpxchg8b); 01078 rm_size = rm_size_invalid; 01079 memType = Param::memInt64; 01080 break; 01081 case modregMemFPacket: 01082 #ifdef DEBUG 01083 ::xmm = 1; 01084 #endif 01085 rm_size = 4; 01086 memType = Param::memFPFloat32; 01087 break; 01088 case modregMem2FPacket: 01089 #ifdef DEBUG 01090 ::xmm = 1; 01091 #endif 01092 rm_size = 4; 01093 memType = Param::memSemiXmm; 01094 break; 01095 case modregMem4FPacket: 01096 #ifdef DEBUG 01097 ::xmm = 1; 01098 #endif 01099 rm_size = 4; 01100 memType = Param::memXmm; 01101 break; 01102 case modregMemPacket: 01103 _PRG_ASSERT(instruction.instruction==istr_pextrw 01104 || instruction.instruction==istr_pmovmskb 01105 || instruction.instruction==istr_cvtpi2ps); 01106 #ifdef DEBUG 01107 if (instruction.instruction==istr_cvtpi2ps) ::xmm = 1; else ::mmx = 1; 01108 #endif 01109 rm_size = (instruction.instruction==istr_cvtpi2ps)?4:3; 01110 memType = Param::memMmx; 01111 break; 01112 case modregMemPacketDword: 01113 _PRG_ASSERT(::mmx && reg_size == modregMmx); 01114 rm_size = (mod==3)?3:2; 01115 memType = Param::memInt32; 01116 break; 01117 case modregMemDescriptor: 01118 rm_size = rm_size_invalid; 01119 memType = Param::memDescriptor; 01120 break; // 16&32 bit 01121 case modregMemPointer: 01122 _PRG_ASSERT(::xmm == 0); 01123 rm_size = rm_size_invalid; 01124 memType = size_large?Param::memFarPointer32:Param::memFarPointer16; 01125 break; 01126 case modregMemBound: 01127 _PRG_ASSERT(::xmm == 0); 01128 rm_size = rm_size_invalid; 01129 memType = size_large?Param::memBound32:Param::memBound32; 01130 break; 01131 default: 01132 // no warning and small optimization 01133 _PRG_ASSERT(0); 01134 case modregMemNone: 01135 rm_size = rm_size_invalid; 01136 memType = Param::memNone; 01137 break; 01138 } 01139 } 01140 01141 // write first 2 arguments 01142 switch ( special&modregType ) 01143 { 01144 case modregMemReg: 01145 instruction.numArg = 2; 01146 mem_param = &instruction.Args[0]; 01147 reg_param = &instruction.Args[1]; 01148 break; 01149 case modregRegMem: 01150 instruction.numArg = 2; 01151 reg_param = &instruction.Args[0]; 01152 mem_param = &instruction.Args[1]; 01153 break; 01154 case modregMem: 01155 instruction.numArg = 1; 01156 mem_param = &instruction.Args[0]; 01157 reg_param = NULL; 01158 break; 01159 default: 01160 // non dovrebbe capitare ma non si sa mai 01161 _PRG_ASSERT(0); 01162 case modregReg: 01163 instruction.numArg = 1; 01164 reg_param = &instruction.Args[0]; 01165 mem_param = NULL; 01166 break; 01167 } 01168 01169 if ( reg_param != NULL ) 01170 { 01171 _PRG_ASSERT(reg_size>=0 && reg_size<=4); 01172 *reg_param = Param(Param::Registry,GETREGS(reg_size,reg)); 01173 } 01174 else 01175 // !!! non sempre la dimensione serve se non c'e' un registro, a volte 01176 // e' implicita nell' operazione 01177 size_needed = true; 01178 01179 if ( mem_param != NULL ) 01180 { 01181 instruction.segOver = over_seg; 01182 additional = do_mod_rm( mod, r_m, rm_size, memType, size_needed, *mem_param ); 01183 #ifdef DEBUG 01184 ::mmx = 0; 01185 ::xmm = 0; 01186 #endif 01187 if ( additional == -1 ) 01188 return 0; 01189 } 01190 #ifdef DEBUG 01191 ::mmx = 0; 01192 ::xmm = 0; 01193 #endif 01194 01195 // process third parameters (if one) 01196 if ( special&modregThird ) 01197 { 01198 uint32_t data; 01199 Param& tParam = instruction.Args[instruction.numArg]; 01200 switch ( special&modregThird ) 01201 { 01202 case modregIsb: 01203 // check no relocation 01204 if ( get_checkc( &data ) ) 01205 return 0; 01206 data = U8TOI(data); 01207 ++additional; 01208 tParam = Param(Param::Literal,data,(uchar)1); 01209 break; 01210 case modregIub: 01211 // check no relocation 01212 if ( get_checkc( &data ) ) 01213 return 0; 01214 ++additional; 01215 tParam = Param(Param::Literal,data,(uchar)1); 01216 break; 01217 case modregIv: 01218 _PRG_ASSERT( size_bytes == (size_large?4:2) ); 01219 tParam = Param(Param::Literal,0,(uchar)size_bytes); 01220 if ( getv_rel( tParam, size_large ) ) 01221 return 0; 01222 additional += size_bytes; 01223 break; 01224 case modreg1: 01225 tParam = Param(Param::Literal,1,(uchar)1); 01226 break; 01227 case modregCL: 01228 tParam = Param(Param::Registry,REG(cl)); 01229 break; 01230 } 01231 ++instruction.numArg; 01232 } 01233 01234 return 2+additional; 01235 } |
|
Definition at line 210 of file x86dasm.cpp. References ObjectModule::DataReader::ReadDword(), reader, and ObjectModule::DataReader::ReadWord().
|
|
Definition at line 300 of file x86table.cpp. Referenced by CheckTables(). |
|
Definition at line 39 of file x86table.cpp. Referenced by CheckTables(), and Decode(). |
|
Definition at line 62 of file x86dasm.h. Referenced by get_checkc(), getv_rel(), InstructionDecoder(), and ReadVar(). |
|
Definition at line 61 of file x86dasm.h. Referenced by getv_rel(), and InstructionDecoder(). |