From 9fb37614f76750b3804175799cc38e3f89d34d85 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Thu, 3 Nov 2005 13:27:24 +0000 Subject: [PATCH] API change: make the handling of syscall-denoting instructions a bit more general, so as to facilitate handling different combinations of syscall/int more easily. git-svn-id: svn://svn.valgrind.org/vex/trunk@1429 --- VEX/priv/guest-amd64/toIR.c | 29 +++++++++++++++++++++++++---- VEX/priv/guest-ppc32/toIR.c | 2 +- VEX/priv/guest-x86/toIR.c | 6 +++--- VEX/priv/host-amd64/hdefs.c | 7 +++++-- VEX/priv/host-ppc32/hdefs.c | 14 +++++++------- VEX/priv/host-x86/hdefs.c | 8 ++++---- VEX/priv/ir/irdefs.c | 26 ++++++++++++++------------ VEX/pub/libvex_ir.h | 10 +++++++--- VEX/pub/libvex_trc_values.h | 20 ++++++++++---------- 9 files changed, 76 insertions(+), 46 deletions(-) diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index ac80db1900..24781e7527 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -11516,6 +11516,27 @@ DisResult disInstr_AMD64_WRK ( goto decode_failure; } + /* ------------------------ INT ------------------------ */ + + case 0xCD: { /* INT imm8 */ + IRJumpKind jk = Ijk_Boring; + if (have66orF2orF3(pfx)) goto decode_failure; + d64 = getUChar(delta); delta++; + switch (d64) { + case 32: jk = Ijk_Sys_int32; break; + default: goto decode_failure; + } + guest_RIP_next_mustcheck = True; + guest_RIP_next_assumed = guest_RIP_bbstart + delta; + jmp_lit(jk, guest_RIP_next_assumed); + /* It's important that all ArchRegs carry their up-to-date value + at this point. So we declare an end-of-block here, which + forces any TempRegs caching ArchRegs to be flushed. */ + dres.whatNext = Dis_StopHere; + DIP("int $0x%02x\n", (UInt)d64); + break; + } + /* ------------------------ Jcond, byte offset --------- */ case 0xEB: /* Jb (jump, byte offset) */ @@ -13221,10 +13242,10 @@ DisResult disInstr_AMD64_WRK ( /* It's important that all guest state is up-to-date at this point. So we declare an end-of-block here, which forces any cached guest state to be flushed. */ - jmp_lit(Ijk_Syscall, guest_RIP_next_assumed); - dres.whatNext = Dis_StopHere; - DIP("syscall\n"); - break; + jmp_lit(Ijk_Sys_syscall, guest_RIP_next_assumed); + dres.whatNext = Dis_StopHere; + DIP("syscall\n"); + break; /* =-=-=-=-=-=-=-=-=- XADD -=-=-=-=-=-=-=-=-=-= */ diff --git a/VEX/priv/guest-ppc32/toIR.c b/VEX/priv/guest-ppc32/toIR.c index 66cb952813..2a38fa19ab 100644 --- a/VEX/priv/guest-ppc32/toIR.c +++ b/VEX/priv/guest-ppc32/toIR.c @@ -3132,7 +3132,7 @@ static Bool dis_syslink ( UInt theInstr, DisResult* dres ) at this point. So we declare an end-of-block here, which forces any TempRegs caching ArchRegs to be flushed. */ irbb->next = mkU32( guest_CIA_curr_instr + 4 ); - irbb->jumpkind = Ijk_Syscall; + irbb->jumpkind = Ijk_Sys_syscall; dres->whatNext = Dis_StopHere; return True; diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 0a8dea27f6..1fa3e0d04e 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -10637,7 +10637,7 @@ DisResult disInstr_X86_WRK ( /* It's important that all ArchRegs carry their up-to-date value at this point. So we declare an end-of-block here, which forces any TempRegs caching ArchRegs to be flushed. */ - jmp_lit(Ijk_Syscall,((Addr32)guest_EIP_bbstart)+delta); + jmp_lit(Ijk_Sys_int128,((Addr32)guest_EIP_bbstart)+delta); dres.whatNext = Dis_StopHere; DIP("int $0x80\n"); break; @@ -12245,13 +12245,13 @@ DisResult disInstr_X86_WRK ( is that the return address is not known -- that is something that is beyond Vex's knowledge. So this IR forces a return to the scheduler, which can do what it - likes to simulate the systemter, but it MUST set this + likes to simulate the systenter, but it MUST set this thread's guest_EIP field with the continuation address before resuming execution. If that doesn't happen, the thread will jump to address zero, which is probably fatal. */ - jmp_lit(Ijk_SysenterX86, 0/*bogus next EIP value*/); + jmp_lit(Ijk_Sys_sysenter, 0/*bogus next EIP value*/); dres.whatNext = Dis_StopHere; DIP("sysenter"); break; diff --git a/VEX/priv/host-amd64/hdefs.c b/VEX/priv/host-amd64/hdefs.c index 383ec274c0..d361b2333c 100644 --- a/VEX/priv/host-amd64/hdefs.c +++ b/VEX/priv/host-amd64/hdefs.c @@ -2585,9 +2585,12 @@ Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i ) case Ijk_ClientReq: *p++ = 0xBD; p = emit32(p, VEX_TRC_JMP_CLIENTREQ); break; - case Ijk_Syscall: + case Ijk_Sys_syscall: *p++ = 0xBD; - p = emit32(p, VEX_TRC_JMP_SYSCALL); break; + p = emit32(p, VEX_TRC_JMP_SYS_SYSCALL); break; + case Ijk_Sys_int32: + *p++ = 0xBD; + p = emit32(p, VEX_TRC_JMP_SYS_INT32); break; case Ijk_Yield: *p++ = 0xBD; p = emit32(p, VEX_TRC_JMP_YIELD); break; diff --git a/VEX/priv/host-ppc32/hdefs.c b/VEX/priv/host-ppc32/hdefs.c index d51161939c..9764884ae1 100644 --- a/VEX/priv/host-ppc32/hdefs.c +++ b/VEX/priv/host-ppc32/hdefs.c @@ -2491,13 +2491,13 @@ Int emit_PPC32Instr ( UChar* buf, Int nbuf, PPC32Instr* i ) /* If a non-boring, set GuestStatePtr appropriately. */ switch (i->Pin.Goto.jk) { - case Ijk_ClientReq: trc = VEX_TRC_JMP_CLIENTREQ; break; - case Ijk_Syscall: trc = VEX_TRC_JMP_SYSCALL; break; - case Ijk_Yield: trc = VEX_TRC_JMP_YIELD; break; - case Ijk_EmWarn: trc = VEX_TRC_JMP_EMWARN; break; - case Ijk_MapFail: trc = VEX_TRC_JMP_MAPFAIL; break; - case Ijk_NoDecode: trc = VEX_TRC_JMP_NODECODE; break; - case Ijk_TInval: trc = VEX_TRC_JMP_TINVAL; break; + case Ijk_ClientReq: trc = VEX_TRC_JMP_CLIENTREQ; break; + case Ijk_Sys_syscall: trc = VEX_TRC_JMP_SYS_SYSCALL; break; + case Ijk_Yield: trc = VEX_TRC_JMP_YIELD; break; + case Ijk_EmWarn: trc = VEX_TRC_JMP_EMWARN; break; + case Ijk_MapFail: trc = VEX_TRC_JMP_MAPFAIL; break; + case Ijk_NoDecode: trc = VEX_TRC_JMP_NODECODE; break; + case Ijk_TInval: trc = VEX_TRC_JMP_TINVAL; 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 411553c625..6355a5772a 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -2147,9 +2147,9 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) case Ijk_ClientReq: *p++ = 0xBD; p = emit32(p, VEX_TRC_JMP_CLIENTREQ); break; - case Ijk_Syscall: + case Ijk_Sys_int128: *p++ = 0xBD; - p = emit32(p, VEX_TRC_JMP_SYSCALL); break; + p = emit32(p, VEX_TRC_JMP_SYS_INT128); break; case Ijk_Yield: *p++ = 0xBD; p = emit32(p, VEX_TRC_JMP_YIELD); break; @@ -2165,9 +2165,9 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) case Ijk_TInval: *p++ = 0xBD; p = emit32(p, VEX_TRC_JMP_TINVAL); break; - case Ijk_SysenterX86: + case Ijk_Sys_sysenter: *p++ = 0xBD; - p = emit32(p, VEX_TRC_JMP_SYSENTER_X86); break; + p = emit32(p, VEX_TRC_JMP_SYS_SYSENTER); 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 1dcdd1cbcb..7297ac1f3d 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -653,18 +653,20 @@ void ppIRDirty ( IRDirty* d ) void ppIRJumpKind ( IRJumpKind kind ) { switch (kind) { - case Ijk_Boring: vex_printf("Boring"); break; - case Ijk_Call: vex_printf("Call"); break; - case Ijk_Ret: vex_printf("Return"); break; - case Ijk_ClientReq: vex_printf("ClientReq"); break; - case Ijk_Syscall: vex_printf("Syscall"); break; - case Ijk_Yield: vex_printf("Yield"); break; - case Ijk_EmWarn: vex_printf("EmWarn"); break; - case Ijk_NoDecode: vex_printf("NoDecode"); break; - case Ijk_MapFail: vex_printf("MapFail"); break; - case Ijk_TInval: vex_printf("Invalidate"); break; - case Ijk_SysenterX86: vex_printf("SysenterX86"); break; - default: vpanic("ppIRJumpKind"); + case Ijk_Boring: vex_printf("Boring"); break; + case Ijk_Call: vex_printf("Call"); break; + case Ijk_Ret: vex_printf("Return"); break; + case Ijk_ClientReq: vex_printf("ClientReq"); break; + case Ijk_Yield: vex_printf("Yield"); break; + case Ijk_EmWarn: vex_printf("EmWarn"); break; + case Ijk_NoDecode: vex_printf("NoDecode"); break; + case Ijk_MapFail: vex_printf("MapFail"); break; + case Ijk_TInval: vex_printf("Invalidate"); 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; + case Ijk_Sys_sysenter: vex_printf("Sys_sysenter"); break; + default: vpanic("ppIRJumpKind"); } } diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index b0d2de4398..2f4049dbc1 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -833,14 +833,18 @@ typedef Ijk_Call, /* guest is doing a call */ Ijk_Ret, /* guest is doing a return */ Ijk_ClientReq, /* do guest client req before continuing */ - Ijk_Syscall, /* do guest syscall before continuing */ Ijk_Yield, /* client is yielding to thread scheduler */ Ijk_EmWarn, /* report emulation warning before continuing */ Ijk_NoDecode, /* next instruction cannot be decoded */ Ijk_MapFail, /* Vex-provided address translation failed */ Ijk_TInval, /* Invalidate translations before continuing. */ - Ijk_SysenterX86 /* X86 sysenter. guest_EIP becomes invalid - at the point this happens. */ + /* Unfortunately, various guest-dependent syscall kinds. They + all mean: do a syscall before continuing. */ + Ijk_Sys_syscall, /* amd64 'syscall', ppc32 'sc' */ + Ijk_Sys_int32, /* amd64/x86 'int $0x20' */ + Ijk_Sys_int128, /* amd64/x86 'int $0x80' */ + Ijk_Sys_sysenter /* x86 'sysenter'. guest_EIP becomes + invalid at the point this happens. */ } IRJumpKind; diff --git a/VEX/pub/libvex_trc_values.h b/VEX/pub/libvex_trc_values.h index 8de587dd03..757ceead25 100644 --- a/VEX/pub/libvex_trc_values.h +++ b/VEX/pub/libvex_trc_values.h @@ -56,20 +56,20 @@ C-specific constructs in it. */ -#define VEX_TRC_JMP_TINVAL 13 /* invalidate translations before +#define VEX_TRC_JMP_TINVAL 61 /* invalidate translations before continuing */ -#define VEX_TRC_JMP_EMWARN 17 /* deliver emulation warning before +#define VEX_TRC_JMP_EMWARN 63 /* deliver emulation warning before continuing */ -#define VEX_TRC_JMP_SYSCALL 19 /* do a system call before continuing */ -#define VEX_TRC_JMP_CLIENTREQ 23 /* do a client req before continuing */ -#define VEX_TRC_JMP_YIELD 27 /* yield to thread sched +#define VEX_TRC_JMP_CLIENTREQ 65 /* do a client req before continuing */ +#define VEX_TRC_JMP_YIELD 67 /* yield to thread sched before continuing */ -#define VEX_TRC_JMP_NODECODE 29 /* next instruction in not decodable */ -#define VEX_TRC_JMP_MAPFAIL 31 /* address translation failed */ - -#define VEX_TRC_JMP_SYSENTER_X86 9 /* simulate X86 sysenter before - continuing */ +#define VEX_TRC_JMP_NODECODE 69 /* next instruction is not decodable */ +#define VEX_TRC_JMP_MAPFAIL 71 /* address translation failed */ +#define VEX_TRC_JMP_SYS_SYSCALL 73 /* do syscall before continuing */ +#define VEX_TRC_JMP_SYS_INT32 75 /* do syscall before continuing */ +#define VEX_TRC_JMP_SYS_INT128 77 /* do syscall before continuing */ +#define VEX_TRC_JMP_SYS_SYSENTER 79 /* do syscall before continuing */ #endif /* ndef __LIBVEX_TRC_VALUES_H */ -- 2.47.3