From dda0d5ddc148540bb64f934d03e510f00123d20a Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Wed, 29 Aug 2007 09:09:17 +0000 Subject: [PATCH] Support x86 $int 0x40 .. 0x43 instructions on Linux. Apparently these generate a segfault and then restart the instruction. git-svn-id: svn://svn.valgrind.org/vex/trunk@1786 --- VEX/priv/guest-amd64/toIR.c | 2 +- VEX/priv/guest-ppc/toIR.c | 4 ++-- VEX/priv/guest-x86/toIR.c | 15 ++++++++++++++- VEX/priv/host-amd64/hdefs.c | 4 ++-- VEX/priv/host-ppc/hdefs.c | 2 +- VEX/priv/host-x86/hdefs.c | 7 +++++-- VEX/priv/ir/irdefs.c | 3 ++- VEX/pub/libvex_ir.h | 3 ++- VEX/pub/libvex_trc_values.h | 4 +++- 9 files changed, 32 insertions(+), 12 deletions(-) diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index aff9971d2a..bd0a422012 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -12446,7 +12446,7 @@ DisResult disInstr_AMD64_WRK ( /* ------------------------ INT ------------------------ */ case 0xCC: /* INT 3 */ - jmp_lit(Ijk_Trap, guest_RIP_bbstart + delta); + jmp_lit(Ijk_SigTRAP, guest_RIP_bbstart + delta); dres.whatNext = Dis_StopHere; DIP("int $0x3\n"); break; diff --git a/VEX/priv/guest-ppc/toIR.c b/VEX/priv/guest-ppc/toIR.c index 35a066e423..35431d3293 100644 --- a/VEX/priv/guest-ppc/toIR.c +++ b/VEX/priv/guest-ppc/toIR.c @@ -4586,7 +4586,7 @@ static Bool do_trap ( UChar TO, testing the arguments. */ stmt( IRStmt_Exit( binop(opCMPEQ, const0, const0), - Ijk_Trap, + Ijk_SigTRAP, mode64 ? IRConst_U64(cia) : IRConst_U32((UInt)cia) )); return True; /* unconditional trap */ @@ -4629,7 +4629,7 @@ static Bool do_trap ( UChar TO, } stmt( IRStmt_Exit( binop(opCMPNE, cond, const0), - Ijk_Trap, + Ijk_SigTRAP, mode64 ? IRConst_U64(cia) : IRConst_U32((UInt)cia) )); return False; /* not an unconditional trap */ diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 0a5c5de014..2f206ea551 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -11232,13 +11232,26 @@ DisResult disInstr_X86_WRK ( /* ------------------------ INT ------------------------ */ case 0xCC: /* INT 3 */ - jmp_lit(Ijk_Trap,((Addr32)guest_EIP_bbstart)+delta); + jmp_lit(Ijk_SigTRAP,((Addr32)guest_EIP_bbstart)+delta); dres.whatNext = Dis_StopHere; DIP("int $0x3\n"); break; case 0xCD: /* INT imm8 */ d32 = getIByte(delta); delta++; + + /* Handle int $0x40 .. $0x43 by synthesising a segfault and a + restart of this instruction (hence the "-2" two lines below, + to get the restart EIP to be this instruction. This is + probably Linux-specific and it would be more correct to only + do this if the VexAbiInfo says that is what we should do. */ + if (d32 >= 0x40 && d32 <= 0x43) { + jmp_lit(Ijk_SigSEGV,((Addr32)guest_EIP_bbstart)+delta-2); + dres.whatNext = Dis_StopHere; + DIP("int $0x%x\n", (Int)d32); + break; + } + if (d32 != 0x80) goto decode_failure; /* It's important that all ArchRegs carry their up-to-date value at this point. So we declare an end-of-block here, which diff --git a/VEX/priv/host-amd64/hdefs.c b/VEX/priv/host-amd64/hdefs.c index 401dc46e2f..2ff737f036 100644 --- a/VEX/priv/host-amd64/hdefs.c +++ b/VEX/priv/host-amd64/hdefs.c @@ -2689,9 +2689,9 @@ Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i, case Ijk_NoRedir: *p++ = 0xBD; p = emit32(p, VEX_TRC_JMP_NOREDIR); break; - case Ijk_Trap: + case Ijk_SigTRAP: *p++ = 0xBD; - p = emit32(p, VEX_TRC_JMP_TRAP); break; + p = emit32(p, VEX_TRC_JMP_SIGTRAP); break; case Ijk_Ret: case Ijk_Call: case Ijk_Boring: diff --git a/VEX/priv/host-ppc/hdefs.c b/VEX/priv/host-ppc/hdefs.c index 60752ec7d4..f8163bb3e0 100644 --- a/VEX/priv/host-ppc/hdefs.c +++ b/VEX/priv/host-ppc/hdefs.c @@ -2949,7 +2949,7 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i, case Ijk_NoDecode: trc = VEX_TRC_JMP_NODECODE; break; case Ijk_TInval: trc = VEX_TRC_JMP_TINVAL; break; case Ijk_NoRedir: trc = VEX_TRC_JMP_NOREDIR; break; - case Ijk_Trap: trc = VEX_TRC_JMP_TRAP; break; + case Ijk_SigTRAP: trc = VEX_TRC_JMP_SIGTRAP; break; case Ijk_Ret: case Ijk_Call: case Ijk_Boring: diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index ec3b6566e4..171663d6c4 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -2297,9 +2297,12 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i, case Ijk_Sys_sysenter: *p++ = 0xBD; p = emit32(p, VEX_TRC_JMP_SYS_SYSENTER); break; - case Ijk_Trap: + case Ijk_SigTRAP: *p++ = 0xBD; - p = emit32(p, VEX_TRC_JMP_TRAP); break; + p = emit32(p, VEX_TRC_JMP_SIGTRAP); break; + case Ijk_SigSEGV: + *p++ = 0xBD; + p = emit32(p, VEX_TRC_JMP_SIGSEGV); break; case Ijk_Ret: case Ijk_Call: case Ijk_Boring: diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index 03b29626d3..cff1c5318e 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -726,7 +726,8 @@ void ppIRJumpKind ( IRJumpKind kind ) case Ijk_MapFail: vex_printf("MapFail"); break; case Ijk_TInval: vex_printf("Invalidate"); break; case Ijk_NoRedir: vex_printf("NoRedir"); break; - case Ijk_Trap: vex_printf("Trap"); break; + case Ijk_SigTRAP: vex_printf("SigTRAP"); break; + case Ijk_SigSEGV: vex_printf("SigSEGV"); break; case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break; case Ijk_Sys_int32: vex_printf("Sys_int32"); break; case Ijk_Sys_int128: vex_printf("Sys_int128"); break; diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 0dc8b2bd3c..84daa6aea8 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -1192,7 +1192,8 @@ typedef Ijk_MapFail, /* Vex-provided address translation failed */ Ijk_TInval, /* Invalidate translations before continuing. */ Ijk_NoRedir, /* Jump to un-redirected guest addr */ - Ijk_Trap, /* current instruction did a user trap */ + Ijk_SigTRAP, /* current instruction synths SIGTRAP */ + Ijk_SigSEGV, /* current instruction synths SIGSEGV */ /* Unfortunately, various guest-dependent syscall kinds. They all mean: do a syscall before continuing. */ Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc' */ diff --git a/VEX/pub/libvex_trc_values.h b/VEX/pub/libvex_trc_values.h index 91dbf983cf..4d8a0644ab 100644 --- a/VEX/pub/libvex_trc_values.h +++ b/VEX/pub/libvex_trc_values.h @@ -62,7 +62,9 @@ #define VEX_TRC_JMP_TINVAL 61 /* invalidate translations before continuing */ #define VEX_TRC_JMP_NOREDIR 81 /* jump to undirected guest addr */ -#define VEX_TRC_JMP_TRAP 85 /* deliver trap (SIGTRAP?) before +#define VEX_TRC_JMP_SIGTRAP 85 /* deliver trap (SIGTRAP) before + continuing */ +#define VEX_TRC_JMP_SIGSEGV 87 /* deliver segv (SIGSEGV) before continuing */ #define VEX_TRC_JMP_EMWARN 63 /* deliver emulation warning before continuing */ -- 2.47.2