Esempio n. 1
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)
{
	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;
	}

	//kprintf("\n in runprogram");
	assignPid();
	/* 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;
	}

	/* Warp to user mode. */
	md_usermode(0 /*argc*/, NULL /*userspace addr of argv*/,
		    stackptr, entrypoint);
	
	/* md_usermode does not return */
	panic("md_usermode returned\n");
	return EINVAL;
}
/*
 * 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;
}
Esempio n. 3
0
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);
	

}
Esempio n. 4
0
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;
	// ************
}
Esempio n. 5
0
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;
}
Esempio n. 6
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 **args, int nargs)
{

    struct vnode *v;
    vaddr_t entrypoint, stackptr, arguments[nargs+1], exactnewstackptr;
    int result, i; 
    size_t len, offset = 0;


    /* 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. */
    struct addrspace * old_vmspace = curthread->t_vmspace;
    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 */
        curthread->t_vmspace = old_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 */
        curthread->t_vmspace = old_vmspace;
        return result;
    }

    if(old_vmspace){
        as_destroy(old_vmspace);
    }

    for (i = 0; i < nargs; i++)
    {
        len = strlen(args[i]) + 1;
        offset += len;
        arguments[i] = stackptr - offset;
        copyout((void *)args[i], (userptr_t) arguments[i], (size_t) len);
    }

    arguments[nargs] = 0;

    offset += sizeof(vaddr_t) * (nargs+1);

    exactnewstackptr = stackptr - offset;

    stackptr = exactnewstackptr - exactnewstackptr%4;

    copyout((void *) arguments, (userptr_t) stackptr, (size_t) sizeof(vaddr_t) * (nargs+1));
    
    md_usermode(nargs, (userptr_t) stackptr, stackptr, entrypoint);

    panic("md_usermode returned\n");

    return EINVAL;
}
Esempio n. 7
0
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;

}
int sys_execv(const char *program, char *args[])
{
	char **args_copy;
	struct vnode *v;
	int argc, result, index;
	vaddr_t stackptr, entrypoint;

	// get number of arguments
	for (argc=0; args[argc] != NULL; argc++);

	// save out copy of args before current address space is scrapped
	char *strtemp;
	args_copy = kmalloc(argc * sizeof(char *) + 1);

	for (index=0; index<argc; index++)
	{
		strtemp = kmalloc(sizeof(char));
		strcpy(strtemp, args[index]);
		args_copy[index] = strtemp;
	}

	// do parameter checks
	if (program != args[0]) {
		//kprintf("Mismatch: program name %s does not match first argument %s.\n", program, args[0]);
	}
	assert(args[argc] == NULL);

	// open the program file
	result = vfs_open((char *)program, O_RDONLY, &v);
	if (result)
	{
		kprintf("open program file: %s\n", strerror(result));
		return result;
	}

	// configure the user address space
	curthread->t_vmspace = as_create();

	if (curthread->t_vmspace==NULL)
	{
		vfs_close(v);
		return ENOMEM;
	}

	as_activate(curthread->t_vmspace);

	// load the elf
	result = load_elf(v, &entrypoint);
	if (result)
	{
		kprintf("load elf: %s\n", strerror(result));
		vfs_close(v);
		return result;
	}

	// close the program file since we're done with it
	vfs_close(v);

	// define the user stack
	result = as_define_stack(curthread->t_vmspace, &stackptr);
	if (result)
	{
		kprintf("define user stack: %s\n", strerror(result));
		return result;
	}

	// put arguments onto user stack
	store_program_arguments(argc, args_copy, &stackptr);

	kfree(args_copy);

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

	// md_usermode should not return (otherwise its an error)
	panic("md_usermode returned\n");

	return EINVAL;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
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)
{
    struct vnode *v;
    int err;

    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. */
    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;
    }

    /* Warp to user mode. */

    // --- fk ---
    // attaching the filedescriptors 1 (stdout) and 2 (stderr) to console
    err = vfs_open("con:", O_WRONLY, &filetable[1]);
    filetable[2] = filetable[1];
    // --- /fk ---

    md_usermode(0 /*argc*/, NULL /*userspace addr of argv*/,
                stackptr, entrypoint);

    /* md_usermode does not return */
    panic("md_usermode returned\n");
    return EINVAL;
}
Esempio n. 13
0
/*
 * runprogram is run from menu, and its arguments 
 * are passed by thread_fork (a ptr & a int)
 * so we need to construct a struct to store progname and args
 */
int
runprogram(struct runprogram_info *prog_info)
{
	char *progname = prog_info->progname;

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

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, &v);
	if (result) {
		return result;
	}
	
	/*
	 * if runprogram is called by sys_execv, it is for sure that 
	 * curthread has its own user addr_space already.
	 * we need to destroy it.
	 * if runprogram is called by menu, there is no addrspace created.  
	 */
	// ===========================================
	struct addrspace *old_as = curthread->t_vmspace;
	if (old_as != NULL) {
		as_destroy(old_as);
		curthread->t_vmspace = NULL;
	}
	// ===========================================

	/* 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. */
	// entrypoint is set by load_elf
	result = load_elf(v, &entrypoint);
	
	// ===========================================
	/*
	 * in dumbvm, we only need to set up the addrspace for stack
	 * now, we need to load stack (set up page table, without dealing with the content)
	 */
	// ===========================================
	
	if (result) {
		/* thread_exit destroys curthread->t_vmspace */
		// which means runprogram is called by some other function, 
		// and when it returns, thread_exit will be called outside runprogram
		// that's why runprom should not return
		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;
	}
	// ============================================
	size_t len;
	void *ks_start = setup_args_mem(prog_info, &stackptr, &len);
	int err = copyout(ks_start, stackptr, len);
	if (err != 0) {
		panic("runprogram: copyout err!\n");
	}
	/*
	int i;
	for (i = 0; i < len/4; i++) {
		//i in terms of word
		//kfree will free 4 bytes at a time?
		kfree((int *)((int *)ks_start+i));
	}
	*/
	kfree(ks_start);
	//kprintf("copyout result: %d\n", err);
	// ============================================
	/* Warp to user mode. */
	int nargc = prog_info->argc;
	kfree(prog_info);
	//cmd_coremapstats(1, NULL);
	md_usermode(nargc /*argc*/, stackptr /*userspace addr of argv*/,
		    stackptr, entrypoint);
	
	/* md_usermode does not return */
	panic("md_usermode returned\n");
	return EINVAL;
}
Esempio n. 14
0
int
runprogram_args(char *progname, int argc, char **args)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result, i;
    size_t buflen = 0;

    char **argv = kmalloc(sizeof(char*) * argc);
    size_t *offsets = kmalloc(sizeof(size_t) * argc);
	//kprintf("We have %d args in runprogram_args.\n", argc);
    for (i = 0; i < argc; ++i) {
        size_t len = strlen(args[i]) + 1;
        argv[i] = kstrdup(args[i]);
        offsets[i] = buflen;
        buflen += len;
    }

	/* 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;
	}

    /* Copy arguments to stack */
	userptr_t argbase, userargv, arg, argv_base;
	vaddr_t stack = stackptr - buflen;
	stack -= (stack & (sizeof(void *) - 1));
	argbase = (userptr_t)stack;

    for (i = 0; i < argc; ++i) {
        result = copyout(argv[i], argbase + offsets[i], strlen(argv[i]) + 1);
        if (result)
            return result;
    }

	stack -= (argc + 1) * sizeof(userptr_t);
	userargv = (userptr_t)stack;
	argv_base = (userptr_t)stack;

	for (i = 0; i < argc; i++) {
		arg = argbase + offsets[i];
		result = copyout(&arg, userargv, sizeof(userptr_t));
		if (result)
			return result;
		userargv += sizeof(userptr_t);
	}

	arg = NULL;
	result = copyout(&arg, userargv, sizeof(userptr_t));
	if (result)
		return result;

	stackptr = stack + sizeof(userptr_t);

	/* Warp to user mode. */
	md_usermode(argc, argv_base,
		    stackptr, entrypoint);
	
	/* md_usermode does not return */
	panic("md_usermode returned\n");
	return EINVAL;
}
Esempio n. 15
0
int sys_execv(const char *prog, char *const *args){
	char *tempdest,**dest;
	const char *userdata;
	int i,j=0,count=0,padding_start=0,next=0,real_counter=0,retval,len;
	struct vnode *v;
	//dest=kmalloc(sizeof(char*)*strlen(args));
	len=sizeof(args)/sizeof(char*); //no of elements in args
	dest=kmalloc(len*sizeof(char*)); 
	vaddr_t entrypoint, stackptr;
	int result;
	//=kmalloc(len);
	//int len=sizeof(prog)+sizeof(args);
	userdata=prog;

	kprintf("\n in execv1");

	//copyin pointers in kernel buffer and align by 4
	kprintf("\n in execv2");
	do{
		kprintf("\n in execv2");
		size_t len=strlen(userdata);//
		tempdest=kmalloc(sizeof(char)*len);	
		retval=copyin((const_userptr_t)userdata,tempdest,len);
		if(retval){
			kprintf("\nreturning");
			return retval;
		}
		kprintf("\n %s %d %d",userdata,retval,len);
		for(count=0;tempdest[count]!='\0';count++);
		padding_start=count;
		//count-1 should be a multiple of 4 else find the next multiple
		count=((count-1)%4==0)?count-1:count+(count-1)%4;
		for(i=padding_start;i<count;i++){
			tempdest[i]='\0';
		}
		kprintf("\ncrossed");
		dest[j]=kmalloc(sizeof(char)*strlen(tempdest));
		dest[j]=tempdest;
		kprintf("\ncrossed");
		userdata=NULL;
		userdata=args[next];
		next++;j++;real_counter=j;
	}while(userdata!=NULL);

	kprintf("\ncrossed");

	//open the executable, create new addr space and load elf into it
	kprintf("\n in execv3");
	/* Open the file. */; 
	result = vfs_open(prog, O_RDONLY, &v);
	kprintf("\n vfs_open result::%d",result);
	if (result) {
		return result;
	}
	kprintf("\ncrossed");

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

	/* 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("\ncrossed");

	/* 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;
	}

	kprintf("\ncrossed");

	//copy args into user stack
	kprintf("\n in execv4");
	
	/*for(i=0;i<len;i++){
		int len_each_str=strlen(dest[i]);
		char *temp=dest[i];
		for(j=0;j<len_each_str;j++){
			//stackptr[i]=*dest;
			stackptr[i]=temp[j];
		}
	}*/

	copyout(dest,stackptr,real_counter);

	//return to user mode using enter_new_process
	kprintf("\n in execv5,%d",len);
	/* Warp to user mode. */
	md_usermode(len /*argc*/, stackptr /*userspace addr of argv*/,
		    stackptr, entrypoint);
	
	/* md_usermode does not return */
	panic("md_usermode returned\n");
	return EINVAL;	
}