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

📄 traps.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
        show_regs(regs);	bust_spinlocks(0);        spin_unlock_irq(&die_lock);        do_exit(SIGSEGV);}static void inline do_trap(long interruption_code, int signr, char *str,                           struct pt_regs *regs, siginfo_t *info){	/*	 * We got all needed information from the lowcore and can	 * now safely switch on interrupts.	 */	if (regs->psw.mask & PSW_PROBLEM_STATE)		__sti();        if (regs->psw.mask & PSW_PROBLEM_STATE) {                struct task_struct *tsk = current;                tsk->thread.trap_no = interruption_code & 0xffff;		if (info)			force_sig_info(signr, info, tsk);		else                	force_sig(signr, tsk);#ifndef CONFIG_SYSCTL#ifdef CONFIG_PROCESS_DEBUG                printk("User process fault: interruption code 0x%lX\n",                       interruption_code);                show_regs(regs);#endif#else		if (sysctl_userprocess_debug) {			printk("User process fault: interruption code 0x%lX\n",			       interruption_code);			show_regs(regs);		}#endif        } else {                unsigned long fixup = search_exception_table(regs->psw.addr);                if (fixup)                        regs->psw.addr = fixup;                else                        die(str, regs, interruption_code);        }}static inline void *get_check_address(struct pt_regs *regs){	return (void *) ADDR_BITS_REMOVE(regs->psw.addr-S390_lowcore.pgm_ilc);}int do_debugger_trap(struct pt_regs *regs,int signal){	if(regs->psw.mask&PSW_PROBLEM_STATE)	{		if(current->ptrace & PT_PTRACED)			force_sig(signal,current);		else			return 1;	}	else	{#if CONFIG_REMOTE_DEBUG		if(gdb_stub_initialised)		{			gdb_stub_handle_exception(regs, signal);			return 0;		}#endif		return 1;	}	return 0;}#define DO_ERROR(signr, str, name) \asmlinkage void name(struct pt_regs * regs, long interruption_code) \{ \	do_trap(interruption_code, signr, str, regs, NULL); \}#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \asmlinkage void name(struct pt_regs * regs, long interruption_code) \{ \        siginfo_t info; \        info.si_signo = signr; \        info.si_errno = 0; \        info.si_code = sicode; \        info.si_addr = (void *)siaddr; \        do_trap(interruption_code, signr, str, regs, &info); \}DO_ERROR(SIGSEGV, "Unknown program exception", default_trap_handler)DO_ERROR_INFO(SIGBUS, "addressing exception", addressing_exception,	      BUS_ADRERR, get_check_address(regs))DO_ERROR_INFO(SIGILL,  "execute exception", execute_exception,	      ILL_ILLOPN, get_check_address(regs))DO_ERROR_INFO(SIGFPE,  "fixpoint divide exception", divide_exception,	      FPE_INTDIV, get_check_address(regs))DO_ERROR_INFO(SIGILL,  "operand exception", operand_exception,	      ILL_ILLOPN, get_check_address(regs))DO_ERROR_INFO(SIGILL,  "privileged operation", privileged_op,	      ILL_PRVOPC, get_check_address(regs))DO_ERROR_INFO(SIGILL,  "special operation exception", special_op_exception,	      ILL_ILLOPN, get_check_address(regs))DO_ERROR_INFO(SIGILL,  "specification exception", specification_exception,	      ILL_ILLOPN, get_check_address(regs))DO_ERROR_INFO(SIGILL,  "translation exception", translation_exception,	      ILL_ILLOPN, get_check_address(regs))static inline voiddo_fp_trap(struct pt_regs *regs, void *location,           int fpc, long interruption_code){	siginfo_t si;	si.si_signo = SIGFPE;	si.si_errno = 0;	si.si_addr = location;	si.si_code = 0;	/* FPC[2] is Data Exception Code */	if ((fpc & 0x00000300) == 0) {		/* bits 6 and 7 of DXC are 0 iff IEEE exception */		if (fpc & 0x8000) /* invalid fp operation */			si.si_code = FPE_FLTINV;		else if (fpc & 0x4000) /* div by 0 */			si.si_code = FPE_FLTDIV;		else if (fpc & 0x2000) /* overflow */			si.si_code = FPE_FLTOVF;		else if (fpc & 0x1000) /* underflow */			si.si_code = FPE_FLTUND;		else if (fpc & 0x0800) /* inexact */			si.si_code = FPE_FLTRES;	}	current->thread.ieee_instruction_pointer = (addr_t) location;	do_trap(interruption_code, SIGFPE,		"floating point exception", regs, &si);}asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code){        __u8 opcode[6];	__u16 *location;	int do_sig = 0;	location = (__u16 *) get_check_address(regs);	/*	 * We got all needed information from the lowcore and can	 * now safely switch on interrupts.	 */	if (regs->psw.mask & PSW_PROBLEM_STATE)		__sti();	/* WARNING don't change this check back to */	/* int problem_state=(regs->psw.mask & PSW_PROBLEM_STATE); */	/* & then doing if(problem_state) an int is too small for this */	/* check on 64 bit. */	if(regs->psw.mask & PSW_PROBLEM_STATE)		get_user(*((__u16 *) opcode), location);	else		*((__u16 *)opcode)=*((__u16 *)location);	if(*((__u16 *)opcode)==S390_BREAKPOINT_U16)        {		if(do_debugger_trap(regs,SIGTRAP))			do_sig=1;	}	else		do_sig = 1;	if (do_sig)		do_trap(interruption_code, SIGILL,			"illegal operation", regs, NULL);}asmlinkage void data_exception(struct pt_regs * regs, long interruption_code){	__u16 *location;	location = (__u16 *) get_check_address(regs);	/*	 * We got all needed information from the lowcore and can	 * now safely switch on interrupts.	 */	if (regs->psw.mask & PSW_PROBLEM_STATE)		__sti();	__asm__ volatile ("stfpc %0\n\t" 			  : "=m" (current->thread.fp_regs.fpc));	if (current->thread.fp_regs.fpc & FPC_DXC_MASK)		do_fp_trap(regs, location,                           current->thread.fp_regs.fpc, interruption_code);        else {		siginfo_t info;		info.si_signo = SIGILL;		info.si_errno = 0;		info.si_code = ILL_ILLOPN;		info.si_addr = location;		do_trap(interruption_code, SIGILL, 			"data exception", regs, &info);	}}/* init is done in lowcore.S and head.S */void __init trap_init(void){        int i;        for (i = 0; i < 128; i++)          pgm_check_table[i] = &default_trap_handler;        pgm_check_table[1] = &illegal_op;        pgm_check_table[2] = &privileged_op;        pgm_check_table[3] = &execute_exception;        pgm_check_table[4] = &do_protection_exception;        pgm_check_table[5] = &addressing_exception;        pgm_check_table[6] = &specification_exception;        pgm_check_table[7] = &data_exception;        pgm_check_table[9] = &divide_exception;        pgm_check_table[0x12] = &translation_exception;        pgm_check_table[0x13] = &special_op_exception;        pgm_check_table[0x15] = &operand_exception;        pgm_check_table[0x10] = &do_segment_exception;        pgm_check_table[0x11] = &do_page_exception;        pgm_check_table[0x1C] = &privileged_op;        pgm_check_table[0x38] = &addressing_exception;        pgm_check_table[0x3B] = &do_region_exception;#ifdef CONFIG_PFAULT	if (MACHINE_IS_VM) {		/* request the 0x2603 external interrupt */		if (register_early_external_interrupt(0x2603, pfault_interrupt,						      &ext_int_pfault) != 0)			panic("Couldn't request external interrupt 0x2603");		/*		 * Try to get pfault pseudo page faults going.		 */		if (pfault_init() != 0) {			/* Tough luck, no pfault. */			unregister_early_external_interrupt(0x2603,							    pfault_interrupt,							    &ext_int_pfault);		}	}#endif}void handle_per_exception(struct pt_regs *regs){	if(regs->psw.mask&PSW_PROBLEM_STATE)	{		per_struct *per_info=&current->thread.per_info;		per_info->lowcore.words.perc_atmid=S390_lowcore.per_perc_atmid;		per_info->lowcore.words.address=S390_lowcore.per_address;		per_info->lowcore.words.access_id=S390_lowcore.per_access_id;	}	if(do_debugger_trap(regs,SIGTRAP))	{		/* I've seen this possibly a task structure being reused ? */		printk("Spurious per exception detected\n");		printk("switching off per tracing for this task.\n");		show_regs(regs);		/* Hopefully switching off per tracing will help us survive */		regs->psw.mask &= ~PSW_PER_MASK;	}}

⌨️ 快捷键说明

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