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

📄 sigbus.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic char *sccsid = "@(#)sigbus.c	4.1	(ULTRIX)	7/3/90";#endif not lint/* ------------------------------------------------------------------ *//* | Copyright Unpublished, MIPS Computer Systems, Inc.  All Rights | *//* | Reserved.  This software contains proprietary and confidential | *//* | information of MIPS and its suppliers.  Use, disclosure or     | *//* | reproduction is prohibited without the prior express written   | *//* | consent of MIPS.                                               | *//* ------------------------------------------------------------------ *//* $Header: sigbus.c,v 1.2 87/08/20 14:44:09 dce Exp $ */#include <sys/param.h>#if defined(BSD) || defined(ultrix)#include <mips/cpu.h>#include <mips/fpu.h>#include <mips/inst.h>#else#include <sys/sbd.h>#include <sys/fpu.h>#include <sys/inst.h>#endif#include <signal.h>#include <stdio.h>#define BYTE_ALIGNED_LH 0#define BYTE_ALIGNED_SH 1#define HALF_ALIGNED_LW 2#define HALF_ALIGNED_SW 3#define BYTE_ALIGNED_LW 4#define BYTE_ALIGNED_SW 5#define HALF_ALIGNED_LWC1 6#define HALF_ALIGNED_SWC1 7#define BYTE_ALIGNED_LWC1 8#define BYTE_ALIGNED_SWC1 9#define NUNALIGNED 10static unsigned sigbus_counts[NUNALIGNED];static char *sigbus_count_names[NUNALIGNED] = {	"byte aligned lh",	"byte aligned sh",	"half aligned lw",	"half aligned sw",	"byte aligned lw",	"byte aligned sw",	"half aligned lwc1",	"half aligned swc1",	"byte aligned lwc1",	"byte aligned swc1"};#define PCTSIZE 8192#define PCTMASK (PCTSIZE-1)static struct {    unsigned pc, count;} pctable[PCTSIZE];static pctable_entries;static voidsigbus (sig, code, scp)    register int sig, code;    register struct sigcontext *scp;{    union mips_instruction cpu_instr;    unsigned long branch_instr;    register long addr;    register unsigned h;        h = scp->sc_pc & PCTMASK;        while (1) {	    if (pctable[h].pc == scp->sc_pc || pctable[h].pc == 0) break;	    h = (h + 1) & PCTMASK;	}	if (pctable[h].pc != 0 || ++pctable_entries <= PCTSIZE*3/4) {	    pctable[h].pc = scp->sc_pc;	    pctable[h].count += 1;	}	/*	 * If the instruction was in a branch delay slot	 * then emulate the branch to determine the target pc to return to.	 * Else the target pc to return to is just address of the next	 * instruction.	 */	if (scp->sc_cause & CAUSE_BD){	    branch_instr = *(unsigned long *)(scp->sc_pc);	    cpu_instr.word = *(unsigned long *)(scp->sc_pc + 4);	    if (emulate_branch(scp, branch_instr) != 0){		fprintf(stderr, "sigbus(): Error: Can't emulate branch instruction: 0x%x at: 0x%x\n", branch_instr, scp->sc_pc);		exit(1);	    }	}	else{	    cpu_instr.word = *(unsigned long *)(scp->sc_pc);	    scp->sc_pc += sizeof(unsigned long);	}	addr = scp->sc_regs[cpu_instr.i_format.rs] +	       cpu_instr.i_format.simmediate;	switch (cpu_instr.r_format.opcode){	case lw_op:	    if ((addr & 1) != 0) {		sigbus_counts[BYTE_ALIGNED_LW] += 1;	    }	    else {		sigbus_counts[HALF_ALIGNED_LW] += 1;	    }	    scp->sc_regs[cpu_instr.i_format.rt] = unaligned_load_word(addr);	    break;	case lwc1_op:	    if ((addr & 1) != 0) {		sigbus_counts[BYTE_ALIGNED_LWC1] += 1;	    }	    else {		sigbus_counts[HALF_ALIGNED_LWC1] += 1;	    }	    scp->sc_fpregs[cpu_instr.i_format.rt] = unaligned_load_word(addr);	    break;	case lh_op:	    sigbus_counts[BYTE_ALIGNED_LH] += 1;	    scp->sc_regs[cpu_instr.i_format.rt] = unaligned_load_half(addr);	    break;	case lhu_op:	    sigbus_counts[BYTE_ALIGNED_LH] += 1;	    scp->sc_regs[cpu_instr.i_format.rt] = unaligned_load_uhalf(addr);	    break;	case sw_op:	    if ((addr & 1) != 0) {		sigbus_counts[BYTE_ALIGNED_SW] += 1;	    }	    else {		sigbus_counts[HALF_ALIGNED_SW] += 1;	    }	    unaligned_store_word(addr, scp->sc_regs[cpu_instr.i_format.rt]);	    break;	case swc1_op:	    if ((addr & 1) != 0) {		sigbus_counts[BYTE_ALIGNED_SWC1] += 1;	    }	    else {		sigbus_counts[HALF_ALIGNED_SWC1] += 1;	    }	    unaligned_store_word(addr, scp->sc_fpregs[cpu_instr.i_format.rt]);	    break;	case sh_op:	    sigbus_counts[BYTE_ALIGNED_SH] += 1;	    unaligned_store_half(addr, scp->sc_regs[cpu_instr.i_format.rt]);	    break;	default:	    fprintf(stderr, "sigbus(): non-load/store instruction. Exiting\n");	    exit(1);	}	sigreturn(scp);}void print_unaligned_summary();voidprint_unaligned_summary_(){	print_unaligned_summary();}voidprint_unaligned_summary(){    register unsigned i, n, t, c;    register int j;    fprintf (stderr, " ##############################################\n");    fprintf (stderr, " #         unaligned reference summary        #\n");    t = 0;    for (i = 0; i != NUNALIGNED; i += 1) t += sigbus_counts[i];    for (i = 0; i != NUNALIGNED; i += 1) {	if (sigbus_counts[i] != 0) {	    fprintf (stderr, " # %-17s %10u %5.1f%%        #\n",		     sigbus_count_names[i],		     sigbus_counts[i],		     (double)sigbus_counts[i]/(double)t*100.0);	}    }    /* insertion sort pc table */    n = 0;    t = 0;    for (i = 0; i != PCTSIZE; i += 1) {	register unsigned pc = pctable[i].pc;	register unsigned count = pctable[i].count;	if (pc != 0) {	    for (j = n-1; j >= 0 && pctable[j].count < count; j -= 1) {		pctable[j+1].pc = pctable[j].pc;		pctable[j+1].count = pctable[j].count;	    }	    pctable[j+1].pc = pc;	    pctable[j+1].count = count;	    n += 1;	    t += count;	}    }    c = 0;    for (i = 0; i != n; i += 1) {	c += pctable[i].count;	fprintf (stderr, " # 0x%.8x/i      %10u %5.1f%% %5.1f%% #\n",		 pctable[i].pc,		 pctable[i].count,		 (double)pctable[i].count/(double)t*100.0,		 (double)c/(double)t*100.0);    }    fprintf (stderr, " ##############################################\n");}void handle_unaligned_traps();voidhandle_unaligned_traps_(){	handle_unaligned_traps();}voidhandle_unaligned_traps(){#ifdef BSD    signal(SIGBUS, sigbus);#endif#ifdef SYSV    sigset(SIGBUS, sigbus);#endif}

⌨️ 快捷键说明

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