#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(). |
1.2.15