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

📄 mips-lite.patch

📁 Linux-2.6.18内核调试工具补丁程序KGDB。
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
-	unsigned char checksum;-	int count;-	unsigned char ch;--	/*-	 * $<packet info>#<checksum>.-	 */--	do {-		putDebugChar('$');-		checksum = 0;-		count = 0;--		while ((ch = buffer[count]) != 0) {-			if (!(putDebugChar(ch)))-				return;-			checksum += ch;-			count += 1;-		}--		putDebugChar('#');-		putDebugChar(hexchars[checksum >> 4]);-		putDebugChar(hexchars[checksum & 0xf]);--	}-	while ((getDebugChar() & 0x7f) != '+');-}---/*- * Convert the memory pointed to by mem into hex, placing result in buf.- * Return a pointer to the last char put in buf (null), in case of mem fault,- * return 0.- * may_fault is non-zero if we are reading from arbitrary memory, but is currently- * not used.- */-static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)-{-	unsigned char ch;--	while (count-- > 0) {-		if (kgdb_read_byte(mem++, &ch) != 0)-			return 0;-		*buf++ = hexchars[ch >> 4];-		*buf++ = hexchars[ch & 0xf];-	}--	*buf = 0;--	return buf;-}--/*- * convert the hex array pointed to by buf into binary to be placed in mem- * return a pointer to the character AFTER the last byte written- * may_fault is non-zero if we are reading from arbitrary memory, but is currently- * not used.- */-static char *hex2mem(char *buf, char *mem, int count, int binary, int may_fault)-{-	int i;-	unsigned char ch;--	for (i=0; i<count; i++)-	{-		if (binary) {-			ch = *buf++;-			if (ch == 0x7d)-				ch = 0x20 ^ *buf++;-		}-		else {-			ch = hex(*buf++) << 4;-			ch |= hex(*buf++);-		}-		if (kgdb_write_byte(ch, mem++) != 0)-			return 0;-	}--	return mem;-}--/*- * This table contains the mapping between SPARC hardware trap types, and- * signals, which are primarily what GDB understands.  It also indicates- * which hardware traps we need to commandeer when initializing the stub.- */-static struct hard_trap_info {-	unsigned char tt;		/* Trap type code for MIPS R3xxx and R4xxx */-	unsigned char signo;		/* Signal that we map this trap into */-} hard_trap_info[] = {-	{ 6, SIGBUS },			/* instruction bus error */-	{ 7, SIGBUS },			/* data bus error */-	{ 9, SIGTRAP },			/* break */-	{ 10, SIGILL },			/* reserved instruction */-/*	{ 11, SIGILL },		*/	/* CPU unusable */-	{ 12, SIGFPE },			/* overflow */-	{ 13, SIGTRAP },		/* trap */-	{ 14, SIGSEGV },		/* virtual instruction cache coherency */-	{ 15, SIGFPE },			/* floating point exception */-	{ 23, SIGSEGV },		/* watch */-	{ 31, SIGSEGV },		/* virtual data cache coherency */-	{ 0, 0}				/* Must be last */-};--/* Save the normal trap handlers for user-mode traps. */-void *saved_vectors[32];--/*- * Set up exception handlers for tracing and breakpoints- */-void set_debug_traps(void)-{-	struct hard_trap_info *ht;-	unsigned long flags;-	unsigned char c;--	local_irq_save(flags);-	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)-		saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low);--	putDebugChar('+'); /* 'hello world' */-	/*-	 * In case GDB is started before us, ack any packets-	 * (presumably "$?#xx") sitting there.-	 */-	while((c = getDebugChar()) != '$');-	while((c = getDebugChar()) != '#');-	c = getDebugChar(); /* eat first csum byte */-	c = getDebugChar(); /* eat second csum byte */-	putDebugChar('+'); /* ack it */--	initialized = 1;-	local_irq_restore(flags);-}--void restore_debug_traps(void)-{-	struct hard_trap_info *ht;-	unsigned long flags;--	local_irq_save(flags);-	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)-		set_except_vector(ht->tt, saved_vectors[ht->tt]);-	local_irq_restore(flags);-}--/*- * Convert the MIPS hardware trap type code to a Unix signal number.- */-static int computeSignal(int tt)-{-	struct hard_trap_info *ht;--	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)-		if (ht->tt == tt)-			return ht->signo;--	return SIGHUP;		/* default for things we don't know about */-}--/*- * While we find nice hex chars, build an int.- * Return number of chars processed.- */-static int hexToInt(char **ptr, int *intValue)-{-	int numChars = 0;-	int hexValue;--	*intValue = 0;--	while (**ptr) {-		hexValue = hex(**ptr);-		if (hexValue < 0)-			break;--		*intValue = (*intValue << 4) | hexValue;-		numChars ++;--		(*ptr)++;-	}--	return (numChars);-}--static int hexToLong(char **ptr, long *longValue)-{-	int numChars = 0;-	int hexValue;--	*longValue = 0;--	while (**ptr) {-		hexValue = hex(**ptr);-		if (hexValue < 0)-			break;--		*longValue = (*longValue << 4) | hexValue;-		numChars ++;--		(*ptr)++;-	}--	return numChars;-}---#if 0-/*- * Print registers (on target console)- * Used only to debug the stub...- */-void show_gdbregs(struct gdb_regs * regs)-{-	/*-	 * Saved main processor registers-	 */-	printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",-	       regs->reg0, regs->reg1, regs->reg2, regs->reg3,-               regs->reg4, regs->reg5, regs->reg6, regs->reg7);-	printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",-	       regs->reg8, regs->reg9, regs->reg10, regs->reg11,-               regs->reg12, regs->reg13, regs->reg14, regs->reg15);-	printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",-	       regs->reg16, regs->reg17, regs->reg18, regs->reg19,-               regs->reg20, regs->reg21, regs->reg22, regs->reg23);-	printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",-	       regs->reg24, regs->reg25, regs->reg26, regs->reg27,-	       regs->reg28, regs->reg29, regs->reg30, regs->reg31);--	/*-	 * Saved cp0 registers-	 */-	printk("epc  : %08lx\nStatus: %08lx\nCause : %08lx\n",-	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);-}-#endif /* dead code */--/*- * We single-step by setting breakpoints. When an exception- * is handled, we need to restore the instructions hoisted- * when the breakpoints were set.- *- * This is where we save the original instructions.- */-static struct gdb_bp_save {-	unsigned long addr;-	unsigned int val;-} step_bp[2];--#define BP 0x0000000d  /* break opcode */--/*- * Set breakpoint instructions for single stepping.- */-static void single_step(struct gdb_regs *regs)-{-	union mips_instruction insn;-	unsigned long targ;-	int is_branch, is_cond, i;--	targ = regs->cp0_epc;-	insn.word = *(unsigned int *)targ;-	is_branch = is_cond = 0;--	switch (insn.i_format.opcode) {-	/*-	 * jr and jalr are in r_format format.-	 */-	case spec_op:-		switch (insn.r_format.func) {-		case jalr_op:-		case jr_op:-			targ = *(&regs->reg0 + insn.r_format.rs);-			is_branch = 1;-			break;-		}-		break;--	/*-	 * This group contains:-	 * bltz_op, bgez_op, bltzl_op, bgezl_op,-	 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.-	 */-	case bcond_op:-		is_branch = is_cond = 1;-		targ += 4 + (insn.i_format.simmediate << 2);-		break;--	/*-	 * These are unconditional and in j_format.-	 */-	case jal_op:-	case j_op:-		is_branch = 1;-		targ += 4;-		targ >>= 28;-		targ <<= 28;-		targ |= (insn.j_format.target << 2);-		break;--	/*-	 * These are conditional.-	 */-	case beq_op:-	case beql_op:-	case bne_op:-	case bnel_op:-	case blez_op:-	case blezl_op:-	case bgtz_op:-	case bgtzl_op:-	case cop0_op:-	case cop1_op:-	case cop2_op:-	case cop1x_op:-		is_branch = is_cond = 1;-		targ += 4 + (insn.i_format.simmediate << 2);-		break;-	}--	if (is_branch) {-		i = 0;-		if (is_cond && targ != (regs->cp0_epc + 8)) {-			step_bp[i].addr = regs->cp0_epc + 8;-			step_bp[i++].val = *(unsigned *)(regs->cp0_epc + 8);-			*(unsigned *)(regs->cp0_epc + 8) = BP;-		}-		step_bp[i].addr = targ;-		step_bp[i].val  = *(unsigned *)targ;-		*(unsigned *)targ = BP;-	} else {-		step_bp[0].addr = regs->cp0_epc + 4;-		step_bp[0].val  = *(unsigned *)(regs->cp0_epc + 4);-		*(unsigned *)(regs->cp0_epc + 4) = BP;-	}-}--/*- *  If asynchronously interrupted by gdb, then we need to set a breakpoint- *  at the interrupted instruction so that we wind up stopped with a- *  reasonable stack frame.- */-static struct gdb_bp_save async_bp;--/*- * Swap the interrupted EPC with our asynchronous breakpoint routine.- * This is safer than stuffing the breakpoint in-place, since no cache- * flushes (or resulting smp_call_functions) are required.  The- * assumption is that only one CPU will be handling asynchronous bp's,- * and only one can be active at a time.- */-extern spinlock_t smp_call_lock;--void set_async_breakpoint(unsigned long *epc)-{-	/* skip breaking into userland */-	if ((*epc & 0x80000000) == 0)-		return;--#ifdef CONFIG_SMP-	/* avoid deadlock if someone is make IPC */-	if (spin_is_locked(&smp_call_lock))-		return;-#endif--	async_bp.addr = *epc;-	*epc = (unsigned long)async_breakpoint;-}--static void kgdb_wait(void *arg)-{-	unsigned flags;-	int cpu = smp_processor_id();--	local_irq_save(flags);--	__raw_spin_lock(&kgdb_cpulock[cpu]);-	__raw_spin_unlock(&kgdb_cpulock[cpu]);--	local_irq_restore(flags);-}---/*- * This function does all command processing for interfacing to gdb.  It- * returns 1 if you should skip the instruction at the trap address, 0- * otherwise.- */-void handle_exception (struct gdb_regs *regs)-{-	int trap;			/* Trap type */-	int sigval;-	long addr;-	int length;-	char *ptr;-	unsigned long *stack;-	int i;-	int bflag = 0;--	kgdb_started = 1;--	/*-	 * acquire the big kgdb spinlock-	 */-	if (!spin_trylock(&kgdb_lock)) {-		/*-		 * some other CPU has the lock, we should go back to-		 * receive the gdb_wait IPC-		 */-		return;-	}--	/*-	 * If we're in async_breakpoint(), restore the real EPC from-	 * the breakpoint.-	 */-	if (regs->cp0_epc == (unsigned long)async_breakinst) {-		regs->cp0_epc = async_bp.addr;-		async_bp.addr = 0;-	}--	/*-	 * acquire the CPU spinlocks-	 */-	for (i = num_online_cpus()-1; i >= 0; i--)-		if (__raw_spin_trylock(&kgdb_cpulock[i]) == 0)-			panic("kgdb: couldn't get cpulock %d\n", i);--	/*-	 * force other cpus to enter kgdb-	 */-	smp_call_function(kgdb_wait, NULL, 0, 0);--	/*-	 * If we're in breakpoint() increment the PC-	 */-	trap = (regs->cp0_cause & 0x7c) >> 2;-	if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)-		regs->cp0_epc += 4;--	/*-	 * If we were single_stepping, restore the opcodes hoisted-	 * for the breakpoint[s].-	 */-	if (step_bp[0].addr) {-		*(unsigned *)step_bp[0].addr = step_bp[0].val;-		step_bp[0].addr = 0;--		if (step_bp[1].addr) {-			*(unsigned *)step_bp[1].addr = step_bp[1].val;-			step_bp[1].addr = 0;-		}-	}--	stack = (long *)regs->reg29;			/* stack ptr */-	sigval = computeSignal(trap);--	/*-	 * reply to host that an exception has occurred-	 */-	ptr = output_buffer;--	/*-	 * Send trap type (converted to signal)-	 */-	*ptr++ = 'T';-	*ptr++ = hexchars[sigval >> 4];-	*ptr++ = hexchars[sigval & 0xf];--	/*-	 * Send Error PC-	 */-	*ptr++ = hexchars[REG_EPC >> 4];-	*ptr++ = hexchars[REG_EPC & 0xf];-	*ptr++ = ':';-	ptr = mem2hex((char *)&regs->cp0_epc, ptr, sizeof(long), 0);-	*ptr++ = ';';--	/*-	 * Send frame pointer-	 */-	*ptr++ = hexchars[REG_FP >> 4];-	*ptr++ = hexchars[REG_FP & 0xf];-	*ptr++ = ':';-	ptr = mem2hex((char *)&regs->reg30, ptr, sizeof(long), 0);-	*ptr++ = ';';--	/*-	 * Send stack pointer-	 */-	*ptr++ = hexchars[REG_SP >> 4];-	*ptr++ = hexchars[REG_SP & 0xf];-	*ptr++ = ':';-	ptr = mem2hex((char *)&regs->reg29, ptr, sizeof(long), 0);-	*ptr++ = ';';-

⌨️ 快捷键说明

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