asmlinkage int px_sys_execve(char *filenameei, char **argv, char **envp, struct pt_regs *regs)
{
	int ret;
	unsigned long lsc;

	INIT_STACK_FRAME; 

	/** 
	 * here we just use the mutex to make sure the fork call is finished, 
	 *   no need to keep the mutex till the call finished 
	 **/
	mutex_lock(&fork_mutex);
	mutex_unlock(&fork_mutex);

	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	ret = px_original_sys_execve(filenameei, argv, envp, regs);

	CUTTAIL_STACK_FRAME;

	if ((ret >= 0) && (gb_enable_os_hooks))
	{
		enum_modules_for_process(current->tgid, lsc);
	}

	return ret;
}
asmlinkage int px_sys_clone(unsigned long clone_flgs, unsigned long newsp, struct pt_regs *regs)
{
	int ret = 0;
	unsigned long lsc;

	INIT_STACK_FRAME; 

	mutex_lock(&fork_mutex);

	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	ret = px_original_sys_clone(clone_flgs, newsp, regs);
	
	mutex_unlock(&fork_mutex);
	CUTTAIL_STACK_FRAME;

	if ((ret >= 0) && (gb_enable_os_hooks))
	{
		if (!(clone_flgs & CLONE_THREAD))
		{
			enum_modules_for_process(ret, lsc);
		}
	}

	//mutex_unlock(&fork_mutex);

	return ret;
}
asmlinkage int px_sys_vfork(struct pt_regs *regs)
{
	int ret = 0;
	unsigned long lsc;

	INIT_STACK_FRAME; 

	mutex_lock(&fork_mutex);
	mutex_unlock(&fork_mutex);
	
	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	ret = px_original_sys_vfork(regs);

	CUTTAIL_STACK_FRAME;

	if ((ret >= 0) && (gb_enable_os_hooks))
	{
		enum_modules_for_process(ret, lsc);
	}

	return ret;
}
static void static_enum_exiting_process_modules(void)
{
	struct task_struct *p_task = &init_task;

	do
	{
		/* static enumeration: load sample count of modules are all zero */
		enum_modules_for_process(p_task->pid, 0);

		read_lock(&tasklist_lock);

		p_task = next_task(p_task);

		read_unlock(&tasklist_lock);
	}while (p_task != &init_task);

}
/* 
 * we hook this system call in order to get the new process name 
 * if it is modified by changing argv[0]
 * assume that it is followed by a prctl(PR_SET_NAME, ...)
 */
asmlinkage long px_sys_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
{
	long ret = 0;
	char * new_name = NULL;
	char * old_name = NULL;
	unsigned long long lsc;

	INIT_STACK_FRAME;

	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	ret = px_original_sys_prctl(option, arg2, arg3, arg4, arg5);
	
	CUTTAIL_STACK_FRAME;

	if ((ret == 0) && (option == PR_SET_NAME))
	{
		new_name = kzalloc(PATH_MAX, GFP_ATOMIC);
		old_name = kzalloc(PATH_MAX, GFP_ATOMIC);
		
		if ((new_name != NULL) && (old_name != NULL))
		{
			if (is_proc_name_modified(current, new_name, old_name))
			{
				enum_modules_for_process(current->tgid, lsc, new_name);
			}
		}
		
		if (new_name != NULL)
			kfree(new_name);

		if (old_name != NULL)
			kfree(old_name);
	}

	return ret;
}