⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copy a thread.. */intcopy_thread(int nr, unsigned long clone_flags, unsigned long usp,	    unsigned long unused, struct task_struct *p, struct pt_regs *regs){	struct pt_regs *childregs, *kregs;	extern void ret_from_fork(void);	unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;	p->set_child_tid = p->clear_child_tid = NULL;	/* Copy registers */	sp -= sizeof(struct pt_regs);	childregs = (struct pt_regs *) sp;	*childregs = *regs;	if ((childregs->msr & MSR_PR) == 0) {		/* for kernel thread, set stackptr in new task */		childregs->gpr[1] = sp + sizeof(struct pt_regs);		p->thread.regs = NULL;	/* no user register state */		clear_ti_thread_flag(p->thread_info, TIF_32BIT);#ifdef CONFIG_PPC_ISERIES		set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT);#endif	} else {		childregs->gpr[1] = usp;		p->thread.regs = childregs;		if (clone_flags & CLONE_SETTLS) {			if (test_thread_flag(TIF_32BIT))				childregs->gpr[2] = childregs->gpr[6];			else				childregs->gpr[13] = childregs->gpr[6];		}	}	childregs->gpr[3] = 0;  /* Result from fork() */	sp -= STACK_FRAME_OVERHEAD;	/*	 * The way this works is that at some point in the future	 * some task will call _switch to switch to the new task.	 * That will pop off the stack frame created below and start	 * the new task running at ret_from_fork.  The new task will	 * do some house keeping and then return from the fork or clone	 * system call, using the stack frame created above.	 */	sp -= sizeof(struct pt_regs);	kregs = (struct pt_regs *) sp;	sp -= STACK_FRAME_OVERHEAD;	p->thread.ksp = sp;	/*	 * The PPC64 ABI makes use of a TOC to contain function 	 * pointers.  The function (ret_from_except) is actually a pointer	 * to the TOC entry.  The first entry is a pointer to the actual	 * function. 	 */	kregs->nip = *((unsigned long *)ret_from_fork);	return 0;}/* * Set up a thread for executing a new program */void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp){	unsigned long entry, toc, load_addr = regs->gpr[2];	/* fdptr is a relocated pointer to the function descriptor for         * the elf _start routine.  The first entry in the function         * descriptor is the entry address of _start and the second         * entry is the TOC value we need to use.         */	set_fs(USER_DS);	__get_user(entry, (unsigned long __user *)fdptr);	__get_user(toc, (unsigned long __user *)fdptr+1);	/* Check whether the e_entry function descriptor entries	 * need to be relocated before we can use them.	 */	if ( load_addr != 0 ) {		entry += load_addr;		toc   += load_addr;	}	regs->nip = entry;	regs->gpr[1] = sp;	regs->gpr[2] = toc;	regs->msr = MSR_USER64;#ifndef CONFIG_SMP	if (last_task_used_math == current)		last_task_used_math = 0;#endif /* CONFIG_SMP */	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));	current->thread.fpscr = 0;#ifdef CONFIG_ALTIVEC#ifndef CONFIG_SMP	if (last_task_used_altivec == current)		last_task_used_altivec = 0;#endif /* CONFIG_SMP */	memset(current->thread.vr, 0, sizeof(current->thread.vr));	current->thread.vscr.u[0] = 0;	current->thread.vscr.u[1] = 0;	current->thread.vscr.u[2] = 0;	current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */	current->thread.vrsave = 0;	current->thread.used_vr = 0;#endif /* CONFIG_ALTIVEC */}int set_fpexc_mode(struct task_struct *tsk, unsigned int val){	struct pt_regs *regs = tsk->thread.regs;	if (val > PR_FP_EXC_PRECISE)		return -EINVAL;	tsk->thread.fpexc_mode = __pack_fe01(val);	if (regs != NULL && (regs->msr & MSR_FP) != 0)		regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))			| tsk->thread.fpexc_mode;	return 0;}int get_fpexc_mode(struct task_struct *tsk, unsigned long adr){	unsigned int val;	val = __unpack_fe01(tsk->thread.fpexc_mode);	return put_user(val, (unsigned int __user *) adr);}int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,	      unsigned long p4, unsigned long p5, unsigned long p6,	      struct pt_regs *regs){	unsigned long parent_tidptr = 0;	unsigned long child_tidptr = 0;	if (p2 == 0)		p2 = regs->gpr[1];	/* stack pointer for child */	if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_SETTID |			   CLONE_CHILD_CLEARTID)) {		parent_tidptr = p3;		child_tidptr = p5;		if (test_thread_flag(TIF_32BIT)) {			parent_tidptr &= 0xffffffff;			child_tidptr &= 0xffffffff;		}	}	return do_fork(clone_flags & ~CLONE_IDLETASK, p2, regs, 0,		    (int __user *)parent_tidptr, (int __user *)child_tidptr);}int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,	     unsigned long p4, unsigned long p5, unsigned long p6,	     struct pt_regs *regs){	return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);}int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,	      unsigned long p4, unsigned long p5, unsigned long p6,	      struct pt_regs *regs){	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0,	            NULL, NULL);}int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,	       unsigned long a3, unsigned long a4, unsigned long a5,	       struct pt_regs *regs){	int error;	char * filename;		filename = getname((char __user *) a0);	error = PTR_ERR(filename);	if (IS_ERR(filename))		goto out;	flush_fp_to_thread(current);	flush_altivec_to_thread(current);	error = do_execve(filename, (char __user * __user *) a1,				    (char __user * __user *) a2, regs);  	if (error == 0)		current->ptrace &= ~PT_DTRACE;	putname(filename);out:	return error;}static int kstack_depth_to_print = 64;static int validate_sp(unsigned long sp, struct task_struct *p,		       unsigned long nbytes){	unsigned long stack_page = (unsigned long)p->thread_info;	if (sp >= stack_page + sizeof(struct thread_struct)	    && sp <= stack_page + THREAD_SIZE - nbytes)		return 1;#ifdef CONFIG_IRQSTACKS	stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];	if (sp >= stack_page + sizeof(struct thread_struct)	    && sp <= stack_page + THREAD_SIZE - nbytes)		return 1;	stack_page = (unsigned long) softirq_ctx[task_cpu(p)];	if (sp >= stack_page + sizeof(struct thread_struct)	    && sp <= stack_page + THREAD_SIZE - nbytes)		return 1;#endif	return 0;}unsigned long get_wchan(struct task_struct *p){	unsigned long ip, sp;	int count = 0;	if (!p || p == current || p->state == TASK_RUNNING)		return 0;	sp = p->thread.ksp;	if (!validate_sp(sp, p, 112))		return 0;	do {		sp = *(unsigned long *)sp;		if (!validate_sp(sp, p, 112))			return 0;		if (count > 0) {			ip = *(unsigned long *)(sp + 16);			if (!in_sched_functions(ip))				return ip;		}	} while (count++ < 16);	return 0;}void show_stack(struct task_struct *p, unsigned long *_sp){	unsigned long ip, newsp, lr;	int count = 0;	unsigned long sp = (unsigned long)_sp;	int firstframe = 1;	if (sp == 0) {		if (p) {			sp = p->thread.ksp;		} else {			sp = __get_SP();			p = current;		}	}	lr = 0;	printk("Call Trace:\n");	do {		if (!validate_sp(sp, p, 112))			return;		_sp = (unsigned long *) sp;		newsp = _sp[0];		ip = _sp[2];		if (!firstframe || ip != lr) {			printk("[%016lx] [%016lx] ", sp, ip);			print_symbol("%s", ip);			if (firstframe)				printk(" (unreliable)");			printk("\n");		}		firstframe = 0;		/*		 * See if this is an exception frame.		 * We look for the "regshere" marker in the current frame.		 */		if (validate_sp(sp, p, sizeof(struct pt_regs) + 400)		    && _sp[12] == 0x7265677368657265ul) {			struct pt_regs *regs = (struct pt_regs *)				(sp + STACK_FRAME_OVERHEAD);			printk("--- Exception: %lx", regs->trap);			print_symbol(" at %s\n", regs->nip);			lr = regs->link;			print_symbol("    LR = %s\n", lr);			firstframe = 1;		}		sp = newsp;	} while (count++ < kstack_depth_to_print);}void dump_stack(void){	show_stack(current, (unsigned long *)__get_SP());}EXPORT_SYMBOL(dump_stack);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -