u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
{
    s32 i, len;
    int status = 0;
    char *temp;
    s32 count = args->args_proc_load.argc_index;
    u8 **argv = NULL, **envp = NULL;
    void *hprocessor = ((struct process_context *)pr_ctxt)->processor;

    if (count <= 0 || count > MAX_LOADARGS) {
        status = -EINVAL;
        goto func_cont;
    }

    argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
    if (!argv) {
        status = -ENOMEM;
        goto func_cont;
    }

    CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
    if (status) {
        kfree(argv);
        argv = NULL;
        goto func_cont;
    }

    for (i = 0; i < count; i++) {
        if (argv[i]) {

            temp = (char *)argv[i];

            len = strlen_user((char *)temp) + 1;

            argv[i] = kmalloc(len, GFP_KERNEL);
            if (argv[i]) {
                CP_FM_USR(argv[i], temp, status, len);
                if (status) {
                    kfree(argv[i]);
                    argv[i] = NULL;
                    goto func_cont;
                }
            } else {
                status = -ENOMEM;
                goto func_cont;
            }
        }
    }

    if (args->args_proc_load.user_envp) {

        count = 0;
        do {
            if (get_user(temp,
                         args->args_proc_load.user_envp + count)) {
                status = -EFAULT;
                goto func_cont;
            }
            count++;
        } while (temp);
        envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
        if (!envp) {
            status = -ENOMEM;
            goto func_cont;
        }

        CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
        if (status) {
            kfree(envp);
            envp = NULL;
            goto func_cont;
        }
        for (i = 0; envp[i]; i++) {

            temp = (char *)envp[i];

            len = strlen_user((char *)temp) + 1;

            envp[i] = kmalloc(len, GFP_KERNEL);
            if (envp[i]) {
                CP_FM_USR(envp[i], temp, status, len);
                if (status) {
                    kfree(envp[i]);
                    envp[i] = NULL;
                    goto func_cont;
                }
            } else {
                status = -ENOMEM;
                goto func_cont;
            }
        }
    }

    if (!status) {
        status = proc_load(hprocessor,
                           args->args_proc_load.argc_index,
                           (const char **)argv, (const char **)envp);
    }
func_cont:
    if (envp) {
        i = 0;
        while (envp[i])
            kfree(envp[i++]);

        kfree(envp);
    }

    if (argv) {
        count = args->args_proc_load.argc_index;
        for (i = 0; (i < count) && argv[i]; i++)
            kfree(argv[i]);

        kfree(argv);
    }

    return status;
}
/*
 * ======== procwrap_load ========
 */
u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
{
	s32 i, len;
	int status = 0;
	char *temp;
	s32 count = args->args_proc_load.argc_index;
	u8 **argv = NULL, **envp = NULL;
	void *hprocessor = ((struct process_context *)pr_ctxt)->processor;

	if (count <= 0 || count > MAX_LOADARGS) {
		status = -EINVAL;
		goto func_cont;
	}

	argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
	if (!argv) {
		status = -ENOMEM;
		goto func_cont;
	}

	CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
	if (status) {
		kfree(argv);
		argv = NULL;
		goto func_cont;
	}

	for (i = 0; i < count; i++) {
		if (argv[i]) {
			/* User space pointer to argument */
			temp = (char *)argv[i];
			/* len is increased by 1 to accommodate NULL */
			len = strlen_user((char *)temp) + 1;
			/* Kernel space pointer to argument */
			argv[i] = kmalloc(len, GFP_KERNEL);
			if (argv[i]) {
				CP_FM_USR(argv[i], temp, status, len);
				if (status) {
					kfree(argv[i]);
					argv[i] = NULL;
					goto func_cont;
				}
			} else {
				status = -ENOMEM;
				goto func_cont;
			}
		}
	}
	/* TODO: validate this */
	if (args->args_proc_load.user_envp) {
		/* number of elements in the envp array including NULL */
		count = 0;
		do {
			if (get_user(temp,
				     args->args_proc_load.user_envp + count)) {
				status = -EFAULT;
				goto func_cont;
			}
			count++;
		} while (temp);
		envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
		if (!envp) {
			status = -ENOMEM;
			goto func_cont;
		}

		CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
		if (status) {
			kfree(envp);
			envp = NULL;
			goto func_cont;
		}
		for (i = 0; envp[i]; i++) {
			/* User space pointer to argument */
			temp = (char *)envp[i];
			/* len is increased by 1 to accommodate NULL */
			len = strlen_user((char *)temp) + 1;
			/* Kernel space pointer to argument */
			envp[i] = kmalloc(len, GFP_KERNEL);
			if (envp[i]) {
				CP_FM_USR(envp[i], temp, status, len);
				if (status) {
					kfree(envp[i]);
					envp[i] = NULL;
					goto func_cont;
				}
			} else {
				status = -ENOMEM;
				goto func_cont;
			}
		}
	}

	if (!status) {
		status = proc_load(hprocessor,
				   args->args_proc_load.argc_index,
				   (const char **)argv, (const char **)envp);
	}
func_cont:
	if (envp) {
		i = 0;
		while (envp[i])
			kfree(envp[i++]);

		kfree(envp);
	}

	if (argv) {
		count = args->args_proc_load.argc_index;
		for (i = 0; (i < count) && argv[i]; i++)
			kfree(argv[i]);

		kfree(argv);
	}

	return status;
}