From: Tom Hughes Date: Sat, 11 Feb 2006 16:26:46 +0000 (+0000) Subject: Implement the vm86 and vm86old system calls based on a patch X-Git-Tag: svn/VALGRIND_3_2_0~279 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c2633355ff45d4fdd0222e45ac48826109d0b80;p=thirdparty%2Fvalgrind.git Implement the vm86 and vm86old system calls based on a patch from Alper Akcan. Fixes bug #118939. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5635 --- diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 8f1ecf5119..e277efe779 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -772,6 +772,8 @@ DECL_TEMPLATE(x86_linux, sys_get_thread_area); DECL_TEMPLATE(x86_linux, sys_ptrace); DECL_TEMPLATE(x86_linux, sys_sigaction); DECL_TEMPLATE(x86_linux, old_select); +DECL_TEMPLATE(x86_linux, sys_vm86old); +DECL_TEMPLATE(x86_linux, sys_vm86); DECL_TEMPLATE(x86_linux, sys_syscall223); PRE(old_select) @@ -1677,6 +1679,32 @@ POST(sys_sigaction) POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction)); } +PRE(sys_vm86old) +{ + PRINT("sys_vm86old ( %p )", ARG1); + PRE_REG_READ1(int, "vm86old", struct vm86_struct *, info); + PRE_MEM_WRITE( "vm86old(info)", ARG1, sizeof(struct vki_vm86_struct)); +} + +POST(sys_vm86old) +{ + POST_MEM_WRITE( ARG1, sizeof(struct vki_vm86_struct)); +} + +PRE(sys_vm86) +{ + PRINT("sys_vm86 ( %d, %p )", ARG1,ARG2); + PRE_REG_READ2(int, "vm86", unsigned long, fn, struct vm86plus_struct *, v86); + if (ARG1 == VKI_VM86_ENTER || ARG1 == VKI_VM86_ENTER_NO_BYPASS) + PRE_MEM_WRITE( "vm86(v86)", ARG2, sizeof(struct vki_vm86plus_struct)); +} + +POST(sys_vm86) +{ + if (ARG1 == VKI_VM86_ENTER || ARG1 == VKI_VM86_ENTER_NO_BYPASS) + POST_MEM_WRITE( ARG2, sizeof(struct vki_vm86plus_struct)); +} + /* --------------------------------------------------------------- PRE/POST wrappers for x86/Linux-variant specific syscalls @@ -1869,7 +1897,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { GENX_(__NR_iopl, sys_iopl), // 110 LINX_(__NR_vhangup, sys_vhangup), // 111 GENX_(__NR_idle, sys_ni_syscall), // 112 -//zz // (__NR_vm86old, sys_vm86old), // 113 x86/Linux-only + PLAXY(__NR_vm86old, sys_vm86old), // 113 x86/Linux-only GENXY(__NR_wait4, sys_wait4), // 114 //zz //zz // (__NR_swapoff, sys_swapoff), // 115 */Linux @@ -1935,7 +1963,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINX_(__NR_setresuid, sys_setresuid16), // 164 LINXY(__NR_getresuid, sys_getresuid16), // 165 -//zz // (__NR_vm86, sys_vm86), // 166 x86/Linux-only + PLAXY(__NR_vm86, sys_vm86), // 166 x86/Linux-only GENX_(__NR_query_module, sys_ni_syscall), // 167 GENXY(__NR_poll, sys_poll), // 168 //zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux diff --git a/include/vki-x86-linux.h b/include/vki-x86-linux.h index 3efc9649cf..eb1c99edac 100644 --- a/include/vki-x86-linux.h +++ b/include/vki-x86-linux.h @@ -785,6 +785,80 @@ struct vki_shminfo64 { #define VKI_PTRACE_GETFPXREGS 18 #define VKI_PTRACE_SETFPXREGS 19 +//---------------------------------------------------------------------- +// From linux-2.6.15.4/include/asm-i386/vm86.h +//---------------------------------------------------------------------- + +#define VKI_VM86_PLUS_INSTALL_CHECK 0 +#define VKI_VM86_ENTER 1 +#define VKI_VM86_ENTER_NO_BYPASS 2 +#define VKI_VM86_REQUEST_IRQ 3 +#define VKI_VM86_FREE_IRQ 4 +#define VKI_VM86_GET_IRQ_BITS 5 +#define VKI_VM86_GET_AND_RESET_IRQ 6 + +struct vki_vm86_regs { +/* + * normal regs, with special meaning for the segment descriptors.. + */ + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + long __null_ds; + long __null_es; + long __null_fs; + long __null_gs; + long orig_eax; + long eip; + unsigned short cs, __csh; + long eflags; + long esp; + unsigned short ss, __ssh; +/* + * these are specific to v86 mode: + */ + unsigned short es, __esh; + unsigned short ds, __dsh; + unsigned short fs, __fsh; + unsigned short gs, __gsh; +}; + +struct vki_revectored_struct { + unsigned long __map[8]; /* 256 bits */ +}; + +struct vki_vm86_struct { + struct vki_vm86_regs regs; + unsigned long flags; + unsigned long screen_bitmap; + unsigned long cpu_type; + struct vki_revectored_struct int_revectored; + struct vki_revectored_struct int21_revectored; +}; + +struct vki_vm86plus_info_struct { + unsigned long force_return_for_pic:1; + unsigned long vm86dbg_active:1; /* for debugger */ + unsigned long vm86dbg_TFpendig:1; /* for debugger */ + unsigned long unused:28; + unsigned long is_vm86pus:1; /* for vm86 internal use */ + unsigned char vm86dbg_intxxtab[32]; /* for debugger */ +}; + +struct vki_vm86plus_struct { + struct vki_vm86_regs regs; + unsigned long flags; + unsigned long screen_bitmap; + unsigned long cpu_type; + struct vki_revectored_struct int_revectored; + struct vki_revectored_struct int21_revectored; + struct vki_vm86plus_info_struct vm86plus; +}; + //---------------------------------------------------------------------- // And that's it! //----------------------------------------------------------------------