instrs: Support far jumps/calls encoded target

This commit is contained in:
Alexis Engelke
2021-01-10 12:31:07 +01:00
parent 2f295e5476
commit dd4263b169
4 changed files with 50 additions and 9 deletions

View File

@@ -508,6 +508,8 @@ prefix_end:
imm_size = 1;
else if (UNLIKELY(instr->type == FDI_RET || instr->type == FDI_RETF))
imm_size = 2;
else if (UNLIKELY(desc->type == FDI_JMPF || desc->type == FDI_CALLF))
imm_size = op_size + 2;
else if (UNLIKELY(instr->type == FDI_ENTER))
imm_size = 3;
else if (instr->type == FDI_MOVABS)
@@ -526,6 +528,8 @@ prefix_end:
instr->imm = LOAD_LE_3(&buffer[off]);
else if (imm_size == 4)
instr->imm = (int32_t) LOAD_LE_4(&buffer[off]);
else if (imm_size == 6)
instr->imm = LOAD_LE_4(&buffer[off]) | LOAD_LE_2(&buffer[off+4]) << 32;
else if (imm_size == 8)
instr->imm = (int64_t) LOAD_LE_8(&buffer[off]);
off += imm_size;

View File

@@ -178,7 +178,7 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
case 8: mnemonic = "jrcxz"; break;
}
break;
case FDI_ENTER:
case FDI_ENTER: {
buf = fd_strplcpy(buf, mnemonic, end-buf);
if (FD_OPSIZE(instr) == 2)
buf = fd_strplcpy(buf, "w", end-buf);
@@ -194,6 +194,28 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
*--fmt = ',';
buf = fd_strplcpy(buf, fmt, end-buf);
return;
}
case FDI_JMPF:
case FDI_CALLF:
if (FD_OP_TYPE(instr, 0) == FD_OT_IMM) {
buf = fd_strplcpy(buf, mnemonic, end-buf);
uint32_t tgt = FD_OP_IMM(instr, 0) & 0xffffffff;
if (FD_OP_SIZE(instr, 0) == 2)
tgt &= 0xffff;
unsigned seg = FD_OP_IMM(instr, 0) >> 8*FD_OP_SIZE(instr, 0);
char* fmt = fd_format_hex(seg & 0xffff, tmp + 3);
*--fmt = 'x';
*--fmt = '0';
*--fmt = ' ';
buf = fd_strplcpy(buf, fmt, end-buf);
fmt = fd_format_hex(tgt, tmp + 3);
*--fmt = 'x';
*--fmt = '0';
*--fmt = ':';
buf = fd_strplcpy(buf, fmt, end-buf);
return;
}
break;
case FDI_PUSH:
if (FD_OP_SIZE(instr, 0) == 2 && FD_OP_TYPE(instr, 0) == FD_OT_IMM)
sizesuffix[0] = 'w';
@@ -275,7 +297,7 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
case FDI_LFS:
case FDI_LGS:
case FDI_LSS:
size = 6;
size += 2;
break;
case FDI_FLD:
case FDI_FSTP:

View File

@@ -157,7 +157,8 @@
90+ OA GP GP - - XCHG_NOP
98 NP - - - - C_EX INSTR_WIDTH
99 NP - - - - C_SEP INSTR_WIDTH
#9a CALLF TODO
# Far jmp/call immediate size adjusted in code
9a I IMM - - - CALLF ONLY32
9b NP - - - - FWAIT
9c NP - - - - PUSHF DEF64 INSTR_WIDTH
9d NP - - - - POPF DEF64 INSTR_WIDTH
@@ -198,8 +199,8 @@ c1/7 MI GP IMM8 - - SAR
# RET immediate size handled in code
c2 I IMM16 - - - RET FORCE64 INSTR_WIDTH
c3 NP - - - - RET FORCE64 INSTR_WIDTH
c4/m RM GP MEMZ - - LES ONLY32
c5/m RM GP MEMZ - - LDS ONLY32
c4/m RM GP MEM - - LES ONLY32
c5/m RM GP MEM - - LDS ONLY32
c6/0 MI GP IMM - - MOV SIZE_8
c6f8 I IMM8 - - - XABORT
c7/0 MI GP IMM - - MOV
@@ -258,7 +259,8 @@ e6 IA GP IMM8 - - OUT SIZE_8
e7 IA GP IMM8 - - OUT
e8 D IMM - - - CALL FORCE64
e9 D IMM - - - JMP FORCE64
#ea JMPf TODO, ONLY32
# Far jmp/call immediate size adjusted in code
ea I IMM - - - JMPF ONLY32
eb D IMM - - - JMP FORCE64 IMM_8
ec NP - - - - IN SIZE_8 INSTR_WIDTH
ed NP - - - - IN INSTR_WIDTH
@@ -295,9 +297,9 @@ fe/1 M GP - - - DEC SIZE_8 LOCK
ff/0 M GP - - - INC LOCK
ff/1 M GP - - - DEC LOCK
ff/2 M GP - - - CALL FORCE64
ff/3m M MEMZ - - - CALLF
ff/3m M MEM - - - CALLF
ff/4 M GP - - - JMP FORCE64
ff/5m M MEMZ - - - JMPF
ff/5m M MEM - - - JMPF
ff/6 M GP - - - PUSH DEF64
0f00/0 M GP16 - - - SLDT
0f00/1 M GP16 - - - STR

View File

@@ -311,7 +311,7 @@ main(int argc, char** argv)
TEST32("\xc5\x00", "lds eax, fword ptr [eax]");
TEST32("\x0f\xb2\x00", "lss eax, fword ptr [eax]");
TEST64("\x0f\xb2\x00", "lss eax, fword ptr [rax]");
TEST64("\x48\x0f\xb2\x00", "lss rax, fword ptr [rax]");
TEST64("\x48\x0f\xb2\x00", "lss rax, tbyte ptr [rax]");
TEST("\xc5\xf2\x2a\xc0", "vcvtsi2ss xmm0, xmm1, eax");
TEST("\xf3\xc5\xf2\x2a\xc0", "UD"); // VEX+REP
TEST("\xf2\xc5\xf2\x2a\xc0", "UD"); // VEX+REPNZ
@@ -429,6 +429,19 @@ main(int argc, char** argv)
TEST64("\xe3\xfe", "jrcxz 0x0");
TEST32("\x67\xe3\xfd", "jcxz 0x0");
TEST64("\x67\xe3\xfd", "jecxz 0x0");
TEST32("\x66\x9a\x23\x01\x23\x00", "call far 0x23:0x123");
TEST32("\x9a\x67\x45\x23\x01\x23\x00", "call far 0x23:0x1234567");
TEST32("\x9a\xff\xff\xff\xff\xff\xff", "call far 0xffff:0xffffffff");
TEST32("\x66\xff\x1f", "call far dword ptr [edi]");
TEST64("\x66\xff\x1f", "call far dword ptr [rdi]");
TEST32("\xff\x1f", "call far fword ptr [edi]");
TEST64("\xff\x1f", "call far fword ptr [rdi]");
TEST64("\x48\xff\x1f", "call far tbyte ptr [rdi]");
TEST32("\x66\x0f\xb4\x07", "lfs ax, dword ptr [edi]");
TEST64("\x66\x0f\xb4\x07", "lfs ax, dword ptr [rdi]");
TEST32("\x0f\xb4\x07", "lfs eax, fword ptr [edi]");
TEST64("\x0f\xb4\x07", "lfs eax, fword ptr [rdi]");
TEST64("\x48\x0f\xb4\x07", "lfs rax, tbyte ptr [rdi]");
TEST("\xa5", "movsd");
TEST("\x64\xa5", "fs movsd");
TEST32("\x2e\xa5", "cs movsd");