зеркало из https://github.com/mozilla/gecko-dev.git
Added more Intel instructions and some more debugging info.
This commit is contained in:
Родитель
1b57208cbf
Коммит
35a9faca72
|
@ -48,6 +48,7 @@ bool gDebug=false;
|
|||
bool gCompact=false;
|
||||
bool gOptimize=false;
|
||||
bool gAssembly=false;
|
||||
bool gfirst=false;
|
||||
|
||||
#define bswap_32(x) \
|
||||
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
||||
|
@ -224,15 +225,6 @@ int DIGIT_MAP[256] = {
|
|||
/*
|
||||
* Dceclation of the Instruction types
|
||||
*/
|
||||
char reg_name[14][4] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
||||
"cs", "ss", "ds", "es", "fs", "gs" };
|
||||
|
||||
char instr_name[][8] = { "unknown", "push", "add", "sub", "cmp", "mov", "j", "lea",
|
||||
"inc", "pop", "xor", "nop", "ret", "call" };
|
||||
|
||||
char cond_name[][4] = { "o", "no", "b", "nb", "z", "nz", "be", "nbe",
|
||||
"s", "ns", "pe", "po", "l", "ge", "le", "g", "mp", "cxz" };
|
||||
|
||||
|
||||
enum eRegister {
|
||||
kNoReg = -1,
|
||||
|
@ -240,11 +232,22 @@ enum eRegister {
|
|||
kcs, kss, kds, kes, kfs, kgs
|
||||
};
|
||||
|
||||
char reg_name[14][4] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
||||
"cs", "ss", "ds", "es", "fs", "gs" };
|
||||
|
||||
|
||||
enum eInstruction {
|
||||
kunknown, kpush, kadd, ksub, kcmp, kmov, kjmp, klea,
|
||||
kinc, kpop, kxor, knop, kret, kcall,
|
||||
kinc, kpop, kxor, knop, kret, kcall, kand,
|
||||
};
|
||||
|
||||
char instr_name[][8] = { "unknown", "push", "add", "sub", "cmp", "mov", "j", "lea",
|
||||
"inc", "pop", "xor", "nop", "ret", "call", "and", };
|
||||
|
||||
|
||||
char cond_name[][4] = { "o", "no", "b", "nb", "z", "nz", "be", "nbe",
|
||||
"s", "ns", "pe", "po", "l", "ge", "le", "g", "mp", "cxz" };
|
||||
|
||||
enum eCond {
|
||||
kjo, kjno, kjb, kjnb, kjz, kjnz, kjbe, kjnbe,
|
||||
kjs, kjns, kjpe, kjpo, kjl, kjge, kjle, kjg, kjt, kjcxz
|
||||
|
@ -355,10 +358,16 @@ struct CPush:CInstruction {
|
|||
|
||||
CPush( char imm8 )
|
||||
{
|
||||
fInstr = kpush;
|
||||
fFormat = kfreg;
|
||||
fImm32 = imm8;
|
||||
}
|
||||
|
||||
CPush( long imm32 )
|
||||
{
|
||||
fInstr = kpush;
|
||||
fFormat = kfreg;
|
||||
fImm32 = imm32;
|
||||
}
|
||||
|
||||
CPush( uchar *pCode, eFormat format )
|
||||
|
@ -375,7 +384,7 @@ struct CPush:CInstruction {
|
|||
struct CInc:CInstruction {
|
||||
CInc( eRegister reg )
|
||||
{
|
||||
fInstr = kpush;
|
||||
fInstr = kinc;
|
||||
fFormat = kfreg;
|
||||
fReg1 = reg;
|
||||
}
|
||||
|
@ -392,6 +401,14 @@ struct CInc:CInstruction {
|
|||
|
||||
|
||||
struct CMov:CInstruction {
|
||||
CMov( eRegister reg, uchar *pCode, eFormat format )
|
||||
{
|
||||
fReg1 = reg;
|
||||
fInstr = kmov;
|
||||
fFormat = format;
|
||||
fSize += am_rm32( pCode );
|
||||
}
|
||||
|
||||
CMov( uchar *pCode, eFormat format )
|
||||
{
|
||||
fInstr = kmov;
|
||||
|
@ -399,6 +416,7 @@ struct CMov:CInstruction {
|
|||
fSize += am_rm32_reg( pCode );
|
||||
}
|
||||
|
||||
virtual void optimize( void );
|
||||
virtual int generate_opcode( uchar *buffer );
|
||||
};
|
||||
|
||||
|
@ -441,6 +459,18 @@ struct CSub:CInstruction {
|
|||
};
|
||||
|
||||
|
||||
struct CAnd:CInstruction {
|
||||
CAnd( uchar *pCode, eFormat format )
|
||||
{
|
||||
fInstr = kand;
|
||||
fFormat = format;
|
||||
fSize += am_rm32_reg( pCode );
|
||||
}
|
||||
|
||||
virtual int generate_opcode( uchar *buffer );
|
||||
};
|
||||
|
||||
|
||||
struct CXor:CInstruction {
|
||||
CXor( uchar *pCode, eFormat format )
|
||||
{
|
||||
|
@ -469,7 +499,7 @@ struct CCall:CInstruction {
|
|||
struct CJmp:CInstruction {
|
||||
eCond fCond;
|
||||
|
||||
CJmp( eCond cond, uchar imm8 )
|
||||
CJmp( eCond cond, char imm8 )
|
||||
{
|
||||
fInstr = kjmp;
|
||||
fImm32 = imm8;
|
||||
|
@ -560,6 +590,13 @@ int CInstruction::am_rm32( uchar *pCode )
|
|||
else if ((reg & 0xC0) == 0x00) // no disp
|
||||
{
|
||||
fFormat = (eFormat)(fFormat | kfmDeref);
|
||||
if (fReg2 == 0x05) // absolute address
|
||||
{
|
||||
fReg2 = kNoReg;
|
||||
fDisp32 = bswap_32( *(long*)pCode );
|
||||
pCode += 4;
|
||||
isize += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (fFormat & kfmImm8)
|
||||
|
@ -624,7 +661,14 @@ int CInstruction::am_encode( uchar *buffer, eRegister reg1 )
|
|||
isize++;
|
||||
}
|
||||
|
||||
if (fDisp32 == 0)
|
||||
if ( (fReg2 == kNoReg) && (fFormat & kfmDeref) ) // absolute address
|
||||
{
|
||||
*buffer = 0x00 | (reg1 << 3) | 0x05;
|
||||
long bsDisp32 = bswap_32( fDisp32 );
|
||||
memcpy( buffer+1, &bsDisp32, 4 );
|
||||
isize += 4;
|
||||
}
|
||||
else if (fDisp32 == 0)
|
||||
{
|
||||
if (format & kfmDeref)
|
||||
{
|
||||
|
@ -744,6 +788,13 @@ int CLea::generate_opcode( uchar *buffer )
|
|||
}
|
||||
|
||||
|
||||
void CMov::optimize( void )
|
||||
{
|
||||
if ( (fReg1 == fReg2) && (fReg3 == kNoReg) && !(fFormat & kfmDeref) )
|
||||
fInstr = knop;
|
||||
}
|
||||
|
||||
|
||||
int CMov::generate_opcode( uchar *buffer )
|
||||
{
|
||||
int isize = 1;
|
||||
|
@ -848,6 +899,43 @@ int CCmp::generate_opcode( uchar *buffer )
|
|||
}
|
||||
|
||||
|
||||
int CAnd::generate_opcode( uchar *buffer )
|
||||
{
|
||||
int isize = 1;
|
||||
eFormat format = (eFormat)(kBaseFormatMask & (int)fFormat);
|
||||
|
||||
if (format == kfrm32)
|
||||
{
|
||||
if (fFormat & kfmSize8)
|
||||
buffer[0] = 0x80;
|
||||
else if (fFormat & kfmImm8)
|
||||
buffer[0] = 0x83;
|
||||
else
|
||||
buffer[0] = 0x81;
|
||||
|
||||
isize += am_encode( &buffer[1], (eRegister)4 );
|
||||
return isize;
|
||||
}
|
||||
else if (format == kfrm32_r32)
|
||||
{
|
||||
if (fFormat & kfmSize8)
|
||||
buffer[0] = 0x20;
|
||||
else
|
||||
buffer[0] = 0x21;
|
||||
}
|
||||
else if (format == kfr32_rm32)
|
||||
{
|
||||
if (fFormat & kfmSize8)
|
||||
buffer[0] = 0x22;
|
||||
else
|
||||
buffer[0] = 0x23;
|
||||
}
|
||||
|
||||
isize += am_encode( &buffer[1], fReg1 );
|
||||
return isize;
|
||||
}
|
||||
|
||||
|
||||
int CXor::generate_opcode( uchar *buffer )
|
||||
{
|
||||
int isize = 1;
|
||||
|
@ -1061,7 +1149,10 @@ void CInstruction::output_text( void )
|
|||
cout << reg_name[fReg1] << ", ";
|
||||
if (fDisp32) cout << fDisp32;
|
||||
if (fFormat & kfmDeref) cout << "(";
|
||||
if (fReg2 != kNoReg)
|
||||
cout << reg_name[fReg2];
|
||||
else
|
||||
cout.form( "0x%08X", (long)(bswap_32(fDisp32)) );
|
||||
if (fFormat & kfmDeref) cout << ")";
|
||||
break;
|
||||
}
|
||||
|
@ -1076,7 +1167,8 @@ void CInstruction::output_text( void )
|
|||
void CJmp::output_text( void )
|
||||
{
|
||||
cout << "j" << cond_name[fCond];
|
||||
cout.form( "\t.+0x%02X\n", fImm32 );
|
||||
// cout.form( "\t.+0x%02X\n", fImm32 );
|
||||
cout.form( "\t.+%ld\n", fImm32 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1100,6 +1192,29 @@ int hexdump( CInstruction *instr )
|
|||
}
|
||||
|
||||
|
||||
CInstruction* get_2byte_instruction( uchar *pCode )
|
||||
{
|
||||
CInstruction *retInstr=NULL;
|
||||
uchar *reg = pCode+1;
|
||||
|
||||
switch (*pCode)
|
||||
{
|
||||
case 0xBE:
|
||||
retInstr = new CMov( reg, (eFormat)(kfr32_rm32 | kfmSize8) );
|
||||
break;
|
||||
case 0xBF:
|
||||
retInstr = new CMov( reg, (eFormat)(kfr32_rm32 | kfmSize16) );
|
||||
break;
|
||||
}
|
||||
|
||||
// ek only until the table above is completed
|
||||
if (retInstr == NULL) retInstr = new CInstruction();
|
||||
|
||||
retInstr->fSize++;
|
||||
return retInstr;
|
||||
}
|
||||
|
||||
|
||||
CInstruction* get_next_instruction( uchar *pCode )
|
||||
{
|
||||
CInstruction *retInstr=NULL;
|
||||
|
@ -1119,6 +1234,15 @@ CInstruction* get_next_instruction( uchar *pCode )
|
|||
case 0x03:
|
||||
retInstr = new CAdd( reg, kfr32_rm32 );
|
||||
break;
|
||||
case 0x06:
|
||||
retInstr = new CPush( kes );
|
||||
break;
|
||||
case 0x0F:
|
||||
retInstr = get_2byte_instruction( reg );
|
||||
break;
|
||||
case 0x25:
|
||||
retInstr = new CAnd( reg, kfr32_rm32 );
|
||||
break;
|
||||
case 0x28:
|
||||
retInstr = new CSub( reg, (eFormat)(kfrm32_r32 | kfmSize8) );
|
||||
break;
|
||||
|
@ -1164,6 +1288,27 @@ CInstruction* get_next_instruction( uchar *pCode )
|
|||
case 0x5f:
|
||||
retInstr = new CPop( (eRegister)(*pCode & 0x07) );
|
||||
break;
|
||||
case 0x6A:
|
||||
retInstr = new CPush( (char)(*reg) );
|
||||
break;
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
case 0x78:
|
||||
case 0x79:
|
||||
case 0x7A:
|
||||
case 0x7B:
|
||||
case 0x7C:
|
||||
case 0x7D:
|
||||
case 0x7E:
|
||||
case 0x7F:
|
||||
retInstr = new CJmp( (eCond)(*pCode - 0x70), (char)*reg );
|
||||
break;
|
||||
case 0x80:
|
||||
switch (DIGIT_MAP[*reg])
|
||||
{
|
||||
|
@ -1233,6 +1378,16 @@ CInstruction* get_next_instruction( uchar *pCode )
|
|||
case 0x90:
|
||||
retInstr = new CNop();
|
||||
break;
|
||||
case 0xB8:
|
||||
case 0xB9:
|
||||
case 0xBA:
|
||||
case 0xBB:
|
||||
case 0xBC:
|
||||
case 0xBD:
|
||||
case 0xBE:
|
||||
case 0xBF:
|
||||
retInstr = new CMov( (eRegister)(*pCode & 0x07), reg, (eFormat)(kfrm32 | kfmImm32) );
|
||||
break;
|
||||
case 0xC3:
|
||||
retInstr = new CRet();
|
||||
break;
|
||||
|
@ -1241,9 +1396,6 @@ CInstruction* get_next_instruction( uchar *pCode )
|
|||
break;
|
||||
|
||||
|
||||
case 0x7E:
|
||||
retInstr = new CJmp( kjle, *reg );
|
||||
break;
|
||||
case 0xE8:
|
||||
retInstr = new CCall( (long)bswap_32( *(long*)reg ));
|
||||
break;
|
||||
|
@ -1271,7 +1423,16 @@ CInstruction* get_next_instruction( uchar *pCode )
|
|||
}
|
||||
|
||||
// ek only until the table above is completed
|
||||
if (retInstr == NULL) retInstr = new CInstruction();
|
||||
if (retInstr == NULL)
|
||||
{
|
||||
if (!gfirst)
|
||||
{
|
||||
cout << (unsigned long)*pCode << " was the first\n";
|
||||
cout << (unsigned long)*(pCode+1) << "\n";
|
||||
}
|
||||
gfirst = true;
|
||||
retInstr = new CInstruction();
|
||||
}
|
||||
|
||||
return retInstr;
|
||||
}
|
||||
|
@ -1353,6 +1514,7 @@ process_mapping(char* mapping, size_t size)
|
|||
else if (name == ".strtab") {
|
||||
strtabsh = shdrs + i;
|
||||
}
|
||||
cout << name << " size = " << (shdrs+i)->sh_size << "\n";
|
||||
}
|
||||
|
||||
// find the .strtab
|
||||
|
@ -1362,6 +1524,7 @@ process_mapping(char* mapping, size_t size)
|
|||
char* text = mapping + textsh->sh_offset;
|
||||
int textaddr = textsh->sh_addr;
|
||||
|
||||
|
||||
// find the symbol table
|
||||
int nentries = symtabsh->sh_size / sizeof(Elf32_Sym);
|
||||
Elf32_Sym* symtab = reinterpret_cast<Elf32_Sym*>(mapping + symtabsh->sh_offset);
|
||||
|
|
Загрузка…
Ссылка в новой задаче