Module Name: src Committed By: reinoud Date: Fri Jan 6 20:44:57 UTC 2012
Modified Files: src/sys/arch/usermode/conf: GENERIC.i386 Makefile.usermode src/sys/arch/usermode/usermode: machdep.c Added Files: src/sys/arch/usermode/conf: GENERIC.amd64 src/sys/arch/usermode/usermode: machdep.i386.c Log Message: Split machdep.c into a MI part and a MD part. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/sys/arch/usermode/conf/GENERIC.amd64 cvs rdiff -u -r1.2 -r1.3 src/sys/arch/usermode/conf/GENERIC.i386 cvs rdiff -u -r1.28 -r1.29 src/sys/arch/usermode/conf/Makefile.usermode cvs rdiff -u -r1.48 -r1.49 src/sys/arch/usermode/usermode/machdep.c cvs rdiff -u -r0 -r1.1 src/sys/arch/usermode/usermode/machdep.i386.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/usermode/conf/GENERIC.i386 diff -u src/sys/arch/usermode/conf/GENERIC.i386:1.2 src/sys/arch/usermode/conf/GENERIC.i386:1.3 --- src/sys/arch/usermode/conf/GENERIC.i386:1.2 Tue Jan 3 21:28:50 2012 +++ src/sys/arch/usermode/conf/GENERIC.i386 Fri Jan 6 20:44:57 2012 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC.i386,v 1.2 2012/01/03 21:28:50 reinoud Exp $ +# $NetBSD: GENERIC.i386,v 1.3 2012/01/06 20:44:57 reinoud Exp $ machine usermode include "arch/usermode/conf/GENERIC.common" @@ -9,9 +9,11 @@ no options EXEC_ELF64 options TEXTADDR=0x40000000 # 1 Gb `phys ram' / total space options KVMSIZE= 0x10000000 # KVM space reserved in VM map, 256 Mb options NKMEMPAGES_MAX=32768 # 128 Mb max + +makeoptions USERMODE_CPU="i386" makeoptions COPTS+="-m32" makeoptions LD="ld -melf_i386" #options INCLUDE_CONFIG_FILE -#ident "GENERIC32-$Revision: 1.2 $" +#ident "GENERIC32-$Revision: 1.3 $" Index: src/sys/arch/usermode/conf/Makefile.usermode diff -u src/sys/arch/usermode/conf/Makefile.usermode:1.28 src/sys/arch/usermode/conf/Makefile.usermode:1.29 --- src/sys/arch/usermode/conf/Makefile.usermode:1.28 Thu Jan 5 12:12:58 2012 +++ src/sys/arch/usermode/conf/Makefile.usermode Fri Jan 6 20:44:57 2012 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.usermode,v 1.28 2012/01/05 12:12:58 jmcneill Exp $ +# $NetBSD: Makefile.usermode,v 1.29 2012/01/06 20:44:57 reinoud Exp $ OPT_CPU_HOST= %CPU_HOST% .if !empty(OPT_CPU_HOST) @@ -53,6 +53,9 @@ MD_OBJS= thunk.o MD_CFILES= ${USERMODE}/usermode/thunk.c MD_SFILES= +MD_OBJS+= machdep.${USERMODE_CPU}.o +MD_CFILES+= ${USERMODE}/usermode/machdep.${USERMODE_CPU}.c + ## ## (5) link settings ## @@ -76,6 +79,8 @@ NVFLAGS= -n .BEGIN: @rm -f i386 && \ ln -s $S/arch/i386/include i386 + @rm -f amd64 && \ + ln -s $S/arch/amd64/include amd64 .endif thunk.d: ${USERMODE}/usermode/thunk.c Index: src/sys/arch/usermode/usermode/machdep.c diff -u src/sys/arch/usermode/usermode/machdep.c:1.48 src/sys/arch/usermode/usermode/machdep.c:1.49 --- src/sys/arch/usermode/usermode/machdep.c:1.48 Tue Jan 3 10:53:46 2012 +++ src/sys/arch/usermode/usermode/machdep.c Fri Jan 6 20:44:57 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.48 2012/01/03 10:53:46 reinoud Exp $ */ +/* $NetBSD: machdep.c,v 1.49 2012/01/06 20:44:57 reinoud Exp $ */ /*- * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org> @@ -37,7 +37,7 @@ #include "opt_memsize.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.48 2012/01/03 10:53:46 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.49 2012/01/06 20:44:57 reinoud Exp $"); #include <sys/types.h> #include <sys/systm.h> @@ -226,304 +226,3 @@ mm_md_physacc(paddr_t pa, vm_prot_t prog return 0; } - -#ifdef __i386__ - -#if 0 -static void dump_regs(register_t *reg);; - -static void -dump_regs(register_t *reg) -{ - int i; - - /* register dump before call */ - const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP", - "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL", - "UESP", "SS"}; - - for (i =0; i < 19; i++) - printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], (uint32_t) reg[i]); -} -#endif - - -/* from sys/arch/i386/include/frame.h : KEEP IN SYNC */ - -/* - * New-style signal frame - */ -struct sigframe_siginfo { - int sf_ra; /* return address for handler */ - int sf_signum; /* "signum" argument for handler */ - siginfo_t *sf_sip; /* "sip" argument for handler */ - ucontext_t *sf_ucp; /* "ucp" argument for handler */ - siginfo_t sf_si; /* actual saved siginfo */ - ucontext_t sf_uc; /* actual saved ucontext */ -}; - - -/* - * mcontext extensions to handle signal delivery. - */ -#define _UC_SETSTACK 0x00010000 -#define _UC_CLRSTACK 0x00020000 -#define _UC_VM 0x00040000 -#define _UC_TLSBASE 0x00080000 - - -void -sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) -{ - struct lwp *l = curlwp; - struct proc *p = l->l_proc; - struct pcb *pcb = lwp_getpcb(l); - struct sigacts *ps = p->p_sigacts; - struct sigframe_siginfo *fp, frame; - int sig = ksi->ksi_signo; - sig_t catcher = SIGACTION(p, sig).sa_handler; - ucontext_t *ucp = &pcb->pcb_userret_ucp; - register_t *reg = (register_t *) &ucp->uc_mcontext; - int onstack, error; - - KASSERT(mutex_owned(p->p_lock)); - -#if 0 - printf("%s: ", __func__); - printf("flags %d, ", (int) ksi->ksi_flags); - printf("to lwp %d, signo %d, code %d, errno %d\n", - (int) ksi->ksi_lid, - ksi->ksi_signo, - ksi->ksi_code, - ksi->ksi_errno); -#endif - - /* do we need to jump onto the signal stack? */ - onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 - && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; - - fp = (void *) reg[17]; /* ESP */ - if (onstack) - fp = (void *) - ((char *) l->l_sigstk.ss_sp + l->l_sigstk.ss_size); - - fp--; - - /* set up stack frame */ - frame.sf_ra = (int)ps->sa_sigdesc[sig].sd_tramp; - frame.sf_signum = sig; - frame.sf_sip = &fp->sf_si; - frame.sf_ucp = &fp->sf_uc; - frame.sf_si._info = ksi->ksi_info; - - /* copy our userret context into sf_uc */ - memcpy(&frame.sf_uc, ucp, sizeof(ucontext_t)); - frame.sf_uc.uc_sigmask = *mask; - frame.sf_uc.uc_link = l->l_ctxlink; /* XXX ??? */ - frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK) - ? _UC_SETSTACK : _UC_CLRSTACK; - memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack)); - - sendsig_reset(l, sig); - - /* copyout our frame to the stackframe */ - mutex_exit(p->p_lock); - error = copyout(&frame, fp, sizeof(frame)); - mutex_enter(p->p_lock); - - if (error != 0) { - /* - * Process has trashed its stack; give it an illegal - * instruction to halt it in its tracks. - */ - sigexit(l, SIGILL); - /* NOTREACHED */ - } - - /* set catcher and the new stack pointer */ - reg[17] = (register_t) fp; /* ESP */ - reg[14] = (register_t) catcher; /* EIP */ - - /* Remember that we're now on the signal stack. */ - if (onstack) - l->l_sigstk.ss_flags |= SS_ONSTACK; -} - -void -setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) -{ - struct pcb *pcb = lwp_getpcb(l); - ucontext_t *ucp = &pcb->pcb_userret_ucp; - uint *reg, i; - -#ifdef DEBUG_EXEC - printf("setregs called: lwp %p, exec package %p, stack %p\n", - l, pack, (void *) stack); - printf("current stat of pcb %p\n", pcb); - printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", - pcb->pcb_ucp.uc_stack.ss_sp); - printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", - (int) pcb->pcb_ucp.uc_stack.ss_size); - printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", - pcb->pcb_userret_ucp.uc_stack.ss_sp); - printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", - (int) pcb->pcb_userret_ucp.uc_stack.ss_size); -#endif - - reg = (int *) &ucp->uc_mcontext; - for (i = 4; i < 11; i++) - reg[i] = 0; - - ucp->uc_stack.ss_sp = (void *) (stack-4); /* to prevent clearing */ - ucp->uc_stack.ss_size = 0; //pack->ep_ssize; - thunk_makecontext(ucp, (void *) pack->ep_entry, 0, NULL, NULL, NULL); - - /* patch up */ - reg[ 8] = l->l_proc->p_psstrp; /* _REG_EBX */ - reg[17] = (stack); /* _REG_UESP */ - - //dump_regs(reg); - -#ifdef DEBUG_EXEC - printf("updated pcb %p\n", pcb); - printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", - pcb->pcb_ucp.uc_stack.ss_sp); - printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", - (int) pcb->pcb_ucp.uc_stack.ss_size); - printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", - pcb->pcb_userret_ucp.uc_stack.ss_sp); - printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", - (int) pcb->pcb_userret_ucp.uc_stack.ss_size); - printf("\tpack->ep_entry = %p\n", - (void *) pack->ep_entry); -#endif -} - -void -md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code) -{ - uint *reg = (int *) &ucp->uc_mcontext; - *code = reg[11]; /* EAX */ -} - -int -md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize, - register_t *args) -{ - uint *reg = (int *) &ucp->uc_mcontext; - register_t *sp = (register_t *) reg[17];/* ESP */ - int ret; - - //dump_regs(reg); - ret = copyin(sp + 1, args, argsize); - - return ret; -} - -void -md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, - int error, register_t *rval) -{ - register_t *reg = (register_t *) &ucp->uc_mcontext; - - reg[16] &= ~PSL_C; /* EFL */ - if (error > 0) { - rval[0] = error; - reg[16] |= PSL_C; /* EFL */ - } - - /* set return parameters */ - reg[11] = rval[0]; /* EAX */ - if (error == 0) - reg[ 9] = rval[1]; /* EDX */ - - //dump_regs(reg); -} - -register_t -md_get_pc(ucontext_t *ucp) -{ - register_t *reg = (register_t *) &ucp->uc_mcontext; - - return reg[14]; /* EIP */ -} - -int -md_syscall_check_opcode(ucontext_t *ucp) -{ - uint32_t opcode; - - md_syscall_get_opcode(ucp, &opcode); - - switch (opcode) { - case 0xff0f: /* UD1 */ - case 0xff0b: /* UD2 */ - case 0x80cd: /* int $80 */ - case 0x340f: /* sysenter */ - return 1; - default: - return 0; - } -} - -void -md_syscall_get_opcode(ucontext_t *ucp, uint32_t *opcode) -{ - register_t *reg = (register_t *) &ucp->uc_mcontext; -// uint8_t *p8 = (uint8_t *) (reg[14]); - uint16_t *p16 = (uint16_t*) (reg[14]); /* EIP */ - - switch (*p16) { - case 0xff0f: /* UD1 */ - case 0xff0b: /* UD2 */ - case 0x80cd: /* int $80 */ - case 0x340f: /* sysenter */ - *opcode = *p16; - break; - default: - *opcode = 0; - } -} - -void -md_syscall_inc_pc(ucontext_t *ucp, uint32_t opcode) -{ - uint *reg = (int *) &ucp->uc_mcontext; - - /* advance program counter */ - switch (opcode) { - case 0xff0f: /* UD1 */ - case 0xff0b: /* UD2 */ - case 0x80cd: /* int $80 */ - case 0x340f: /* sysenter */ - reg[14] += 2; /* EIP */ - break; - default: - panic("%s, unknown illegal instruction: opcode = %x\n", - __func__, (uint32_t) opcode); - } -} - -void -md_syscall_dec_pc(ucontext_t *ucp, uint32_t opcode) -{ - uint *reg = (int *) &ucp->uc_mcontext; - - switch (opcode) { - case 0xff0f: /* UD1 */ - case 0xff0b: /* UD2 */ - case 0x80cd: /* int $80 */ - case 0x340f: /* sysenter */ - reg[14] -= 2; /* EIP */ - break; - default: - panic("%s, unknown illegal instruction: opcode = %x\n", - __func__, (uint32_t) opcode); - } -} - - -#else -# error machdep functions not yet ported to this architecture -#endif - Added files: Index: src/sys/arch/usermode/conf/GENERIC.amd64 diff -u /dev/null src/sys/arch/usermode/conf/GENERIC.amd64:1.1 --- /dev/null Fri Jan 6 20:44:57 2012 +++ src/sys/arch/usermode/conf/GENERIC.amd64 Fri Jan 6 20:44:57 2012 @@ -0,0 +1,19 @@ +# $NetBSD: GENERIC.amd64,v 1.1 2012/01/06 20:44:57 reinoud Exp $ + +machine usermode +include "arch/usermode/conf/GENERIC.common" +include "arch/amd64/conf/majors.amd64" + +no options EXEC_ELF32 + +options TEXTADDR=0x40000000 # 1 Gb `phys ram' / total space +options KVMSIZE= 0x10000000 # KVM space reserved in VM map, 256 Mb +options NKMEMPAGES_MAX=32768 # 128 Mb max + +makeoptions USERMODE_CPU="amd64" +makeoptions COPTS+="-m64" +makeoptions LD="ld -melf_amd64" + +#options INCLUDE_CONFIG_FILE +#ident "GENERIC32-$Revision: 1.1 $" + Index: src/sys/arch/usermode/usermode/machdep.i386.c diff -u /dev/null src/sys/arch/usermode/usermode/machdep.i386.c:1.1 --- /dev/null Fri Jan 6 20:44:57 2012 +++ src/sys/arch/usermode/usermode/machdep.i386.c Fri Jan 6 20:44:57 2012 @@ -0,0 +1,356 @@ +/* $NetBSD: machdep.i386.c,v 1.1 2012/01/06 20:44:57 reinoud Exp $ */ + +/*- + * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org> + * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Note that this machdep.c uses the `dummy' mcontext_t defined for usermode. + * This is basicly a blob of PAGE_SIZE big. We might want to switch over to + * non-generic mcontext_t's one day, but will this break non-NetBSD hosts? + */ + + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: machdep.i386.c,v 1.1 2012/01/06 20:44:57 reinoud Exp $"); + +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/param.h> +#include <sys/time.h> +#include <sys/exec.h> +#include <sys/buf.h> +#include <sys/boot_flag.h> +#include <sys/ucontext.h> +#include <sys/utsname.h> +#include <machine/pcb.h> +#include <machine/psl.h> + +#include <uvm/uvm_extern.h> +#include <uvm/uvm_page.h> + +#include <dev/mm.h> +#include <machine/machdep.h> +#include <machine/thunk.h> + + +#ifdef __i386__ + +#if 0 +static void dump_regs(register_t *reg);; + +static void +dump_regs(register_t *reg) +{ + int i; + + /* register dump before call */ + const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP", + "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL", + "UESP", "SS"}; + + for (i =0; i < 19; i++) + printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], (uint32_t) reg[i]); +} +#endif + + +/* from sys/arch/i386/include/frame.h : KEEP IN SYNC */ + +/* + * New-style signal frame + */ +struct sigframe_siginfo { + int sf_ra; /* return address for handler */ + int sf_signum; /* "signum" argument for handler */ + siginfo_t *sf_sip; /* "sip" argument for handler */ + ucontext_t *sf_ucp; /* "ucp" argument for handler */ + siginfo_t sf_si; /* actual saved siginfo */ + ucontext_t sf_uc; /* actual saved ucontext */ +}; + + +/* + * mcontext extensions to handle signal delivery. + */ +#define _UC_SETSTACK 0x00010000 +#define _UC_CLRSTACK 0x00020000 +#define _UC_VM 0x00040000 +#define _UC_TLSBASE 0x00080000 + + +void +sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) +{ + struct lwp *l = curlwp; + struct proc *p = l->l_proc; + struct pcb *pcb = lwp_getpcb(l); + struct sigacts *ps = p->p_sigacts; + struct sigframe_siginfo *fp, frame; + int sig = ksi->ksi_signo; + sig_t catcher = SIGACTION(p, sig).sa_handler; + ucontext_t *ucp = &pcb->pcb_userret_ucp; + register_t *reg = (register_t *) &ucp->uc_mcontext; + int onstack, error; + + KASSERT(mutex_owned(p->p_lock)); + +#if 0 + printf("%s: ", __func__); + printf("flags %d, ", (int) ksi->ksi_flags); + printf("to lwp %d, signo %d, code %d, errno %d\n", + (int) ksi->ksi_lid, + ksi->ksi_signo, + ksi->ksi_code, + ksi->ksi_errno); +#endif + + /* do we need to jump onto the signal stack? */ + onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 + && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; + + fp = (void *) reg[17]; /* ESP */ + if (onstack) + fp = (void *) + ((char *) l->l_sigstk.ss_sp + l->l_sigstk.ss_size); + + fp--; + + /* set up stack frame */ + frame.sf_ra = (int)ps->sa_sigdesc[sig].sd_tramp; + frame.sf_signum = sig; + frame.sf_sip = &fp->sf_si; + frame.sf_ucp = &fp->sf_uc; + frame.sf_si._info = ksi->ksi_info; + + /* copy our userret context into sf_uc */ + memcpy(&frame.sf_uc, ucp, sizeof(ucontext_t)); + frame.sf_uc.uc_sigmask = *mask; + frame.sf_uc.uc_link = l->l_ctxlink; /* XXX ??? */ + frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK) + ? _UC_SETSTACK : _UC_CLRSTACK; + memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack)); + + sendsig_reset(l, sig); + + /* copyout our frame to the stackframe */ + mutex_exit(p->p_lock); + error = copyout(&frame, fp, sizeof(frame)); + mutex_enter(p->p_lock); + + if (error != 0) { + /* + * Process has trashed its stack; give it an illegal + * instruction to halt it in its tracks. + */ + sigexit(l, SIGILL); + /* NOTREACHED */ + } + + /* set catcher and the new stack pointer */ + reg[17] = (register_t) fp; /* ESP */ + reg[14] = (register_t) catcher; /* EIP */ + + /* Remember that we're now on the signal stack. */ + if (onstack) + l->l_sigstk.ss_flags |= SS_ONSTACK; +} + +void +setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) +{ + struct pcb *pcb = lwp_getpcb(l); + ucontext_t *ucp = &pcb->pcb_userret_ucp; + uint *reg, i; + +#ifdef DEBUG_EXEC + printf("setregs called: lwp %p, exec package %p, stack %p\n", + l, pack, (void *) stack); + printf("current stat of pcb %p\n", pcb); + printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", + pcb->pcb_ucp.uc_stack.ss_sp); + printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", + (int) pcb->pcb_ucp.uc_stack.ss_size); + printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", + pcb->pcb_userret_ucp.uc_stack.ss_sp); + printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", + (int) pcb->pcb_userret_ucp.uc_stack.ss_size); +#endif + + reg = (int *) &ucp->uc_mcontext; + for (i = 4; i < 11; i++) + reg[i] = 0; + + ucp->uc_stack.ss_sp = (void *) (stack-4); /* to prevent clearing */ + ucp->uc_stack.ss_size = 0; //pack->ep_ssize; + thunk_makecontext(ucp, (void *) pack->ep_entry, 0, NULL, NULL, NULL); + + /* patch up */ + reg[ 8] = l->l_proc->p_psstrp; /* _REG_EBX */ + reg[17] = (stack); /* _REG_UESP */ + + //dump_regs(reg); + +#ifdef DEBUG_EXEC + printf("updated pcb %p\n", pcb); + printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", + pcb->pcb_ucp.uc_stack.ss_sp); + printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", + (int) pcb->pcb_ucp.uc_stack.ss_size); + printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", + pcb->pcb_userret_ucp.uc_stack.ss_sp); + printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", + (int) pcb->pcb_userret_ucp.uc_stack.ss_size); + printf("\tpack->ep_entry = %p\n", + (void *) pack->ep_entry); +#endif +} + +void +md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code) +{ + uint *reg = (int *) &ucp->uc_mcontext; + *code = reg[11]; /* EAX */ +} + +int +md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize, + register_t *args) +{ + uint *reg = (int *) &ucp->uc_mcontext; + register_t *sp = (register_t *) reg[17];/* ESP */ + int ret; + + //dump_regs(reg); + ret = copyin(sp + 1, args, argsize); + + return ret; +} + +void +md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, + int error, register_t *rval) +{ + register_t *reg = (register_t *) &ucp->uc_mcontext; + + reg[16] &= ~PSL_C; /* EFL */ + if (error > 0) { + rval[0] = error; + reg[16] |= PSL_C; /* EFL */ + } + + /* set return parameters */ + reg[11] = rval[0]; /* EAX */ + if (error == 0) + reg[ 9] = rval[1]; /* EDX */ + + //dump_regs(reg); +} + +register_t +md_get_pc(ucontext_t *ucp) +{ + register_t *reg = (register_t *) &ucp->uc_mcontext; + + return reg[14]; /* EIP */ +} + +int +md_syscall_check_opcode(ucontext_t *ucp) +{ + uint32_t opcode; + + md_syscall_get_opcode(ucp, &opcode); + + switch (opcode) { + case 0xff0f: /* UD1 */ + case 0xff0b: /* UD2 */ + case 0x80cd: /* int $80 */ + case 0x340f: /* sysenter */ + return 1; + default: + return 0; + } +} + +void +md_syscall_get_opcode(ucontext_t *ucp, uint32_t *opcode) +{ + register_t *reg = (register_t *) &ucp->uc_mcontext; +// uint8_t *p8 = (uint8_t *) (reg[14]); + uint16_t *p16 = (uint16_t*) (reg[14]); /* EIP */ + + switch (*p16) { + case 0xff0f: /* UD1 */ + case 0xff0b: /* UD2 */ + case 0x80cd: /* int $80 */ + case 0x340f: /* sysenter */ + *opcode = *p16; + break; + default: + *opcode = 0; + } +} + +void +md_syscall_inc_pc(ucontext_t *ucp, uint32_t opcode) +{ + uint *reg = (int *) &ucp->uc_mcontext; + + /* advance program counter */ + switch (opcode) { + case 0xff0f: /* UD1 */ + case 0xff0b: /* UD2 */ + case 0x80cd: /* int $80 */ + case 0x340f: /* sysenter */ + reg[14] += 2; /* EIP */ + break; + default: + panic("%s, unknown illegal instruction: opcode = %x\n", + __func__, (uint32_t) opcode); + } +} + +void +md_syscall_dec_pc(ucontext_t *ucp, uint32_t opcode) +{ + uint *reg = (int *) &ucp->uc_mcontext; + + switch (opcode) { + case 0xff0f: /* UD1 */ + case 0xff0b: /* UD2 */ + case 0x80cd: /* int $80 */ + case 0x340f: /* sysenter */ + reg[14] -= 2; /* EIP */ + break; + default: + panic("%s, unknown illegal instruction: opcode = %x\n", + __func__, (uint32_t) opcode); + } +} + +#endif +