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

📄 traps.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (regs->tstate & TSTATE_PRIV)		die_if_kernel("Penguin overflow trap from kernel mode", regs);	if (test_thread_flag(TIF_32BIT)) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}	info.si_signo = SIGEMT;	info.si_errno = 0;	info.si_code = EMT_TAGOVF;	info.si_addr = (void __user *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGEMT, &info, current);}void do_div0(struct pt_regs *regs){	siginfo_t info;	if (notify_die(DIE_TRAP, "integer division by zero", regs,		       0, 0x28, SIGFPE) == NOTIFY_STOP)		return;	if (regs->tstate & TSTATE_PRIV)		die_if_kernel("TL0: Kernel divide by zero.", regs);	if (test_thread_flag(TIF_32BIT)) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}	info.si_signo = SIGFPE;	info.si_errno = 0;	info.si_code = FPE_INTDIV;	info.si_addr = (void __user *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGFPE, &info, current);}void instruction_dump (unsigned int *pc){	int i;	if ((((unsigned long) pc) & 3))		return;	printk("Instruction DUMP:");	for (i = -3; i < 6; i++)		printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>');	printk("\n");}static void user_instruction_dump (unsigned int __user *pc){	int i;	unsigned int buf[9];		if ((((unsigned long) pc) & 3))		return;			if (copy_from_user(buf, pc - 3, sizeof(buf)))		return;	printk("Instruction DUMP:");	for (i = 0; i < 9; i++)		printk("%c%08x%c",i==3?' ':'<',buf[i],i==3?' ':'>');	printk("\n");}void show_stack(struct task_struct *tsk, unsigned long *_ksp){	unsigned long pc, fp, thread_base, ksp;	struct thread_info *tp = tsk->thread_info;	struct reg_window *rw;	int count = 0;	ksp = (unsigned long) _ksp;	if (tp == current_thread_info())		flushw_all();	fp = ksp + STACK_BIAS;	thread_base = (unsigned long) tp;	printk("Call Trace:");#ifdef CONFIG_KALLSYMS	printk("\n");#endif	do {		/* Bogus frame pointer? */		if (fp < (thread_base + sizeof(struct thread_info)) ||		    fp >= (thread_base + THREAD_SIZE))			break;		rw = (struct reg_window *)fp;		pc = rw->ins[7];		printk(" [%016lx] ", pc);		print_symbol("%s\n", pc);		fp = rw->ins[6] + STACK_BIAS;	} while (++count < 16);#ifndef CONFIG_KALLSYMS	printk("\n");#endif}void dump_stack(void){	unsigned long *ksp;	__asm__ __volatile__("mov	%%fp, %0"			     : "=r" (ksp));	show_stack(current, ksp);}EXPORT_SYMBOL(dump_stack);static inline int is_kernel_stack(struct task_struct *task,				  struct reg_window *rw){	unsigned long rw_addr = (unsigned long) rw;	unsigned long thread_base, thread_end;	if (rw_addr < PAGE_OFFSET) {		if (task != &init_task)			return 0;	}	thread_base = (unsigned long) task->thread_info;	thread_end = thread_base + sizeof(union thread_union);	if (rw_addr >= thread_base &&	    rw_addr < thread_end &&	    !(rw_addr & 0x7UL))		return 1;	return 0;}static inline struct reg_window *kernel_stack_up(struct reg_window *rw){	unsigned long fp = rw->ins[6];	if (!fp)		return NULL;	return (struct reg_window *) (fp + STACK_BIAS);}void die_if_kernel(char *str, struct pt_regs *regs){	static int die_counter;	extern void __show_regs(struct pt_regs * regs);	extern void smp_report_regs(void);	int count = 0;		/* Amuse the user. */	printk("              \\|/ ____ \\|/\n""              \"@'/ .. \\`@\"\n""              /_| \\__/ |_\\\n""                 \\__U_/\n");	printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);	notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);	__asm__ __volatile__("flushw");	__show_regs(regs);	if (regs->tstate & TSTATE_PRIV) {		struct reg_window *rw = (struct reg_window *)			(regs->u_regs[UREG_FP] + STACK_BIAS);		/* Stop the back trace when we hit userland or we		 * find some badly aligned kernel stack.		 */		while (rw &&		       count++ < 30&&		       is_kernel_stack(current, rw)) {			printk("Caller[%016lx]", rw->ins[7]);			print_symbol(": %s", rw->ins[7]);			printk("\n");			rw = kernel_stack_up(rw);		}		instruction_dump ((unsigned int *) regs->tpc);	} else {		if (test_thread_flag(TIF_32BIT)) {			regs->tpc &= 0xffffffff;			regs->tnpc &= 0xffffffff;		}		user_instruction_dump ((unsigned int __user *) regs->tpc);	}#ifdef CONFIG_SMP	smp_report_regs();#endif                                                		if (regs->tstate & TSTATE_PRIV)		do_exit(SIGKILL);	do_exit(SIGSEGV);}extern int handle_popc(u32 insn, struct pt_regs *regs);extern int handle_ldf_stq(u32 insn, struct pt_regs *regs);void do_illegal_instruction(struct pt_regs *regs){	unsigned long pc = regs->tpc;	unsigned long tstate = regs->tstate;	u32 insn;	siginfo_t info;	if (notify_die(DIE_TRAP, "illegal instruction", regs,		       0, 0x10, SIGILL) == NOTIFY_STOP)		return;	if (tstate & TSTATE_PRIV)		die_if_kernel("Kernel illegal instruction", regs);	if (test_thread_flag(TIF_32BIT))		pc = (u32)pc;	if (get_user(insn, (u32 __user *) pc) != -EFAULT) {		if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ {			if (handle_popc(insn, regs))				return;		} else if ((insn & 0xc1580000) == 0xc1100000) /* LDQ/STQ */ {			if (handle_ldf_stq(insn, regs))				return;		}	}	info.si_signo = SIGILL;	info.si_errno = 0;	info.si_code = ILL_ILLOPC;	info.si_addr = (void __user *)pc;	info.si_trapno = 0;	force_sig_info(SIGILL, &info, current);}void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr){	siginfo_t info;	if (notify_die(DIE_TRAP, "memory address unaligned", regs,		       0, 0x34, SIGSEGV) == NOTIFY_STOP)		return;	if (regs->tstate & TSTATE_PRIV) {		extern void kernel_unaligned_trap(struct pt_regs *regs,						  unsigned int insn, 						  unsigned long sfar,						  unsigned long sfsr);		kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc),				      sfar, sfsr);		return;	}	info.si_signo = SIGBUS;	info.si_errno = 0;	info.si_code = BUS_ADRALN;	info.si_addr = (void __user *)sfar;	info.si_trapno = 0;	force_sig_info(SIGBUS, &info, current);}void do_privop(struct pt_regs *regs){	siginfo_t info;	if (notify_die(DIE_TRAP, "privileged operation", regs,		       0, 0x11, SIGILL) == NOTIFY_STOP)		return;	if (test_thread_flag(TIF_32BIT)) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}	info.si_signo = SIGILL;	info.si_errno = 0;	info.si_code = ILL_PRVOPC;	info.si_addr = (void __user *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGILL, &info, current);}void do_privact(struct pt_regs *regs){	do_privop(regs);}/* Trap level 1 stuff or other traps we should never see... */void do_cee(struct pt_regs *regs){	die_if_kernel("TL0: Cache Error Exception", regs);}void do_cee_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Cache Error Exception", regs);}void do_dae_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Data Access Exception", regs);}void do_iae_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Instruction Access Exception", regs);}void do_div0_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: DIV0 Exception", regs);}void do_fpdis_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: FPU Disabled", regs);}void do_fpieee_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: FPU IEEE Exception", regs);}void do_fpother_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: FPU Other Exception", regs);}void do_ill_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Illegal Instruction Exception", regs);}void do_irq_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: IRQ Exception", regs);}void do_lddfmna_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: LDDF Exception", regs);}void do_stdfmna_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: STDF Exception", regs);}void do_paw(struct pt_regs *regs){	die_if_kernel("TL0: Phys Watchpoint Exception", regs);}void do_paw_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Phys Watchpoint Exception", regs);}void do_vaw(struct pt_regs *regs){	die_if_kernel("TL0: Virt Watchpoint Exception", regs);}void do_vaw_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Virt Watchpoint Exception", regs);}void do_tof_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Tag Overflow Exception", regs);}void do_getpsr(struct pt_regs *regs){	regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate);	regs->tpc   = regs->tnpc;	regs->tnpc += 4;	if (test_thread_flag(TIF_32BIT)) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}}extern void thread_info_offsets_are_bolixed_dave(void);/* Only invoked on boot processor. */void __init trap_init(void){	/* Compile time sanity check. */	if (TI_TASK != offsetof(struct thread_info, task) ||	    TI_FLAGS != offsetof(struct thread_info, flags) ||	    TI_CPU != offsetof(struct thread_info, cpu) ||	    TI_FPSAVED != offsetof(struct thread_info, fpsaved) ||	    TI_KSP != offsetof(struct thread_info, ksp) ||	    TI_FAULT_ADDR != offsetof(struct thread_info, fault_address) ||	    TI_KREGS != offsetof(struct thread_info, kregs) ||	    TI_UTRAPS != offsetof(struct thread_info, utraps) ||	    TI_EXEC_DOMAIN != offsetof(struct thread_info, exec_domain) ||	    TI_REG_WINDOW != offsetof(struct thread_info, reg_window) ||	    TI_RWIN_SPTRS != offsetof(struct thread_info, rwbuf_stkptrs) ||	    TI_GSR != offsetof(struct thread_info, gsr) ||	    TI_XFSR != offsetof(struct thread_info, xfsr) ||	    TI_USER_CNTD0 != offsetof(struct thread_info, user_cntd0) ||	    TI_USER_CNTD1 != offsetof(struct thread_info, user_cntd1) ||	    TI_KERN_CNTD0 != offsetof(struct thread_info, kernel_cntd0) ||	    TI_KERN_CNTD1 != offsetof(struct thread_info, kernel_cntd1) ||	    TI_PCR != offsetof(struct thread_info, pcr_reg) ||	    TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) ||	    TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||	    TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||	    TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) ||	    TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) ||	    TI_KUNA_REGS != offsetof(struct thread_info, kern_una_regs) ||	    TI_KUNA_INSN != offsetof(struct thread_info, kern_una_insn) ||	    TI_FPREGS != offsetof(struct thread_info, fpregs) ||	    (TI_FPREGS & (64 - 1)))		thread_info_offsets_are_bolixed_dave();	/* Attach to the address space of init_task.  On SMP we	 * do this in smp.c:smp_callin for other cpus.	 */	atomic_inc(&init_mm.mm_count);	current->active_mm = &init_mm;}

⌨️ 快捷键说明

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