コード例 #1
0
/*
 * copy arguments onto the stack in the normal way, then copy out
 * any ELF-like AUX entries used by the dynamic loading scheme.
 */
int
osf1_copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp)
{
	struct osf1_exec_emul_arg *emul_arg = pack->ep_emul_arg;
	struct osf1_auxv ai[OSF1_MAX_AUX_ENTRIES], *a;
	char *prognameloc, *loadernameloc;
	size_t len;
	int error;

	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
		goto out;

	a = ai;
	memset(ai, 0, sizeof ai);

	prognameloc = *stackp + sizeof ai;
	if ((error = copyoutstr(emul_arg->exec_name, prognameloc,
	    MAXPATHLEN + 1, NULL)) != 0)
	    goto out;
	a->a_type = OSF1_AT_EXEC_FILENAME;
	a->a_un.a_ptr = prognameloc;
	a++;

	/*
	 * if there's a loader, push additional auxv entries on the stack.
	 */
	if (emul_arg->flags & OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER) {

		loadernameloc = prognameloc + MAXPATHLEN + 1;
		if ((error = copyoutstr(emul_arg->loader_name, loadernameloc,
		    MAXPATHLEN + 1, NULL)) != 0)
			goto out;
		a->a_type = OSF1_AT_EXEC_LOADER_FILENAME;
		a->a_un.a_ptr = loadernameloc;
		a++;

		a->a_type = OSF1_AT_EXEC_LOADER_FLAGS;
		a->a_un.a_val = 0;
                if (pack->ep_vap->va_mode & S_ISUID)
                        a->a_un.a_val |= OSF1_LDR_EXEC_SETUID_F;
                if (pack->ep_vap->va_mode & S_ISGID)
                        a->a_un.a_val |= OSF1_LDR_EXEC_SETGID_F;
	        if (l->l_proc->p_slflag & PSL_TRACED)
                        a->a_un.a_val |= OSF1_LDR_EXEC_PTRACE_F;
		a++;
	}

	a->a_type = OSF1_AT_NULL;
	a->a_un.a_val = 0;
	a++;

	len = (a - ai) * sizeof(struct osf1_auxv);
	if ((error = copyout(ai, *stackp, len)) != 0)
		goto out;
	*stackp += len;

out:
	exec_free_emul_arg(pack);
	return error;
}
コード例 #2
0
ファイル: linux_exec.c プロジェクト: sofuture/bitrig
static void *
linux_aout_copyargs(struct exec_package *pack, struct ps_strings *arginfo,
    void *stack, void *argp)
{
	char **cpp = stack;
	char **stk = stack;
	char *dp, *sp;
	size_t len;
	void *nullp = NULL;
	int argc = arginfo->ps_nargvstr;
	int envc = arginfo->ps_nenvstr;

	if (copyout(&argc, cpp++, sizeof(argc)))
		return (NULL);

	/* leave room for envp and argv */
	cpp += 2;
	if (copyout(&cpp, &stk[1], sizeof (cpp)))
		return (NULL);

	dp = (char *)(cpp + argc + envc + 2);
	sp = argp;

	/* XXX don't copy them out, remap them! */
	arginfo->ps_argvstr = cpp; /* remember location of argv for later */

	for (; --argc >= 0; sp += len, dp += len)
		if (copyout(&dp, cpp++, sizeof(dp)) ||
		    copyoutstr(sp, dp, ARG_MAX, &len))
			return (NULL);

	if (copyout(&nullp, cpp++, sizeof(nullp)))
		return (NULL);

	if (copyout(&cpp, &stk[2], sizeof (cpp)))
		return (NULL);

	arginfo->ps_envstr = cpp; /* remember location of envp for later */

	for (; --envc >= 0; sp += len, dp += len)
		if (copyout(&dp, cpp++, sizeof(dp)) ||
		    copyoutstr(sp, dp, ARG_MAX, &len))
			return (NULL);

	if (copyout(&nullp, cpp++, sizeof(nullp)))
		return (NULL);

	return (cpp);
}
コード例 #3
0
ファイル: sys_lwp.c プロジェクト: ryo/netbsd-src
int
sys__lwp_getname(struct lwp *l, const struct sys__lwp_getname_args *uap,
    register_t *retval)
{
	/* {
		syscallarg(lwpid_t)		target;
		syscallarg(char *)		name;
		syscallarg(size_t)		len;
	} */
	char name[MAXCOMLEN];
	lwpid_t target;
	proc_t *p;
	lwp_t *t;

	if ((target = SCARG(uap, target)) == 0)
		target = l->l_lid;

	p = curproc;
	mutex_enter(p->p_lock);
	if ((t = lwp_find(p, target)) == NULL) {
		mutex_exit(p->p_lock);
		return ESRCH;
	}
	lwp_lock(t);
	if (t->l_name == NULL)
		name[0] = '\0';
	else
		strcpy(name, t->l_name);
	lwp_unlock(t);
	mutex_exit(p->p_lock);

	return copyoutstr(name, SCARG(uap, name), SCARG(uap, len), NULL);
}
コード例 #4
0
ファイル: mem.c プロジェクト: MatiasNAmendola/AuroraUX-SunOS
/*
 * Given a memory name, return its associated serial id
 */
static int
mmioctl_get_mem_sid(intptr_t data)
{
	mem_name_t mem_name;
	void *buf;
	void *name;
	size_t	name_len;
	size_t bufsize;
	int len, err;

	if ((bufsize = cpu_get_name_bufsize()) == 0)
		return (ENOTSUP);

	if ((err = mm_read_mem_name(data, &mem_name)) < 0)
		return (err);

	buf = kmem_alloc(bufsize, KM_SLEEP);

	if (mem_name.m_namelen > 1024)
		mem_name.m_namelen = 1024; /* cap at 1024 bytes */

	name = kmem_alloc(mem_name.m_namelen, KM_SLEEP);

	if ((err = copyinstr((char *)mem_name.m_name, (char *)name,
	    mem_name.m_namelen, &name_len)) != 0) {
		kmem_free(buf, bufsize);
		kmem_free(name, mem_name.m_namelen);
		return (err);
	}

	/*
	 * Call into cpu specific code to do the lookup.
	 */
	if ((err = cpu_get_mem_sid(name, buf, bufsize, &len)) != 0) {
		kmem_free(buf, bufsize);
		kmem_free(name, mem_name.m_namelen);
		return (err);
	}

	if (len > mem_name.m_sidlen) {
		kmem_free(buf, bufsize);
		kmem_free(name, mem_name.m_namelen);
		return (ENAMETOOLONG);
	}

	if (copyoutstr(buf, (char *)mem_name.m_sid,
	    mem_name.m_sidlen, NULL) != 0) {
		kmem_free(buf, bufsize);
		kmem_free(name, mem_name.m_namelen);
		return (EFAULT);
	}

	kmem_free(buf, bufsize);
	kmem_free(name, mem_name.m_namelen);
	return (0);
}
コード例 #5
0
ファイル: kern_exec.c プロジェクト: orumin/openbsd-efivars
void *
copyargs(struct exec_package *pack, struct ps_strings *arginfo, void *stack,
    void *argp)
{
	char **cpp = stack;
	char *dp, *sp;
	size_t len;
	void *nullp = NULL;
	long argc = arginfo->ps_nargvstr;
	int envc = arginfo->ps_nenvstr;

	if (copyout(&argc, cpp++, sizeof(argc)))
		return (NULL);

	dp = (char *) (cpp + argc + envc + 2 + pack->ep_emul->e_arglen);
	sp = argp;

	/* XXX don't copy them out, remap them! */
	arginfo->ps_argvstr = cpp; /* remember location of argv for later */

	for (; --argc >= 0; sp += len, dp += len)
		if (copyout(&dp, cpp++, sizeof(dp)) ||
		    copyoutstr(sp, dp, ARG_MAX, &len))
			return (NULL);

	if (copyout(&nullp, cpp++, sizeof(nullp)))
		return (NULL);

	arginfo->ps_envstr = cpp; /* remember location of envp for later */

	for (; --envc >= 0; sp += len, dp += len)
		if (copyout(&dp, cpp++, sizeof(dp)) ||
		    copyoutstr(sp, dp, ARG_MAX, &len))
			return (NULL);

	if (copyout(&nullp, cpp++, sizeof(nullp)))
		return (NULL);

	return (cpp);
}
コード例 #6
0
ファイル: mem.c プロジェクト: MatiasNAmendola/AuroraUX-SunOS
/*
 * Given a syndrome, syndrome type, and address return the
 * associated memory name in the provided data buffer.
 */
static int
mmioctl_get_mem_name(intptr_t data)
{
	mem_name_t mem_name;
	void *buf;
	size_t bufsize;
	int len, err;

	if ((bufsize = cpu_get_name_bufsize()) == 0)
		return (ENOTSUP);

	if ((err = mm_read_mem_name(data, &mem_name)) < 0)
		return (err);

	buf = kmem_alloc(bufsize, KM_SLEEP);

	/*
	 * Call into cpu specific code to do the lookup.
	 */
	if ((err = cpu_get_mem_name(mem_name.m_synd, mem_name.m_type,
	    mem_name.m_addr, buf, bufsize, &len)) != 0) {
		kmem_free(buf, bufsize);
		return (err);
	}

	if (len >= mem_name.m_namelen) {
		kmem_free(buf, bufsize);
		return (ENOSPC);
	}

	if (copyoutstr(buf, (char *)mem_name.m_name,
	    mem_name.m_namelen, NULL) != 0) {
		kmem_free(buf, bufsize);
		return (EFAULT);
	}

	kmem_free(buf, bufsize);
	return (0);
}
コード例 #7
0
void
run_process(void *ptr, unsigned long num)
{
    (void)num;
    int result;
	vaddr_t entrypoint, stackptr;
    
    // extract and free passed-in context
    struct new_process_context *ctxt = (struct new_process_context *)ptr;
    struct process *proc = ctxt->proc;
    struct vnode *v = ctxt->executable;
    int nargs = ctxt->nargs;
    char **args = ctxt->args;
    kfree(ctxt);
    
    // attach process to thread
    curthread->t_proc = proc;
    proc->ps_thread = curthread;
    
	// Activate address space
	as_activate(proc->ps_addrspace);
    
	// Load the executable
	result = load_elf(v, &entrypoint);
	if (result) {
		vfs_close(v);
        kprintf("runprogram failed: %s\n", strerror(result));
        // alert the kernel menu that the process aborted
        process_finish(proc, _MKWAIT_SIG(SIGABRT));
		return;
	}
    
	// Done with the file now
	vfs_close(v);
    
	// Define the user stack in the address space
	result = as_define_stack(proc->ps_addrspace, &stackptr);
	if (result) {
        kprintf("runprogram failed: %s\n", strerror(result));
        // alert the kernel menu that the process aborted
        process_finish(proc, _MKWAIT_SIG(SIGABRT));
		return;
	}
	
	// Copy out arguments
	userptr_t uargv[nargs + 1];
    for (int i = 0; i < nargs; i++)
    {
        int aligned_length = WORD_ALIGN(strlen(args[i]) + 1);
        stackptr -= aligned_length;
        uargv[i] = (userptr_t)stackptr;
        size_t arg_len;
        result = copyoutstr(args[i], uargv[i], strlen(args[i]) + 1, &arg_len);
        if (result) {
            kprintf("runprogram failed: %s\n", strerror(result));
            // alert the kernel menu that the process aborted
            process_finish(proc, _MKWAIT_SIG(SIGABRT));
            return;
        }
    }
    uargv[nargs] =(userptr_t)NULL;
    
    // Copy out the argv array itself
	stackptr -= (nargs + 1) * sizeof(userptr_t);
	result = copyout(uargv, (userptr_t)stackptr,
                     (nargs + 1) * sizeof(userptr_t));
	if (result) {
        kprintf("runprogram failed: %s\n", strerror(result));
        // alert the kernel menu that the process aborted
        process_finish(proc, _MKWAIT_SIG(SIGABRT));
	    return;
	}
    
    enter_new_process(nargs, (userptr_t)stackptr, stackptr, entrypoint);
    
    // enter_new_process() does not return
	panic("enter_new_process returned\n");
}
コード例 #8
0
ファイル: execv.c プロジェクト: WasifKhan/os161-1.11
int sys_execv(const char* program, char** args, int* errno)
{
	int ret;
	// simple error check
	// *************
	if (program == NULL)
	{
		*errno = EFAULT;
		return -1;
	}
	// ************

	// copies progname into kernel buffer
	// ***************
	char* fname = (char*)kmalloc(PATH_MAX);
	ret = copyinstr((userptr_t)program, fname, PATH_MAX, NULL);
	if (ret != 0)
	{
		*errno = EFAULT;
		return -1;
	}
	// opens executable	
	// ***************
	struct vnode* v;
	ret = vfs_open(fname, O_RDONLY, &v);
	if (ret != 0)
	{
		*errno = ret;
		return -1;
	}
	// **************


	// gets argc
	// **************
	int i = 0;
	while (args[i] != NULL)
	{
		i++;
	}
	int argc = i;
	// *************

	// copies all arguments into kernel buffer
	// *****************
	char** argv;
	argv= (char**)kmalloc(PATH_MAX);
	
	ret = copyin(args, argv, sizeof(userptr_t));
	if (ret != 0)
	{
		*errno = EFAULT;
		return -1;
	}
	
	for(i = 0; i < argc; i++)
	{
		argv[i]=(char*)kmalloc(PATH_MAX);
		ret = copyinstr((userptr_t)args[i],argv[i], PATH_MAX, NULL);
		if (ret != 0)
		{
			*errno = EFAULT;
			return -1;
		}
	}
	argv[argc] = NULL;
	// *******************

	// error check
	// ************
	if (curthread->t_vmspace != NULL)
	{
		as_destroy(curthread->t_vmspace);
		curthread->t_vmspace = NULL;
	}
	// **************



	// creates new address space and loads elf into it
	// **************	
	curthread->t_vmspace = as_create();
	if (curthread->t_vmspace == NULL)
	{
		vfs_close(v);
		*errno = ENOMEM;
		return -1;
	}

	vaddr_t entrypoint,stackptr;

	as_activate(curthread->t_vmspace);
	ret = load_elf(v,&entrypoint);
	if (ret != 0){
		vfs_close(v);
		*errno = ret;
		return -1;
	}
	vfs_close(v);
	ret = as_define_stack(curthread->t_vmspace,&stackptr);
	if (ret != 0)
	{
		*errno = ret;
		return -1;
	}
	// ********************

	// copies arguments into userstack and increments stack ptr
	// **************
	unsigned int pstack[argc];
	for (i = argc-1; i >= 0; i--)
	{
		
		int len = strlen(argv[i]) + 1;
		stackptr -= len;
		stackptr -= stackptr%4;
		ret = copyoutstr(argv[i], (userptr_t)stackptr, PATH_MAX, NULL);
		if (ret != 0)
		{
			*errno = EFAULT;
			return -1;
		}
		pstack[i] = stackptr;
	}
	pstack[argc] = (int)NULL;
	for (i = argc-1; i >= 0; i--)
	{
		stackptr -= 4;
		ret = copyout(&pstack[i], (userptr_t)stackptr, sizeof(pstack[i]));
		if (ret != 0)
		{
			*errno = EFAULT;
			return -1;
		}
	}
	
	// free unused memory	
	for (i = 0; i < argc; i++)
	{
		kfree(argv[i]);
	}
	kfree(argv);
	kfree(fname);
	// *******************


	// enters usermode, should not return
	// *******************
	md_usermode(argc, (userptr_t)stackptr, stackptr, entrypoint);
	// ******************
	
	// if usermode returns, that is an error
	// **********
	*errno = EINVAL;
	return -1;
	// ************
}
コード例 #9
0
int
corectl(int subcode, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
{
	int error = 0;
	proc_t *p;
	refstr_t *rp;
	size_t size;
	char *path;
	core_content_t content = CC_CONTENT_INVALID;
	struct core_globals *cg;
	zone_t *zone = curproc->p_zone;

	cg = zone_getspecific(core_zone_key, zone);
	ASSERT(cg != NULL);

	switch (subcode) {
	case CC_SET_OPTIONS:
		if ((error = secpolicy_coreadm(CRED())) == 0) {
			if (arg1 & ~CC_OPTIONS)
				error = EINVAL;
			else
				cg->core_options = (uint32_t)arg1;
		}
		break;

	case CC_GET_OPTIONS:
		return (cg->core_options);

	case CC_GET_GLOBAL_PATH:
	case CC_GET_DEFAULT_PATH:
	case CC_GET_PROCESS_PATH:
		if (subcode == CC_GET_GLOBAL_PATH) {
			mutex_enter(&cg->core_lock);
			if ((rp = cg->core_file) != NULL)
				refstr_hold(rp);
			mutex_exit(&cg->core_lock);
		} else if (subcode == CC_GET_DEFAULT_PATH) {
			rp = corectl_path_value(cg->core_default_path);
		} else {
			rp = NULL;
			mutex_enter(&pidlock);
			if ((p = prfind((pid_t)arg3)) == NULL ||
			    p->p_stat == SIDL) {
				mutex_exit(&pidlock);
				error = ESRCH;
			} else {
				mutex_enter(&p->p_lock);
				mutex_exit(&pidlock);
				mutex_enter(&p->p_crlock);
				if (!hasprocperm(p->p_cred, CRED()))
					error = EPERM;
				else if (p->p_corefile != NULL)
					rp = corectl_path_value(p->p_corefile);
				mutex_exit(&p->p_crlock);
				mutex_exit(&p->p_lock);
			}
		}
		if (rp == NULL) {
			if (error == 0 && suword8((void *)arg1, 0))
				error = EFAULT;
		} else {
			error = copyoutstr(refstr_value(rp), (char *)arg1,
			    (size_t)arg2, NULL);
			refstr_rele(rp);
		}
		break;

	case CC_SET_GLOBAL_PATH:
	case CC_SET_DEFAULT_PATH:
		if ((error = secpolicy_coreadm(CRED())) != 0)
			break;

		/* FALLTHROUGH */
	case CC_SET_PROCESS_PATH:
		if ((size = MIN((size_t)arg2, MAXPATHLEN)) == 0) {
			error = EINVAL;
			break;
		}
		path = kmem_alloc(size, KM_SLEEP);
		error = copyinstr((char *)arg1, path, size, NULL);
		if (error == 0) {
			if (subcode == CC_SET_PROCESS_PATH) {
				error = set_proc_info((pid_t)arg3, path, 0);
			} else if (subcode == CC_SET_DEFAULT_PATH) {
				corectl_path_set(cg->core_default_path, path);
			} else if (*path != '\0' && *path != '/') {
				error = EINVAL;
			} else {
				refstr_t *nrp = refstr_alloc(path);

				mutex_enter(&cg->core_lock);
				rp = cg->core_file;
				if (*path == '\0')
					cg->core_file = NULL;
				else
					refstr_hold(cg->core_file = nrp);
				mutex_exit(&cg->core_lock);

				if (rp != NULL)
					refstr_rele(rp);

				refstr_rele(nrp);
			}
		}
		kmem_free(path, size);
		break;

	case CC_SET_GLOBAL_CONTENT:
	case CC_SET_DEFAULT_CONTENT:
		if ((error = secpolicy_coreadm(CRED())) != 0)
			break;

		/* FALLTHROUGH */
	case CC_SET_PROCESS_CONTENT:
		error = copyin((void *)arg1, &content, sizeof (content));
		if (error != 0)
			break;

		/*
		 * If any unknown bits are set, don't let this charade
		 * continue.
		 */
		if (content & ~CC_CONTENT_ALL) {
			error = EINVAL;
			break;
		}

		if (subcode == CC_SET_PROCESS_CONTENT) {
			error = set_proc_info((pid_t)arg2, NULL, content);
		} else if (subcode == CC_SET_DEFAULT_CONTENT) {
			corectl_content_set(cg->core_default_content, content);
		} else {
			mutex_enter(&cg->core_lock);
			cg->core_content = content;
			mutex_exit(&cg->core_lock);
		}

		break;

	case CC_GET_GLOBAL_CONTENT:
		content = cg->core_content;
		error = copyout(&content, (void *)arg1, sizeof (content));
		break;

	case CC_GET_DEFAULT_CONTENT:
		content = corectl_content_value(cg->core_default_content);
		error = copyout(&content, (void *)arg1, sizeof (content));
		break;

	case CC_GET_PROCESS_CONTENT:
		mutex_enter(&pidlock);
		if ((p = prfind((pid_t)arg2)) == NULL || p->p_stat == SIDL) {
			mutex_exit(&pidlock);
			error = ESRCH;
			break;
		}

		mutex_enter(&p->p_lock);
		mutex_exit(&pidlock);
		mutex_enter(&p->p_crlock);
		if (!hasprocperm(p->p_cred, CRED()))
			error = EPERM;
		else if (p->p_content == NULL)
			content = CC_CONTENT_NONE;
		else
			content = corectl_content_value(p->p_content);
		mutex_exit(&p->p_crlock);
		mutex_exit(&p->p_lock);

		if (error == 0)
			error = copyout(&content, (void *)arg1,
			    sizeof (content));
		break;

	default:
		error = EINVAL;
		break;
	}

	if (error)
		return (set_errno(error));
	return (0);
}
コード例 #10
0
ファイル: thread.c プロジェクト: MattMarji/os161
int sys_execv(char* progname, char** args){

    struct vnode *v;
    vaddr_t stackptr, entrypoint;
    int result;
    int string_size = 0; //s_size
    int kargc = 0; //kargc
    int err;
    char ** kernel_args; //kargs
    size_t check; //tt
    
	//CHECKS BEFORE WE BEGIN!!
    if(args == NULL)
		return EFAULT;
		
    if(progname == NULL)
		return ENOEXEC;
    
    struct addrspace* temp =(struct addrspace*)kmalloc(sizeof(struct addrspace));
		if(temp == NULL)
			return ENOMEM;
    
		while(args[kargc] != NULL){
			kargc++;
	   }

	   //Copy the address space to the one on the kernel heap.
		err = as_copy(curthread->t_vmspace, &(temp));
		
		//If there is an error on copy.
		if(err){
		kfree(temp);
		return ENOMEM;
		}
   
   //make a copy of the kernel args on the heap.
   kernel_args = (char **)kmalloc((kargc)*sizeof(char*));
		if(kernel_args == NULL){
		 kfree(kernel_args);
		return ENOMEM;
		}
   int i,j;
	//Transfer the items passed in to the kernel heap array.
    for(i = 0; i<kargc; i++){
	string_size = strlen(args[i]);
	kernel_args[i] =(char *)kmalloc(string_size * sizeof(char));
	
	//If there is not enough memory...
	if(kernel_args[i]== NULL){
	    kfree(temp);
	    for(j =0; j<i; j++){
		kfree(kernel_args[j]);
		}
	    kfree(kernel_args);
	    return ENOMEM;
	}
	
	//If we get here, we have successfully copied the arguments. Copy in now.
	
	err = copyinstr(args[i], kernel_args[i], string_size+1, &check);
	
	//Check if copyinstr Success/Fail
	if(err){
	
	    for(i = 0; i<kargc; i++){
		kfree(kernel_args[i]);
		}
	    kfree(temp);
		kfree(kernel_args);
	    return err;
		}
    }
	
    kernel_args[kargc]= NULL;

	//NOW, WE FOLLOW THE SAME PROCEDURE AS RUNPROGRAM!!


/* Open the file. */
    result = vfs_open(progname, O_RDONLY, &v);
    if (result) {
	 kfree(temp);
	for(i = 0; i<kargc; i++)
	    kfree(kernel_args[i]);
		kfree(kernel_args);
	return result;
    }

//Destroy the old address space, and setup the new one!
	
    as_destroy(curthread->t_vmspace);
    curthread->t_vmspace = NULL;

    //Setup new vmspace.
    curthread->t_vmspace = as_create();
	
    if (curthread->t_vmspace==NULL) {
	curthread->t_vmspace = temp;
	
	for(i = 0; i<kargc; i++)
	    kfree(kernel_args[i]);
		kfree(kernel_args);
		vfs_close(v);
		return ENOMEM;
    }

    /* Activate vmspace */
    as_activate(curthread->t_vmspace);

    /* Load the executable. */
    result = load_elf(v, &entrypoint);
    if (result) {
	as_destroy(curthread->t_vmspace);
	curthread->t_vmspace = temp;
	
	 
	for(i = 0; i<kargc; i++)
	    kfree(kernel_args[i]);
	kfree(kernel_args);
	vfs_close(v);
	return result;
    }

    /* Done with the file now. */
    vfs_close(v);

   //We now prepare the user stack by placing the arguments on it, like we did in runprogram.
   
    result = as_define_stack(curthread->t_vmspace, &stackptr);
    
	//If error:
	if (result) {
	as_destroy(curthread->t_vmspace);
	curthread->t_vmspace = temp;

	for(i = 0; i<kargc; i++)
	    kfree(kernel_args[i]);
		kfree(kernel_args);
	return result;
    }
	// new addr space user stack
    vaddr_t new_args[kargc];
    int padding; 
     
    /*place all the strings on the stack*/
    
    for(i = (kargc-1); i>=0 ; i--){
	string_size = strlen(kernel_args[i]);
	padding = ((string_size / 4 ) + 1)*4;
	
	stackptr = stackptr - padding;
	
	//Do a copyout and check if success/fail
	err = copyoutstr(kernel_args[i], stackptr, string_size+1, &check);
		if(err){
			return err;
		}
	
		//Success!
		new_args[i] = stackptr;
    }

  
    new_args[kargc] = NULL;
    for(i = kargc-1; i>=0 ; i--){
	stackptr= stackptr- 4;
	err = copyout(&(new_args[i]), stackptr, 4);
		if(err){
			return err;
		}
   }
    for(i =0; i<kargc; i++){
		kfree(kernel_args[i]);
	}
    kfree(temp);
	kfree(kernel_args);
        
    /* Warp to user mode. */
    md_usermode(kargc, stackptr, stackptr, entrypoint);
	

}
コード例 #11
0
ファイル: exec_v.c プロジェクト: kevinkhuang/OS-161
int
sys_execv(const char *progname, char**args) {
    kprintf("hello world");
    struct vnode *v;
    vaddr_t entrypoint, stackptr;
    int result;
    int argc = getargc(args);

    /* Copy the arguments into the kernel buffer */
    char** kbuffer = kmalloc(argc*sizeof(char*));
    int i;
    for (i=0; i<argc; i++) {
        kbuffer[i] = kmalloc(strlen(args[i])*sizeof(char*)+1);
        copyinstr(args[i], kbuffer[i], strlen(args[i])*sizeof(char*)+1, NULL);
    }
    
    args = kbuffer;
    
    /* Open the file. */
    result = vfs_open(progname, O_RDONLY, &v);
    if (result) {
        return result;
    }

    /* This is not the first process, we have to make sure
     the previous process address space is not NULL. */
    assert(curthread->t_vmspace != NULL);

    /* Destroy the old process address space */
    as_destroy(curthread->t_vmspace);

    /* Create a new address space. */
    curthread->t_vmspace = as_create();
    if (curthread->t_vmspace == NULL) {
        vfs_close(v);
        return ENOMEM;
    }

    /* Activate it. */
    as_activate(curthread->t_vmspace);

    /* Load the executable. */
    result = load_elf(v, &entrypoint);
    if (result) {
        /* thread_exit destroys curthread->t_vmspace */
        vfs_close(v);
        return result;
    }

    /* Done with the file now. */
    vfs_close(v);
    /* Free the current process user stack */
    kfree(curthread->t_stack);

    /* Define the user stack in the address space */
    result = as_define_stack(curthread->t_vmspace, &stackptr);
    if (result) {
        /* thread_exit destroys curthread->t_vmspace */
        return result;
    }
    
    /* copy arguments to user space */
    char **args_u; /* user space arguments.(array of ptrs
                   to string arguments.*/
    /* string length of the arguments */
    size_t argstrlen = getlen(argc, args);
    /* address space for the string arguments value. */
    char* arg_str = (char *) stackptr - argstrlen;
    /* address space for the pointers to string arguments. */
    args_u = (char **) arg_str - (argc + 1) * sizeof (char**);
    /* adjust the address so that its divisable by 4 */
    args_u = (int) args_u - (int) args_u % 4;

    /* copy the arguments to the user address space */
    int len;
    for (i = 0; i < argc; i++) {
        /* copy a single argument  to the user address space */
        copyoutstr(args[i], (userptr_t) arg_str, strlen(args[i]) + 1, &len);
        /* set the user argument to the current argument string pointer */
        args_u[i] = arg_str;
        /* increment the argument pointer to the next argument */
        arg_str += (strlen(args[i]) + 1) * sizeof (char);
    }
    /* set the n+1th argument to be NULL */
    args_u[argc] = NULL;
    /* set the stackptr to the starting point of args_u and adjust the stack pointer */
    stackptr = args_u - sizeof (char**) - ((int)args_u%8);

    /* Warp to user mode. */
    md_usermode(argc, (userptr_t) args_u, stackptr, entrypoint);
    /*********************** end of A2 stuff *****************/

    /* md_usermode does not return */
    panic("md_usermode returned\n");
    return EINVAL;
}
コード例 #12
0
ファイル: psyscall.c プロジェクト: coderpm/OS161
int
sys___execv(char * p_name,char **ar )
{
	struct vnode *p_vnode;
		vaddr_t  stackptr;
		vaddr_t entrypoint;

		int result;
		size_t copied_length;
		char *kname;

		if(p_name==NULL)
			return EFAULT;

		if(ar==NULL)
			return EFAULT;

		if(p_name == '\0')
			return ENOEXEC;


		kname = (char *) kmalloc(sizeof(p_name));
		result = copyinstr((const_userptr_t)p_name,kname,NAME_MAX,&copied_length);
		if(copied_length == 1)
		{
			kfree(kname);
			return EINVAL;
		}
		if(result)
		{
			kfree(kname);
			return result;
		}

		char **karguments1 = kmalloc(100*sizeof(char*));
		result = copyin((const_userptr_t) ar,karguments1,(100*sizeof(char*)));
		if(result)
		{
			kfree(karguments1);
			kfree(kname);
			return result;
		}
		else
			kfree(karguments1);

		char **arguments_kernel =(char **) kmalloc(sizeof(char**));
		result = copyin((const_userptr_t) ar,arguments_kernel,(sizeof(char**)));
		if(result)
		{
			kfree(kname);
			kfree(arguments_kernel);
			return result;

		}

		char **karguments = (char **) kmalloc(sizeof(char **));

		int counter=0;
		size_t actual_lenght1;
		while(!(ar[counter]==NULL))
		{
			int string_length = strlen(ar[counter])+1;
			karguments[counter] = (char *) kmalloc(sizeof(char) * string_length);
			result = copyinstr((const_userptr_t) ar[counter],karguments[counter],string_length,&actual_lenght1);
			if(result)
			{
				kfree(kname);
				kfree(arguments_kernel);
				return result;
			}

			counter++;
		}
		karguments[counter] = NULL;

		result = vfs_open(kname, O_RDONLY, 0, &p_vnode);
		if (result) {
			return result;
		}

		as_destroy(curthread->t_addrspace);

		//Create a new address space.
		curthread->t_addrspace = as_create();
		if (curthread->t_addrspace==NULL)
		{
			vfs_close(p_vnode);
			return ENOMEM;
		}

		//Activate it.
		as_activate(curthread->t_addrspace);

		/* Load the executable. */
		result = load_elf(p_vnode, &entrypoint);
		if (result)
		{
			/* thread_exit destroys curthread->t_addrspace */
			vfs_close(p_vnode);
			return result;
		}

		/* Done with the file now. */
		vfs_close(p_vnode);

		//Get the pointer to the stack starting
		result = as_define_stack(curthread->t_addrspace, &stackptr);
		if (result)
		{
			/* thread_exit destroys curthread->t_addrspace */
			return result;
		}

		//Now copy the arguments
		int count =0;
		char **karray= kmalloc(sizeof(char**));
		size_t final_stack=0;

		while(karguments[count] != NULL)
		{
			int string_length = strlen(karguments[count])+1;
			char *k_des= karguments[count];

			int new_length = string_length;
			if((string_length) % 4 != 0)
			{
				while(new_length%4 !=0)
				{
					new_length++;
				}
				for(int i=string_length;i<=new_length;i++)
				{
					k_des[i]= '\0';
				}
			}

			//Argument aligned by 4

			size_t final_length= (size_t)new_length;

			if(count==0)
			{
				final_stack= stackptr- final_length;
			}
			else
			{
				final_stack= (size_t)karray[count-1]- final_length;
			}

			size_t actual_length1;
			result= copyoutstr(k_des, (userptr_t) (final_stack), final_length, &actual_length1);
			if(result)
			{
				return result;
			}

			karray[count]=  (char*)(final_stack);

			count++;
		} //End of While

		karray[count]= (char*)NULL;
		int value= count+1;
		int arr_length = (value+1)*sizeof(char*);
		final_stack= (size_t)karray[count-1]- arr_length;
		result= copyout(karray, (userptr_t) (final_stack),arr_length);
		if(result)
		{
			return result;
		}


			/* Warp to user mode. */
				enter_new_process(count /*argc*/, (userptr_t)(final_stack) /*userspace addr of argv*/,
						final_stack, entrypoint);

		return 0;
}
コード例 #13
0
static int
shmif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
	struct shmif_sc *sc = ifp->if_softc;
	struct ifdrv *ifd;
	char *path;
	int s, rv, memfd;

	s = splnet();
	switch (cmd) {
	case SIOCGLINKSTR:
		ifd = data;

		if (sc->sc_backfilelen == 0) {
			rv = ENOENT;
			break;
		}

		ifd->ifd_len = sc->sc_backfilelen;
		if (ifd->ifd_cmd == IFLINKSTR_QUERYLEN) {
			rv = 0;
			break;
		}

		if (ifd->ifd_cmd != 0) {
			rv = EINVAL;
			break;
		}

		rv = copyoutstr(sc->sc_backfile, ifd->ifd_data,
		    MIN(sc->sc_backfilelen, ifd->ifd_len), NULL);
		break;
	case SIOCSLINKSTR:
		if (ifp->if_flags & IFF_UP) {
			rv = EBUSY;
			break;
		}

		ifd = data;
		if (ifd->ifd_cmd == IFLINKSTR_UNSET) {
			finibackend(sc);
			rv = 0;
			break;
		} else if (ifd->ifd_cmd != 0) {
			rv = EINVAL;
			break;
		} else if (sc->sc_backfile) {
			rv = EBUSY;
			break;
		}

		if (ifd->ifd_len > MAXPATHLEN) {
			rv = E2BIG;
			break;
		} else if (ifd->ifd_len < 1) {
			rv = EINVAL;
			break;
		}

		path = kmem_alloc(ifd->ifd_len, KM_SLEEP);
		rv = copyinstr(ifd->ifd_data, path, ifd->ifd_len, NULL);
		if (rv) {
			kmem_free(path, ifd->ifd_len);
			break;
		}
		rv = rumpuser_open(path,
		    RUMPUSER_OPEN_RDWR | RUMPUSER_OPEN_CREATE, &memfd);
		if (rv) {
			kmem_free(path, ifd->ifd_len);
			break;
		}
		rv = initbackend(sc, memfd);
		if (rv) {
			kmem_free(path, ifd->ifd_len);
			rumpuser_close(memfd);
			break;
		}
		sc->sc_backfile = path;
		sc->sc_backfilelen = ifd->ifd_len;

		break;
	default:
		rv = ether_ioctl(ifp, cmd, data);
		if (rv == ENETRESET)
			rv = 0;
		break;
	}
	splx(s);

	return rv;
}
コード例 #14
0
STATIC int
eval_parameter(connection_t *conn, negotiation_state_t *state,
			   negotiation_parameter_t *par)
{
	uint32_t n = par->val.nval[0];
	size_t sz;
	text_key_t key = par->key;
	bool sent = (state->kflags[key] & NS_SENT) != 0;

	state->kflags[key] |= NS_RECEIVED;

	switch (key) {
		/*
		 *  keys connected to security negotiation
		 */
	case K_AuthMethod:
		if (n) {
			DEBOUT(("eval_par: AuthMethod nonzero (%d)\n", n));
			return ISCSI_STATUS_NEGOTIATION_ERROR;
		}
		break;

	case K_Auth_CHAP_Algorithm:
	case K_Auth_CHAP_Challenge:
	case K_Auth_CHAP_Identifier:
	case K_Auth_CHAP_Name:
	case K_Auth_CHAP_Response:
		DEBOUT(("eval_par: Authorization Key in Operational Phase\n"));
		return ISCSI_STATUS_NEGOTIATION_ERROR;

		/*
		 * keys we always send
		 */
	case K_DataDigest:
		state->DataDigest = n;
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_HeaderDigest:
		state->HeaderDigest = n;
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_ErrorRecoveryLevel:
		state->ErrorRecoveryLevel = n;
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_ImmediateData:
		state->ImmediateData = n;
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_InitialR2T:
		state->InitialR2T = n;
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_MaxRecvDataSegmentLength:
		state->MaxRecvDataSegmentLength = n;
		/* this is basically declarative, not negotiated */
		/* (each side has its own value) */
		break;

		/*
		 * keys we don't always send, so we may have to reflect the value
		 */
	case K_DefaultTime2Retain:
		state->DefaultTime2Retain = n = min(state->DefaultTime2Retain, n);
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_DefaultTime2Wait:
		state->DefaultTime2Wait = n = min(state->DefaultTime2Wait, n);
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_MaxConnections:
		if (state->MaxConnections)
			state->MaxConnections = n = min(state->MaxConnections, n);
		else
			state->MaxConnections = n;

		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_MaxOutstandingR2T:
		state->MaxOutstandingR2T = n;
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_FirstBurstLength:
		state->FirstBurstLength = n;
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_MaxBurstLength:
		state->MaxBurstLength = n;
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_IFMarker:
	case K_OFMarker:
		/* not (yet) supported */
		if (!sent)
			set_key_n(state, key, 0);
		break;

	case K_IFMarkInt:
	case K_OFMarkInt:
		/* it's a range, and list_num will be 1, so this will reply "Reject" */
		if (!sent)
			set_key_n(state, key, 0);
		break;

	case K_DataPDUInOrder:
	case K_DataSequenceInOrder:
		/* values are don't care */
		if (!sent)
			set_key_n(state, key, n);
		break;

	case K_NotUnderstood:
		/* return "NotUnderstood" */
		set_key_s(state, key, par->val.sval);
		break;

		/*
		 * Declarative keys (no response required)
		 */
	case K_TargetAddress:
		/* ignore for now... */
		break;

	case K_TargetAlias:
		if (conn->login_par->is_present.TargetAlias) {
			copyoutstr(par->val.sval, conn->login_par->TargetAlias,
				ISCSI_STRING_LENGTH - 1, &sz);
			/* do anything with return code?? */
		}
		break;

	case K_TargetPortalGroupTag:
		/* ignore for now... */
		break;

	default:
		DEBOUT(("eval_par: Invalid parameter type %d\n", par->key));
		return ISCSI_STATUS_NEGOTIATION_ERROR;
	}
	return 0;
}
コード例 #15
0
ファイル: runprogram.c プロジェクト: kevinkhuang/OS-161
int
runprogram(char *progname, unsigned int argc, char**args)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;
    
	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, &v);
	if (result) {
		return result;
	}
    
	/* We should be a new thread. */
	assert(curthread->t_vmspace == NULL);
    
	/* Create a new address space. */
	curthread->t_vmspace = as_create();
	if (curthread->t_vmspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}
    
	/* Activate it. */
	as_activate(curthread->t_vmspace);
    
	/* Load the executable. */
#if OPT_A3
    curthread->t_vmspace->elf_file = kstrdup(progname);
#endif
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_vmspace */
		vfs_close(v);
		return result;
	}
    
	/* Done with the file now. */
	vfs_close(v);
    
	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_vmspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_vmspace */
		return result;
	}
    
    /*********************** stuff for A2 *******************/
    char **args_u; /* user space arguments.(array of ptrs
                   to string arguments.*/
    /* string length of the arguments */
    size_t argstrlen = getlen(argc, args);
    /* address space for the string arguments value. */
    char *arg_str = (char *)stackptr - argstrlen;
    /* address space for the pointers to string arguments. */
    args_u = (char **)arg_str - (argc+1)*sizeof(char**);
    /* adjust the address so that its divisable by 4 */
    args_u = (int)args_u - (int)args_u%4;
    
    /* copy the arguments to the user address space */
    int len;
    int i;
    for (i=0; i<argc; i++){
        /* copy a single argument  to the user address space */
        copyoutstr(args[i], (userptr_t)arg_str, strlen(args[i])+1, &len);
        /* set the user argument to the current argument string pointer */
        args_u[i] = arg_str;
        /* increment the argument pointer to the next argument */
        arg_str += (strlen(args[i])+1)*sizeof(char);
    }
    /* set the n+1th argument to be NULL */
    args_u[argc] = NULL;
    /* set the stackptr to the starting point of args_u and adjust the stack pointer */
    stackptr = args_u - sizeof(char**) - ((int)args_u%8);
    
    /* Warp to user mode. */
    md_usermode(argc, (userptr_t) args_u, stackptr, entrypoint);
    /*********************** end of A2 stuff *****************/
    
    /* md_usermode does not return */
    panic("md_usermode returned\n");
    return EINVAL;
}
コード例 #16
0
ファイル: simple_syscalls.c プロジェクト: dlyrikz/OS
int 
sys_execv(userptr_t progname, userptr_t args){ /*This function implements the execv functionality*/
    size_t get, offset;
    struct vnode *v;
    vaddr_t entrypoint, stackptr;
    userptr_t userdest;
    int i=0, append_zero, argc=0, result, part=0;
    char *buf_mem;
    int n=0;
    struct addrspace *old_addr = curthread->t_vmspace;
    char **usr_args = (char**)args;
    buf_mem = (void *) kmalloc(sizeof(void *));
    result = copyin((const_userptr_t)args,buf_mem,4);
    if (result){
        kfree(buf_mem);
        return result;
    }

   lock_acquire(execv_lock);


    kfree(buf_mem);


    while(usr_args[argc] != NULL){
        argc++;
    }
    size_t len_string[argc];
    userptr_t user_argv[argc];

    char *args_buf = kmalloc(PAGE_SIZE*sizeof(char));

    // Check user pointer
    buf_mem = (char *)kmalloc(1024*sizeof(char));
    if (buf_mem == NULL){
        result = ENOMEM;
        kfree(args_buf);
    }
    

    result = copyinstr((const_userptr_t)progname,buf_mem,1024,&get);
    if (result){
        kfree(buf_mem);
    }
	//Implementation from runprogram from here
    /* Open the file. */
    result = vfs_open((char *)progname, O_RDONLY, &v);
    if (result) {
        kfree(buf_mem);
    }
    // Keep old addrspace in case of failure
    struct addrspace *new_addr = as_create();
    if (new_addr == NULL){
        result = ENOMEM;
        vfs_close(v);
    }
    while (usr_args[i] != NULL){
        result = copyinstr((const_userptr_t)usr_args[i], &args_buf[part], PAGE_SIZE, &len_string[i]);
        if (result){
            as_destroy(new_addr);
        }
        part += len_string[i];
        i++;
    }
    /* Swap addrspace and Activate it*/
    curthread->t_vmspace = new_addr;
    as_activate(curthread->t_vmspace);

    /* Load the executable. */
    result = load_elf(v, &entrypoint);
    if (result) {
        curthread->t_vmspace = old_addr;
        as_activate(curthread->t_vmspace);
    }
    /* Define the user stack in the address space */
    result = as_define_stack(curthread->t_vmspace, &stackptr);
    if (result) {
        curthread->t_vmspace = old_addr;
        as_activate(curthread->t_vmspace);
    }

    // Copy args to new addrspace
    offset = 0;
    for (i=argc-1; i>-1; i--){
        part -= len_string[i]; // readjust inherited part index
        append_zero = (4 - (len_string[i]%4) ) % 4; // Word align
        offset += append_zero;
        offset += len_string[i];

        user_argv[i] = (userptr_t)(stackptr - offset);

        result = copyoutstr((const char*)&args_buf[part], user_argv[i], len_string[i], &get);
        if (result){
        curthread->t_vmspace = old_addr;
        as_activate(curthread->t_vmspace);
        }
    }

    // Copy pointers to argv
    userdest = user_argv[0] - 4 * (argc+1);
    stackptr = (vaddr_t)userdest; // Set stack pointer
    for (i=0; i<argc; i++){
        result = copyout((const void *)&user_argv[i], userdest, 4);
        if (result)
        curthread->t_vmspace = old_addr;
        as_activate(curthread->t_vmspace);
        userdest += 4;
    }

    // Wrap up
    kfree(args_buf);
    vfs_close(v);



    /* Warp to user mode. */
    md_usermode(argc, (userptr_t)stackptr, stackptr, entrypoint);


	lock_release(execv_lock);
    	return EINVAL;

}
コード例 #17
0
ファイル: syscall.c プロジェクト: ShuranXu/OS161
int sys_execv(const char *prog_path, char **args) {
	int spl = splhigh();
	// the prog_path is in user space, we need to copy it into kernel space
	if(prog_path == NULL) {
		return EINVAL;
	}
	// frist the program path
	char* program = (char *) kmalloc(MAX_PATH_LEN * sizeof(char));
	int size;
	int result = copyinstr((const_userptr_t) prog_path, program, MAX_PATH_LEN, &size);
	if(result) {
		kfree(program);
		return EFAULT;
	}
	// arguments
	char** argv = (char**) kmalloc(sizeof(char**));
	// char** argv;
	result = copyin((const_userptr_t)args, argv, sizeof(char **));
	if(result) {
		kfree(program);
		kfree(argv);
		return EFAULT;
	}
	// count the number of arguments
	int i = 0;
	while(args[i] != NULL){
		argv[i] = (char*) kmalloc(sizeof(char) * MAX_ARG_LEN);
		if(copyinstr((const_userptr_t) args[i], argv[i], MAX_ARG_LEN, &size) != 0) {
			return EFAULT;
		}
		i++;
	}
	argv[i] = NULL;
	// runprogram_exev_syscall(program, argv, i);
	/*********************** runprogram starts*****************/

	struct vnode *v;
	vaddr_t entrypoint, stackptr;	

	result = vfs_open(program, O_RDONLY, &v);

	if (result) {
		return result;
	}

	// destroy the old addrspace
	if(curthread->t_vmspace != NULL){
		as_destroy(curthread->t_vmspace);
		curthread->t_vmspace = NULL;
	}

	assert(curthread->t_vmspace == NULL);

	// Create a new address space. 
	curthread->t_vmspace = as_create();
	if (curthread->t_vmspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	// Activate it. 
	as_activate(curthread->t_vmspace);

	// Load the executable. 
	result = load_elf(v, &entrypoint); // Load an ELF executable user program into the current address space and
	// returns the entry point (initial PC) for the program in ENTRYPOINT.
	if (result) {
		vfs_close(v);
		return result;
	}
	vfs_close(v);

	result = as_define_stack(curthread->t_vmspace, &stackptr);
	if (result) {
		// thread_exit destroys curthread->t_vmspace 
		return result;
	}

	int narg = i - 1;
	int j;
	for(j = 0; j < narg; ++j){
	    int len = 1 + strlen(argv[j]);
	    len = ROUNDUP(len, 8);
		stackptr -= len;

		result = copyoutstr(argv[j],(userptr_t)stackptr, len, &len); 
		if(result){
			return result;
		}	
		argv[j] = (char*)stackptr;
    }

    argv[i] = NULL;
    size_t arg_size = (narg + 1) * sizeof(char*);
    arg_size = ROUNDUP(arg_size, 8);
    // align the stackptr to 8 byte aligned
    stackptr -= arg_size;
    // stackptr -= stackptr % 8;

    copyout(argv, stackptr, (narg + 1) * 4);
	md_usermode(i, stackptr, stackptr, entrypoint); 
	panic("md_usermode returned\n");
	return EINVAL;
}
コード例 #18
0
ファイル: if_virt.c プロジェクト: yazshel/netbsd-kernel
static int
virtif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
	struct virtif_sc *sc = ifp->if_softc;
	int rv;

	switch (cmd) {
#ifdef RUMP_VIF_LINKSTR
	struct ifdrv *ifd;
	size_t linkstrlen;

#ifndef RUMP_VIF_LINKSTRMAX
#define RUMP_VIF_LINKSTRMAX 4096
#endif

	case SIOCGLINKSTR:
		ifd = data;

		if (!sc->sc_linkstr) {
			rv = ENOENT;
			break;
		}
		linkstrlen = strlen(sc->sc_linkstr)+1;

		if (ifd->ifd_cmd == IFLINKSTR_QUERYLEN) {
			ifd->ifd_len = linkstrlen;
			rv = 0;
			break;
		}
		if (ifd->ifd_cmd != 0) {
			rv = ENOTTY;
			break;
		}

		rv = copyoutstr(sc->sc_linkstr,
		    ifd->ifd_data, MIN(ifd->ifd_len,linkstrlen), NULL);
		break;
	case SIOCSLINKSTR:
		if (ifp->if_flags & IFF_UP) {
			rv = EBUSY;
			break;
		}

		ifd = data;

		if (ifd->ifd_cmd == IFLINKSTR_UNSET) {
			panic("unset linkstr not implemented");
		} else if (ifd->ifd_cmd != 0) {
			rv = ENOTTY;
			break;
		} else if (sc->sc_linkstr) {
			rv = EBUSY;
			break;
		}

		if (ifd->ifd_len > RUMP_VIF_LINKSTRMAX) {
			rv = E2BIG;
			break;
		} else if (ifd->ifd_len < 1) {
			rv = EINVAL;
			break;
		}


		sc->sc_linkstr = kmem_alloc(ifd->ifd_len, KM_SLEEP);
		rv = copyinstr(ifd->ifd_data, sc->sc_linkstr,
		    ifd->ifd_len, NULL);
		if (rv) {
			kmem_free(sc->sc_linkstr, ifd->ifd_len);
			break;
		}

		rv = virtif_create(ifp);
		if (rv) {
			kmem_free(sc->sc_linkstr, ifd->ifd_len);
		}
		break;
#endif /* RUMP_VIF_LINKSTR */
	default:
		if (!sc->sc_linkstr)
			rv = ENXIO;
		else
			rv = ether_ioctl(ifp, cmd, data);
		if (rv == ENETRESET)
			rv = 0;
		break;
	}

	return rv;
}
コード例 #19
0
ファイル: dump.c プロジェクト: madhavsuresh/illumos-gate
/*ARGSUSED*/
int
dump_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred, int *rvalp)
{
	uint64_t size;
	uint64_t dumpsize_in_pages;
	int error = 0;
	char *pathbuf = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
	char uuidbuf[36 + 1];
	size_t len;
	vnode_t *vp;

	switch (cmd) {
	case DIOCGETDUMPSIZE:
		if (dump_conflags & DUMP_ALL)
			size = ptob((uint64_t)physmem) / DUMP_COMPRESS_RATIO;
		else {
			/*
			 * We can't give a good answer for the DUMP_CURPROC
			 * because we won't know which process to use until it
			 * causes a panic.  We'll therefore punt and give the
			 * caller the size for the kernel.
			 *
			 * This kernel size equation takes care of the
			 * boot time kernel footprint and also accounts
			 * for availrmem changes due to user explicit locking.
			 * Refer to common/vm/vm_page.c for an explanation
			 * of these counters.
			 */
			dumpsize_in_pages = (physinstalled - obp_pages -
			    availrmem -
			    anon_segkp_pages_locked -
			    k_anoninfo.ani_mem_resv -
			    pages_locked -
			    pages_claimed -
			    pages_useclaim);

			/*
			 * Protect against vm vagaries.
			 */
			if (dumpsize_in_pages > (uint64_t)physmem)
				dumpsize_in_pages = (uint64_t)physmem;

			size = ptob(dumpsize_in_pages) / DUMP_COMPRESS_RATIO;
		}
		if (copyout(&size, (void *)arg, sizeof (size)) < 0)
			error = EFAULT;
		break;

	case DIOCGETCONF:
		mutex_enter(&dump_lock);
		*rvalp = dump_conflags;
		if (dumpvp && !(dumpvp->v_flag & VISSWAP))
			*rvalp |= DUMP_EXCL;
		mutex_exit(&dump_lock);
		break;

	case DIOCSETCONF:
		mutex_enter(&dump_lock);
		if (arg == DUMP_KERNEL || arg == DUMP_ALL ||
		    arg == DUMP_CURPROC)
			dump_conflags = arg;
		else
			error = EINVAL;
		mutex_exit(&dump_lock);
		break;

	case DIOCGETDEV:
		mutex_enter(&dump_lock);
		if (dumppath == NULL) {
			mutex_exit(&dump_lock);
			error = ENODEV;
			break;
		}
		(void) strcpy(pathbuf, dumppath);
		mutex_exit(&dump_lock);
		error = copyoutstr(pathbuf, (void *)arg, MAXPATHLEN, NULL);
		break;

	case DIOCSETDEV:
	case DIOCTRYDEV:
		if ((error = copyinstr((char *)arg, pathbuf, MAXPATHLEN,
		    NULL)) != 0 || (error = lookupname(pathbuf, UIO_SYSSPACE,
		    FOLLOW, NULLVPP, &vp)) != 0)
			break;
		mutex_enter(&dump_lock);
		if (vp->v_type == VBLK)
			error = dumpinit(vp, pathbuf, cmd == DIOCTRYDEV);
		else
			error = ENOTBLK;
		mutex_exit(&dump_lock);
		VN_RELE(vp);
		break;

	case DIOCDUMP:
		mutex_enter(&dump_lock);
		if (dumpvp == NULL)
			error = ENODEV;
		else if (dumpvp->v_flag & VISSWAP)
			error = EBUSY;
		else
			dumpsys();
		mutex_exit(&dump_lock);
		break;

	case DIOCSETUUID:
		if ((error = copyinstr((char *)arg, uuidbuf, sizeof (uuidbuf),
		    &len)) != 0)
			break;

		if (len != 37) {
			error = EINVAL;
			break;
		}

		error = dump_set_uuid(uuidbuf);
		break;

	case DIOCGETUUID:
		error = copyoutstr(dump_get_uuid(), (void *)arg, 37, NULL);
		break;

	default:
		error = ENXIO;
	}

	kmem_free(pathbuf, MAXPATHLEN);
	return (error);
}
コード例 #20
0
ファイル: runprogram.c プロジェクト: MattMarji/os161
int
runprogram(char *progname, char** args, int num)
{
    struct vnode *v;
    vaddr_t entrypoint, stackptr;
    int result;
    int s_size = 0;
    int kargc = num;
    int i=0, err;
    size_t tt; 


    /* Open the file. */
    result = vfs_open(progname, O_RDONLY, &v);
    if (result) {
	return result;
    }

    /* We should be a new thread. */
    assert(curthread->t_vmspace == NULL);

    /* Create a new address space. */
    curthread->t_vmspace = as_create();
    if (curthread->t_vmspace==NULL) {
	vfs_close(v);
	return ENOMEM;
    }

    /* Activate it. */
    as_activate(curthread->t_vmspace);

    /* Load the executable. */
    result = load_elf(v, &entrypoint);
    if (result) {
	/* thread_exit destroys curthread->t_vmspace */
	vfs_close(v);
	return result;
    }

    /* Done with the file now. */
    vfs_close(v);

    /* Define the user stack in the address space */
    result = as_define_stack(curthread->t_vmspace, &stackptr);
    if (result) {
	/* thread_exit destroys curthread->t_vmspace */
	return result;
    }

    if(args!=NULL)
    {
	vaddr_t new_args[kargc];
	vaddr_t  new_argv;
	int w_size; /*word alligned size of string*/
     
	/*place all the strings on the stack*/
	/*carefully ignore the first element because contains the program name*/
	for(i = (kargc-1); i>=0 ; i--)
	{
	    
	    s_size = strlen(args[i]);
	    w_size = ((s_size / 4 ) + 1)*4;
	   
	    stackptr -= w_size;
	    err = copyoutstr(args[i], stackptr, s_size+1, &tt);
	   
	    if(err!=0){
		kprintf("2: err %d, the official length is %d, the given length is %d \n ", err, tt, s_size+1);
		return err;
	    }
	    new_args[i] = stackptr;
	}
	kprintf("finished all my strlens \n");

	/*place all the pointers to the strings on the stack*/
	new_args[kargc] = NULL;
	for(i = kargc; i>=0 ; i--){
	    stackptr-= 4;
	    err = copyout(&(new_args[i]), stackptr, 4);
	    if(err!=0){
		kprintf("3: err %d \n ", err);
		return err;
	    }
	}


	/* Warp to user mode. */
	md_usermode(kargc, stackptr, stackptr, entrypoint);
    }
    else
	md_usermode(0, NULL, stackptr, entrypoint);
    /* md_usermode does not return */
    panic("md_usermode returned\n");
    return EINVAL;
}
コード例 #21
0
ファイル: runprogram.c プロジェクト: gapry/os161
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, int argc, char** args)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

	/* Initialize an array of pointers that stores the pointer to the
	 * string arguments in the user stack */
	char** argv = (char **)kmalloc((argc + 1) * sizeof(char*));
	if (argv == NULL) {
		return ENOMEM;
	}
	argv[argc] = 0;

	int i;
	size_t actual;
	int total = 0;

	/* Copy string arguments from kernel memory onto the user stack,
	 * and store the user pointer to the argument in argv */
	for (i = argc - 1; i >= 0; i--) {
		int len = strlen(args[i]) + 1;
		total = total + len;
		stackptr = stackptr - len;
		copyoutstr(args[i], (userptr_t)stackptr, len, &actual);
		argv[i] = (char *)stackptr;
	}

	/* Add any necessary padding to the user stack */
	int padding = 4 - (total % 4);
	if (padding) {
		stackptr = stackptr - padding;
	}

	/* Copy the array of user pointers argv onto the user stack  */
	for (i = argc; i >= 0; i--) {
		stackptr = stackptr - 4;
		copyout(&argv[i], (userptr_t)stackptr, 4);
	}

	kfree(argv);

	/* Warp to user mode. */
	enter_new_process(argc, (userptr_t)stackptr /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
コード例 #22
0
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, char **argv, unsigned long argc)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;
	pid_t pidRetVal;


	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	assert(curthread->t_vmspace == NULL);

	/* Create filetable for process*/
	curthread->ft = create_process_filetable();
	if(curthread->ft == NULL)
	{
		vfs_close(v);
		return ENOMEM;
	}
	
	/* Initialize STDIN, STDOUT, STDERR */
	struct ft_node* standardIn = create_ft_node();
	struct ft_node* standardOut = create_ft_node();
	struct ft_node* standardErr = create_ft_node();

	char console1[] = "con:";
	result = vfs_open(console1, O_RDONLY, &standardIn->v);
	if(result)
	{
		kprintf("Cannot open STDIN\n");
		vfs_close(v);
		return result;
	}
	standardIn->mode = O_RDONLY;
	array_add(curthread->ft->file_descriptors, standardIn);

	char console2[] = "con:";
	result = vfs_open(console2, O_WRONLY, &standardOut->v);
	if(result)
	{
		kprintf("Cannot open STDOUT\n");
		vfs_close(v);
		return result;
	}
	standardOut->mode = O_WRONLY;
	array_add(curthread->ft->file_descriptors, standardOut);

	char console3[] = "con:";
	result = vfs_open(console3, O_WRONLY, &standardErr->v);
	if(result)
	{
		kprintf("Cannot open STDERR\n");
		vfs_close(v);
		return result;
	}
	standardErr->mode = O_WRONLY;
	array_add(curthread->ft->file_descriptors, standardErr);

	/* Allocate initial PID for this first program */
	result = allocate_pid(&pidRetVal);
	if(result)
	{
		kprintf("Could not allocate PID\n");
		vfs_close(v);
		return result;
	}
	curthread->PID = pidRetVal; 
	((struct p_node *)array_getguy(pid_table, curthread->PID))->is_interested = 0;
	
	/* Create a new address space. */
	curthread->t_vmspace = as_create();
	if (curthread->t_vmspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_vmspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_vmspace */
		vfs_close(v);
		return result;
	}
	//kprintf("finished loadelf in runprog\n");

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_vmspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_vmspace */
		return result;
	}
	vaddr_t stackptrv[argc+1];
	int i;
	size_t actual;
	for(i = argc-1; i >= 0; i--)
	{
		int len = strlen(argv[i]);
		len++;
		int padding = len % 4;
		stackptr -= len + (4 - padding);
		result = copyoutstr(argv[i], (userptr_t)stackptr, len, &actual);
		if(result)
		{

			return result;
		}
		stackptrv[i] = stackptr;
	}
	stackptrv[argc] = 0;
	for(i = argc; i >= 0; i--)
	{
		stackptr -= sizeof(vaddr_t);
		result = copyout(&stackptrv[i], (userptr_t)stackptr, sizeof(vaddr_t));
		if(result)
		{
			return result;
		}
	}
	//kprintf("Before usernmode\n");
	/* Warp to user mode. */
	md_usermode(argc /*argc*/, (userptr_t)stackptr /*userspace addr of argv*/,
		    stackptr, entrypoint);
	
	/* md_usermode does not return */
	panic("md_usermode returned\n");
	return EINVAL;
}
コード例 #23
0
ファイル: runprogram.c プロジェクト: HeliWang/cs350OS
runprogram(char *progname)
#endif
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);

	/* Create a new address space. */
	as = as_create();
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Switch to it and activate it. */
  curproc_setas(as);
  as_activate();

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

#if OPT_A2
  // How much space do we need for args in stack?
  // We need space for each pointer (4argc)
  // We need space for each character, including NULL termination, plus
  // padding to make multiples of 4
  int stringSpace = 0;
  for (unsigned long i = 0; i < argc; i++) {
    stringSpace += strlen(argv[i]) + 1;
  }

  // Align stack pointer to an 8-byte alignment
  while ((stackptr - (4*argc) - stringSpace) % 8 != 0) {
    stackptr--;
  }

  // Use a vaddr array to track the addresses the strings end up in
  // One bigger than argc to also have the pointer to the final NULL
  // value
  vaddr_t stringAddr[argc+1];

  // Copy argument strings onto stack
  // Array must end with NULL pointer, so do that first
  stackptr -= 4;
  copyout((void *)NULL, (userptr_t)stackptr, (size_t)4);
  stringAddr[argc] = stackptr;
  for (int i = argc-1; i >= 0; i--) {
    stackptr -= strlen(argv[i]) + 1;
    while (stackptr % 4 != 0) stackptr--;
    copyoutstr(argv[i], (userptr_t)stackptr, (size_t)strlen(argv[i]), NULL);
    stringAddr[i] = stackptr;
  }

  // Now use the stored addresses of the string to add the appropriate
  // pointers to the stack
  for (int i = argc; i >= 0; i--) {
    stackptr -= sizeof(vaddr_t);
    copyout(&stringAddr[i], (userptr_t)stackptr, sizeof(vaddr_t));
  }

	/* Warp to user mode. */
	enter_new_process(argc /*argc*/, (userptr_t)stackptr /*userspace addr of argv*/,
			  stackptr, entrypoint);
#else
	/* Warp to user mode. */
	enter_new_process(0 /*argc*/, NULL /*userspace addr of argv*/,
			  stackptr, entrypoint);
#endif

	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
コード例 #24
0
ファイル: runprogram.c プロジェクト: mellwa/os
int
runprogram(char *progname, unsigned long argc, char **argv)
{	
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;
    
	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}
    
	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);
    
	/* Create a new address space. */
	#if OPT_A3
	as = as_create(progname);
	#else
	as = as_create();
	#endif
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

    
	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();
    

    
	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);
    
 
	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr); // find the stack pointer
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

    
    //add stuff
    stackptr = stackptr - (argc + 1)*sizeof(vaddr_t); //subtract number of arguments + 1 (space for pointers)
    
    unsigned long i;
    unsigned int len;
    unsigned int len2;
    char **buf = (char **)stackptr; // argv

    for(i=0; i<argc; i++){
        len = (strlen(argv[i])+1)*(sizeof(char)); // first str length + null char
        stackptr = stackptr - len; // adjust stack pointer for length of str

        buf[i] = (char*)stackptr; // assign pointer to argv[i]
        copyoutstr((void *)argv[i],(userptr_t)buf[i],len,&len2); // copy to userstack
    }
    unsigned int remainder = stackptr % 8;
	if(remainder != 0){
		stackptr = stackptr - remainder;
	}
    
    // pass arguments to user program
	/* Warp to user mode. */
	enter_new_process(argc, (userptr_t)buf /*userspace addr of argv*/,
                      stackptr, entrypoint);

	// stores into trap->a0 as argc
	// stores trap->a1 as argv
	// sets stack pointer
	
    
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
コード例 #25
0
ファイル: runprogram.c プロジェクト: saifmahamood/cs350-os161
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, char** args, size_t nargs)
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;
	int argc = 0;

	while(args[argc] != NULL) {
	    argc++;
	}



	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);

	/* Create a new address space. */
	as = as_create();
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

	#if OPT_A2

	while(stackptr %8 != 0)
		stackptr--;

	vaddr_t argptr[argc + 1];
	for (int i = argc - 1; i >= 0; i--)
	{
		stackptr -= strlen(args[i]) + 1;
		result = copyoutstr(args[i], (userptr_t) stackptr, strlen(args[i]) + 1, NULL);
		if(result)
			return result;
		argptr[i] = stackptr;
	}

	while(stackptr % 4 != 0)
		stackptr--;
	//int hack = (int) nargs;

	argptr[nargs] = 0;

	for (int i = argc; i >= 0; i--)
	{
		stackptr -= ROUNDUP(sizeof(vaddr_t), 4);
		result = copyout(&argptr[i], (userptr_t) stackptr, sizeof(vaddr_t));
		if(result)
			return result;
	}
	#endif
	/* Warp to user mode. */
	enter_new_process(nargs /*argc*/, (userptr_t) stackptr /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
コード例 #26
0
ファイル: process_syscalls.c プロジェクト: Nullset14/OS161
int
sys_execv(char *progname, char **args, int *err) {

    struct addrspace *as;
    struct vnode *v;
    vaddr_t entrypoint, stackptr;
    int result;

    /* Validations */
    if (progname == NULL) {
        *err = EFAULT;
        return -1;
    }

    if (args == NULL || (int *)args == (int *)0x40000000 || (int *)args == (int *)0x80000000) {
        *err = EFAULT;
        return -1;
    }

    /* Count number of arguments and total size of input */
    int args_count = 0;
    for (;args_count < ARG_MAX && args[args_count] != NULL; args_count++);

    if (args_count > ARG_MAX) {
        *err = E2BIG;
        return -1;
    }

    /* Copy File name */
    char *progname_copy = (char *) kmalloc(sizeof(char) * NAME_MAX);
    size_t actual = 0;
    result = copyinstr((userptr_t)progname, progname_copy, NAME_MAX, &actual);

    if (result) {
        kfree(progname_copy);
        *err = result;
        return -1;
    }

    if (strlen(progname_copy) == 0) {
        kfree(progname_copy);
        *err = EINVAL;
        return -1;
    }

    /* Allocate Kernel Memory for arguments */
    char **args_copy = (char **) kmalloc(sizeof(char *) * args_count);

    int c_args_count = 0,
            arg_size = 0,
            padded_size = 0;

    for (;c_args_count < args_count; c_args_count++) {
        if ((int *)args[c_args_count] == (int *)0x40000000 || (int *)args[c_args_count] == (int *)0x80000000) {
            kfree(progname_copy);
            *err = EFAULT;
            return -1;
        }
    }

    c_args_count = 0;
    /* Calculate total length accounting for padding */
    for (;c_args_count < args_count; c_args_count++) {
        arg_size = strlen(args[c_args_count]) + 1;

        args_copy[c_args_count] = (char *) kmalloc(sizeof(char) * arg_size);
        copyinstr((userptr_t)args[c_args_count], args_copy[c_args_count], arg_size, &actual);

        padded_size += arg_size;
        if (padded_size % 4) {
            padded_size += (4 - (padded_size % 4)) % 4;
        }
    }

    /* Open the file. */
    result = vfs_open(progname_copy, O_RDONLY, 0, &v);
    if (result) {
        kfree(progname_copy);
        *err = result;
        return -1;
    }

    /* Destroy the current process's address space to create a new one. */
    as = curproc->p_addrspace;
    curproc->p_addrspace = NULL;

    as_destroy(as);

    /* We should be a new process. */
    KASSERT(proc_getas() == NULL);

    /* Create a new address space. */
    as = as_create();
    if (as == NULL) {
        kfree(progname_copy);
        vfs_close(v);
        *err = ENOMEM;
        return -1;
    }

    /* Switch to it and activate it. */
    proc_setas(as);
    as_activate();

    /* Load the executable. */
    result = load_elf(v, &entrypoint);
    if (result) {
        /* p_addrspace will go away when curproc is destroyed */
        kfree(progname_copy);
        vfs_close(v);
        *err = result;
        return -1;
    }

    /* Done with the file now. */
    vfs_close(v);

    /* Define the user stack in the address space */
    result = as_define_stack(as, &stackptr);
    if (result) {
        /* p_addrspace will go away when curproc is destroyed */
        kfree(progname_copy);
        *err = result;
        return -1;
    }

    stackptr -= padded_size;
    char **arg_address = (char **) kmalloc(sizeof(char *) * args_count + 1);

    /* Copy arguments into user stack */
    for(int i = 0; i < args_count; i++) {
        arg_size = strlen(args_copy[i]) + 1;

        if (arg_size % 4) {
            arg_size += (4 - arg_size % 4) % 4;
        }

        /* Store address of arguments */
        arg_address[i] = (char *)stackptr;

        copyoutstr(args_copy[i], (userptr_t)stackptr, arg_size, &actual);
        stackptr += arg_size;
    }

    /* Add Null Pointer at the end */
    arg_address[args_count] = 0;

    stackptr -= padded_size;
    stackptr -= (args_count + 1) * sizeof(char *);

    /* Copy address locations into user stack*/
    for (int i = 0; i < args_count + 1; i++) {
        copyout((arg_address + i), (userptr_t)stackptr, sizeof(char *));
        stackptr += sizeof(char *);
    }

    /* Reset pointer to start of the stack */
    stackptr -= ((args_count + 1) * sizeof(char *));

    kfree(progname_copy);

    c_args_count = 0;
    for (;c_args_count < args_count; c_args_count++) {
        kfree(args_copy[c_args_count]);
    }

    kfree(args_copy);
    kfree(arg_address);

    /* Warp to user mode. */
    enter_new_process(args_count /*argc*/, (userptr_t) stackptr /*userspace addr of argv*/,
                      (userptr_t) stackptr /*userspace addr of environment*/, stackptr, entrypoint);

    /* enter_new_process does not return. */
    panic("enter_new_process returned\n");

    *err = EINVAL;
    return -1;
}
コード例 #27
0
ファイル: runprogram.c プロジェクト: MagicZou/petrel-os
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, char **args, int argc)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	// Variables for argument passing
	int i, pad;
	size_t offset, get;
	userptr_t userdest;

    size_t got[argc];
    userptr_t user_argv[argc];

    // Count length of each arg
    i = 0;
    for (i=0; i<argc; i++){
    	got[i] = strlen(args[i]) + 1; // Need +1 to account for /0
    }

    /* We enforce that the kernel is only allowed to start ONE user process
     * directly through runprogram with PID_MIN as its pid. Thereafter any
     * new user process needs to be forked from existing ones.
     */
	KASSERT(process_table[PID_MIN] == NULL);
	curthread->pid = PID_MIN;

	stdio_init();

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

    // Copy args to new addrspace
    offset = 0;
    for (i=argc-1; i>-1; i--){
        pad = (4 - (got[i]%4) ) % 4; // Word align
        offset += pad;
        offset += got[i];

        user_argv[i] = (userptr_t)(stackptr - offset);

        result = copyoutstr((const char*)args[i], user_argv[i], got[i], &get);
        if (result){
            return result;
        }
    }

    // Copy pointers to argv
    userdest = user_argv[0] - 4 * (argc+1);
    stackptr = (vaddr_t)userdest; // Set stack pointer
    for (i=0; i<argc; i++){
        result = copyout((const void *)&user_argv[i], userdest, 4);
        if (result){
        	return result;
        }
        userdest += 4;
    }

	/* Warp to user mode. */
	enter_new_process(argc, (userptr_t)stackptr, stackptr, entrypoint);

	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
コード例 #28
0
ファイル: darwin_exec.c プロジェクト: Tommmster/netbsd-avr32
/*
 * Copy arguments onto the stack in the normal way, but add some
 * extra information in case of dynamic binding.
 */
int
exec_darwin_copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp)
{
	struct exec_macho_emul_arg *emea;
	struct exec_macho_object_header *macho_hdr;
	struct proc *p = l->l_proc;
	char **cpp, *dp, *sp, *progname;
	size_t len;
	void *nullp = NULL;
	long argc, envc;
	int error;

	/*
	 * Prepare the comm pages
	 */
	if ((error = darwin_commpage_map(p)) != 0)
		return error;

	/*
	 * Set up the stack
	 */
	*stackp = (char *)(((unsigned long)*stackp - 1) & ~0xfUL);

	emea = (struct exec_macho_emul_arg *)pack->ep_emul_arg;

	if (emea->dynamic == 1) {
		macho_hdr = (struct exec_macho_object_header *)emea->macho_hdr;
		error = copyout(&macho_hdr, *stackp, sizeof(macho_hdr));
		if (error != 0)
			return error;
		*stackp += sizeof(macho_hdr);
	}

	cpp = (char **)*stackp;
	argc = arginfo->ps_nargvstr;
	envc = arginfo->ps_nenvstr;
	if ((error = copyout(&argc, cpp++, sizeof(argc))) != 0)
		return error;

	dp = (char *) (cpp + argc + envc + 4);

	if ((error = copyoutstr(emea->filename, dp,
	    (ARG_MAX < MAXPATHLEN) ? ARG_MAX : MAXPATHLEN, &len)) != 0)
		return error;
	progname = dp;
	dp += len;

	sp = argp;
	arginfo->ps_argvstr = cpp; /* remember location of argv for later */
	for (; --argc >= 0; sp += len, dp += len)
		if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
		    (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
			return error;

	if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
		return error;

	arginfo->ps_envstr = cpp; /* remember location of envp for later */
	for (; --envc >= 0; sp += len, dp += len)
		if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
		    (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
			return error;

	if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
		return error;

	if ((error = copyout(&progname, cpp++, sizeof(progname))) != 0)
		return error;

	if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
		return error;

	*stackp = (char *)cpp;

	/* We don't need this anymore */
	free(pack->ep_emul_arg, M_TEMP);
	pack->ep_emul_arg = NULL;

	return 0;
}
コード例 #29
0
runprogram(char *progname)
#endif
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	//kprintf("bla0\n");
	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}
	//kprintf("bla1\n");
	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);
	//kprintf("bla2\n");
	/* Create a new address space. */
	as = as_create();
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}
	//kprintf("bla3\n");
	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();
	//kprintf("bla4\n");
	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}
	//kprintf("bla5\n");
	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

#if OPT_A2
	//kprintf("bla6\n");
	if(args == NULL){
		return EFAULT;
	}	
	// copy args to user
	size_t len = sizeof(char *) * (num + 1);
	char **copyargs = kmalloc(len);
 	for(unsigned long int i = 0; i < num; i++){
    	len = strlen(args[i]) + 1;
    	stackptr = stackptr - ROUNDUP(len, 8);//? limit or valid stackptr //new

    	result = copyoutstr(args[i], (userptr_t)stackptr, len, NULL);//new
    	if(result){
    		kfree(copyargs);
      		return result;
    	}

    	copyargs[i] = (char *)stackptr;
  	}
  	copyargs[num] = NULL;

  	// copy arr
  	len = sizeof(char *) * (num + 1);
 	stackptr = stackptr - ROUNDUP(len, 8);
  	result = copyout(copyargs, (userptr_t)stackptr, len);
  	kfree(copyargs);
  	if(result){
    	return result;
  	}

  	userptr_t stackk = (userptr_t)stackptr;

  	enter_new_process(num /*argc*/, stackk /*userspace addr of argv*/,
			  stackptr, entrypoint);
#else
	/* Warp to user mode. */
	enter_new_process(0 /*argc*/, NULL /*userspace addr of argv*/,
			  stackptr, entrypoint);
#endif
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
コード例 #30
0
ファイル: syscall.c プロジェクト: gmumar/os161
void
mips_syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;
	int s,act;
	char *d;

	//convert user level pointers to user level pointers
	assert(curspl==0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */

	retval = 0;

	switch (callno) {
		case SYS_reboot:
			err = sys_reboot(tf->tf_a0);
			break;
			// syscall.h has all the callno numbers for differnt syscalls
		case SYS_fork:
			err = sysfork(&retval,tf);
			break;

		case SYS_getpid :
			err = sysgetpid(&retval);
			break;

		case SYS_write :
			s=splhigh();
			char *c = (char *)tf->tf_a1;
			kprintf("%c",*c);
			retval = 1;
			splx(s);
			err=0;
			break;

		case SYS_read :
			d = (char *)kmalloc(sizeof(char)*((tf->tf_a2)+1));
			//char *b;
			//b = (char *)kmalloc(sizeof(char)*((tf->tf_a2)+1));

			d[0] = getch();
			d[1] ='\0';
			putch(d[0]);
			putch('\n');

			s=splhigh();
			copyoutstr(d,(userptr_t)(tf->tf_a1),(tf->tf_a2)+1,&act);
			//DEBUG(1,"actual: %d tf size: %d\n",act,(tf->tf_a2)+1);

			//copyinstr((tf->tf_a1),b,(tf->tf_a2)+1,&act);
			//DEBUG(1,"copied bacl:%s\n",b);
			err=0;
			kfree(d);
			retval = strlen(d)+1;
			splx(s);
			break;

		case SYS_waitpid :
			err = syswaitpid(tf->tf_a0,(int *)tf->tf_a1,tf->tf_a2,&retval);
			//syswaitpid(&retval);
			break;

		case SYS__exit :
			err = sysexit(&retval,tf);
			break;

		case SYS_execv:
			err=sysexecv((char*)tf->tf_a0, (char**)tf->tf_a1);
			break;

		case SYS_sbrk:
			err = sys_sbrk((int)tf->tf_a0, &retval);
			break;

		default:
			kprintf("Unknown syscall %d\n", callno);
			err = ENOSYS;
			break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}

	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */

	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	assert(curspl==0);
}