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

📄 xmon.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		bp = new_breakpoint(a);		if (bp != NULL)			bp->enabled |= BP_TRAP;		break;	}}/* Very cheap human name for vector lookup. */staticconst char *getvecname(unsigned long vec){	char *ret;	switch (vec) {	case 0x100:	ret = "(System Reset)"; break;	case 0x200:	ret = "(Machine Check)"; break;	case 0x300:	ret = "(Data Access)"; break;	case 0x380:	ret = "(Data SLB Access)"; break;	case 0x400:	ret = "(Instruction Access)"; break;	case 0x480:	ret = "(Instruction SLB Access)"; break;	case 0x500:	ret = "(Hardware Interrupt)"; break;	case 0x600:	ret = "(Alignment)"; break;	case 0x700:	ret = "(Program Check)"; break;	case 0x800:	ret = "(FPU Unavailable)"; break;	case 0x900:	ret = "(Decrementer)"; break;	case 0xc00:	ret = "(System Call)"; break;	case 0xd00:	ret = "(Single Step)"; break;	case 0xf00:	ret = "(Performance Monitor)"; break;	case 0xf20:	ret = "(Altivec Unavailable)"; break;	case 0x1300:	ret = "(Instruction Breakpoint)"; break;	default: ret = "";	}	return ret;}static void get_function_bounds(unsigned long pc, unsigned long *startp,				unsigned long *endp){	unsigned long size, offset;	const char *name;	char *modname;	*startp = *endp = 0;	if (pc == 0)		return;	if (setjmp(bus_error_jmp) == 0) {		catch_memory_errors = 1;		sync();		name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);		if (name != NULL) {			*startp = pc - offset;			*endp = pc - offset + size;		}		sync();	}	catch_memory_errors = 0;}static int xmon_depth_to_print = 64;static void xmon_show_stack(unsigned long sp, unsigned long lr,			    unsigned long pc){	unsigned long ip;	unsigned long newsp;	unsigned long marker;	int count = 0;	struct pt_regs regs;	do {		if (sp < PAGE_OFFSET) {			if (sp != 0)				printf("SP (%lx) is in userspace\n", sp);			break;		}		if (!mread(sp + 16, &ip, sizeof(unsigned long))		    || !mread(sp, &newsp, sizeof(unsigned long))) {			printf("Couldn't read stack frame at %lx\n", sp);			break;		}		/*		 * For the first stack frame, try to work out if		 * LR and/or the saved LR value in the bottommost		 * stack frame are valid.		 */		if ((pc | lr) != 0) {			unsigned long fnstart, fnend;			unsigned long nextip;			int printip = 1;			get_function_bounds(pc, &fnstart, &fnend);			nextip = 0;			if (newsp > sp)				mread(newsp + 16, &nextip,				      sizeof(unsigned long));			if (lr == ip) {				if (lr < PAGE_OFFSET				    || (fnstart <= lr && lr < fnend))					printip = 0;			} else if (lr == nextip) {				printip = 0;			} else if (lr >= PAGE_OFFSET				   && !(fnstart <= lr && lr < fnend)) {				printf("[link register   ] ");				xmon_print_symbol(lr, " ", "\n");			}			if (printip) {				printf("[%.16lx] ", sp);				xmon_print_symbol(ip, " ", " (unreliable)\n");			}			pc = lr = 0;		} else {			printf("[%.16lx] ", sp);			xmon_print_symbol(ip, " ", "\n");		}		/* Look for "regshere" marker to see if this is		   an exception frame. */		if (mread(sp + 0x60, &marker, sizeof(unsigned long))		    && marker == 0x7265677368657265ul) {			if (mread(sp + 0x70, &regs, sizeof(regs))			    != sizeof(regs)) {				printf("Couldn't read registers at %lx\n",				       sp + 0x70);				break;			}                        printf("--- Exception: %lx %s at ", regs.trap,			       getvecname(TRAP(&regs)));			pc = regs.nip;			lr = regs.link;			xmon_print_symbol(pc, " ", "\n");		}		if (newsp == 0)			break;		sp = newsp;	} while (count++ < xmon_depth_to_print);}static void backtrace(struct pt_regs *excp){	unsigned long sp;	if (scanhex(&sp))		xmon_show_stack(sp, 0, 0);	else		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);	scannl();}void excprint(struct pt_regs *fp){	unsigned long trap;#ifdef CONFIG_SMP	printf("cpu 0x%x: ", smp_processor_id());#endif /* CONFIG_SMP */	trap = TRAP(fp);	printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);	printf("    pc: ");	xmon_print_symbol(fp->nip, ": ", "\n");	printf("    lr: ", fp->link);	xmon_print_symbol(fp->link, ": ", "\n");	printf("    sp: %lx\n", fp->gpr[1]);	printf("   msr: %lx\n", fp->msr);	if (trap == 0x300 || trap == 0x380 || trap == 0x600) {		printf("   dar: %lx\n", fp->dar);		if (trap != 0x380)			printf(" dsisr: %lx\n", fp->dsisr);	}	printf("  current = 0x%lx\n", current);	printf("  paca    = 0x%lx\n", get_paca());	if (current) {		printf("    pid   = %ld, comm = %s\n",		       current->pid, current->comm);	}}void prregs(struct pt_regs *fp){	int n;	unsigned long base;	struct pt_regs regs;	if (scanhex(&base)) {		if (setjmp(bus_error_jmp) == 0) {			catch_memory_errors = 1;			sync();			regs = *(struct pt_regs *)base;			sync();			__delay(200);		} else {			catch_memory_errors = 0;			printf("*** Error reading registers from %.16lx\n",			       base);			return;		}		catch_memory_errors = 0;		fp = &regs;	}	if (FULL_REGS(fp)) {		for (n = 0; n < 16; ++n)			printf("R%.2ld = %.16lx   R%.2ld = %.16lx\n",			       n, fp->gpr[n], n+16, fp->gpr[n+16]);	} else {		for (n = 0; n < 7; ++n)			printf("R%.2ld = %.16lx   R%.2ld = %.16lx\n",			       n, fp->gpr[n], n+7, fp->gpr[n+7]);	}	printf("pc  = ");	xmon_print_symbol(fp->nip, " ", "\n");	printf("lr  = ");	xmon_print_symbol(fp->link, " ", "\n");	printf("msr = %.16lx   cr  = %.8lx\n", fp->msr, fp->ccr);	printf("ctr = %.16lx   xer = %.16lx   trap = %8lx\n",	       fp->ctr, fp->xer, fp->trap);}void cacheflush(void){	int cmd;	unsigned long nflush;	cmd = inchar();	if (cmd != 'i')		termch = cmd;	scanhex((void *)&adrs);	if (termch != '\n')		termch = 0;	nflush = 1;	scanhex(&nflush);	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;	if (setjmp(bus_error_jmp) == 0) {		catch_memory_errors = 1;		sync();		if (cmd != 'i') {			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)				cflush((void *) adrs);		} else {			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)				cinval((void *) adrs);		}		sync();		/* wait a little while to see if we get a machine check */		__delay(200);	}	catch_memory_errors = 0;}unsigned longread_spr(int n){	unsigned int instrs[2];	unsigned long (*code)(void);	unsigned long opd[3];	unsigned long ret = -1UL;	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);	instrs[1] = 0x4e800020;	opd[0] = (unsigned long)instrs;	opd[1] = 0;	opd[2] = 0;	store_inst(instrs);	store_inst(instrs+1);	code = (unsigned long (*)(void)) opd;	ret = code();	return ret;}voidwrite_spr(int n, unsigned long val){	unsigned int instrs[2];	unsigned long (*code)(unsigned long);	unsigned long opd[3];	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);	instrs[1] = 0x4e800020;	opd[0] = (unsigned long)instrs;	opd[1] = 0;	opd[2] = 0;	store_inst(instrs);	store_inst(instrs+1);	code = (unsigned long (*)(unsigned long)) opd;	code(val);}static unsigned long regno;extern char exc_prolog;extern char dec_exc;voidsuper_regs(){	int cmd;	unsigned long val;#ifdef CONFIG_PPC_ISERIES	struct paca_struct *ptrPaca = NULL;	struct ItLpPaca *ptrLpPaca = NULL;	struct ItLpRegSave *ptrLpRegSave = NULL;#endif	cmd = skipbl();	if (cmd == '\n') {	        unsigned long sp, toc;		asm("mr %0,1" : "=r" (sp) :);		asm("mr %0,2" : "=r" (toc) :);		printf("msr  = %.16lx  sprg0= %.16lx\n", get_msr(), get_sprg0());		printf("pvr  = %.16lx  sprg1= %.16lx\n", get_pvr(), get_sprg1()); 		printf("dec  = %.16lx  sprg2= %.16lx\n", get_dec(), get_sprg2());		printf("sp   = %.16lx  sprg3= %.16lx\n", sp, get_sprg3());		printf("toc  = %.16lx  dar  = %.16lx\n", toc, get_dar());		printf("srr0 = %.16lx  srr1 = %.16lx\n", get_srr0(), get_srr1());#ifdef CONFIG_PPC_ISERIES		// Dump out relevant Paca data areas.		printf("Paca: \n");		ptrPaca = get_paca();    		printf("  Local Processor Control Area (LpPaca): \n");		ptrLpPaca = ptrPaca->lppaca_ptr;		printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",		       ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);		printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",		       ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);		printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5);    		printf("  Local Processor Register Save Area (LpRegSave): \n");		ptrLpRegSave = ptrPaca->reg_save_ptr;		printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx \n",		       ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);		printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx \n",		       ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);		printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx \n",		       ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);#endif		return;	}	scanhex(&regno);	switch (cmd) {	case 'w':		val = read_spr(regno);		scanhex(&val);		write_spr(regno, val);		/* fall through */	case 'r':		printf("spr %lx = %lx\n", regno, read_spr(regno));		break;	case 'm':		val = get_msr();		scanhex(&val);		set_msrd(val);		break;	}	scannl();}/* * Stuff for reading and writing memory safely */intmread(unsigned long adrs, void *buf, int size){	volatile int n;	char *p, *q;	n = 0;	if (setjmp(bus_error_jmp) == 0) {		catch_memory_errors = 1;		sync();		p = (char *)adrs;		q = (char *)buf;		switch (size) {		case 2:			*(short *)q = *(short *)p;			break;		case 4:			*(int *)q = *(int *)p;			break;		case 8:			*(long *)q = *(long *)p;			break;		default:			for( ; n < size; ++n) {				*q++ = *p++;				sync();			}		}		sync();		/* wait a little while to see if we get a machine check */		__delay(200);		n = size;	}	catch_memory_errors = 0;	return n;}intmwrite(unsigned long adrs, void *buf, int size){	volatile int n;	char *p, *q;	n = 0;	if (setjmp(bus_error_jmp) == 0) {		catch_memory_errors = 1;		sync();		p = (char *) adrs;		q = (char *) buf;		switch (size) {		case 2:			*(short *)p = *(short *)q;			break;		case 4:			*(int *)p = *(int *)q;			break;		case 8:			*(long *)p = *(long *)q;			break;		default:			for ( ; n < size; ++n) {				*p++ = *q++;				sync();			}		}		sync();		/* wait a little while to see if we get a machine check */		__delay(200);		n = size;	} else {		printf("*** Error writing address %x\n", adrs + n);	}	catch_memory_errors = 0;	return n;}static int fault_type;static char *fault_chars[] = { "--", "**", "##" };static inthandle_fault(struct pt_regs *regs){	switch (TRAP(regs)) {	case 0x200:		fault_type = 0;		break;	case 0x300:	case 0x380:		fault_type = 1;		break;	default:		fault_type = 2;	}	longjmp(bus_error_jmp, 1);	return 0;}#define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))voidbyterev(unsigned char *val, int size){	int t;		switch (size) {	case 2:		SWAP(val[0], val[1], t);		break;	case 4:		SWAP(val[0], val[3], t);		SWAP(val[1], val[2], t);		break;	case 8: /* is there really any use for this? */		SWAP(val[0], val[7], t);		SWAP(val[1], val[6], t);		SWAP(val[2], val[5], t);		SWAP(val[3], val[4], t);		break;	}}static int brev;static int mnoread;static char *memex_help_string =     "Memory examine command usage:\n"    "m [addr] [flags] examine/change memory\n"    "  addr is optional.  will start where left off.\n"    "  flags may include chars from this set:\n"    "    b   modify by bytes (default)\n"    "    w   modify by words (2 byte)\n"    "    l   modify by longs (4 byte)\n"    "    d   modify by doubleword (8 byte)\n"    "    r   toggle reverse byte order mode\n"    "    n   do not read memory (for i/o spaces)\n"    "    .   ok to read (default)\n"    "NOTE: flags are saved as defaults\n"    "";static char *memex_subcmd_help_string =     "Memory examine subcommands:\n"    "  hexval   write this val to current location\n"    "  'string' write chars from string to this location\n"    "  '        increment address\n"    "  ^        decrement address\n"    "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"    "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"    "  `        clear no-read flag\n"    "  ;        stay at this addr\n"    "  v        change to byte mode\n"    "  w        change to word (2 byte) mode\n"    "  l        change to long (4 byte) mode\n"    "  u        change to doubleword (8 byte) mode\n"    "  m addr   change current addr\n"    "  n        toggle no-read flag\n"    "  r        toggle byte reverse flag\n"    "  < count  back up count bytes\n"    "  > count  skip forward count bytes\n"    "  x        exit this mode\n"    "";voidmemex(){	int cmd, inc, i, nslash;	unsigned long n;	unsigned char val[16];	scanhex((void *)&adrs);	cmd = skipbl();	if (cmd == '?') {		printf(memex_help_string);		return;	} else {		termch = cmd;	}	last_cmd = "m\n";	while ((cmd = skipbl()) != '\n') {		switch( cmd ){		case 'b':	size = 1;	break;		case 'w':	size = 2;	break;		case 'l':	size = 4;	break;		case 'd':	size = 8;	break;		case 'r': 	brev = !brev;	break;		case 'n':	mnoread = 1;	break;		case '.':	mnoread = 0;	break;		}	}	if( size <= 0 )		size = 1;	else if( size > 8 )		size = 8;	for(;;){		if (!mnoread)			n = mread(adrs, val, size);		printf("%.16x%c", adrs, brev? 'r': ' ');		if (!mnoread) {			if (brev)				byterev(val, size);			putchar(' ');			for (i = 0; i < n; ++i)				printf("%.2x", val[i]);			for (; i < size; ++i)				printf("%s", fault_chars[fault_type]);		}		putchar(' ');		inc = size;		nslash = 0;		for(;;){			if( scanhex(&n) ){				for (i = 0; i < size; ++i)					val[i] = n >> (i * 8);				if (!brev)					byterev(val, size);				mwrite(adrs, val, size);				inc = size;			}			cmd = skipbl();			if (cmd == '\n')				break;			inc = 0;			switch (cmd) {			case '\'':				for(;;){					n = inchar();					if( n == '\\' )						n = bsesc();					else if( n == '\'' )						break;					for (i = 0; i < size; ++i)						val[i] = n >> (i * 8);					if (!brev)						byterev(val, size);					mwrite(adrs, val, size);					adrs += size;				}				adrs -= size;				inc = size;				break;			case ',':				adrs += size;				break;			case '.':				mnoread = 0;				break;			case ';':				break;			case 'x':			case EOF:				scannl();				return;			case 'b':			case 'v':				size = 1;				break;			case 'w':				size = 2;				break;			case 'l':				size = 4;				break;			case 'u':

⌨️ 快捷键说明

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