format: Emit XACQUIRE/XRELEASE
As CMPXCHGD has a mandatory prefix table, it is absolutely necessary that the presence of any tables does not modify any decoding state.
This commit is contained in:
1
decode.c
1
decode.c
@@ -244,7 +244,6 @@ prefix_end:
|
||||
// there is a REP prefix, then the 66h prefix is ignored here.
|
||||
uint8_t mandatory_prefix = prefix_rep ? prefix_rep : !!prefix_66;
|
||||
table_idx = table_walk(table_idx, mandatory_prefix, &kind);
|
||||
prefix_rep = 0; // Don't include REP/REPNZ in instr flags
|
||||
}
|
||||
|
||||
// Then, walk through ModR/M-encoded opcode extensions.
|
||||
|
||||
18
format.c
18
format.c
@@ -125,6 +125,7 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
|
||||
const char* mnemonic = fdi_name(FD_TYPE(instr));
|
||||
|
||||
bool prefix_rep = false;
|
||||
bool prefix_xacq_xrel = false;
|
||||
bool prefix_addrsize = false;
|
||||
bool prefix_segment = false;
|
||||
|
||||
@@ -183,6 +184,16 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
|
||||
FD_OP_REG_TYPE(instr, 0) == FD_RT_SEG)
|
||||
sizesuffix[0] = 'w';
|
||||
break;
|
||||
case FDI_XCHG:
|
||||
if (FD_OP_TYPE(instr, 0) == FD_OT_MEM)
|
||||
prefix_xacq_xrel = true;
|
||||
break;
|
||||
case FDI_MOV:
|
||||
// MOV C6h/C7h can have XRELEASE prefix.
|
||||
if (FD_HAS_REP(instr) && FD_OP_TYPE(instr, 0) == FD_OT_MEM &&
|
||||
FD_OP_TYPE(instr, 1) == FD_OT_IMM)
|
||||
prefix_xacq_xrel = true;
|
||||
break;
|
||||
case FDI_FXSAVE:
|
||||
case FDI_FXRSTOR:
|
||||
case FDI_XSAVE:
|
||||
@@ -217,7 +228,12 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (prefix_rep) {
|
||||
if (prefix_xacq_xrel || FD_HAS_LOCK(instr)) {
|
||||
if (FD_HAS_REP(instr))
|
||||
buf = fd_strplcpy(buf, "xrelease ", end-buf);
|
||||
if (FD_HAS_REPNZ(instr))
|
||||
buf = fd_strplcpy(buf, "xacquire ", end-buf);
|
||||
} else if (prefix_rep) {
|
||||
if (FD_HAS_REP(instr))
|
||||
buf = fd_strplcpy(buf, "rep ", end-buf);
|
||||
if (FD_HAS_REPNZ(instr))
|
||||
|
||||
@@ -90,6 +90,32 @@ main(int argc, char** argv)
|
||||
TEST64("\xf2\x0f\xc7\x0f", "cmpxchg8b qword ptr [rdi]");
|
||||
TEST32("\xf3\x0f\xc7\x0f", "cmpxchg8b qword ptr [edi]");
|
||||
TEST64("\xf3\x0f\xc7\x0f", "cmpxchg8b qword ptr [rdi]");
|
||||
TEST32("\xf2\xf0\x0f\xc7\x0f", "xacquire lock cmpxchg8b qword ptr [edi]");
|
||||
TEST64("\xf2\xf0\x0f\xc7\x0f", "xacquire lock cmpxchg8b qword ptr [rdi]");
|
||||
TEST32("\xf3\xf0\x0f\xc7\x0f", "xrelease lock cmpxchg8b qword ptr [edi]");
|
||||
TEST64("\xf3\xf0\x0f\xc7\x0f", "xrelease lock cmpxchg8b qword ptr [rdi]");
|
||||
TEST32("\x87\x0f", "xchg dword ptr [edi], ecx");
|
||||
TEST64("\x87\x0f", "xchg dword ptr [rdi], ecx");
|
||||
TEST32("\xf2\x87\x0f", "xacquire xchg dword ptr [edi], ecx");
|
||||
TEST64("\xf2\x87\x0f", "xacquire xchg dword ptr [rdi], ecx");
|
||||
TEST32("\xf3\x87\x0f", "xrelease xchg dword ptr [edi], ecx");
|
||||
TEST64("\xf3\x87\x0f", "xrelease xchg dword ptr [rdi], ecx");
|
||||
TEST32("\xf2\xf0\x87\x0f", "xacquire lock xchg dword ptr [edi], ecx");
|
||||
TEST64("\xf2\xf0\x87\x0f", "xacquire lock xchg dword ptr [rdi], ecx");
|
||||
TEST32("\xf3\xf0\x87\x0f", "xrelease lock xchg dword ptr [edi], ecx");
|
||||
TEST64("\xf3\xf0\x87\x0f", "xrelease lock xchg dword ptr [rdi], ecx");
|
||||
TEST32("\xc6\x07\x12", "mov byte ptr [edi], 0x12");
|
||||
TEST64("\xc6\x07\x12", "mov byte ptr [rdi], 0x12");
|
||||
TEST32("\xf2\xc6\x07\x12", "mov byte ptr [edi], 0x12"); // no xacquire
|
||||
TEST64("\xf2\xc6\x07\x12", "mov byte ptr [rdi], 0x12"); // no xacquire
|
||||
TEST32("\xf3\xc6\x07\x12", "xrelease mov byte ptr [edi], 0x12");
|
||||
TEST64("\xf3\xc6\x07\x12", "xrelease mov byte ptr [rdi], 0x12");
|
||||
TEST32("\x66\xc7\x07\x34\x12", "mov word ptr [edi], 0x1234");
|
||||
TEST64("\x66\xc7\x07\x34\x12", "mov word ptr [rdi], 0x1234");
|
||||
TEST32("\x66\xf2\xc7\x07\x34\x12", "mov word ptr [edi], 0x1234"); // no xacquire
|
||||
TEST64("\x66\xf2\xc7\x07\x34\x12", "mov word ptr [rdi], 0x1234"); // no xacquire
|
||||
TEST32("\x66\xf3\xc7\x07\x34\x12", "xrelease mov word ptr [edi], 0x1234");
|
||||
TEST64("\x66\xf3\xc7\x07\x34\x12", "xrelease mov word ptr [rdi], 0x1234");
|
||||
TEST("\x66", "PARTIAL");
|
||||
TEST("\xf0", "PARTIAL");
|
||||
TEST("\x0f", "PARTIAL");
|
||||
|
||||
Reference in New Issue
Block a user