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

📄 rtl-stub.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* for some reason, the mappings in reg.h are not *completely* correct.  That * is, they don't match up with the mappings in GDB.  For instance, EF_PC is * supposed to be the 64th integer in the gdb_regs array, not the 28th.  i * don't know how gdb possibly works with normal core files, but to get things * to work here, we are going to *ignore* asm-alpha/regs.h and go with what * gdb says. -Nathan */static void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs){	gdb_regs[EF_V0] = regs->r0;	/* return value */	gdb_regs[EF_T0] = regs->r1;	/* temporary registers 1-8 */	gdb_regs[EF_T1] = regs->r2;	gdb_regs[EF_T2] = regs->r3;	gdb_regs[EF_T3] = regs->r4;	gdb_regs[EF_T4] = regs->r5;	gdb_regs[EF_T5] = regs->r6;	gdb_regs[EF_T6] = regs->r7;	gdb_regs[EF_T7] = regs->r8;	gdb_regs[EF_S0] = 0;	/* saved regs 9-15; we don't deal */	/* with these */	gdb_regs[EF_S1] = 0;	gdb_regs[EF_S2] = 0;	gdb_regs[EF_S3] = 0;	gdb_regs[EF_S4] = 0;	gdb_regs[EF_S5] = 0;	gdb_regs[EF_S6] = 0;	gdb_regs[16] = regs->r16;	/* argument regs 16-21 */	gdb_regs[17] = regs->r17;	gdb_regs[18] = regs->r18;	gdb_regs[19] = regs->r19;	gdb_regs[20] = regs->r20;	gdb_regs[21] = regs->r21;	gdb_regs[22] = regs->r22;	/* temporary regs 22-25 */	gdb_regs[23] = regs->r23;	gdb_regs[24] = regs->r24;	gdb_regs[25] = regs->r25;	gdb_regs[26] = regs->r26;	/* return address */	gdb_regs[27] = regs->r27;	/* procedure value */	gdb_regs[28] = regs->r28;	/* assembler temp */	gdb_regs[30] = rdusp();	/* stack pointer */	gdb_regs[65] = regs->ps;	/* processor status */	gdb_regs[64] = regs->pc;	/* processor counter */	gdb_regs[EF_GP] = regs->gp;	/* global pointer */}				/* static void regs_to_gdb_regs(int *gdb_regs, struct pt_regs *regs) */static void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs){	regs->r0 = gdb_regs[EF_V0];	regs->r1 = gdb_regs[EF_T0];	regs->r2 = gdb_regs[EF_T1];	regs->r3 = gdb_regs[EF_T2];	regs->r4 = gdb_regs[EF_T3];	regs->r5 = gdb_regs[EF_T4];	regs->r6 = gdb_regs[EF_T5];	regs->r7 = gdb_regs[EF_T6];	regs->r8 = gdb_regs[EF_T7];	regs->r16 = gdb_regs[EF_A0];	regs->r17 = gdb_regs[EF_A1];	regs->r18 = gdb_regs[EF_A2];	regs->r19 = gdb_regs[EF_A3];	regs->r20 = gdb_regs[EF_A4];	regs->r21 = gdb_regs[EF_A5];	regs->r22 = gdb_regs[EF_T8];	regs->r23 = gdb_regs[EF_T9];	regs->r24 = gdb_regs[EF_T10];	regs->r25 = gdb_regs[EF_T11];	regs->r26 = gdb_regs[EF_RA];	regs->r27 = gdb_regs[EF_T12];	regs->r28 = gdb_regs[EF_AT];	regs->ps = gdb_regs[EF_PS];	regs->pc = gdb_regs[EF_PC];	regs->gp = gdb_regs[EF_GP];}				/* static void gdb_regs_to_regs(int *gdb_regs, struct pt_regs *regs) */static int handle_exception(int exceptionVector,			    int signo, struct pt_regs *regs){	long addr, length, newPC;	unsigned long flags;	char *ptr;	unsigned long gdb_regs[NUMREGS];#ifdef CONFIG_RTL_DEBUGGER_THREADS	pthread_t current_thread = pthread_self();#endif				/* CONFIG_RTL_DEBUGGER_THREADS */	rtl_hard_savef_and_cli(flags);	if (user_mode(regs) && !(rtl_is_psc_active())) {		rtl_printf("rtl_debug: got a user-mode exception\n");		return 0;	}	memset(gdb_regs, 0, NUMREGBYTES);	if (remote_debug)		show_regs(regs);	if ((exceptionVector == 6) && (mem_err_expected == 1)) {		mem_err = 1;	/* set mem error flag */		mem_err_expected = 0;		conpr("mem2hex() croaked\n");		if (remote_debug)			conpr("Return after memory error\n");		if (remote_debug)			show_regs(regs);		rtl_hard_restore_flags(flags);		return (1);	}	if (rtl_running_linux()) {		rtl_hard_restore_flags(flags);		rtl_printf("rtl_debug: not our fault; Linux's\n");		return 0;	/* let Linux handle it's own faults */	}	/* ok, here we know pthread_self() is an RT-thread */	pthread_cleanup_push(&rtl_exit_debugger, 0);	rtl_enter_debugger(exceptionVector, (void *) regs->pc);	/* reply to host that an exception has occurred */	set_bit(0, &send_exception_info);	while (1) {		error = 0;		remcomOutBuffer[0] = 0;		if (test_and_clear_bit(0, &send_exception_info)) {			strcpy(remcomInBuffer, "?");		} else {			getpacket(remcomInBuffer);/*conpr("getpacket: ");conpr(remcomInBuffer);conpr("\n");*/		}		switch (remcomInBuffer[0]) {		case 'q':			if (!strcmp(remcomInBuffer, "qOffsets") && text			    && data && bss) {				sprintf(remcomOutBuffer,					"Text=%x;Data=%x;Bss=%x",					(unsigned) text, (unsigned) data,					(unsigned) bss);			}#ifdef CONFIG_RTL_DEBUGGER_THREADS			if (!strcmp(remcomInBuffer, "qC")) {				sprintf(remcomOutBuffer, "QC%x",					(unsigned long) (pthread_self()));			} else if (!strncmp(remcomInBuffer, "qL", 2)) {				/* we assume we have a limit of 31 threads -- 				 * to fit in one packet */				char packethead[17];				pthread_t task;				int ntasks = 0;				int i;				strcpy(remcomOutBuffer, remcomInBuffer);				for (i = 0; i < rtl_num_cpus(); i++) {					int cpu_id = cpu_logical_map(i);					schedule_t *s = &rtl_sched[cpu_id];					spin_lock(&s->rtl_tasks_lock);					task = s->rtl_tasks;					while (task != &s->rtl_linux_task					       && ntasks < 31) {						sprintf((remcomOutBuffer) +							strlen							(remcomOutBuffer),							"00000000%08x",							(unsigned long)							task);						task = task->next;						ntasks++;					}					spin_unlock(&s->rtl_tasks_lock);				}				sprintf(packethead, "qM%02x%01x", ntasks,					1 /* done */ );				memcpy(remcomOutBuffer, packethead,				       strlen(packethead));			}#endif				/* CONFIG_RTL_DEBUGGER_THREADS */			break;#ifdef CONFIG_RTL_DEBUGGER_THREADS		case 'H':			if (	/* remcomInBuffer[1] == 'c' || */				   remcomInBuffer[1] == 'g') {				if (remcomInBuffer[2] == '-') {					current_thread =					    (pthread_t) -					    strtoul(remcomInBuffer + 3, 0,						    16);				} else {					current_thread = (pthread_t)					    strtoul(remcomInBuffer + 2, 0,						    16);				}				debugpr("Hc/g: %x",					(unsigned long) current_thread);				strcpy(remcomOutBuffer, "OK");			}			break;		case 'T':{				pthread_t thread;				if (remcomInBuffer[1] == '-') {					thread =					    (pthread_t) -					    strtoul(remcomInBuffer + 2, 0,						    16);				} else {					thread = (pthread_t)					    strtoul(remcomInBuffer + 1, 0,						    16);				}				if (!pthread_kill(thread, 0)) {					strcpy(remcomOutBuffer, "OK");				} else {					strcpy(remcomOutBuffer, "ERROR");				}			}			break;#endif				/* CONFIG_RTL_DEBUGGER_THREADS */#ifdef CONFIG_RTL_DEBUGGER_Z_PROTOCOL		case 'Z':		case 'z':			{				int type = remcomInBuffer[1] - '0';				long address =				    strtoul(remcomInBuffer + 3, 0, 16);				int res;				if (type != 0) {					strcpy(remcomOutBuffer, "ERROR");					break;				}				spin_lock(&bp_lock);				if (remcomInBuffer[0] == 'Z') {					res = insert_bp((char *) address);				} else {					remove_bp((char *) address);					res = 0;				}				spin_unlock(&bp_lock);				if (res) {					strcpy(remcomOutBuffer, "ERROR");				} else {					strcpy(remcomOutBuffer, "OK");				}			}			break;#endif				/* CONFIG_RTL_DEBUGGER_Z_PROTOCOL */		case '?':#ifdef CONFIG_RTL_DEBUGGER_THREADS			sprintf(remcomOutBuffer, "T%02xthread:%x;", signo,				(unsigned long) pthread_self());#else			remcomOutBuffer[0] = 'S';			remcomOutBuffer[1] = hexchars[signo >> 4];			remcomOutBuffer[2] = hexchars[signo % 16];			remcomOutBuffer[3] = 0;#endif				/* CONFIG_RTL_DEBUGGER_THREADS */			break;		case 'd':			remote_debug = !(remote_debug);	/* toggle debug flag */			printk("Remote debug %s\n",			       remote_debug ? "on" : "off");			break;		case 'g':	/* return the value of the CPU registers */			regs_to_gdb_regs(gdb_regs, regs);#ifdef CONFIG_RTL_DEBUGGER_THREADS			if (current_thread != pthread_self()) {				gdb_regs[EF_SP] =				    (long) current_thread->stack;				gdb_regs[EF_PC] = *(current_thread->stack);				rtl_printf("*(current_thread->stack: %x\n",					   (current_thread->stack));				debugpr("reg read for %x",					(unsigned long) current_thread);			}#endif				/* CONFIG_RTL_DEBUGGER_THREADS */			mem2hex((char *) gdb_regs, remcomOutBuffer,				NUMREGBYTES);			break;		case 'G':	/* set the value of the CPU registers - return OK */			hex2mem(&remcomInBuffer[1], (char *) gdb_regs,				NUMREGBYTES);			gdb_regs_to_regs(gdb_regs, regs);			strcpy(remcomOutBuffer, "OK");			break;			/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */		case 'm':			/* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */			ptr = &remcomInBuffer[1];			if (hexToInt(&ptr, &addr))				if (*(ptr++) == ',')					if (hexToInt(&ptr, &length)) {						ptr = 0;						if (!mem2hex						    ((char *) addr,						     remcomOutBuffer,						     length)) {							strcpy							    (remcomOutBuffer,							     "E03");							debug_error							    ("memory fault\n",							     NULL);						}					}			if (ptr) {				strcpy(remcomOutBuffer, "E01");				debug_error				    ("malformed read memory command: %s\n",				     remcomInBuffer);			}			break;			/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */		case 'M':			/* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */			ptr = &remcomInBuffer[1];			if (hexToInt(&ptr, &addr))				if (*(ptr++) == ',')					if (hexToInt(&ptr, &length))						if (*(ptr++) == ':') {							if (!hex2mem							    (ptr,							     (char *) addr,							     length)) {								strcpy								    (remcomOutBuffer,								     "E03");								debug_error								    ("memory fault\n",								     NULL);							} else {								strcpy								    (remcomOutBuffer,								     "OK");							}							ptr = 0;						}			if (ptr) {				strcpy(remcomOutBuffer, "E02");				debug_error				    ("malformed write memory command: %s\n",				     remcomInBuffer);			}			break;			/* cAA..AA    Continue at address AA..AA(optional) */			/* sAA..AA   Step one instruction from AA..AA(optional) */		case 'c':		case 's':			/* try to read optional parameter, pc unchanged if no 			 * parm */			ptr = &remcomInBuffer[1];			if (hexToInt(&ptr, &addr)) {				if (remote_debug)					printk("Changing EF_PC to 0x%x\n",					       addr);				regs->pc = addr;			}			newPC = regs->pc;			/* clear the trace bit */#if 0			/* XXX don't know how to do these yet. -Nathan			   regs->ps &= 0xfffffeff; */			/* set the trace bit if we're stepping */			if (remcomInBuffer[0] == 's')				regs.eflags |= 0x100;#endif				/* 0 */			if (remote_debug) {				printk("Resuming execution\n");				show_regs(regs);			}			debugpr("cont\n");			goto cleanup;			/* kill the program */		case 'k':			goto cleanup;		}		/* switch *//*conpr("putpacket: ");conpr(remcomOutBuffer);conpr("\n");*/		/* reply to the request */		putpacket(remcomOutBuffer);	}			/* while (1) */      cleanup:pthread_cleanup_pop(1);	rtl_hard_restore_flags(flags);	return (1);#undef regs}/* we don't have a hard_trap_info struct and we have to use this gigantic * switch statement because of the special case of generic traps.  This also * means that we have to pass across the registers so that we can get the * value from r16 to determine which generic trap it is. */static int computeSignal(unsigned int tt, struct pt_regs *regs){	switch (tt) {	case 0:		/* breakpoint */	case 1:		/* bugcheck */		return SIGTRAP;	case 2:		/* gentrap */		switch ((long) regs->r16) {		case GEN_INTOVF:		case GEN_INTDIV:		case GEN_FLTOVF:		case GEN_FLTDIV:		case GEN_FLTUND:		case GEN_FLTINV:		case GEN_FLTINE:		case GEN_ROPRAND:			return SIGFPE;		case GEN_DECOVF:		case GEN_DECDIV:		case GEN_DECINV:		case GEN_ASSERTERR:		case GEN_NULPTRERR:		case GEN_STKOVF:		case GEN_STRLENERR:		case GEN_SUBSTRERR:		case GEN_RANGERR:		case GEN_SUBRNG:		case GEN_SUBRNG1:		case GEN_SUBRNG2:		case GEN_SUBRNG3:		case GEN_SUBRNG4:		case GEN_SUBRNG5:		case GEN_SUBRNG6:		case GEN_SUBRNG7:			return SIGTRAP;		}		/* switch ((long) regs->r16) */	case 3:		/* FEN fault */		return SIGILL;	case 4:		/* opDEC */		return SIGILL;	}			/* switch (tt) */	/* don't know what signal to return?  SIGHUP to the rescue! */	return SIGHUP;}int rtl_debug_exception(int vector, struct pt_regs *regs){	int signo = computeSignal(vector, regs);	return handle_exception(vector, signo, regs);}

⌨️ 快捷键说明

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