示例#1
0
static int
linux_fixup(register_t **stack_base, struct image_params *imgp)
{
	register_t *argv, *envp;

	argv = *stack_base;
	envp = *stack_base + (imgp->args->argc + 1);
	(*stack_base)--;
	suword(*stack_base, (intptr_t)(void *)envp);
	(*stack_base)--;
	suword(*stack_base, (intptr_t)(void *)argv);
	(*stack_base)--;
	suword(*stack_base, imgp->args->argc);
	return (0);
}
示例#2
0
/*
 * Set that machine state for performing an upcall that starts
 * the entry function with the given argument.
 */
void
cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
    stack_t *stack)
{

	/* 
	 * Do any extra cleaning that needs to be done.
	 * The thread may have optional components
	 * that are not present in a fresh thread.
	 * This may be a recycled thread so make it look
	 * as though it's newly allocated.
	 */
	cpu_thread_clean(td);

#ifdef COMPAT_FREEBSD32
	if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
		/*
		 * Set the trap frame to point at the beginning of the entry
		 * function.
		 */
		td->td_frame->tf_rbp = 0;
		td->td_frame->tf_rsp =
		   (((uintptr_t)stack->ss_sp + stack->ss_size - 4) & ~0x0f) - 4;
		td->td_frame->tf_rip = (uintptr_t)entry;

		/* Return address sentinel value to stop stack unwinding. */
		suword32((void *)td->td_frame->tf_rsp, 0);

		/* Pass the argument to the entry point. */
		suword32((void *)(td->td_frame->tf_rsp + sizeof(int32_t)),
		    (uint32_t)(uintptr_t)arg);

		return;
	}
#endif

	/*
	 * Set the trap frame to point at the beginning of the uts
	 * function.
	 */
	td->td_frame->tf_rbp = 0;
	td->td_frame->tf_rsp =
	    ((register_t)stack->ss_sp + stack->ss_size) & ~0x0f;
	td->td_frame->tf_rsp -= 8;
	td->td_frame->tf_rip = (register_t)entry;
	td->td_frame->tf_ds = _udatasel;
	td->td_frame->tf_es = _udatasel;
	td->td_frame->tf_fs = _ufssel;
	td->td_frame->tf_gs = _ugssel;
	td->td_frame->tf_flags = TF_HASSEGS;

	/* Return address sentinel value to stop stack unwinding. */
	suword((void *)td->td_frame->tf_rsp, 0);

	/* Pass the argument to the entry point. */
	td->td_frame->tf_rdi = (register_t)arg;
}
示例#3
0
times()
{
	register *p;

	for(p = &u.u_utime; p  < &u.u_utime+6;) {
		suword(u.u_arg[0], *p++);
		u.u_arg[0] =+ 2;
	}
}
示例#4
0
static int
elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
{
	struct proc *p;
	Elf32_Auxargs *args;
	Elf32_Addr *uplatform;
	struct ps_strings *arginfo;
	register_t *pos;

	KASSERT(curthread->td_proc == imgp->proc,
	    ("unsafe elf_linux_fixup(), should be curproc"));

	p = imgp->proc;
	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
	uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform);
	args = (Elf32_Auxargs *)imgp->auxargs;
	pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);

	AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);

	/*
	 * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0,
	 * as it has appeared in the 2.4.0-rc7 first time.
	 * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK),
	 * glibc falls back to the hard-coded CLK_TCK value when aux entry
	 * is not present.
	 * Also see linux_times() implementation.
	 */
	if (linux_kernver(curthread) >= LINUX_KERNVER_2004000)
		AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz);
	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
	AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
	AUXARGS_ENTRY(pos, AT_BASE, args->base);
	AUXARGS_ENTRY(pos, LINUX_AT_SECURE, 0);
	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
	AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
	AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
	AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
	AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(uplatform));
	if (args->execfd != -1)
		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
	AUXARGS_ENTRY(pos, AT_NULL, 0);

	free(imgp->auxargs, M_TEMP);
	imgp->auxargs = NULL;

	(*stack_base)--;
	suword(*stack_base, (register_t)imgp->args->argc);
	return (0);
}
示例#5
0
static inline int
suword_lwpid(void *addr, lwpid_t lwpid)
{
	int error;

	if (SV_CURPROC_FLAG(SV_LP64))
		error = suword(addr, lwpid);
	else
		error = suword32(addr, lwpid);
	return (error);
}
示例#6
0
static int
sparc_utrap_install(struct thread *td, char *args)
{
	struct sparc_utrap_install_args uia;
	struct sparc_utrap_args ua;
	struct md_utrap *ut;
	int error;
	int i;

	ut = td->td_proc->p_md.md_utrap;
	if ((error = copyin(args, &uia, sizeof(uia))) != 0)
		return (error);
	if (uia.num < 0 || uia.num > UT_MAX ||
	    (uia.handlers == NULL && uia.num > 0))
		return (EINVAL);
	for (i = 0; i < uia.num; i++) {
		if ((error = copyin(&uia.handlers[i], &ua, sizeof(ua))) != 0)
			return (error);
		if (ua.type != UTH_NOCHANGE &&
		    (ua.type < 0 || ua.type >= UT_MAX))
			return (EINVAL);
		if (ua.old_deferred != NULL) {
			if ((error = suword(ua.old_deferred, 0)) != 0)
				return (error);
		}
		if (ua.old_precise != NULL) {
			error = suword(ua.old_precise,
			    ut != NULL ? (long)ut->ut_precise[ua.type] : 0);
			if (error != 0)
				return (error);
		}
		if (ua.type != UTH_NOCHANGE) {
			if (ut == NULL) {
				ut = utrap_alloc();
				td->td_proc->p_md.md_utrap = ut;
			}
			ut->ut_precise[ua.type] = ua.new_precise;
		}
	}
	return (0);
}
示例#7
0
static int
elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
{
	Elf_Auxargs *args;
	Elf_Addr *base;
	Elf_Addr *pos;
	struct ps_strings *arginfo;
	struct proc *p;
	int issetugid;

	p = imgp->proc;
	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;

	KASSERT(curthread->td_proc == imgp->proc,
	    ("unsafe elf_linux_fixup(), should be curproc"));
	base = (Elf64_Addr *)*stack_base;
	args = (Elf64_Auxargs *)imgp->auxargs;
	pos = base + (imgp->args->argc + imgp->args->envc + 2);

	issetugid = p->p_flag & P_SUGID ? 1 : 0;
	AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO_EHDR,
	    imgp->proc->p_sysent->sv_shared_page_base);
	AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);
	AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz);
	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
	AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
	AUXARGS_ENTRY(pos, AT_BASE, args->base);
	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
	AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
	AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
	AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
	AUXARGS_ENTRY(pos, LINUX_AT_SECURE, issetugid);
	AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(linux_platform));
	AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, imgp->canary);
	if (imgp->execpathp != 0)
		AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, imgp->execpathp);
	if (args->execfd != -1)
		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
	AUXARGS_ENTRY(pos, AT_NULL, 0);
	free(imgp->auxargs, M_TEMP);
	imgp->auxargs = NULL;

	base--;
	suword(base, (uint64_t)imgp->args->argc);

	*stack_base = (register_t *)base;
	return (0);
}
示例#8
0
static int
sparc_sigtramp_install(struct thread *td, char *args)
{
	struct sparc_sigtramp_install_args sia;
	struct proc *p;
	int error;

	p = td->td_proc;
	if ((error = copyin(args, &sia, sizeof(sia))) != 0)
		return (error);
	if (sia.sia_old != NULL) {
		if (suword(sia.sia_old, (long)p->p_md.md_sigtramp) != 0)
			return (EFAULT);
	}
	p->p_md.md_sigtramp = sia.sia_new;
	return (0);
}
示例#9
0
void
cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
	stack_t *stack)
{
	struct ia64_fdesc *fd;
	struct trapframe *tf;
	uint64_t ndirty, sp;

	tf = td->td_frame;
	ndirty = tf->tf_special.ndirty + (tf->tf_special.bspstore & 0x1ffUL);

	KASSERT((ndirty & ~PAGE_MASK) == 0,
	    ("Whoa there! We have more than 8KB of dirty registers!"));

	fd = (struct ia64_fdesc *)entry;
	sp = (uint64_t)stack->ss_sp;

	bzero(&tf->tf_special, sizeof(tf->tf_special));
	tf->tf_special.iip = fuword(&fd->func);
	tf->tf_special.gp = fuword(&fd->gp);
	tf->tf_special.sp = (sp + stack->ss_size - 16) & ~15;
	tf->tf_special.rsc = 0xf;
	tf->tf_special.fpsr = IA64_FPSR_DEFAULT;
	tf->tf_special.psr = IA64_PSR_IC | IA64_PSR_I | IA64_PSR_IT |
	    IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_DFH | IA64_PSR_BN |
	    IA64_PSR_CPL_USER;

	if (tf->tf_flags & FRAME_SYSCALL) {
		tf->tf_special.cfm = (3UL<<62) | (1UL<<7) | 1UL;
		tf->tf_special.bspstore = sp + 8;
		suword((caddr_t)sp, (uint64_t)arg);
	} else {
		tf->tf_special.cfm = (1UL<<63) | (1UL<<7) | 1UL;
		tf->tf_special.bspstore = sp;
		tf->tf_special.ndirty = 8;
		sp = td->td_kstack + ndirty - 8;
		if ((sp & 0x1ff) == 0x1f8) {
			*(uint64_t*)sp = 0;
			tf->tf_special.ndirty += 8;
			sp -= 8;
		}
		*(uint64_t*)sp = (uint64_t)arg;
	}
}
示例#10
0
/*
 * Copied from kern/kern_exec.c
 */
static register_t *
linux_copyout_strings(struct image_params *imgp)
{
	int argc, envc;
	char **vectp;
	char *stringp, *destp;
	register_t *stack_base;
	struct ps_strings *arginfo;
	struct proc *p;

	/*
	 * Calculate string base and vector table pointers.
	 * Also deal with signal trampoline code for this exec type.
	 */
	p = imgp->proc;
	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
	destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform -
	    roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));

	/*
	 * install LINUX_PLATFORM
	 */
	copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform),
	    linux_szplatform);

	/*
	 * If we have a valid auxargs ptr, prepare some room
	 * on the stack.
	 */
	if (imgp->auxargs) {
		/*
		 * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
		 * lower compatibility.
		 */
		imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size :
		    (LINUX_AT_COUNT * 2);
		/*
		 * The '+ 2' is for the null pointers at the end of each of
		 * the arg and env vector sets,and imgp->auxarg_size is room
		 * for argument of Runtime loader.
		 */
		vectp = (char **)(destp - (imgp->args->argc +
		    imgp->args->envc + 2 + imgp->auxarg_size) * sizeof(char *));
	} else {
		/*
		 * The '+ 2' is for the null pointers at the end of each of
		 * the arg and env vector sets
		 */
		vectp = (char **)(destp - (imgp->args->argc + imgp->args->envc + 2) *
		    sizeof(char *));
	}

	/*
	 * vectp also becomes our initial stack base
	 */
	stack_base = (register_t *)vectp;

	stringp = imgp->args->begin_argv;
	argc = imgp->args->argc;
	envc = imgp->args->envc;

	/*
	 * Copy out strings - arguments and environment.
	 */
	copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);

	/*
	 * Fill in "ps_strings" struct for ps, w, etc.
	 */
	suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp);
	suword(&arginfo->ps_nargvstr, argc);

	/*
	 * Fill in argument portion of vector table.
	 */
	for (; argc > 0; --argc) {
		suword(vectp++, (long)(intptr_t)destp);
		while (*stringp++ != 0)
			destp++;
		destp++;
	}

	/* a null vector table pointer separates the argp's from the envp's */
	suword(vectp++, 0);

	suword(&arginfo->ps_envstr, (long)(intptr_t)vectp);
	suword(&arginfo->ps_nenvstr, envc);

	/*
	 * Fill in environment portion of vector table.
	 */
	for (; envc > 0; --envc) {
		suword(vectp++, (long)(intptr_t)destp);
		while (*stringp++ != 0)
			destp++;
		destp++;
	}

	/* end of vector table is a null pointer */
	suword(vectp, 0);

	return (stack_base);
}
示例#11
0
static void
netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
{
    struct lwp *l = curlwp;
    struct proc *p = l->l_proc;
    struct sigacts *ps = p->p_sigacts;
    int onstack;
    int sig = ksi->ksi_signo;
    ucontext32_t uc;
    struct sparc32_sigframe_siginfo *fp;
    netbsd32_intptr_t catcher;
    struct trapframe64 *tf = l->l_md.md_tf;
    struct rwindow32 *oldsp, *newsp;
    int ucsz, error;

    /* Need to attempt to zero extend this 32-bit pointer */
    oldsp = (struct rwindow32*)(u_long)(u_int)tf->tf_out[6];
    /* 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;

    /* Allocate space for the signal handler context. */
    if (onstack)
        fp = (struct sparc32_sigframe_siginfo *)
             ((char *)l->l_sigstk.ss_sp +
              l->l_sigstk.ss_size);
    else
        fp = (struct sparc32_sigframe_siginfo *)oldsp;
    fp = (struct sparc32_sigframe_siginfo*)((u_long)(fp - 1) & ~7);
    /*
     * Build the signal context to be used by sigreturn.
     */
    uc.uc_flags = _UC_SIGMASK |
                  ((l->l_sigstk.ss_flags & SS_ONSTACK)
                   ? _UC_SETSTACK : _UC_CLRSTACK);
    uc.uc_sigmask = *mask;
    uc.uc_link = (uint32_t)(uintptr_t)l->l_ctxlink;
    memset(&uc.uc_stack, 0, sizeof(uc.uc_stack));

    sendsig_reset(l, sig);

    /*
     * Now copy the stack contents out to user space.
     * We need to make sure that when we start the signal handler,
     * its %i6 (%fp), which is loaded from the newly allocated stack area,
     * joins seamlessly with the frame it was in when the signal occurred,
     * so that the debugger and _longjmp code can back up through it.
     * Since we're calling the handler directly, allocate a full size
     * C stack frame.
     */
    mutex_exit(p->p_lock);
    cpu_getmcontext32(l, &uc.uc_mcontext, &uc.uc_flags);
    ucsz = (int)(intptr_t)&uc.__uc_pad - (int)(intptr_t)&uc;
    newsp = (struct rwindow32*)((intptr_t)fp - sizeof(struct frame32));
    error = (copyout(&ksi->ksi_info, &fp->sf_si, sizeof ksi->ksi_info) ||
             copyout(&uc, &fp->sf_uc, ucsz) ||
             suword(&newsp->rw_in[6], (intptr_t)oldsp));
    mutex_enter(p->p_lock);

    if (error) {
        /*
         * Process has trashed its stack; give it an illegal
         * instruction to halt it in its tracks.
         */
        sigexit(l, SIGILL);
        /* NOTREACHED */
    }

    switch (ps->sa_sigdesc[sig].sd_vers) {
    default:
        /* Unsupported trampoline version; kill the process. */
        sigexit(l, SIGILL);
    case 2:
        /*
         * Arrange to continue execution at the user's handler.
         * It needs a new stack pointer, a return address and
         * three arguments: (signo, siginfo *, ucontext *).
         */
        catcher = (intptr_t)SIGACTION(p, sig).sa_handler;
        tf->tf_pc = catcher;
        tf->tf_npc = catcher + 4;
        tf->tf_out[0] = sig;
        tf->tf_out[1] = (intptr_t)&fp->sf_si;
        tf->tf_out[2] = (intptr_t)&fp->sf_uc;
        tf->tf_out[6] = (intptr_t)newsp;
        tf->tf_out[7] = (intptr_t)ps->sa_sigdesc[sig].sd_tramp - 8;
        break;
    }

    /* Remember that we're now on the signal stack. */
    if (onstack)
        l->l_sigstk.ss_flags |= SS_ONSTACK;
}
示例#12
0
static void
netbsd32_sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask)
{
    int sig = ksi->ksi_signo;
    struct lwp *l = curlwp;
    struct proc *p = l->l_proc;
    struct sparc32_sigframe *fp;
    struct trapframe64 *tf;
    int addr, onstack, error;
    struct rwindow32 *oldsp, *newsp;
    sig_t catcher = SIGACTION(p, sig).sa_handler;
    struct sparc32_sigframe sf;
    extern char netbsd32_sigcode[], netbsd32_esigcode[];
#define	szsigcode	(netbsd32_esigcode - netbsd32_sigcode)

    tf = l->l_md.md_tf;
    /* Need to attempt to zero extend this 32-bit pointer */
    oldsp = (struct rwindow32 *)(u_long)(u_int)tf->tf_out[6];
    /* 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;
    if (onstack) {
        fp = (struct sparc32_sigframe *)((char *)l->l_sigstk.ss_sp +
                                         l->l_sigstk.ss_size);
        l->l_sigstk.ss_flags |= SS_ONSTACK;
    } else
        fp = (struct sparc32_sigframe *)oldsp;
    fp = (struct sparc32_sigframe *)((u_long)(fp - 1) & ~7);

#ifdef DEBUG
    sigpid = p->p_pid;
    if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
        printf("sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n",
               p->p_comm, p->p_pid, sig, fp, &fp->sf_sc, oldsp);
        if (sigdebug & SDB_DDB) Debugger();
    }
#endif
    /*
     * Now set up the signal frame.  We build it in kernel space
     * and then copy it out.  We probably ought to just build it
     * directly in user space....
     */
    sf.sf_signo = sig;
    sf.sf_code = (u_int)ksi->ksi_trap;
#if defined(COMPAT_SUNOS) || defined(MODULAR)
    sf.sf_scp = (u_long)&fp->sf_sc;
#endif
    sf.sf_addr = 0;			/* XXX */

    /*
     * Build the signal context to be used by sigreturn.
     */
    sf.sf_sc.sc_onstack = onstack;
    sf.sf_sc.sc_mask = *mask;
    sf.sf_sc.sc_sp = (u_long)oldsp;
    sf.sf_sc.sc_pc = tf->tf_pc;
    sf.sf_sc.sc_npc = tf->tf_npc;
    sf.sf_sc.sc_psr = TSTATECCR_TO_PSR(tf->tf_tstate); /* XXX */
    sf.sf_sc.sc_g1 = tf->tf_global[1];
    sf.sf_sc.sc_o0 = tf->tf_out[0];

    /*
     * Put the stack in a consistent state before we whack away
     * at it.  Note that write_user_windows may just dump the
     * registers into the pcb; we need them in the process's memory.
     * We also need to make sure that when we start the signal handler,
     * its %i6 (%fp), which is loaded from the newly allocated stack area,
     * joins seamlessly with the frame it was in when the signal occurred,
     * so that the debugger and _longjmp code can back up through it.
     */
    sendsig_reset(l, sig);
    mutex_exit(p->p_lock);
    newsp = (struct rwindow32 *)((long)fp - sizeof(struct rwindow32));
    write_user_windows();
#ifdef DEBUG
    if ((sigdebug & SDB_KSTACK))
        printf("sendsig: saving sf to %p, setting stack pointer %p to %p\n",
               fp, &(((struct rwindow32 *)newsp)->rw_in[6]), oldsp);
#endif
    error = (rwindow_save(l) ||
             copyout((void *)&sf, (void *)fp, sizeof sf) ||
             suword(&(((struct rwindow32 *)newsp)->rw_in[6]), (u_long)oldsp));
    mutex_enter(p->p_lock);
    if (error) {
        /*
         * Process has trashed its stack; give it an illegal
         * instruction to halt it in its tracks.
         */
#ifdef DEBUG
        mutex_exit(p->p_lock);
        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
            printf("sendsig: window save or copyout error\n");
        printf("sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig);
        if (sigdebug & SDB_DDB) Debugger();
        mutex_enter(p->p_lock);
#endif
        sigexit(l, SIGILL);
        /* NOTREACHED */
    }

#ifdef DEBUG
    if (sigdebug & SDB_FOLLOW) {
        printf("sendsig: %s[%d] sig %d scp %p\n",
               p->p_comm, p->p_pid, sig, &fp->sf_sc);
    }
#endif
    /*
     * Arrange to continue execution at the code copied out in exec().
     * It needs the function to call in %g1, and a new stack pointer.
     */
    addr = p->p_psstrp - szsigcode;
    tf->tf_global[1] = (long)catcher;
    tf->tf_pc = addr;
    tf->tf_npc = addr + 4;
    tf->tf_out[6] = (uint64_t)(u_int)(u_long)newsp;

    /* Remember that we're now on the signal stack. */
    if (onstack)
        l->l_sigstk.ss_flags |= SS_ONSTACK;

#ifdef DEBUG
    if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
        mutex_exit(p->p_lock);
        printf("sendsig: about to return to catcher %p thru %p\n",
               catcher, addr);
        if (sigdebug & SDB_DDB) Debugger();
        mutex_enter(p->p_lock);
    }
#endif
}
示例#13
0
/*
 * Copy strings out to the new process address space, constructing new arg
 * and env vector tables. Return a pointer to the base so that it can be used
 * as the initial stack pointer.
 */
static register_t *
linux_copyout_strings(struct image_params *imgp)
{
	int argc, envc;
	char **vectp;
	char *stringp, *destp;
	register_t *stack_base;
	struct ps_strings *arginfo;
	char canary[LINUX_AT_RANDOM_LEN];
	size_t execpath_len;
	struct proc *p;

	/*
	 * Calculate string base and vector table pointers.
	 */
	if (imgp->execpath != NULL && imgp->auxargs != NULL)
		execpath_len = strlen(imgp->execpath) + 1;
	else
		execpath_len = 0;

	p = imgp->proc;
	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
	destp =	(caddr_t)arginfo - SPARE_USRSPACE -
	    roundup(sizeof(canary), sizeof(char *)) -
	    roundup(execpath_len, sizeof(char *)) -
	    roundup(ARG_MAX - imgp->args->stringspace, sizeof(char *));

	if (execpath_len != 0) {
		imgp->execpathp = (uintptr_t)arginfo - execpath_len;
		copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len);
	}

	/*
	 * Prepare the canary for SSP.
	 */
	arc4rand(canary, sizeof(canary), 0);
	imgp->canary = (uintptr_t)arginfo -
	    roundup(execpath_len, sizeof(char *)) -
	    roundup(sizeof(canary), sizeof(char *));
	copyout(canary, (void *)imgp->canary, sizeof(canary));

	/*
	 * If we have a valid auxargs ptr, prepare some room
	 * on the stack.
	 */
	if (imgp->auxargs) {
		/*
		 * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
		 * lower compatibility.
		 */
		imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size :
		    (LINUX_AT_COUNT * 2);

		/*
		 * The '+ 2' is for the null pointers at the end of each of
		 * the arg and env vector sets,and imgp->auxarg_size is room
		 * for argument of Runtime loader.
		 */
		vectp = (char **)(destp - (imgp->args->argc +
		    imgp->args->envc + 2 + imgp->auxarg_size) * sizeof(char *));

	} else {
		/*
		 * The '+ 2' is for the null pointers at the end of each of
		 * the arg and env vector sets
		 */
		vectp = (char **)(destp - (imgp->args->argc +
		    imgp->args->envc + 2) * sizeof(char *));
	}

	/*
	 * vectp also becomes our initial stack base
	 */
	stack_base = (register_t *)vectp;

	stringp = imgp->args->begin_argv;
	argc = imgp->args->argc;
	envc = imgp->args->envc;

	/*
	 * Copy out strings - arguments and environment.
	 */
	copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);

	/*
	 * Fill in "ps_strings" struct for ps, w, etc.
	 */
	suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp);
	suword(&arginfo->ps_nargvstr, argc);

	/*
	 * Fill in argument portion of vector table.
	 */
	for (; argc > 0; --argc) {
		suword(vectp++, (long)(intptr_t)destp);
		while (*stringp++ != 0)
			destp++;
		destp++;
	}

	/* a null vector table pointer separates the argp's from the envp's */
	suword(vectp++, 0);

	suword(&arginfo->ps_envstr, (long)(intptr_t)vectp);
	suword(&arginfo->ps_nenvstr, envc);

	/*
	 * Fill in environment portion of vector table.
	 */
	for (; envc > 0; --envc) {
		suword(vectp++, (long)(intptr_t)destp);
		while (*stringp++ != 0)
			destp++;
		destp++;
	}

	/* end of vector table is a null pointer */
	suword(vectp, 0);
	return (stack_base);
}
示例#14
0
static void 
put_fs_long(u_long val, u_int32_t *adr)
	{ (void)suword(adr,val); }
示例#15
0
static int
ibcs2_fixup(register_t **stack_base, struct image_params *imgp)
{

	return (suword(--(*stack_base), imgp->args->argc));
}
示例#16
0
int
suword32(void *addr, int32_t word)
{

    return (suword(addr, (long)word));
}
示例#17
0
void sunos_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
{
	struct lwp *l = curlwp;
	struct proc *p = l->l_proc;
	struct sunos_sigframe *fp;
	struct trapframe *tf;
	int addr, onstack, oldsp, newsp, error;
	int sig = ksi->ksi_signo;
	u_long code = ksi->ksi_code;
	sig_t catcher = SIGACTION(p, sig).sa_handler;
	struct sunos_sigframe sf;

	tf = l->l_md.md_tf;
	oldsp = tf->tf_out[6];

	/*
	 * Compute new user stack addresses, subtract off
	 * one signal frame, and align.
	 */
	onstack =
	    (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;

	if (onstack)
		fp = (struct sunos_sigframe *)
		     ((char *)l->l_sigstk.ss_sp + l->l_sigstk.ss_size);
	else
		fp = (struct sunos_sigframe *)oldsp;

	fp = (struct sunos_sigframe *)((int)(fp - 1) & ~7);

#ifdef DEBUG
	if ((sunos_sigdebug & SDB_KSTACK) && p->p_pid == sunos_sigpid)
		printf("sendsig: %s[%d] sig %d newusp %p scp %p\n",
		    p->p_comm, p->p_pid, sig, fp, &fp->sf_sc);
#endif
	/*
	 * Now set up the signal frame.  We build it in kernel space
	 * and then copy it out.  We probably ought to just build it
	 * directly in user space....
	 */
	sf.sf_signo = sig;
	sf.sf_code = code;
	sf.sf_scp = &fp->sf_sc;
	sf.sf_addr = 0;			/* XXX */

	/*
	 * Build the signal context to be used by sigreturn.
	 */
	sf.sf_sc.sc_onstack = l->l_sigstk.ss_flags & SS_ONSTACK;
	native_sigset_to_sigset13(mask, &sf.sf_sc.sc_mask);
	sf.sf_sc.sc_sp = oldsp;
	sf.sf_sc.sc_pc = tf->tf_pc;
	sf.sf_sc.sc_npc = tf->tf_npc;
	sf.sf_sc.sc_psr = tf->tf_psr;
	sf.sf_sc.sc_g1 = tf->tf_global[1];
	sf.sf_sc.sc_o0 = tf->tf_out[0];

	/*
	 * Put the stack in a consistent state before we whack away
	 * at it.  Note that write_user_windows may just dump the
	 * registers into the pcb; we need them in the process's memory.
	 * We also need to make sure that when we start the signal handler,
	 * its %i6 (%fp), which is loaded from the newly allocated stack area,
	 * joins seamlessly with the frame it was in when the signal occurred,
	 * so that the debugger and _longjmp code can back up through it.
	 */
	sendsig_reset(l, sig);
	mutex_exit(p->p_lock);
	newsp = (int)fp - sizeof(struct rwindow);
	write_user_windows();
	error = (rwindow_save(l) || copyout((void *)&sf, (void *)fp, sizeof sf) ||
	    suword(&((struct rwindow *)newsp)->rw_in[6], oldsp));
	mutex_enter(p->p_lock);

	if (error) {
		/*
		 * Process has trashed its stack; give it an illegal
		 * instruction to halt it in its tracks.
		 */
#ifdef DEBUG
		if ((sunos_sigdebug & SDB_KSTACK) && p->p_pid == sunos_sigpid)
			printf("sendsig: window save or copyout error\n");
#endif
		sigexit(l, SIGILL);
		/* NOTREACHED */
	}
#ifdef DEBUG
	if (sunos_sigdebug & SDB_FOLLOW)
		printf("sendsig: %s[%d] sig %d scp %p\n",
		       p->p_comm, p->p_pid, sig, &fp->sf_sc);
#endif
	/*
	 * Arrange to continue execution at the code copied out in exec().
	 * It needs the function to call in %g1, and a new stack pointer.
	 */
	addr = (int)catcher;	/* user does his own trampolining */
	tf->tf_pc = addr;
	tf->tf_npc = addr + 4;
	tf->tf_out[6] = newsp;

	/* Remember that we're now on the signal stack. */
	if (onstack)
		l->l_sigstk.ss_flags |= SS_ONSTACK;

#ifdef DEBUG
	if ((sunos_sigdebug & SDB_KSTACK) && p->p_pid == sunos_sigpid)
		printf("sendsig: about to return to catcher\n");
#endif
}
示例#18
0
static void 
put_fs_long(u_long val, unsigned long *adr)
	{ (void)suword(adr,val); }
示例#19
-1
/*
 * Code that the child process
 * executes to implement the command
 * of the parent process in tracing.
 */
procxmt()
{
	register int i;
	register *p;
	register struct text *xp;

	if (ipc.ip_lock != u.u_procp->p_pid)
		return (0);
	u.u_procp->p_slptime = 0;
	i = ipc.ip_req;
	ipc.ip_req = 0;
	switch (i) {

	case PT_READ_I:			/* read the child's text space */
		if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
			goto error;
		ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
		break;

	case PT_READ_D:			/* read the child's data space */
		if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
			goto error;
		ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
		break;

	case PT_READ_U:			/* read the child's u. */
		i = (int)ipc.ip_addr;
		if (i<0 || i >= ctob(UPAGES))
			goto error;
		ipc.ip_data = *(int *)PHYSOFF(&u, i);
		break;

	case PT_WRITE_I:		/* write the child's text space */
		/*
		 * If text, must assure exclusive use
		 */
		if (xp = u.u_procp->p_textp) {
			if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
				goto error;
			xp->x_flag |= XTRC;
		}
		i = -1;
		if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
			if (chgprot((caddr_t)ipc.ip_addr, RW) &&
			    chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
				i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
			(void) chgprot((caddr_t)ipc.ip_addr, RO);
			(void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
		}
		if (i < 0)
			goto error;
		if (xp)
			xp->x_flag |= XWRIT;
		break;

	case PT_WRITE_D:		/* write the child's data space */
		if (suword((caddr_t)ipc.ip_addr, 0) < 0)
			goto error;
		(void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
		break;

	case PT_WRITE_U:		/* write the child's u. */
		i = (int)ipc.ip_addr;
		p = (int *)PHYSOFF(&u, i);
		for (i=0; i<NIPCREG; i++)
			if (p == &u.u_ar0[ipcreg[i]])
				goto ok;
		if (p == &u.u_ar0[PS]) {
			ipc.ip_data |= PSL_USERSET;
			ipc.ip_data &=  ~PSL_USERCLR;
			goto ok;
		}
		goto error;

	ok:
		*p = ipc.ip_data;
		break;

	case PT_STEP:			/* single step the child */
	case PT_CONTINUE:		/* continue the child */
		if ((int)ipc.ip_addr != 1)
			u.u_ar0[PC] = (int)ipc.ip_addr;
		if ((unsigned)ipc.ip_data > NSIG)
			goto error;
		u.u_procp->p_cursig = ipc.ip_data;	/* see issig */
		if (i == PT_STEP) 
			u.u_ar0[PS] |= PSL_T;
		wakeup((caddr_t)&ipc);
		return (1);

	case PT_KILL:			/* kill the child process */
		wakeup((caddr_t)&ipc);
		exit(u.u_procp->p_cursig);

	default:
	error:
		ipc.ip_req = -1;
	}
	wakeup((caddr_t)&ipc);
	return (0);
}