int __mac_execve(proc_t p, struct __mac_execve_args *uap, int32_t *retval)
{
? ? // 字段設(shè)置
? ? ...
? ? int is_64 = IS_64BIT_PROCESS(p);
? ? struct vfs_context context;
? ? struct uthread? *uthread; // 線程
? ? task_t new_task = NULL;? // Mach Task
? ? ...
? ?
? ? context.vc_thread = current_thread();
? ? context.vc_ucred = kauth_cred_proc_ref(p);
? ?
? ? // 分配大塊內(nèi)存,不用堆棧是因?yàn)?Mach-O 結(jié)構(gòu)很大绒净。
? ? MALLOC(bufp, char *, (sizeof(*imgp) + sizeof(*vap) + sizeof(*origvap)), M_TEMP, M_WAITOK | M_ZERO);
? ? imgp = (struct image_params *) bufp;
? ?
? ? // 初始化 imgp 結(jié)構(gòu)里的公共數(shù)據(jù)
? ? ...
? ?
? ? uthread = get_bsdthread_info(current_thread());
? ? if (uthread->uu_flag & UT_VFORK) {
? ? ? ? imgp->ip_flags |= IMGPF_VFORK_EXEC;
? ? ? ? in_vfexec = TRUE;
? ? } else {
? ? ? ? // 程序如果是啟動(dòng)態(tài)妹田,就需要 fork 新進(jìn)程
? ? ? ? imgp->ip_flags |= IMGPF_EXEC;
? ? ? ? // fork 進(jìn)程
? ? ? ? imgp->ip_new_thread = fork_create_child(current_task(),
? ? ? ? ? ? ? ? ? ? NULL, p, FALSE, p->p_flag & P_LP64, TRUE);
? ? ? ? // 異常處理
? ? ? ? ...
? ? ? ? new_task = get_threadtask(imgp->ip_new_thread);
? ? ? ? context.vc_thread = imgp->ip_new_thread;
? ? }
? ?
? ? // 加載解析 Mach-O
? ? error = exec_activate_image(imgp);
? ?
? ? if (imgp->ip_new_thread != NULL) {
? ? ? ? new_task = get_threadtask(imgp->ip_new_thread);
? ? }
? ? if (!error && !in_vfexec) {
? ? ? ? p = proc_exec_switch_task(p, current_task(), new_task, imgp->ip_new_thread);
? ?
? ? ? ? should_release_proc_ref = TRUE;
? ? }
? ? kauth_cred_unref(&context.vc_ucred);
? ?
? ? if (!error) {
? ? ? ? task_bank_init(get_threadtask(imgp->ip_new_thread));
? ? ? ? proc_transend(p, 0);
? ? ? ? thread_affinity_exec(current_thread());
? ? ? ? // 繼承進(jìn)程處理
? ? ? ? if (!in_vfexec) {
? ? ? ? ? ? proc_inherit_task_role(get_threadtask(imgp->ip_new_thread), current_task());
? ? ? ? }
? ? ? ? // 設(shè)置進(jìn)程的主線程
? ? ? ? thread_t main_thread = imgp->ip_new_thread;
? ? ? ? task_set_main_thread_qos(new_task, main_thread);
? ? }
? ? ...
}