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

📄 traps.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
}#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,  "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 signal = 0;	location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc);	/*	 * 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)		get_user(*((__u16 *) opcode), location);	else		*((__u16 *)opcode)=*((__u16 *)location);	if (*((__u16 *)opcode)==S390_BREAKPOINT_U16)        {		if(do_debugger_trap(regs,SIGTRAP))			signal = SIGILL;	}#ifdef CONFIG_MATHEMU        else if (regs->psw.mask & PSW_PROBLEM_STATE)	{		if (opcode[0] == 0xb3) {			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_b3(opcode, regs);                } else if (opcode[0] == 0xed) {			get_user(*((__u32 *) (opcode+2)),				 (__u32 *)(location+1));			signal = math_emu_ed(opcode, regs);		} else if (*((__u16 *) opcode) == 0xb299) {			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_srnm(opcode, regs);		} else if (*((__u16 *) opcode) == 0xb29c) {			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_stfpc(opcode, regs);		} else if (*((__u16 *) opcode) == 0xb29d) {			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_lfpc(opcode, regs);		} else			signal = SIGILL;        }#endif 	else		signal = SIGILL;        if (signal == SIGFPE)		do_fp_trap(regs, location,                           current->thread.fp_regs.fpc, interruption_code);        else if (signal)		do_trap(interruption_code, signal,			"illegal operation", regs, NULL);}#ifdef CONFIG_MATHEMUasmlinkage void specification_exception(struct pt_regs * regs, long interruption_code){        __u8 opcode[6];	__u16 *location = NULL;	int signal = 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();		        if (regs->psw.mask & PSW_PROBLEM_STATE) {		get_user(*((__u16 *) opcode), location);		switch (opcode[0]) {		case 0x28: /* LDR Rx,Ry   */			signal = math_emu_ldr(opcode);			break;		case 0x38: /* LER Rx,Ry   */			signal = math_emu_ler(opcode);			break;		case 0x60: /* STD R,D(X,B) */			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_std(opcode, regs);			break;		case 0x68: /* LD R,D(X,B) */			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_ld(opcode, regs);			break;		case 0x70: /* STE R,D(X,B) */			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_ste(opcode, regs);			break;		case 0x78: /* LE R,D(X,B) */			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_le(opcode, regs);			break;		default:			signal = SIGILL;			break;                }        } else		signal = SIGILL;        if (signal == SIGFPE)		do_fp_trap(regs, location,                           current->thread.fp_regs.fpc, interruption_code);        else if (signal) {		siginfo_t info;		info.si_signo = signal;		info.si_errno = 0;		info.si_code = ILL_ILLOPN;		info.si_addr = location;		do_trap(interruption_code, signal, 			"specification exception", regs, &info);	}}#elseDO_ERROR_INFO(SIGILL, "specification exception", specification_exception,	      ILL_ILLOPN, get_check_address(regs));#endifasmlinkage void data_exception(struct pt_regs * regs, long interruption_code){        __u8 opcode[6];	__u16 *location;	int signal = 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();	if (MACHINE_HAS_IEEE)		__asm__ volatile ("stfpc %0\n\t" 				  : "=m" (current->thread.fp_regs.fpc));#ifdef CONFIG_MATHEMU        else if (regs->psw.mask & PSW_PROBLEM_STATE) {		get_user(*((__u16 *) opcode), location);		switch (opcode[0]) {		case 0x28: /* LDR Rx,Ry   */			signal = math_emu_ldr(opcode);			break;		case 0x38: /* LER Rx,Ry   */			signal = math_emu_ler(opcode);			break;		case 0x60: /* STD R,D(X,B) */			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_std(opcode, regs);			break;		case 0x68: /* LD R,D(X,B) */			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_ld(opcode, regs);			break;		case 0x70: /* STE R,D(X,B) */			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_ste(opcode, regs);			break;		case 0x78: /* LE R,D(X,B) */			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_le(opcode, regs);			break;		case 0xb3:			get_user(*((__u16 *) (opcode+2)), location+1);			signal = math_emu_b3(opcode, regs);			break;                case 0xed:			get_user(*((__u32 *) (opcode+2)),				 (__u32 *)(location+1));			signal = math_emu_ed(opcode, regs);			break;	        case 0xb2:			if (opcode[1] == 0x99) {				get_user(*((__u16 *) (opcode+2)), location+1);				signal = math_emu_srnm(opcode, regs);			} else if (opcode[1] == 0x9c) {				get_user(*((__u16 *) (opcode+2)), location+1);				signal = math_emu_stfpc(opcode, regs);			} else if (opcode[1] == 0x9d) {				get_user(*((__u16 *) (opcode+2)), location+1);				signal = math_emu_lfpc(opcode, regs);			} else				signal = SIGILL;			break;		default:			signal = SIGILL;			break;                }        }#endif 	if (current->thread.fp_regs.fpc & FPC_DXC_MASK)		signal = SIGFPE;	else		signal = SIGILL;        if (signal == SIGFPE)		do_fp_trap(regs, location,                           current->thread.fp_regs.fpc, interruption_code);        else if (signal) {		siginfo_t info;		info.si_signo = signal;		info.si_errno = 0;		info.si_code = ILL_ILLOPN;		info.si_addr = location;		do_trap(interruption_code, signal, 			"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[0x10] = &do_segment_exception;        pgm_check_table[0x11] = &do_page_exception;        pgm_check_table[0x12] = &translation_exception;        pgm_check_table[0x13] = &special_op_exception; 	pgm_check_table[0x14] = &do_pseudo_page_fault;        pgm_check_table[0x15] = &operand_exception;        pgm_check_table[0x1C] = &privileged_op;#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");		/*		 * First try to get pfault pseudo page faults going.		 * If this isn't available turn on pagex page faults.		 */		if (pfault_init() != 0) {			/* Tough luck, no pfault. */			unregister_early_external_interrupt(0x2603,							    pfault_interrupt,							    &ext_int_pfault);			cpcmd("SET PAGEX ON", NULL, 0);		}	}#else	if (MACHINE_IS_VM)		cpcmd("SET PAGEX ON", NULL, 0);#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 + -