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

📄 sh-lite.patch

📁 Linux-2.6.18内核调试工具补丁程序KGDB。
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
--/* Is a thread alive? */-static void thread_status_msg(void)-{-	char *ptr;-	int threadid;-	struct task_struct *thread = NULL;--	ptr = &in_buffer[1];-	hex_to_int(&ptr, &threadid);-	thread = get_thread(threadid);-	if (thread)-		send_ok_msg();-	else-		send_err_msg();-}-/* Send the current thread ID */-static void thread_id_msg(void)-{-	int threadid;-	threadref thref;--	out_buffer[0] = 'Q';-	out_buffer[1] = 'C';--	if (current_thread)-		threadid = current_thread->pid;-	else if (trapped_thread)-		threadid = trapped_thread->pid;-	else /* Impossible, but just in case! */-	{-		send_err_msg();-		return;-	}--	/* Translate pid 0 to PID_MAX for gdb */-	if (threadid == 0) threadid = PID_MAX;--	int_to_threadref(&thref, threadid);-	pack_threadid(out_buffer + 2, &thref);-	out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0';-	put_packet(out_buffer);-}--/* Send thread info */-static void thread_info_msg(void)-{-	struct task_struct *thread = NULL;-	int threadid;-	char *pos;-	threadref thref;--	/* Start with 'm' */-	out_buffer[0] = 'm';-	pos = &out_buffer[1];--	/* For all possible thread IDs - this will overrun if > 44 threads! */-	/* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */-	for (threadid = 1; threadid <= PID_MAX; threadid++) {--		read_lock(&tasklist_lock);-		thread = get_thread(threadid);-		read_unlock(&tasklist_lock);--		/* If it's a valid thread */-		if (thread) {-			int_to_threadref(&thref, threadid);-			pack_threadid(pos, &thref);-			pos += BUF_THREAD_ID_SIZE;-			*pos++ = ',';-		}-	}-	*--pos = 0;		/* Lose final comma */-	put_packet(out_buffer);--}--/* Return printable info for gdb's 'info threads' command */-static void thread_extra_info_msg(void)-{-	int threadid;-	struct task_struct *thread = NULL;-	char buffer[20], *ptr;-	int i;--	/* Extract thread ID */-	ptr = &in_buffer[17];-	hex_to_int(&ptr, &threadid);-	thread = get_thread(threadid);--	/* If we don't recognise it, say so */-	if (thread == NULL)-		strcpy(buffer, "(unknown)");-	else-		strcpy(buffer, thread->comm);--	/* Construct packet */-	for (i = 0, ptr = out_buffer; buffer[i]; i++)-		ptr = pack_hex_byte(ptr, buffer[i]);--	if (thread->thread.pc == (unsigned long)ret_from_fork) {-		strcpy(buffer, "<new fork>");-		for (i = 0; buffer[i]; i++)-			ptr = pack_hex_byte(ptr, buffer[i]);-	}--	*ptr = '\0';-	put_packet(out_buffer);-}--/* Handle all qFooBarBaz messages - have to use an if statement as-   opposed to a switch because q messages can have > 1 char id. */-static void query_msg(void)-{-	const char *q_start = &in_buffer[1];--	/* qC = return current thread ID */-	if (strncmp(q_start, "C", 1) == 0)-		thread_id_msg();--	/* qfThreadInfo = query all threads (first) */-	else if (strncmp(q_start, "fThreadInfo", 11) == 0)-		thread_info_msg();--	/* qsThreadInfo = query all threads (subsequent). We know we have sent-	   them all after the qfThreadInfo message, so there are no to send */-	else if (strncmp(q_start, "sThreadInfo", 11) == 0)-		put_packet("l");	/* el = last */--	/* qThreadExtraInfo = supply printable information per thread */-	else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0)-		thread_extra_info_msg();--	/* Unsupported - empty message as per spec */-	else-		send_empty_msg();-}-#endif /* CONFIG_KGDB_THREAD */--/*- * Bring up the ports..- */-static int kgdb_serial_setup(void)-{-	extern int kgdb_console_setup(struct console *co, char *options);-	struct console dummy;--	kgdb_console_setup(&dummy, 0);--	return 0;-}--/* The command loop, read and act on requests */-static void kgdb_command_loop(const int excep_code, const int trapa_value)-{-	int sigval;--	if (excep_code == NMI_VEC) {-#ifndef CONFIG_KGDB_NMI-		KGDB_PRINTK("Ignoring unexpected NMI?\n");-		return;-#else /* CONFIG_KGDB_NMI */-		if (!kgdb_enabled) {-			kgdb_enabled = 1;-			kgdb_init();-		}-#endif /* CONFIG_KGDB_NMI */-	}--	/* Ignore if we're disabled */-	if (!kgdb_enabled)-		return;--#ifdef CONFIG_KGDB_THREAD-	/* Until GDB specifies a thread */-	current_thread = NULL;-	trapped_thread = current;-#endif--	/* Enter GDB mode (e.g. after detach) */-	if (!kgdb_in_gdb_mode) {-		/* Do serial setup, notify user, issue preemptive ack */-		kgdb_serial_setup();-		KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n",-			    (kgdb_porttype ? kgdb_porttype->name : ""),-			    kgdb_portnum, kgdb_baud);-		kgdb_in_gdb_mode = 1;-		put_debug_char('+');-	}--	/* Reply to host that an exception has occurred */-	sigval = compute_signal(excep_code);-	send_signal_msg(sigval);--	/* TRAP_VEC exception indicates a software trap inserted in place of-	   code by GDB so back up PC by one instruction, as this instruction-	   will later be replaced by its original one.  Do NOT do this for-	   trap 0xff, since that indicates a compiled-in breakpoint which-	   will not be replaced (and we would retake the trap forever) */-	if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) {-		trap_registers.pc -= 2;-	}--	/* Undo any stepping we may have done */-	undo_single_step();--	while (1) {--		out_buffer[0] = 0;-		get_packet(in_buffer, BUFMAX);--		/* Examine first char of buffer to see what we need to do */-		switch (in_buffer[0]) {--		case '?':	/* Send which signal we've received */-			send_signal_msg(sigval);-			break;--		case 'g':	/* Return the values of the CPU registers */-			send_regs_msg();-			break;--		case 'G':	/* Set the value of the CPU registers */-			set_regs_msg();-			break;--		case 'm':	/* Read LLLL bytes address AA..AA */-			read_mem_msg();-			break;--		case 'M':	/* Write LLLL bytes address AA..AA, ret OK */-			write_mem_msg(0);	/* 0 = data in hex */-			break;--		case 'X':	/* Write LLLL bytes esc bin address AA..AA */-			if (kgdb_bits == '8')-				write_mem_msg(1); /* 1 = data in binary */-			else-				send_empty_msg();-			break;--		case 'C':	/* Continue, signum included, we ignore it */-			continue_with_sig_msg();-			return;--		case 'c':	/* Continue at address AA..AA (optional) */-			continue_msg();-			return;--		case 'S':	/* Step, signum included, we ignore it */-			step_with_sig_msg();-			return;--		case 's':	/* Step one instruction from AA..AA */-			step_msg();-			return;--#ifdef CONFIG_KGDB_THREAD--		case 'H':	/* Task related */-			set_thread_msg();-			break;--		case 'T':	/* Query thread status */-			thread_status_msg();-			break;--		case 'q':	/* Handle query - currently thread-related */-			query_msg();-			break;-#endif--		case 'k':	/* 'Kill the program' with a kernel ? */-			break;--		case 'D':	/* Detach from program, send reply OK */-			kgdb_in_gdb_mode = 0;-			send_ok_msg();-			get_debug_char();-			return;--		default:-			send_empty_msg();-			break;-		}-	}-}--/* There has been an exception, most likely a breakpoint. */-void kgdb_handle_exception(struct pt_regs *regs)-{-	int excep_code, vbr_val;-	int count;-	int trapa_value = ctrl_inl(TRA);--	/* Copy kernel regs (from stack) */-	for (count = 0; count < 16; count++)-		trap_registers.regs[count] = regs->regs[count];-	trap_registers.pc = regs->pc;-	trap_registers.pr = regs->pr;-	trap_registers.sr = regs->sr;-	trap_registers.gbr = regs->gbr;-	trap_registers.mach = regs->mach;-	trap_registers.macl = regs->macl;--	asm("stc vbr, %0":"=r"(vbr_val));-	trap_registers.vbr = vbr_val;--	/* Get excode for command loop call, user access */-	asm("stc r2_bank, %0":"=r"(excep_code));-	kgdb_excode = excep_code;--	/* Other interesting environment items for reference */-	asm("stc r6_bank, %0":"=r"(kgdb_g_imask));-	kgdb_current = current;-	kgdb_trapa_val = trapa_value;--	/* Act on the exception */-	kgdb_command_loop(excep_code >> 5, trapa_value);--	kgdb_current = NULL;--	/* Copy back the (maybe modified) registers */-	for (count = 0; count < 16; count++)-		regs->regs[count] = trap_registers.regs[count];-	regs->pc = trap_registers.pc;-	regs->pr = trap_registers.pr;-	regs->sr = trap_registers.sr;-	regs->gbr = trap_registers.gbr;-	regs->mach = trap_registers.mach;-	regs->macl = trap_registers.macl;--	vbr_val = trap_registers.vbr;-	asm("ldc %0, vbr": :"r"(vbr_val));--	return;-}--/* Trigger a breakpoint by function */-void breakpoint(void)-{-	if (!kgdb_enabled) {-		kgdb_enabled = 1;-		kgdb_init();-	}-	BREAKPOINT();-}--/* Initialise the KGDB data structures and serial configuration */-int kgdb_init(void)-{-	if (!kgdb_enabled)-		return 1;--	in_nmi = 0;-	kgdb_nofault = 0;-	stepped_opcode = 0;-	kgdb_in_gdb_mode = 0;--	if (kgdb_serial_setup() != 0) {-		KGDB_PRINTK("serial setup error\n");-		return -1;-	}--	/* Init ptr to exception handler */-	kgdb_debug_hook = kgdb_handle_exception;-	kgdb_bus_err_hook = kgdb_handle_bus_error;--	/* Enter kgdb now if requested, or just report init done */-	if (kgdb_halt) {-		kgdb_in_gdb_mode = 1;-		put_debug_char('+');-		breakpoint();-	}-	else-	{-		KGDB_PRINTK("stub is initialized.\n");-	}--	return 0;-}--/* Make function available for "user messages"; console will use it too. */--char gdbmsgbuf[BUFMAX];-#define MAXOUT ((BUFMAX-2)/2)--static void kgdb_msg_write(const char *s, unsigned count)-{-	int i;-	int wcount;-	char *bufptr;--	/* 'O'utput */-	gdbmsgbuf[0] = 'O';--	/* Fill and send buffers... */-	while (count > 0) {-		bufptr = gdbmsgbuf + 1;--		/* Calculate how many this time */-		wcount = (count > MAXOUT) ? MAXOUT : count;-		-		/* Pack in hex chars */-		for (i = 0; i < wcount; i++)-			bufptr = pack_hex_byte(bufptr, s[i]);-		*bufptr = '\0';--		/* Move up */-		s += wcount;-		count -= wcount;--		/* Write packet */-		put_packet(gdbmsgbuf);-	}-}--static void kgdb_to_gdb(const char *s)-{-	kgdb_msg_write(s, strlen(s));-}--#ifdef CONFIG_SH_KGDB_CONSOLE-void kgdb_console_write(struct console *co, const char *s, unsigned count)-{-	/* Bail if we're not talking to GDB */-	if (!kgdb_in_gdb_mode)-		return;--	kgdb_msg_write(s, count);-}-#endifIndex: linux-2.6.16/arch/sh/kernel/kgdb.c===================================================================--- linux-2.6.16.orig/arch/sh/kernel/kgdb.c	2006-04-25 10:59:23.506518750 +0530+++ linux-2.6.16/arch/sh/kernel/kgdb.c	2006-04-25 11:34:01.000000000 +0530@@ -0,0 +1,363 @@+/*+ * arch/sh/kernel/kgdb.c+ *+ * Contains SH-specific low-level support for KGDB.+ *+ * Containes extracts from code by Glenn Engel, Jim Kingdon,+ * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,+ * Amit S. Kale <akale@veritas.com>,  William Gatliff <bgat@open-widgets.com>,+ * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>,+ * Henry Bell <henry.bell@st.com> and Jeremy Siegel <jsiegel@mvista.com>+ *+ * Maintainer: Tom Rini <trini@kernel.crashing.org>+ *+ * 2004 (c) MontaVista Software, Inc. This file is licensed under+ * the terms of the GNU General Public License version 2. This program+ * is licensed "as is" without any warranty of any kind, whether express+ * or implied.+ */++#include <linux/string.h>+#include <linux/kernel.h>+#include <linux/sched.h>+#include <linux/smp.h>+#include <linux/spinlock.h>+#include <linux/delay.h>+#include <linux/linkage.h>+#include <linux/init.h>+#include <linux/kgdb.h>++#include <asm/system.h>+#include <asm/current.h>+#include <asm/signal.h>+#include <asm/pgtable.h>+#include <asm/ptrace.h>++extern void per_cpu_trap_init(void);+extern atomic_t cpu_doing_single_step;++/* Function pointers for linkage */+static struct kgdb_regs trap_registers;++/* Globals. */+char in_nmi;			/* Set during NMI to prevent reentry */++/* TRA differs sh3/4 */+#if defined(CONFIG_CPU_SH3)+#define TRA 0xffffffd0+#elif defined(CONFIG_CPU_SH4)+#define TRA 0xff000020+#endif++/* Macros for single step instruction identification */+#define OPCODE_BT(op)         (((op) & 0xff00) == 0x8900)+#define OPCODE_BF(op)         (((op) & 0xff00) == 0x8b00)+#def

⌨️ 快捷键说明

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